Michael S. Tsirkin
2020-Dec-22 22:32 UTC
[PATCH] virtio_net: Fix recursive call to cpus_read_lock()
On Mon, Dec 21, 2020 at 10:36:48PM -0500, Jeff Dike wrote:> virtnet_set_channels can recursively call cpus_read_lock if CONFIG_XPS > and CONFIG_HOTPLUG are enabled. > > The path is: > virtnet_set_channels - calls get_online_cpus(), which is a trivial > wrapper around cpus_read_lock() > netif_set_real_num_tx_queues > netif_reset_xps_queues_gt > netif_reset_xps_queues - calls cpus_read_lock() > > This call chain and potential deadlock happens when the number of TX > queues is reduced. > > This commit the removes netif_set_real_num_[tr]x_queues calls from > inside the get/put_online_cpus section, as they don't require that it > be held. > > Signed-off-by: Jeff Dike <jdike at akamai.com>Acked-by: Michael S. Tsirkin <mst at redhat.com>> --- > drivers/net/virtio_net.c | 12 +++++++----- > 1 file changed, 7 insertions(+), 5 deletions(-) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index 052975ea0af4..e02c7e0f1cf9 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -2093,14 +2093,16 @@ static int virtnet_set_channels(struct net_device *dev, > > get_online_cpus(); > err = _virtnet_set_queues(vi, queue_pairs); > - if (!err) { > - netif_set_real_num_tx_queues(dev, queue_pairs); > - netif_set_real_num_rx_queues(dev, queue_pairs); > - > - virtnet_set_affinity(vi); > + if (err){ > + put_online_cpus(); > + goto err; > } > + virtnet_set_affinity(vi); > put_online_cpus(); > > + netif_set_real_num_tx_queues(dev, queue_pairs); > + netif_set_real_num_rx_queues(dev, queue_pairs); > + err: > return err; > } > > -- > 2.17.1