On Thu, 17 Oct 2019 11:10:06 -0700, Cong Wang wrote: > On Wed, Oct 16, 2019 at 4:22 PM Jakub Kicinski wrote: > > On Wed, 16 Oct 2019 15:42:28 -0700, Cong Wang wrote: > > > > @@ -612,7 +613,7 @@ static int netem_enqueue(struct sk_buff *skb, > > > > struct Qdisc *sch, > > > > } > > > > segs = skb2; > > > > } > > > > - qdisc_tree_reduce_backlog(sch, -nb, prev_len - len); > > > > + qdisc_tree_reduce_backlog(sch, !skb - nb, prev_len - > > > > len); > > > > > > Am I the only one has trouble to understand the expression > > > "!skb - nb"? > > > > The backward logic of qdisc_tree_reduce_backlog() always gives me a > > pause :S > > Yeah, reducing with a negative value is actually an add. Feel free > to add a wrapper for this if you think it is better.
I was avoiding adding the wrapper due to stable, but perhaps it should be okay. How does this look? --->8-------------- diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 637548d54b3e..66c2dc6a4742 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -630,6 +630,13 @@ void qdisc_reset(struct Qdisc *qdisc); void qdisc_put(struct Qdisc *qdisc); void qdisc_put_unlocked(struct Qdisc *qdisc); void qdisc_tree_reduce_backlog(struct Qdisc *qdisc, int n, int len); + +static inline void +qdisc_tree_increase_backlog(struct Qdisc *qdisc, int n, int len) +{ + qdisc_tree_reduce_backlog(qdisc, -n, -len); +} + #ifdef CONFIG_NET_SCHED int qdisc_offload_dump_helper(struct Qdisc *q, enum tc_setup_type type, void *type_data); diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 0e44039e729c..e22c13b56bfc 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -509,6 +509,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) { qdisc_drop(skb, sch, to_free); + skb = NULL; goto finish_segs; } @@ -592,10 +593,13 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, finish_segs: if (segs) { - unsigned int len, last_len; + unsigned int last_len, len = 0; int nb = 0; - len = skb->len; + if (skb) { + len += skb->len; + nb++; + } while (segs) { skb2 = segs->next; @@ -612,7 +616,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, } segs = skb2; } - qdisc_tree_reduce_backlog(sch, -nb, prev_len - len); + /* Parent qdiscs accounted for 1 skb of size @prev_len */ + qdisc_tree_increase_backlog(sch, nb - 1, len - prev_len); } return NET_XMIT_SUCCESS; }