lkml.org 
[lkml]   [2021]   [Jan]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 24/77] net-sysfs: take the rtnl lock when accessing xps_cpus_map and num_tc
    Date
    From: Antoine Tenart <atenart@kernel.org>

    [ 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>
    ---
    net/core/net-sysfs.c | 29 ++++++++++++++++++++++-------
    1 file changed, 22 insertions(+), 7 deletions(-)

    --- a/net/core/net-sysfs.c
    +++ b/net/core/net-sysfs.c
    @@ -1244,8 +1244,8 @@ static const struct attribute_group dql_
    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;
    @@ -1255,22 +1255,31 @@ static ssize_t xps_cpus_show(struct netd

    index = get_netdev_queue_index(queue);

    + if (!rtnl_trylock())
    + return restart_syscall();
    +
    if (dev->num_tc) {
    /* Do not allow XPS on subordinate device directly */
    num_tc = dev->num_tc;
    - if (num_tc < 0)
    - return -EINVAL;
    + if (num_tc < 0) {
    + ret = -EINVAL;
    + goto err_rtnl_unlock;
    + }

    /* If queue belongs to subordinate dev use its map */
    dev = netdev_get_tx_queue(dev, index)->sb_dev ? : dev;

    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_cpus_map);
    @@ -1293,9 +1302,15 @@ static ssize_t xps_cpus_show(struct netd
    }
    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,

    \
     
     \ /
      Last update: 2021-01-11 14:10    [W:2.933 / U:0.092 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site