net: Fix data-races around weight_p and dev_weight_[rt]x_bias.
[ 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:3d48b53fb2
("net: dev_weight: TX/RX orthogonality") Fixes:1da177e4c3
("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>
This commit is contained in:
parent
dbd0f1991a
commit
c1d0ef0e6f
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user