All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
To: davem@davemloft.net
Cc: Jacob Keller <jacob.e.keller@intel.com>,
	netdev@vger.kernel.org, nhorman@redhat.com, sassmann@redhat.com,
	jogreene@redhat.com, guru.anbalagane@oracle.com,
	Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Subject: [net-next 11/22] i40e: avoid looping to check whether we're in VLAN mode
Date: Mon, 31 Oct 2016 15:29:41 -0700	[thread overview]
Message-ID: <1477952992-125662-12-git-send-email-jeffrey.t.kirsher@intel.com> (raw)
In-Reply-To: <1477952992-125662-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Jacob Keller <jacob.e.keller@intel.com>

We determine that a VSI is in vlan_mode whenever it has any filters
with a VLAN other than -1 (I40E_VLAN_ALL). The previous method of doing
so was to perform a loop whenever we needed the check. However, we can
notice that only place where filters are added (i40e_add_filter) can
change the condition from false to true, and the only place we can
return to false is in i40e_vsi_sync_filters_subtask. Thus, we can remove
the loop and use a boolean directly.

Doing this avoids looping over filters repeatedly especially while we're
already inside a loop over all the filters. This should reduce the
latency of filter operations throughout the driver.

Change-ID: Iafde08df588da2a2ea666997d05e11fad8edc338
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e.h      |  1 +
 drivers/net/ethernet/intel/i40e/i40e_main.c | 48 ++++++++++++++++++++++-------
 2 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index 6545550..60dbb5b 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -517,6 +517,7 @@ struct i40e_vsi {
 	spinlock_t mac_filter_hash_lock;
 	/* Fixed size hash table with 2^8 buckets for MAC filters */
 	DECLARE_HASHTABLE(mac_filter_hash, 8);
+	bool has_vlan_filter;
 
 	/* VSI stats */
 	struct rtnl_link_stats64 net_stats;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 6cf9089..b4529b5 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -1198,19 +1198,31 @@ struct i40e_mac_filter *i40e_find_mac(struct i40e_vsi *vsi, const u8 *macaddr)
  **/
 bool i40e_is_vsi_in_vlan(struct i40e_vsi *vsi)
 {
-	struct i40e_mac_filter *f;
-	struct hlist_node *h;
-	int bkt;
+	/* If we have a PVID, always operate in VLAN mode */
+	if (vsi->info.pvid)
+		return true;
 
-	/* Only -1 for all the filters denotes not in vlan mode
-	 * so we have to go through all the list in order to make sure
+	/* We need to operate in VLAN mode whenever we have any filters with
+	 * a VLAN other than I40E_VLAN_ALL. We could check the table each
+	 * time, incurring search cost repeatedly. However, we can notice two
+	 * things:
+	 *
+	 * 1) the only place where we can gain a VLAN filter is in
+	 *    i40e_add_filter.
+	 *
+	 * 2) the only place where filters are actually removed is in
+	 *    i40e_vsi_sync_filters_subtask.
+	 *
+	 * Thus, we can simply use a boolean value, has_vlan_filters which we
+	 * will set to true when we add a VLAN filter in i40e_add_filter. Then
+	 * we have to perform the full search after deleting filters in
+	 * i40e_vsi_sync_filters_subtask, but we already have to search
+	 * filters here and can perform the check at the same time. This
+	 * results in avoiding embedding a loop for VLAN mode inside another
+	 * loop over all the filters, and should maintain correctness as noted
+	 * above.
 	 */
-	hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
-		if (f->vlan >= 0 || vsi->info.pvid)
-			return true;
-	}
-
-	return false;
+	return vsi->has_vlan_filter;
 }
 
 /**
@@ -1246,6 +1258,12 @@ struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,
 		if (!f)
 			return NULL;
 
+		/* Update the boolean indicating if we need to function in
+		 * VLAN mode.
+		 */
+		if (vlan >= 0)
+			vsi->has_vlan_filter = true;
+
 		ether_addr_copy(f->macaddr, macaddr);
 		f->vlan = vlan;
 		/* If we're in overflow promisc mode, set the state directly
@@ -1979,6 +1997,14 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
 		del_list = NULL;
 	}
 
+	/* After finishing notifying firmware of the deleted filters, update
+	 * the cached value of vsi->has_vlan_filter. Note that we are safe to
+	 * use just !!vlan_filters here because if we only have VLAN=0 (that
+	 * is, non_vlan_filters) these will all be converted to VLAN=-1 in the
+	 * logic above already so this value would still be correct.
+	 */
+	vsi->has_vlan_filter = !!vlan_filters;
+
 	if (!hlist_empty(&tmp_add_list)) {
 		/* Do all the adds now. */
 		filter_list_len = hw->aq.asq_buf_size /
-- 
2.7.4

  parent reply	other threads:[~2016-10-31 22:29 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-31 22:29 [net-next 00/22][pull request] 40GbE Intel Wired LAN Driver Updates 2016-10-31 Jeff Kirsher
2016-10-31 22:29 ` [net-next 01/22] i40e: Add missing \n to end of dev_err message Jeff Kirsher
2016-10-31 22:29 ` [net-next 02/22] i40e: drop is_vf and is_netdev fields in struct i40e_mac_filter Jeff Kirsher
2016-10-31 22:29 ` [net-next 03/22] i40e: make use of __dev_uc_sync and __dev_mc_sync Jeff Kirsher
2016-10-31 22:29 ` [net-next 04/22] i40e: move i40e_put_mac_in_vlan and i40e_del_mac_all_vlan Jeff Kirsher
2016-10-31 22:29 ` [net-next 05/22] i40e: refactor i40e_put_mac_in_vlan to avoid changing f->vlan Jeff Kirsher
2016-10-31 22:29 ` [net-next 06/22] i40e: When searching all MAC/VLAN filters, ignore removed filters Jeff Kirsher
2016-10-31 22:29 ` [net-next 07/22] i40e: implement __i40e_del_filter and use where applicable Jeff Kirsher
2016-10-31 22:29 ` [net-next 08/22] i40e: store MAC/VLAN filters in a hash with the MAC Address as key Jeff Kirsher
2016-10-31 22:29 ` [net-next 09/22] i40e: properly cleanup on allocation failure in i40e_sync_vsi_filters Jeff Kirsher
2016-10-31 22:29 ` [net-next 10/22] i40e: fix MAC filters when removing VLANs Jeff Kirsher
2016-10-31 22:29 ` Jeff Kirsher [this message]
2016-10-31 22:29 ` [net-next 12/22] i40e: remove duplicate add/delete adminq command code for filters Jeff Kirsher
2016-10-31 22:29 ` [net-next 13/22] i40e: correct check for reading TSYNINDX from the receive descriptor Jeff Kirsher
2016-10-31 22:29 ` [net-next 14/22] i40e: use a mutex instead of spinlock in PTP user entry points Jeff Kirsher
2016-10-31 22:29 ` [net-next 15/22] i40e: replace PTP Rx timestamp hang logic Jeff Kirsher
2016-10-31 22:29 ` [net-next 16/22] i40evf: avoid an extra msleep while Jeff Kirsher
2016-10-31 22:29 ` [net-next 17/22] i40e: Add common function for finding VSI by type Jeff Kirsher
2016-10-31 22:29 ` [net-next 18/22] i40e: Reorder logic for coalescing RS bits Jeff Kirsher
2016-10-31 22:29 ` [net-next 19/22] i40e: clear mac filter count on reset Jeff Kirsher
2016-10-31 22:29 ` [net-next 20/22] i40e: Fix for division by zero Jeff Kirsher
2016-10-31 22:29 ` [net-next 21/22] i40e: Implementation of ERROR state for NVM update state machine Jeff Kirsher
2016-10-31 22:29 ` [net-next 22/22] i40e: removed unreachable code Jeff Kirsher
2016-11-01 14:59 ` [net-next 00/22][pull request] 40GbE Intel Wired LAN Driver Updates 2016-10-31 David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1477952992-125662-12-git-send-email-jeffrey.t.kirsher@intel.com \
    --to=jeffrey.t.kirsher@intel.com \
    --cc=davem@davemloft.net \
    --cc=guru.anbalagane@oracle.com \
    --cc=jacob.e.keller@intel.com \
    --cc=jogreene@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=nhorman@redhat.com \
    --cc=sassmann@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.