Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 00ac0dc

Browse files
committedApr 19, 2024
Merge branch 'net_sched-dump-no-rtnl'
Eric Dumazet says: ==================== net_sched: first series for RTNL-less qdisc dumps Medium term goal is to implement "tc qdisc show" without needing to acquire RTNL. This first series makes the requested changes in 14 qdisc. Notes : - RTNL is still held in "tc qdisc show", more changes are needed. - Qdisc returning many attributes might want/need to provide a consistent set of attributes. If that is the case, their dump() method could acquire the qdisc spinlock, to pair the spinlock acquision in their change() method. V2: Addressed Simon feedback (Thanks a lot Simon) ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents fdf4123 + c85cedb commit 00ac0dc

15 files changed

+323
-234
lines changed
 

‎include/net/red.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -233,18 +233,18 @@ static inline void red_set_parms(struct red_parms *p,
233233
int delta = qth_max - qth_min;
234234
u32 max_p_delta;
235235

236-
p->qth_min = qth_min << Wlog;
237-
p->qth_max = qth_max << Wlog;
238-
p->Wlog = Wlog;
239-
p->Plog = Plog;
236+
WRITE_ONCE(p->qth_min, qth_min << Wlog);
237+
WRITE_ONCE(p->qth_max, qth_max << Wlog);
238+
WRITE_ONCE(p->Wlog, Wlog);
239+
WRITE_ONCE(p->Plog, Plog);
240240
if (delta <= 0)
241241
delta = 1;
242242
p->qth_delta = delta;
243243
if (!max_P) {
244244
max_P = red_maxp(Plog);
245245
max_P *= delta; /* max_P = (qth_max - qth_min)/2^Plog */
246246
}
247-
p->max_P = max_P;
247+
WRITE_ONCE(p->max_P, max_P);
248248
max_p_delta = max_P / delta;
249249
max_p_delta = max(max_p_delta, 1U);
250250
p->max_P_reciprocal = reciprocal_value(max_p_delta);
@@ -257,7 +257,7 @@ static inline void red_set_parms(struct red_parms *p,
257257
p->target_min = qth_min + 2*delta;
258258
p->target_max = qth_min + 3*delta;
259259

260-
p->Scell_log = Scell_log;
260+
WRITE_ONCE(p->Scell_log, Scell_log);
261261
p->Scell_max = (255 << Scell_log);
262262

263263
if (stab)

‎net/sched/sch_cake.c

+63-47
Original file line numberDiff line numberDiff line change
@@ -2572,17 +2572,20 @@ static int cake_change(struct Qdisc *sch, struct nlattr *opt,
25722572
{
25732573
struct cake_sched_data *q = qdisc_priv(sch);
25742574
struct nlattr *tb[TCA_CAKE_MAX + 1];
2575+
u16 rate_flags;
2576+
u8 flow_mode;
25752577
int err;
25762578

25772579
err = nla_parse_nested_deprecated(tb, TCA_CAKE_MAX, opt, cake_policy,
25782580
extack);
25792581
if (err < 0)
25802582
return err;
25812583

2584+
flow_mode = q->flow_mode;
25822585
if (tb[TCA_CAKE_NAT]) {
25832586
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
2584-
q->flow_mode &= ~CAKE_FLOW_NAT_FLAG;
2585-
q->flow_mode |= CAKE_FLOW_NAT_FLAG *
2587+
flow_mode &= ~CAKE_FLOW_NAT_FLAG;
2588+
flow_mode |= CAKE_FLOW_NAT_FLAG *
25862589
!!nla_get_u32(tb[TCA_CAKE_NAT]);
25872590
#else
25882591
NL_SET_ERR_MSG_ATTR(extack, tb[TCA_CAKE_NAT],
@@ -2592,29 +2595,34 @@ static int cake_change(struct Qdisc *sch, struct nlattr *opt,
25922595
}
25932596

25942597
if (tb[TCA_CAKE_BASE_RATE64])
2595-
q->rate_bps = nla_get_u64(tb[TCA_CAKE_BASE_RATE64]);
2598+
WRITE_ONCE(q->rate_bps,
2599+
nla_get_u64(tb[TCA_CAKE_BASE_RATE64]));
25962600

25972601
if (tb[TCA_CAKE_DIFFSERV_MODE])
2598-
q->tin_mode = nla_get_u32(tb[TCA_CAKE_DIFFSERV_MODE]);
2602+
WRITE_ONCE(q->tin_mode,
2603+
nla_get_u32(tb[TCA_CAKE_DIFFSERV_MODE]));
25992604

2605+
rate_flags = q->rate_flags;
26002606
if (tb[TCA_CAKE_WASH]) {
26012607
if (!!nla_get_u32(tb[TCA_CAKE_WASH]))
2602-
q->rate_flags |= CAKE_FLAG_WASH;
2608+
rate_flags |= CAKE_FLAG_WASH;
26032609
else
2604-
q->rate_flags &= ~CAKE_FLAG_WASH;
2610+
rate_flags &= ~CAKE_FLAG_WASH;
26052611
}
26062612

26072613
if (tb[TCA_CAKE_FLOW_MODE])
2608-
q->flow_mode = ((q->flow_mode & CAKE_FLOW_NAT_FLAG) |
2614+
flow_mode = ((flow_mode & CAKE_FLOW_NAT_FLAG) |
26092615
(nla_get_u32(tb[TCA_CAKE_FLOW_MODE]) &
26102616
CAKE_FLOW_MASK));
26112617

26122618
if (tb[TCA_CAKE_ATM])
2613-
q->atm_mode = nla_get_u32(tb[TCA_CAKE_ATM]);
2619+
WRITE_ONCE(q->atm_mode,
2620+
nla_get_u32(tb[TCA_CAKE_ATM]));
26142621

26152622
if (tb[TCA_CAKE_OVERHEAD]) {
2616-
q->rate_overhead = nla_get_s32(tb[TCA_CAKE_OVERHEAD]);
2617-
q->rate_flags |= CAKE_FLAG_OVERHEAD;
2623+
WRITE_ONCE(q->rate_overhead,
2624+
nla_get_s32(tb[TCA_CAKE_OVERHEAD]));
2625+
rate_flags |= CAKE_FLAG_OVERHEAD;
26182626

26192627
q->max_netlen = 0;
26202628
q->max_adjlen = 0;
@@ -2623,7 +2631,7 @@ static int cake_change(struct Qdisc *sch, struct nlattr *opt,
26232631
}
26242632

26252633
if (tb[TCA_CAKE_RAW]) {
2626-
q->rate_flags &= ~CAKE_FLAG_OVERHEAD;
2634+
rate_flags &= ~CAKE_FLAG_OVERHEAD;
26272635

26282636
q->max_netlen = 0;
26292637
q->max_adjlen = 0;
@@ -2632,54 +2640,58 @@ static int cake_change(struct Qdisc *sch, struct nlattr *opt,
26322640
}
26332641

26342642
if (tb[TCA_CAKE_MPU])
2635-
q->rate_mpu = nla_get_u32(tb[TCA_CAKE_MPU]);
2643+
WRITE_ONCE(q->rate_mpu,
2644+
nla_get_u32(tb[TCA_CAKE_MPU]));
26362645

26372646
if (tb[TCA_CAKE_RTT]) {
2638-
q->interval = nla_get_u32(tb[TCA_CAKE_RTT]);
2647+
u32 interval = nla_get_u32(tb[TCA_CAKE_RTT]);
26392648

2640-
if (!q->interval)
2641-
q->interval = 1;
2649+
WRITE_ONCE(q->interval, max(interval, 1U));
26422650
}
26432651

26442652
if (tb[TCA_CAKE_TARGET]) {
2645-
q->target = nla_get_u32(tb[TCA_CAKE_TARGET]);
2653+
u32 target = nla_get_u32(tb[TCA_CAKE_TARGET]);
26462654

2647-
if (!q->target)
2648-
q->target = 1;
2655+
WRITE_ONCE(q->target, max(target, 1U));
26492656
}
26502657

26512658
if (tb[TCA_CAKE_AUTORATE]) {
26522659
if (!!nla_get_u32(tb[TCA_CAKE_AUTORATE]))
2653-
q->rate_flags |= CAKE_FLAG_AUTORATE_INGRESS;
2660+
rate_flags |= CAKE_FLAG_AUTORATE_INGRESS;
26542661
else
2655-
q->rate_flags &= ~CAKE_FLAG_AUTORATE_INGRESS;
2662+
rate_flags &= ~CAKE_FLAG_AUTORATE_INGRESS;
26562663
}
26572664

26582665
if (tb[TCA_CAKE_INGRESS]) {
26592666
if (!!nla_get_u32(tb[TCA_CAKE_INGRESS]))
2660-
q->rate_flags |= CAKE_FLAG_INGRESS;
2667+
rate_flags |= CAKE_FLAG_INGRESS;
26612668
else
2662-
q->rate_flags &= ~CAKE_FLAG_INGRESS;
2669+
rate_flags &= ~CAKE_FLAG_INGRESS;
26632670
}
26642671

26652672
if (tb[TCA_CAKE_ACK_FILTER])
2666-
q->ack_filter = nla_get_u32(tb[TCA_CAKE_ACK_FILTER]);
2673+
WRITE_ONCE(q->ack_filter,
2674+
nla_get_u32(tb[TCA_CAKE_ACK_FILTER]));
26672675

26682676
if (tb[TCA_CAKE_MEMORY])
2669-
q->buffer_config_limit = nla_get_u32(tb[TCA_CAKE_MEMORY]);
2677+
WRITE_ONCE(q->buffer_config_limit,
2678+
nla_get_u32(tb[TCA_CAKE_MEMORY]));
26702679

26712680
if (tb[TCA_CAKE_SPLIT_GSO]) {
26722681
if (!!nla_get_u32(tb[TCA_CAKE_SPLIT_GSO]))
2673-
q->rate_flags |= CAKE_FLAG_SPLIT_GSO;
2682+
rate_flags |= CAKE_FLAG_SPLIT_GSO;
26742683
else
2675-
q->rate_flags &= ~CAKE_FLAG_SPLIT_GSO;
2684+
rate_flags &= ~CAKE_FLAG_SPLIT_GSO;
26762685
}
26772686

26782687
if (tb[TCA_CAKE_FWMARK]) {
2679-
q->fwmark_mask = nla_get_u32(tb[TCA_CAKE_FWMARK]);
2680-
q->fwmark_shft = q->fwmark_mask ? __ffs(q->fwmark_mask) : 0;
2688+
WRITE_ONCE(q->fwmark_mask, nla_get_u32(tb[TCA_CAKE_FWMARK]));
2689+
WRITE_ONCE(q->fwmark_shft,
2690+
q->fwmark_mask ? __ffs(q->fwmark_mask) : 0);
26812691
}
26822692

2693+
WRITE_ONCE(q->rate_flags, rate_flags);
2694+
WRITE_ONCE(q->flow_mode, flow_mode);
26832695
if (q->tins) {
26842696
sch_tree_lock(sch);
26852697
cake_reconfigure(sch);
@@ -2774,68 +2786,72 @@ static int cake_dump(struct Qdisc *sch, struct sk_buff *skb)
27742786
{
27752787
struct cake_sched_data *q = qdisc_priv(sch);
27762788
struct nlattr *opts;
2789+
u16 rate_flags;
2790+
u8 flow_mode;
27772791

27782792
opts = nla_nest_start_noflag(skb, TCA_OPTIONS);
27792793
if (!opts)
27802794
goto nla_put_failure;
27812795

2782-
if (nla_put_u64_64bit(skb, TCA_CAKE_BASE_RATE64, q->rate_bps,
2783-
TCA_CAKE_PAD))
2796+
if (nla_put_u64_64bit(skb, TCA_CAKE_BASE_RATE64,
2797+
READ_ONCE(q->rate_bps), TCA_CAKE_PAD))
27842798
goto nla_put_failure;
27852799

2786-
if (nla_put_u32(skb, TCA_CAKE_FLOW_MODE,
2787-
q->flow_mode & CAKE_FLOW_MASK))
2800+
flow_mode = READ_ONCE(q->flow_mode);
2801+
if (nla_put_u32(skb, TCA_CAKE_FLOW_MODE, flow_mode & CAKE_FLOW_MASK))
27882802
goto nla_put_failure;
27892803

2790-
if (nla_put_u32(skb, TCA_CAKE_RTT, q->interval))
2804+
if (nla_put_u32(skb, TCA_CAKE_RTT, READ_ONCE(q->interval)))
27912805
goto nla_put_failure;
27922806

2793-
if (nla_put_u32(skb, TCA_CAKE_TARGET, q->target))
2807+
if (nla_put_u32(skb, TCA_CAKE_TARGET, READ_ONCE(q->target)))
27942808
goto nla_put_failure;
27952809

2796-
if (nla_put_u32(skb, TCA_CAKE_MEMORY, q->buffer_config_limit))
2810+
if (nla_put_u32(skb, TCA_CAKE_MEMORY,
2811+
READ_ONCE(q->buffer_config_limit)))
27972812
goto nla_put_failure;
27982813

2814+
rate_flags = READ_ONCE(q->rate_flags);
27992815
if (nla_put_u32(skb, TCA_CAKE_AUTORATE,
2800-
!!(q->rate_flags & CAKE_FLAG_AUTORATE_INGRESS)))
2816+
!!(rate_flags & CAKE_FLAG_AUTORATE_INGRESS)))
28012817
goto nla_put_failure;
28022818

28032819
if (nla_put_u32(skb, TCA_CAKE_INGRESS,
2804-
!!(q->rate_flags & CAKE_FLAG_INGRESS)))
2820+
!!(rate_flags & CAKE_FLAG_INGRESS)))
28052821
goto nla_put_failure;
28062822

2807-
if (nla_put_u32(skb, TCA_CAKE_ACK_FILTER, q->ack_filter))
2823+
if (nla_put_u32(skb, TCA_CAKE_ACK_FILTER, READ_ONCE(q->ack_filter)))
28082824
goto nla_put_failure;
28092825

28102826
if (nla_put_u32(skb, TCA_CAKE_NAT,
2811-
!!(q->flow_mode & CAKE_FLOW_NAT_FLAG)))
2827+
!!(flow_mode & CAKE_FLOW_NAT_FLAG)))
28122828
goto nla_put_failure;
28132829

2814-
if (nla_put_u32(skb, TCA_CAKE_DIFFSERV_MODE, q->tin_mode))
2830+
if (nla_put_u32(skb, TCA_CAKE_DIFFSERV_MODE, READ_ONCE(q->tin_mode)))
28152831
goto nla_put_failure;
28162832

28172833
if (nla_put_u32(skb, TCA_CAKE_WASH,
2818-
!!(q->rate_flags & CAKE_FLAG_WASH)))
2834+
!!(rate_flags & CAKE_FLAG_WASH)))
28192835
goto nla_put_failure;
28202836

2821-
if (nla_put_u32(skb, TCA_CAKE_OVERHEAD, q->rate_overhead))
2837+
if (nla_put_u32(skb, TCA_CAKE_OVERHEAD, READ_ONCE(q->rate_overhead)))
28222838
goto nla_put_failure;
28232839

2824-
if (!(q->rate_flags & CAKE_FLAG_OVERHEAD))
2840+
if (!(rate_flags & CAKE_FLAG_OVERHEAD))
28252841
if (nla_put_u32(skb, TCA_CAKE_RAW, 0))
28262842
goto nla_put_failure;
28272843

2828-
if (nla_put_u32(skb, TCA_CAKE_ATM, q->atm_mode))
2844+
if (nla_put_u32(skb, TCA_CAKE_ATM, READ_ONCE(q->atm_mode)))
28292845
goto nla_put_failure;
28302846

2831-
if (nla_put_u32(skb, TCA_CAKE_MPU, q->rate_mpu))
2847+
if (nla_put_u32(skb, TCA_CAKE_MPU, READ_ONCE(q->rate_mpu)))
28322848
goto nla_put_failure;
28332849

28342850
if (nla_put_u32(skb, TCA_CAKE_SPLIT_GSO,
2835-
!!(q->rate_flags & CAKE_FLAG_SPLIT_GSO)))
2851+
!!(rate_flags & CAKE_FLAG_SPLIT_GSO)))
28362852
goto nla_put_failure;
28372853

2838-
if (nla_put_u32(skb, TCA_CAKE_FWMARK, q->fwmark_mask))
2854+
if (nla_put_u32(skb, TCA_CAKE_FWMARK, READ_ONCE(q->fwmark_mask)))
28392855
goto nla_put_failure;
28402856

28412857
return nla_nest_end(skb, opts);

‎net/sched/sch_cbs.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -389,11 +389,11 @@ static int cbs_change(struct Qdisc *sch, struct nlattr *opt,
389389
}
390390

391391
/* Everything went OK, save the parameters used. */
392-
q->hicredit = qopt->hicredit;
393-
q->locredit = qopt->locredit;
394-
q->idleslope = qopt->idleslope * BYTES_PER_KBIT;
395-
q->sendslope = qopt->sendslope * BYTES_PER_KBIT;
396-
q->offload = qopt->offload;
392+
WRITE_ONCE(q->hicredit, qopt->hicredit);
393+
WRITE_ONCE(q->locredit, qopt->locredit);
394+
WRITE_ONCE(q->idleslope, qopt->idleslope * BYTES_PER_KBIT);
395+
WRITE_ONCE(q->sendslope, qopt->sendslope * BYTES_PER_KBIT);
396+
WRITE_ONCE(q->offload, qopt->offload);
397397

398398
return 0;
399399
}
@@ -459,11 +459,11 @@ static int cbs_dump(struct Qdisc *sch, struct sk_buff *skb)
459459
if (!nest)
460460
goto nla_put_failure;
461461

462-
opt.hicredit = q->hicredit;
463-
opt.locredit = q->locredit;
464-
opt.sendslope = div64_s64(q->sendslope, BYTES_PER_KBIT);
465-
opt.idleslope = div64_s64(q->idleslope, BYTES_PER_KBIT);
466-
opt.offload = q->offload;
462+
opt.hicredit = READ_ONCE(q->hicredit);
463+
opt.locredit = READ_ONCE(q->locredit);
464+
opt.sendslope = div64_s64(READ_ONCE(q->sendslope), BYTES_PER_KBIT);
465+
opt.idleslope = div64_s64(READ_ONCE(q->idleslope), BYTES_PER_KBIT);
466+
opt.offload = READ_ONCE(q->offload);
467467

468468
if (nla_put(skb, TCA_CBS_PARMS, sizeof(opt), &opt))
469469
goto nla_put_failure;

‎net/sched/sch_choke.c

+11-10
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,8 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt,
405405
} else
406406
sch_tree_lock(sch);
407407

408-
q->flags = ctl->flags;
409-
q->limit = ctl->limit;
408+
WRITE_ONCE(q->flags, ctl->flags);
409+
WRITE_ONCE(q->limit, ctl->limit);
410410

411411
red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog,
412412
ctl->Plog, ctl->Scell_log,
@@ -431,23 +431,24 @@ static int choke_init(struct Qdisc *sch, struct nlattr *opt,
431431
static int choke_dump(struct Qdisc *sch, struct sk_buff *skb)
432432
{
433433
struct choke_sched_data *q = qdisc_priv(sch);
434+
u8 Wlog = READ_ONCE(q->parms.Wlog);
434435
struct nlattr *opts = NULL;
435436
struct tc_red_qopt opt = {
436-
.limit = q->limit,
437-
.flags = q->flags,
438-
.qth_min = q->parms.qth_min >> q->parms.Wlog,
439-
.qth_max = q->parms.qth_max >> q->parms.Wlog,
440-
.Wlog = q->parms.Wlog,
441-
.Plog = q->parms.Plog,
442-
.Scell_log = q->parms.Scell_log,
437+
.limit = READ_ONCE(q->limit),
438+
.flags = READ_ONCE(q->flags),
439+
.qth_min = READ_ONCE(q->parms.qth_min) >> Wlog,
440+
.qth_max = READ_ONCE(q->parms.qth_max) >> Wlog,
441+
.Wlog = Wlog,
442+
.Plog = READ_ONCE(q->parms.Plog),
443+
.Scell_log = READ_ONCE(q->parms.Scell_log),
443444
};
444445

445446
opts = nla_nest_start_noflag(skb, TCA_OPTIONS);
446447
if (opts == NULL)
447448
goto nla_put_failure;
448449

449450
if (nla_put(skb, TCA_CHOKE_PARMS, sizeof(opt), &opt) ||
450-
nla_put_u32(skb, TCA_CHOKE_MAX_P, q->parms.max_P))
451+
nla_put_u32(skb, TCA_CHOKE_MAX_P, READ_ONCE(q->parms.max_P)))
451452
goto nla_put_failure;
452453
return nla_nest_end(skb, opts);
453454

0 commit comments

Comments
 (0)
Please sign in to comment.