netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 0/2] fixes for XPS configuration after Symmetric queue selection
@ 2018-11-29 13:14 Sabrina Dubroca
  2018-11-29 13:14 ` [PATCH net 1/2] net: restore call to netdev_queue_numa_node_write when resetting XPS Sabrina Dubroca
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Sabrina Dubroca @ 2018-11-29 13:14 UTC (permalink / raw)
  To: netdev; +Cc: Sabrina Dubroca, Amritha Nambiar, Alexander Duyck

This fixes some bugs introduced by the "Symmetric queue selection
using XPS for Rx queues".

First, the refactoring of the cleanup function skipped resetting the
queue's NUMA node under some conditions.

Second, the accounting on static keys for XPS and RXQS-XPS is
unbalanced, so the static key for XPS won't actually disable itself,
once enabled. The RXQS-XPS static key can actually be disabled by
reconfiguring a device that didn't have RXQS-XPS configured at all.

Sabrina Dubroca (2):
  net: restore call to netdev_queue_numa_node_write when resetting XPS
  net: fix XPS static_key accounting

 net/core/dev.c | 53 +++++++++++++++++++++++++++-----------------------
 1 file changed, 29 insertions(+), 24 deletions(-)

-- 
2.19.2

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH net 1/2] net: restore call to netdev_queue_numa_node_write when resetting XPS
  2018-11-29 13:14 [PATCH net 0/2] fixes for XPS configuration after Symmetric queue selection Sabrina Dubroca
@ 2018-11-29 13:14 ` Sabrina Dubroca
  2018-11-29 13:14 ` [PATCH net 2/2] net: fix XPS static_key accounting Sabrina Dubroca
  2018-11-29 19:10 ` [PATCH net 0/2] fixes for XPS configuration after Symmetric queue selection David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Sabrina Dubroca @ 2018-11-29 13:14 UTC (permalink / raw)
  To: netdev; +Cc: Sabrina Dubroca, Amritha Nambiar, Alexander Duyck

Before commit 80d19669ecd3 ("net: Refactor XPS for CPUs and Rx queues"),
netif_reset_xps_queues() did netdev_queue_numa_node_write() for all the
queues being reset. Now, this is only done when the "active" variable in
clean_xps_maps() is false, ie when on all the CPUs, there's no active
XPS mapping left.

Fixes: 80d19669ecd3 ("net: Refactor XPS for CPUs and Rx queues")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
---
 net/core/dev.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index ddc551f24ba2..32a63f4c3a92 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2187,17 +2187,19 @@ static void clean_xps_maps(struct net_device *dev, const unsigned long *mask,
 		active |= remove_xps_queue_cpu(dev, dev_maps, j, offset,
 					       count);
 	if (!active) {
-		if (is_rxqs_map) {
+		if (is_rxqs_map)
 			RCU_INIT_POINTER(dev->xps_rxqs_map, NULL);
-		} else {
+		else
 			RCU_INIT_POINTER(dev->xps_cpus_map, NULL);
+		kfree_rcu(dev_maps, rcu);
+	}
 
-			for (i = offset + (count - 1); count--; i--)
-				netdev_queue_numa_node_write(
-					netdev_get_tx_queue(dev, i),
-							NUMA_NO_NODE);
+	if (!is_rxqs_map) {
+		for (i = offset + (count - 1); count--; i--) {
+			netdev_queue_numa_node_write(
+				netdev_get_tx_queue(dev, i),
+				NUMA_NO_NODE);
 		}
-		kfree_rcu(dev_maps, rcu);
 	}
 }
 
-- 
2.19.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH net 2/2] net: fix XPS static_key accounting
  2018-11-29 13:14 [PATCH net 0/2] fixes for XPS configuration after Symmetric queue selection Sabrina Dubroca
  2018-11-29 13:14 ` [PATCH net 1/2] net: restore call to netdev_queue_numa_node_write when resetting XPS Sabrina Dubroca
@ 2018-11-29 13:14 ` Sabrina Dubroca
  2018-11-29 19:10 ` [PATCH net 0/2] fixes for XPS configuration after Symmetric queue selection David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Sabrina Dubroca @ 2018-11-29 13:14 UTC (permalink / raw)
  To: netdev; +Cc: Sabrina Dubroca, Amritha Nambiar, Alexander Duyck

Commit 04157469b7b8 ("net: Use static_key for XPS maps") introduced a
static key for XPS, but the increments/decrements don't match.

First, the static key's counter is incremented once for each queue, but
only decremented once for a whole batch of queues, leading to large
unbalances.

Second, the xps_rxqs_needed key is decremented whenever we reset a batch
of queues, whether they had any rxqs mapping or not, so that if we setup
cpu-XPS on em1 and RXQS-XPS on em2, resetting the queues on em1 would
decrement the xps_rxqs_needed key.

This reworks the accounting scheme so that the xps_needed key is
incremented only once for each type of XPS for all the queues on a
device, and the xps_rxqs_needed key is incremented only once for all
queues. This is sufficient to let us retrieve queues via
get_xps_queue().

This patch introduces a new reset_xps_maps(), which reinitializes and
frees the appropriate map (xps_rxqs_map or xps_cpus_map), and drops a
reference to the needed keys:
 - both xps_needed and xps_rxqs_needed, in case of rxqs maps,
 - only xps_needed, in case of CPU maps.

Now, we also need to call reset_xps_maps() at the end of
__netif_set_xps_queue() when there's no active map left, for example
when writing '00000000,00000000' to all queues' xps_rxqs setting.

Fixes: 04157469b7b8 ("net: Use static_key for XPS maps")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
---
 net/core/dev.c | 45 ++++++++++++++++++++++++---------------------
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 32a63f4c3a92..3470e7fff1f4 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2175,6 +2175,20 @@ static bool remove_xps_queue_cpu(struct net_device *dev,
 	return active;
 }
 
+static void reset_xps_maps(struct net_device *dev,
+			   struct xps_dev_maps *dev_maps,
+			   bool is_rxqs_map)
+{
+	if (is_rxqs_map) {
+		static_key_slow_dec_cpuslocked(&xps_rxqs_needed);
+		RCU_INIT_POINTER(dev->xps_rxqs_map, NULL);
+	} else {
+		RCU_INIT_POINTER(dev->xps_cpus_map, NULL);
+	}
+	static_key_slow_dec_cpuslocked(&xps_needed);
+	kfree_rcu(dev_maps, rcu);
+}
+
 static void clean_xps_maps(struct net_device *dev, const unsigned long *mask,
 			   struct xps_dev_maps *dev_maps, unsigned int nr_ids,
 			   u16 offset, u16 count, bool is_rxqs_map)
@@ -2186,13 +2200,8 @@ static void clean_xps_maps(struct net_device *dev, const unsigned long *mask,
 	     j < nr_ids;)
 		active |= remove_xps_queue_cpu(dev, dev_maps, j, offset,
 					       count);
-	if (!active) {
-		if (is_rxqs_map)
-			RCU_INIT_POINTER(dev->xps_rxqs_map, NULL);
-		else
-			RCU_INIT_POINTER(dev->xps_cpus_map, NULL);
-		kfree_rcu(dev_maps, rcu);
-	}
+	if (!active)
+		reset_xps_maps(dev, dev_maps, is_rxqs_map);
 
 	if (!is_rxqs_map) {
 		for (i = offset + (count - 1); count--; i--) {
@@ -2236,10 +2245,6 @@ static void netif_reset_xps_queues(struct net_device *dev, u16 offset,
 		       false);
 
 out_no_maps:
-	if (static_key_enabled(&xps_rxqs_needed))
-		static_key_slow_dec_cpuslocked(&xps_rxqs_needed);
-
-	static_key_slow_dec_cpuslocked(&xps_needed);
 	mutex_unlock(&xps_map_mutex);
 	cpus_read_unlock();
 }
@@ -2357,9 +2362,12 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
 	if (!new_dev_maps)
 		goto out_no_new_maps;
 
-	static_key_slow_inc_cpuslocked(&xps_needed);
-	if (is_rxqs_map)
-		static_key_slow_inc_cpuslocked(&xps_rxqs_needed);
+	if (!dev_maps) {
+		/* Increment static keys at most once per type */
+		static_key_slow_inc_cpuslocked(&xps_needed);
+		if (is_rxqs_map)
+			static_key_slow_inc_cpuslocked(&xps_rxqs_needed);
+	}
 
 	for (j = -1; j = netif_attrmask_next(j, possible_mask, nr_ids),
 	     j < nr_ids;) {
@@ -2457,13 +2465,8 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
 	}
 
 	/* free map if not active */
-	if (!active) {
-		if (is_rxqs_map)
-			RCU_INIT_POINTER(dev->xps_rxqs_map, NULL);
-		else
-			RCU_INIT_POINTER(dev->xps_cpus_map, NULL);
-		kfree_rcu(dev_maps, rcu);
-	}
+	if (!active)
+		reset_xps_maps(dev, dev_maps, is_rxqs_map);
 
 out_no_maps:
 	mutex_unlock(&xps_map_mutex);
-- 
2.19.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net 0/2] fixes for XPS configuration after Symmetric queue selection
  2018-11-29 13:14 [PATCH net 0/2] fixes for XPS configuration after Symmetric queue selection Sabrina Dubroca
  2018-11-29 13:14 ` [PATCH net 1/2] net: restore call to netdev_queue_numa_node_write when resetting XPS Sabrina Dubroca
  2018-11-29 13:14 ` [PATCH net 2/2] net: fix XPS static_key accounting Sabrina Dubroca
@ 2018-11-29 19:10 ` David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2018-11-29 19:10 UTC (permalink / raw)
  To: sd; +Cc: netdev, amritha.nambiar, alexander.h.duyck

From: Sabrina Dubroca <sd@queasysnail.net>
Date: Thu, 29 Nov 2018 14:14:47 +0100

> This fixes some bugs introduced by the "Symmetric queue selection
> using XPS for Rx queues".
> 
> First, the refactoring of the cleanup function skipped resetting the
> queue's NUMA node under some conditions.
> 
> Second, the accounting on static keys for XPS and RXQS-XPS is
> unbalanced, so the static key for XPS won't actually disable itself,
> once enabled. The RXQS-XPS static key can actually be disabled by
> reconfiguring a device that didn't have RXQS-XPS configured at all.

Series applied and queued up for -stable, thanks.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-11-30  6:16 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-29 13:14 [PATCH net 0/2] fixes for XPS configuration after Symmetric queue selection Sabrina Dubroca
2018-11-29 13:14 ` [PATCH net 1/2] net: restore call to netdev_queue_numa_node_write when resetting XPS Sabrina Dubroca
2018-11-29 13:14 ` [PATCH net 2/2] net: fix XPS static_key accounting Sabrina Dubroca
2018-11-29 19:10 ` [PATCH net 0/2] fixes for XPS configuration after Symmetric queue selection David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).