Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net_sched: sch_sfq: annotate data-races around q->perturb_period

sfq_perturbation() reads q->perturb_period locklessly.
Add annotations to fix potential issues.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240430180015.3111398-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
a17ef9e6 4c7f3950

+9 -4
+9 -4
net/sched/sch_sfq.c
··· 608 608 struct Qdisc *sch = q->sch; 609 609 spinlock_t *root_lock; 610 610 siphash_key_t nkey; 611 + int period; 611 612 612 613 get_random_bytes(&nkey, sizeof(nkey)); 613 614 rcu_read_lock(); ··· 619 618 sfq_rehash(sch); 620 619 spin_unlock(root_lock); 621 620 622 - if (q->perturb_period) 623 - mod_timer(&q->perturb_timer, jiffies + q->perturb_period); 621 + /* q->perturb_period can change under us from 622 + * sfq_change() and sfq_destroy(). 623 + */ 624 + period = READ_ONCE(q->perturb_period); 625 + if (period) 626 + mod_timer(&q->perturb_timer, jiffies + period); 624 627 rcu_read_unlock(); 625 628 } 626 629 ··· 667 662 q->quantum = ctl->quantum; 668 663 q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum); 669 664 } 670 - q->perturb_period = ctl->perturb_period * HZ; 665 + WRITE_ONCE(q->perturb_period, ctl->perturb_period * HZ); 671 666 if (ctl->flows) 672 667 q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS); 673 668 if (ctl->divisor) { ··· 729 724 struct sfq_sched_data *q = qdisc_priv(sch); 730 725 731 726 tcf_block_put(q->block); 732 - q->perturb_period = 0; 727 + WRITE_ONCE(q->perturb_period, 0); 733 728 del_timer_sync(&q->perturb_timer); 734 729 sfq_free(q->ht); 735 730 sfq_free(q->slots);