All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andre Guedes <andre.guedes@intel.com>
To: intel-wired-lan@osuosl.org
Subject: [Intel-wired-lan] [PATCH 13/19] igc: Fix NFC rules restoration
Date: Fri, 24 Apr 2020 13:16:17 -0700	[thread overview]
Message-ID: <20200424201623.10971-14-andre.guedes@intel.com> (raw)
In-Reply-To: <20200424201623.10971-1-andre.guedes@intel.com>

When network interface is brought up, the driver re-enables the NFC
rules previously configured. However, this is done in reverse order
the rules were added and hardware filters are configured differently.

For example, consider the following rules:

$ ethtool -N eth0 flow-type ether dst 00:00:00:00:00:AA queue 0
$ ethtool -N eth0 flow-type ether dst 00:00:00:00:00:BB queue 1
$ ethtool -N eth0 flow-type ether dst 00:00:00:00:00:CC queue 2
$ ethtool -N eth0 flow-type ether dst 00:00:00:00:00:DD queue 3

RAL/RAH registers are configure so filter index 1 has address ending
with AA, filter index 2 has address ending in BB, and so on.

If we bring the interface down and up again, RAL/RAH registers are
configured so filter index 1 has address ending in DD, filter index 2
has CC, and so on. IOW, in reverse order we had before bringing the
interface down.

This issue can be fixed by traversing adapter->nfc_rule_list in
backwards when restoring the rules. Since hlist doesn't support
backwards traversal, this patch replaces it by list_head and fixes
igc_restore_nfc_rules() accordingly.

Signed-off-by: Andre Guedes <andre.guedes@intel.com>
---
 drivers/net/ethernet/intel/igc/igc.h         |  4 ++--
 drivers/net/ethernet/intel/igc/igc_ethtool.c | 19 ++++++++-----------
 drivers/net/ethernet/intel/igc/igc_main.c    | 16 +++++++++-------
 3 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index ae7d48070ee2..76bc3a51ad70 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -191,7 +191,7 @@ struct igc_adapter {
 	 * nfc_rule_lock.
 	 */
 	spinlock_t nfc_rule_lock;
-	struct hlist_head nfc_rule_list;
+	struct list_head nfc_rule_list;
 	unsigned int nfc_rule_count;
 
 	u8 rss_indir_tbl[IGC_RETA_SIZE];
@@ -461,7 +461,7 @@ struct igc_nfc_filter {
 };
 
 struct igc_nfc_rule {
-	struct hlist_node nfc_node;
+	struct list_head list;
 	struct igc_nfc_filter filter;
 	u32 location;
 	u16 action;
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index e975efea4a15..944cad748e61 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -941,7 +941,7 @@ static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter,
 
 	spin_lock(&adapter->nfc_rule_lock);
 
-	hlist_for_each_entry(rule, &adapter->nfc_rule_list, nfc_node) {
+	list_for_each_entry(rule, &adapter->nfc_rule_list, list) {
 		if (fsp->location <= rule->location)
 			break;
 	}
@@ -997,7 +997,7 @@ static int igc_ethtool_get_nfc_rules(struct igc_adapter *adapter,
 
 	spin_lock(&adapter->nfc_rule_lock);
 
-	hlist_for_each_entry(rule, &adapter->nfc_rule_list, nfc_node) {
+	list_for_each_entry(rule, &adapter->nfc_rule_list, list) {
 		if (cnt == cmd->rule_cnt) {
 			spin_unlock(&adapter->nfc_rule_lock);
 			return -EMSGSIZE;
@@ -1261,7 +1261,7 @@ static int igc_ethtool_update_nfc_rule(struct igc_adapter *adapter,
 	parent = NULL;
 	rule = NULL;
 
-	hlist_for_each_entry(rule, &adapter->nfc_rule_list, nfc_node) {
+	list_for_each_entry(rule, &adapter->nfc_rule_list, list) {
 		/* hash found, or no matching entry */
 		if (rule->location >= location)
 			break;
@@ -1272,7 +1272,7 @@ static int igc_ethtool_update_nfc_rule(struct igc_adapter *adapter,
 	if (rule && rule->location == location) {
 		err = igc_disable_nfc_rule(adapter, rule);
 
-		hlist_del(&rule->nfc_node);
+		list_del(&rule->list);
 		kfree(rule);
 		adapter->nfc_rule_count--;
 	}
@@ -1283,11 +1283,8 @@ static int igc_ethtool_update_nfc_rule(struct igc_adapter *adapter,
 	if (!input)
 		return err;
 
-	/* add filter to the list */
-	if (parent)
-		hlist_add_behind(&input->nfc_node, &parent->nfc_node);
-	else
-		hlist_add_head(&input->nfc_node, &adapter->nfc_rule_list);
+	list_add(&input->list, parent ? &parent->list :
+					&adapter->nfc_rule_list);
 
 	/* update counts */
 	adapter->nfc_rule_count++;
@@ -1298,7 +1295,7 @@ static int igc_ethtool_update_nfc_rule(struct igc_adapter *adapter,
 static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule,
 				      const struct ethtool_rx_flow_spec *fsp)
 {
-	INIT_HLIST_NODE(&rule->nfc_node);
+	INIT_LIST_HEAD(&rule->list);
 
 	rule->action = fsp->ring_cookie;
 	rule->location = fsp->location;
@@ -1362,7 +1359,7 @@ static int igc_ethtool_check_nfc_rule(struct igc_adapter *adapter,
 		return -EOPNOTSUPP;
 	}
 
-	hlist_for_each_entry(tmp, &adapter->nfc_rule_list, nfc_node) {
+	list_for_each_entry(tmp, &adapter->nfc_rule_list, list) {
 		if (!memcmp(&rule->filter, &tmp->filter,
 			    sizeof(rule->filter))) {
 			netdev_dbg(dev, "Rule already exists");
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index b0c4206f9c7d..1b554b3a63c2 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -2181,7 +2181,7 @@ static void igc_restore_nfc_rules(struct igc_adapter *adapter)
 
 	spin_lock(&adapter->nfc_rule_lock);
 
-	hlist_for_each_entry(rule, &adapter->nfc_rule_list, nfc_node)
+	list_for_each_entry_reverse(rule, &adapter->nfc_rule_list, list)
 		igc_enable_nfc_rule(adapter, rule);
 
 	spin_unlock(&adapter->nfc_rule_lock);
@@ -3420,6 +3420,9 @@ static int igc_sw_init(struct igc_adapter *adapter)
 	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
 
 	spin_lock_init(&adapter->nfc_rule_lock);
+	INIT_LIST_HEAD(&adapter->nfc_rule_list);
+	adapter->nfc_rule_count = 0;
+
 	spin_lock_init(&adapter->stats64_lock);
 	/* Assume MSI-X interrupts, will be checked during IRQ allocation */
 	adapter->flags |= IGC_FLAG_HAS_MSIX;
@@ -3652,7 +3655,7 @@ static void igc_nfc_rule_exit(struct igc_adapter *adapter)
 
 	spin_lock(&adapter->nfc_rule_lock);
 
-	hlist_for_each_entry(rule, &adapter->nfc_rule_list, nfc_node)
+	list_for_each_entry(rule, &adapter->nfc_rule_list, list)
 		igc_disable_nfc_rule(adapter, rule);
 
 	spin_unlock(&adapter->nfc_rule_lock);
@@ -3827,14 +3830,13 @@ static int igc_set_features(struct net_device *netdev,
 		return 0;
 
 	if (!(features & NETIF_F_NTUPLE)) {
-		struct hlist_node *node2;
-		struct igc_nfc_rule *rule;
+		struct igc_nfc_rule *rule, *tmp;
 
 		spin_lock(&adapter->nfc_rule_lock);
-		hlist_for_each_entry_safe(rule, node2,
-					  &adapter->nfc_rule_list, nfc_node) {
+		list_for_each_entry_safe(rule, tmp,
+					 &adapter->nfc_rule_list, list) {
 			igc_disable_nfc_rule(adapter, rule);
-			hlist_del(&rule->nfc_node);
+			list_del(&rule->list);
 			kfree(rule);
 		}
 		spin_unlock(&adapter->nfc_rule_lock);
-- 
2.26.0


  parent reply	other threads:[~2020-04-24 20:16 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-24 20:16 [Intel-wired-lan] [PATCH 00/19] igc: Fixes to NFC support code Andre Guedes
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 01/19] igc: Remove unused field from igc_nfc_filter Andre Guedes
2020-05-01 22:01   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 02/19] igc: Get rid of igc_max_channels() Andre Guedes
2020-05-01 22:05   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 03/19] igc: Cleanup _get|set_rxnfc ethtool ops Andre Guedes
2020-05-01 22:10   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 04/19] igc: Early return in igc_get_ethtool_nfc_entry() Andre Guedes
2020-05-01 22:12   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 05/19] igc: Add 'igc_ethtool_' prefix to functions in igc_ethtool.c Andre Guedes
2020-05-01 22:15   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 06/19] igc: Align terms used in NFC support code Andre Guedes
2020-05-01 22:18   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 07/19] igc: Change byte order in struct igc_nfc_filter Andre Guedes
2020-05-01 22:21   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 08/19] igc: Refactor igc_ethtool_add_nfc_rule() Andre Guedes
2020-05-01 22:23   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 09/19] igc: Fix 'sw_idx' type in struct igc_nfc_rule Andre Guedes
2020-05-01 22:26   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 10/19] igc: Fix locking issue when retrieving NFC rules Andre Guedes
2020-05-01 22:28   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 11/19] igc: Fix NFC rule overwrite cases Andre Guedes
2020-05-01 22:29   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 12/19] igc: Fix NFC rules with multicast addresses Andre Guedes
2020-05-01 22:32   ` Brown, Aaron F
2020-04-24 20:16 ` Andre Guedes [this message]
2020-05-01 22:41   ` [Intel-wired-lan] [PATCH 13/19] igc: Fix NFC rules restoration Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 14/19] igc: Refactor igc_ethtool_update_nfc_rule() Andre Guedes
2020-05-01 22:42   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 15/19] igc: Fix NFC rules leak when driver is unloaded Andre Guedes
2020-05-01 22:44   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 16/19] igc: Fix NFC rule validation Andre Guedes
2020-05-01 22:47   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 17/19] igc: Change return type from igc_disable_nfc_rule() Andre Guedes
2020-05-01 22:57   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 18/19] igc: Change adapter->nfc_rule_lock to mutex Andre Guedes
2020-05-01 22:49   ` Brown, Aaron F
2020-05-01 22:52   ` Brown, Aaron F
2020-04-24 20:16 ` [Intel-wired-lan] [PATCH 19/19] igc: Remove igc_nfc_rule_exit() Andre Guedes
2020-05-01 22:54   ` Brown, Aaron F

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=20200424201623.10971-14-andre.guedes@intel.com \
    --to=andre.guedes@intel.com \
    --cc=intel-wired-lan@osuosl.org \
    /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.