lkml.org 
[lkml]   [2022]   [Sep]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 26/77] net: Fix data-races around weight_p and dev_weight_[rt]x_bias.
    Date
    From: Kuniyuki Iwashima <kuniyu@amazon.com>

    [ Upstream commit bf955b5ab8f6f7b0632cdef8e36b14e4f6e77829 ]

    While reading weight_p, it can be changed concurrently. Thus, we need
    to add READ_ONCE() to its reader.

    Also, dev_[rt]x_weight can be read/written at the same time. So, we
    need to use READ_ONCE() and WRITE_ONCE() for its access. Moreover, to
    use the same weight_p while changing dev_[rt]x_weight, we add a mutex
    in proc_do_dev_weight().

    Fixes: 3d48b53fb2ae ("net: dev_weight: TX/RX orthogonality")
    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/core/dev.c | 2 +-
    net/core/sysctl_net_core.c | 15 +++++++++------
    net/sched/sch_generic.c | 2 +-
    3 files changed, 11 insertions(+), 8 deletions(-)

    diff --git a/net/core/dev.c b/net/core/dev.c
    index a03036456221b..517fb03a0bb89 100644
    --- a/net/core/dev.c
    +++ b/net/core/dev.c
    @@ -5892,7 +5892,7 @@ static int process_backlog(struct napi_struct *napi, int quota)
    net_rps_action_and_irq_enable(sd);
    }

    - napi->weight = dev_rx_weight;
    + napi->weight = READ_ONCE(dev_rx_weight);
    while (again) {
    struct sk_buff *skb;

    diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
    index 48041f50ecfb4..586598887095d 100644
    --- a/net/core/sysctl_net_core.c
    +++ b/net/core/sysctl_net_core.c
    @@ -238,14 +238,17 @@ static int set_default_qdisc(struct ctl_table *table, int write,
    static int proc_do_dev_weight(struct ctl_table *table, int write,
    void __user *buffer, size_t *lenp, loff_t *ppos)
    {
    - int ret;
    + static DEFINE_MUTEX(dev_weight_mutex);
    + int ret, weight;

    + mutex_lock(&dev_weight_mutex);
    ret = proc_dointvec(table, write, buffer, lenp, ppos);
    - if (ret != 0)
    - return ret;
    -
    - dev_rx_weight = weight_p * dev_weight_rx_bias;
    - dev_tx_weight = weight_p * dev_weight_tx_bias;
    + if (!ret && write) {
    + weight = READ_ONCE(weight_p);
    + WRITE_ONCE(dev_rx_weight, weight * dev_weight_rx_bias);
    + WRITE_ONCE(dev_tx_weight, weight * dev_weight_tx_bias);
    + }
    + mutex_unlock(&dev_weight_mutex);

    return ret;
    }
    diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
    index ae5847de94c88..81fcf6c5bde96 100644
    --- a/net/sched/sch_generic.c
    +++ b/net/sched/sch_generic.c
    @@ -403,7 +403,7 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets)

    void __qdisc_run(struct Qdisc *q)
    {
    - int quota = dev_tx_weight;
    + int quota = READ_ONCE(dev_tx_weight);
    int packets;

    while (qdisc_restart(q, &packets)) {
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-09-02 16:46    [W:4.048 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site