diff options
| author | Antoine Tenart <atenart@kernel.org> | 2020-12-23 22:23:21 +0100 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-01-12 20:09:09 +0100 |
| commit | 5919581838dcc61aa1b933303a6e43cea86c75f7 (patch) | |
| tree | 9852659bb87c030bfddf0944a1495de4f19f4811 /net | |
| parent | 7e6953fa83a67b907a5a1fc8796b45aa2807cdeb (diff) | |
| download | linux-5919581838dcc61aa1b933303a6e43cea86c75f7.tar.gz linux-5919581838dcc61aa1b933303a6e43cea86c75f7.tar.bz2 linux-5919581838dcc61aa1b933303a6e43cea86c75f7.zip | |
net-sysfs: take the rtnl lock when accessing xps_cpus_map and num_tc
[ Upstream commit fb25038586d0064123e393cadf1fadd70a9df97a ]
Accesses to dev->xps_cpus_map (when using dev->num_tc) should be
protected by the rtnl lock, like we do for netif_set_xps_queue. I didn't
see an actual bug being triggered, but let's be safe here and take the
rtnl lock while accessing the map in sysfs.
Fixes: 184c449f91fe ("net: Add support for XPS with QoS via traffic classes")
Signed-off-by: Antoine Tenart <atenart@kernel.org>
Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
| -rw-r--r-- | net/core/net-sysfs.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 1e0d97b4e1a0..7d8c6ba5cbd2 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -1207,23 +1207,30 @@ static const struct attribute_group dql_group = { static ssize_t xps_cpus_show(struct netdev_queue *queue, char *buf) { + int cpu, len, ret, num_tc = 1, tc = 0; struct net_device *dev = queue->dev; - int cpu, len, num_tc = 1, tc = 0; struct xps_dev_maps *dev_maps; cpumask_var_t mask; unsigned long index; index = get_netdev_queue_index(queue); + if (!rtnl_trylock()) + return restart_syscall(); + if (dev->num_tc) { num_tc = dev->num_tc; tc = netdev_txq_to_tc(dev, index); - if (tc < 0) - return -EINVAL; + if (tc < 0) { + ret = -EINVAL; + goto err_rtnl_unlock; + } } - if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) - return -ENOMEM; + if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) { + ret = -ENOMEM; + goto err_rtnl_unlock; + } rcu_read_lock(); dev_maps = rcu_dereference(dev->xps_maps); @@ -1246,9 +1253,15 @@ static ssize_t xps_cpus_show(struct netdev_queue *queue, } rcu_read_unlock(); + rtnl_unlock(); + len = snprintf(buf, PAGE_SIZE, "%*pb\n", cpumask_pr_args(mask)); free_cpumask_var(mask); return len < PAGE_SIZE ? len : -EINVAL; + +err_rtnl_unlock: + rtnl_unlock(); + return ret; } static ssize_t xps_cpus_store(struct netdev_queue *queue, |
