All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrei Vagin <avagin@virtuozzo.com>
To: "Nambiar, Amritha" <amritha.nambiar@intel.com>
Cc: netdev@vger.kernel.org, davem@davemloft.net,
	alexander.h.duyck@intel.com, willemdebruijn.kernel@gmail.com,
	sridhar.samudrala@intel.com, alexander.duyck@gmail.com,
	edumazet@google.com, hannes@stressinduktion.org,
	tom@herbertland.com, tom@quantonium.net, jasowang@redhat.com,
	gaowanlong@cn.fujitsu.com, "Michael S. Tsirkin" <mst@redhat.com>,
	virtualization@lists.linux-foundation.org
Subject: Re: [net-next, v6, 6/7] net-sysfs: Add interface for Rx queue(s) map per Tx queue
Date: Wed, 1 Aug 2018 17:11:59 -0700	[thread overview]
Message-ID: <20180802001157.GA29171@outlook.office365.com> (raw)
In-Reply-To: <4b7f5d42-1b81-f095-f313-f43e41cf8601@intel.com>

[-- Attachment #1: Type: text/plain, Size: 1463 bytes --]

On Tue, Jul 10, 2018 at 07:28:49PM -0700, Nambiar, Amritha wrote:
> With this patch series, I introduced static_key for XPS maps
> (xps_needed), so static_key_slow_inc() is used to switch branches. The
> definition of static_key_slow_inc() has cpus_read_lock in place. In the
> virtio_net driver, XPS queues are initialized after setting the
> queue:cpu affinity in virtnet_set_affinity() which is already protected
> within cpus_read_lock. Hence, the warning here trying to acquire
> cpus_read_lock when it is already held.
> 
> A quick fix for this would be to just extract netif_set_xps_queue() out
> of the lock by simply wrapping it with another put/get_online_cpus
> (unlock right before and hold lock right after).

virtnet_set_affinity() is called from virtnet_cpu_online(), which is
called under cpus_read_lock too.

It looks like now we can't call netif_set_xps_queue() from cpu hotplug
callbacks.

I can suggest a very straightforward fix for this problem. The patch is
attached.

> But this may not a
> clean solution. It'd help if I can get suggestions on what would be a
> clean option to fix this without extensively changing the code in
> virtio_net. Is it mandatory to protect the affinitization with
> read_lock? I don't see similar lock in other drivers while setting the
> affinity. I understand this warning should go away, but isn't it safe to
> have multiple readers.
> 
> > On Fri, Jun 29, 2018 at 09:27:07PM -0700, Amritha Nambiar wrote:

[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 4258 bytes --]

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 1880c86e84b4..ebb5470090e5 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1941,7 +1941,7 @@ static void virtnet_set_affinity(struct virtnet_info *vi)
 	for_each_online_cpu(cpu) {
 		virtqueue_set_affinity(vi->rq[i].vq, cpu);
 		virtqueue_set_affinity(vi->sq[i].vq, cpu);
-		netif_set_xps_queue(vi->dev, cpumask_of(cpu), i);
+		__netif_set_xps_queue(vi->dev, cpumask_bits(cpumask_of(cpu)), i, false, true);
 		i++;
 	}
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 9c917467a2c7..37c88e566806 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3320,7 +3320,7 @@ static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index)
 int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
 			u16 index);
 int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
-			  u16 index, bool is_rxqs_map);
+			  u16 index, bool is_rxqs_map, bool cpuslocked);
 
 /**
  *	netif_attr_test_mask - Test a CPU or Rx queue set in a mask
diff --git a/net/core/dev.c b/net/core/dev.c
index 38b0c414d780..96ade614a23e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2176,6 +2176,7 @@ static void netif_reset_xps_queues(struct net_device *dev, u16 offset,
 	if (!static_key_false(&xps_needed))
 		return;
 
+	cpus_read_lock();
 	mutex_lock(&xps_map_mutex);
 
 	if (static_key_false(&xps_rxqs_needed)) {
@@ -2199,10 +2200,11 @@ static void netif_reset_xps_queues(struct net_device *dev, u16 offset,
 
 out_no_maps:
 	if (static_key_enabled(&xps_rxqs_needed))
-		static_key_slow_dec(&xps_rxqs_needed);
+		static_key_slow_dec_cpuslocked(&xps_rxqs_needed);
 
-	static_key_slow_dec(&xps_needed);
+	static_key_slow_dec_cpuslocked(&xps_needed);
 	mutex_unlock(&xps_map_mutex);
+	cpus_read_unlock();
 }
 
 static void netif_reset_xps_queues_gt(struct net_device *dev, u16 index)
@@ -2251,7 +2253,7 @@ static struct xps_map *expand_xps_map(struct xps_map *map, int attr_index,
 }
 
 int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
-			  u16 index, bool is_rxqs_map)
+			  u16 index, bool is_rxqs_map, bool cpuslocked)
 {
 	const unsigned long *online_mask = NULL, *possible_mask = NULL;
 	struct xps_dev_maps *dev_maps, *new_dev_maps = NULL;
@@ -2275,6 +2277,9 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
 			return -EINVAL;
 	}
 
+	if (!cpuslocked)
+		cpus_read_lock();
+
 	mutex_lock(&xps_map_mutex);
 	if (is_rxqs_map) {
 		maps_sz = XPS_RXQ_DEV_MAPS_SIZE(num_tc, dev->num_rx_queues);
@@ -2317,9 +2322,9 @@ 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(&xps_needed);
+	static_key_slow_inc_cpuslocked(&xps_needed);
 	if (is_rxqs_map)
-		static_key_slow_inc(&xps_rxqs_needed);
+		static_key_slow_inc_cpuslocked(&xps_rxqs_needed);
 
 	for (j = -1; j = netif_attrmask_next(j, possible_mask, nr_ids),
 	     j < nr_ids;) {
@@ -2427,6 +2432,8 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
 
 out_no_maps:
 	mutex_unlock(&xps_map_mutex);
+	if (!cpuslocked)
+		cpus_read_unlock();
 
 	return 0;
 error:
@@ -2444,15 +2451,18 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
 	}
 
 	mutex_unlock(&xps_map_mutex);
+	if (!cpuslocked)
+		cpus_read_unlock();
 
 	kfree(new_dev_maps);
 	return -ENOMEM;
 }
+EXPORT_SYMBOL_GPL(__netif_set_xps_queue);
 
 int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
 			u16 index)
 {
-	return __netif_set_xps_queue(dev, cpumask_bits(mask), index, false);
+	return __netif_set_xps_queue(dev, cpumask_bits(mask), index, false, false);
 }
 EXPORT_SYMBOL(netif_set_xps_queue);
 
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 0a95bcf64cdc..06a141445d80 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1400,7 +1400,7 @@ static ssize_t xps_rxqs_store(struct netdev_queue *queue, const char *buf,
 		return err;
 	}
 
-	err = __netif_set_xps_queue(dev, mask, index, true);
+	err = __netif_set_xps_queue(dev, mask, index, true, false);
 	kfree(mask);
 	return err ? : len;
 }

  parent reply	other threads:[~2018-08-02  2:00 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-30  4:26 [net-next PATCH v6 0/7] Symmetric queue selection using XPS for Rx queues Amritha Nambiar
2018-06-30  4:26 ` [net-next PATCH v6 1/7] net: Refactor XPS for CPUs and " Amritha Nambiar
2018-06-30  4:26 ` [net-next PATCH v6 2/7] net: Use static_key for XPS maps Amritha Nambiar
2018-06-30  4:26 ` [net-next PATCH v6 3/7] net: sock: Change tx_queue_mapping in sock_common to unsigned short Amritha Nambiar
2018-06-30  4:26 ` [net-next PATCH v6 4/7] net: Record receive queue number for a connection Amritha Nambiar
2018-06-30  4:27 ` [net-next PATCH v6 5/7] net: Enable Tx queue selection based on Rx queues Amritha Nambiar
2018-06-30  4:27 ` [net-next PATCH v6 6/7] net-sysfs: Add interface for Rx queue(s) map per Tx queue Amritha Nambiar
2018-07-04  7:20   ` [net-next, v6, " Andrei Vagin
2018-07-11  2:28     ` Nambiar, Amritha
2018-07-18 18:22       ` Andrei Vagin
2018-07-18 19:24         ` Stephen Hemminger
2018-07-19  9:16         ` Peter Zijlstra
2018-08-02  0:11       ` Andrei Vagin [this message]
2018-08-02 21:04         ` Nambiar, Amritha
2018-08-02 21:08           ` Michael S. Tsirkin
2018-08-02 21:08           ` Michael S. Tsirkin
2018-08-03 19:06             ` Andrei Vagin
2018-08-03 19:12               ` Michael S. Tsirkin
2018-08-03 21:19                 ` Andrei Vagin
2018-08-04  4:30                 ` Andrei Vagin
2018-08-03 19:12               ` Michael S. Tsirkin
2018-06-30  4:27 ` [net-next PATCH v6 7/7] Documentation: Add explanation for XPS using Rx-queue(s) map Amritha Nambiar
2018-07-02  0:11 ` [net-next PATCH v6 0/7] Symmetric queue selection using XPS for Rx queues 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=20180802001157.GA29171@outlook.office365.com \
    --to=avagin@virtuozzo.com \
    --cc=alexander.duyck@gmail.com \
    --cc=alexander.h.duyck@intel.com \
    --cc=amritha.nambiar@intel.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=gaowanlong@cn.fujitsu.com \
    --cc=hannes@stressinduktion.org \
    --cc=jasowang@redhat.com \
    --cc=mst@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=sridhar.samudrala@intel.com \
    --cc=tom@herbertland.com \
    --cc=tom@quantonium.net \
    --cc=virtualization@lists.linux-foundation.org \
    --cc=willemdebruijn.kernel@gmail.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.