mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
Merge branch 'net-sched-sch_htb-first-round-of-fixes'
Eric Dumazet says: ==================== net/sched: sch_htb: first round of fixes First round of fixes in sch_htb. I chose to send a small series, to reduce chances of multiple versions. ==================== Link: https://patch.msgid.link/20260514095935.3926276-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
dccfc06e4e
|
|
@ -114,7 +114,8 @@ struct htb_class {
|
|||
*/
|
||||
struct gnet_stats_basic_sync bstats;
|
||||
struct gnet_stats_basic_sync bstats_bias;
|
||||
struct tc_htb_xstats xstats; /* our special stats */
|
||||
u32 xstats_lends;
|
||||
u32 xstats_borrows;
|
||||
|
||||
/* token bucket parameters */
|
||||
s64 tokens, ctokens;/* current number of tokens */
|
||||
|
|
@ -567,8 +568,8 @@ htb_change_class_mode(struct htb_sched *q, struct htb_class *cl, s64 *diff)
|
|||
return;
|
||||
|
||||
if (new_mode == HTB_CANT_SEND) {
|
||||
cl->overlimits++;
|
||||
q->overlimits++;
|
||||
WRITE_ONCE(cl->overlimits, cl->overlimits + 1);
|
||||
WRITE_ONCE(q->overlimits, q->overlimits + 1);
|
||||
}
|
||||
|
||||
if (cl->prio_activity) { /* not necessary: speed optimization */
|
||||
|
|
@ -628,7 +629,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
|||
/* enqueue to helper queue */
|
||||
if (q->direct_queue.qlen < q->direct_qlen) {
|
||||
__qdisc_enqueue_tail(skb, &q->direct_queue);
|
||||
q->direct_pkts++;
|
||||
WRITE_ONCE(q->direct_pkts, q->direct_pkts + 1);
|
||||
} else {
|
||||
return qdisc_drop(skb, sch, to_free);
|
||||
}
|
||||
|
|
@ -643,7 +644,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
|||
to_free)) != NET_XMIT_SUCCESS) {
|
||||
if (net_xmit_drop_count(ret)) {
|
||||
qdisc_qstats_drop(sch);
|
||||
cl->drops++;
|
||||
WRITE_ONCE(cl->drops, cl->drops + 1);
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
|
|
@ -665,7 +666,7 @@ static inline void htb_accnt_tokens(struct htb_class *cl, int bytes, s64 diff)
|
|||
if (toks <= -cl->mbuffer)
|
||||
toks = 1 - cl->mbuffer;
|
||||
|
||||
cl->tokens = toks;
|
||||
WRITE_ONCE(cl->tokens, toks);
|
||||
}
|
||||
|
||||
static inline void htb_accnt_ctokens(struct htb_class *cl, int bytes, s64 diff)
|
||||
|
|
@ -678,7 +679,7 @@ static inline void htb_accnt_ctokens(struct htb_class *cl, int bytes, s64 diff)
|
|||
if (toks <= -cl->mbuffer)
|
||||
toks = 1 - cl->mbuffer;
|
||||
|
||||
cl->ctokens = toks;
|
||||
WRITE_ONCE(cl->ctokens, toks);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -707,11 +708,12 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
|
|||
diff = min_t(s64, q->now - cl->t_c, cl->mbuffer);
|
||||
if (cl->level >= level) {
|
||||
if (cl->level == level)
|
||||
cl->xstats.lends++;
|
||||
WRITE_ONCE(cl->xstats_lends, cl->xstats_lends + 1);
|
||||
htb_accnt_tokens(cl, bytes, diff);
|
||||
} else {
|
||||
cl->xstats.borrows++;
|
||||
cl->tokens += diff; /* we moved t_c; update tokens */
|
||||
WRITE_ONCE(cl->xstats_borrows, cl->xstats_borrows + 1);
|
||||
/* we moved t_c; update tokens */
|
||||
WRITE_ONCE(cl->tokens, cl->tokens + diff);
|
||||
}
|
||||
htb_accnt_ctokens(cl, bytes, diff);
|
||||
cl->t_c = q->now;
|
||||
|
|
@ -1147,6 +1149,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt,
|
|||
* parts (especially calling ndo_setup_tc) on errors.
|
||||
*/
|
||||
q->offload = true;
|
||||
sch->flags |= TCQ_F_OFFLOADED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1207,17 +1210,12 @@ static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
|
|||
struct nlattr *nest;
|
||||
struct tc_htb_glob gopt;
|
||||
|
||||
if (q->offload)
|
||||
sch->flags |= TCQ_F_OFFLOADED;
|
||||
else
|
||||
sch->flags &= ~TCQ_F_OFFLOADED;
|
||||
|
||||
sch->qstats.overlimits = q->overlimits;
|
||||
sch->qstats.overlimits = READ_ONCE(q->overlimits);
|
||||
/* Its safe to not acquire qdisc lock. As we hold RTNL,
|
||||
* no change can happen on the qdisc parameters.
|
||||
*/
|
||||
|
||||
gopt.direct_pkts = q->direct_pkts;
|
||||
gopt.direct_pkts = READ_ONCE(q->direct_pkts);
|
||||
gopt.version = HTB_VER;
|
||||
gopt.rate2quantum = q->rate2quantum;
|
||||
gopt.defcls = q->defcls;
|
||||
|
|
@ -1323,19 +1321,23 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
|
|||
{
|
||||
struct htb_class *cl = (struct htb_class *)arg;
|
||||
struct htb_sched *q = qdisc_priv(sch);
|
||||
struct tc_htb_xstats xstats = {
|
||||
.lends = READ_ONCE(cl->xstats_lends),
|
||||
.borrows = READ_ONCE(cl->xstats_borrows),
|
||||
};
|
||||
struct gnet_stats_queue qs = {
|
||||
.drops = cl->drops,
|
||||
.overlimits = cl->overlimits,
|
||||
.drops = READ_ONCE(cl->drops),
|
||||
.overlimits = READ_ONCE(cl->overlimits),
|
||||
};
|
||||
__u32 qlen = 0;
|
||||
|
||||
if (!cl->level && cl->leaf.q)
|
||||
qdisc_qstats_qlen_backlog(cl->leaf.q, &qlen, &qs.backlog);
|
||||
|
||||
cl->xstats.tokens = clamp_t(s64, PSCHED_NS2TICKS(cl->tokens),
|
||||
INT_MIN, INT_MAX);
|
||||
cl->xstats.ctokens = clamp_t(s64, PSCHED_NS2TICKS(cl->ctokens),
|
||||
INT_MIN, INT_MAX);
|
||||
xstats.tokens = clamp_t(s64, PSCHED_NS2TICKS(READ_ONCE(cl->tokens)),
|
||||
INT_MIN, INT_MAX);
|
||||
xstats.ctokens = clamp_t(s64, PSCHED_NS2TICKS(READ_ONCE(cl->ctokens)),
|
||||
INT_MIN, INT_MAX);
|
||||
|
||||
if (q->offload) {
|
||||
if (!cl->level) {
|
||||
|
|
@ -1356,7 +1358,7 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
|
|||
gnet_stats_copy_queue(d, NULL, &qs, qlen) < 0)
|
||||
return -1;
|
||||
|
||||
return gnet_stats_copy_app(d, &cl->xstats, sizeof(cl->xstats));
|
||||
return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
|
||||
}
|
||||
|
||||
static struct netdev_queue *
|
||||
|
|
@ -1516,8 +1518,8 @@ static void htb_parent_to_leaf(struct Qdisc *sch, struct htb_class *cl,
|
|||
parent->level = 0;
|
||||
memset(&parent->inner, 0, sizeof(parent->inner));
|
||||
parent->leaf.q = new_q ? new_q : &noop_qdisc;
|
||||
parent->tokens = parent->buffer;
|
||||
parent->ctokens = parent->cbuffer;
|
||||
WRITE_ONCE(parent->tokens, parent->buffer);
|
||||
WRITE_ONCE(parent->ctokens, parent->cbuffer);
|
||||
parent->t_c = ktime_get_ns();
|
||||
parent->cmode = HTB_CAN_SEND;
|
||||
if (q->offload)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user