Skip to content

Commit

Permalink
net_sched: factorize qdisc stats handling
Browse files Browse the repository at this point in the history
HTB takes into account skb is segmented in stats updates.
Generalize this to all schedulers.

They should use qdisc_bstats_update() helper instead of manipulating
bstats.bytes and bstats.packets

Add bstats_update() helper too for classes that use
gnet_stats_basic_packed fields.

Note : Right now, TCQ_F_CAN_BYPASS shortcurt can be taken only if no
stab is setup on qdisc.

Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Eric Dumazet authored and davem330 committed Jan 11, 2011
1 parent f1593d2 commit bfe0d02
Show file tree
Hide file tree
Showing 24 changed files with 50 additions and 72 deletions.
20 changes: 14 additions & 6 deletions include/net/sch_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ static inline int qdisc_qlen(struct Qdisc *q)
return q->q.qlen;
}

static inline struct qdisc_skb_cb *qdisc_skb_cb(struct sk_buff *skb)
static inline struct qdisc_skb_cb *qdisc_skb_cb(const struct sk_buff *skb)
{
return (struct qdisc_skb_cb *)skb->cb;
}
Expand Down Expand Up @@ -394,7 +394,7 @@ static inline bool qdisc_tx_is_noop(const struct net_device *dev)
return true;
}

static inline unsigned int qdisc_pkt_len(struct sk_buff *skb)
static inline unsigned int qdisc_pkt_len(const struct sk_buff *skb)
{
return qdisc_skb_cb(skb)->pkt_len;
}
Expand Down Expand Up @@ -426,18 +426,26 @@ static inline int qdisc_enqueue_root(struct sk_buff *skb, struct Qdisc *sch)
return qdisc_enqueue(skb, sch) & NET_XMIT_MASK;
}

static inline void __qdisc_update_bstats(struct Qdisc *sch, unsigned int len)

static inline void bstats_update(struct gnet_stats_basic_packed *bstats,
const struct sk_buff *skb)
{
bstats->bytes += qdisc_pkt_len(skb);
bstats->packets += skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1;
}

static inline void qdisc_bstats_update(struct Qdisc *sch,
const struct sk_buff *skb)
{
sch->bstats.bytes += len;
sch->bstats.packets++;
bstats_update(&sch->bstats, skb);
}

static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff_head *list)
{
__skb_queue_tail(list, skb);
sch->qstats.backlog += qdisc_pkt_len(skb);
__qdisc_update_bstats(sch, qdisc_pkt_len(skb));
qdisc_bstats_update(sch, skb);

return NET_XMIT_SUCCESS;
}
Expand Down
5 changes: 4 additions & 1 deletion net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2297,7 +2297,10 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
*/
if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE))
skb_dst_force(skb);
__qdisc_update_bstats(q, skb->len);

qdisc_skb_cb(skb)->pkt_len = skb->len;
qdisc_bstats_update(q, skb);

if (sch_direct_xmit(skb, q, dev, txq, root_lock)) {
if (unlikely(contended)) {
spin_unlock(&q->busylock);
Expand Down
3 changes: 1 addition & 2 deletions net/sched/act_csum.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,7 @@ static int tcf_csum(struct sk_buff *skb,

spin_lock(&p->tcf_lock);
p->tcf_tm.lastuse = jiffies;
p->tcf_bstats.bytes += qdisc_pkt_len(skb);
p->tcf_bstats.packets++;
bstats_update(&p->tcf_bstats, skb);
action = p->tcf_action;
update_flags = p->update_flags;
spin_unlock(&p->tcf_lock);
Expand Down
3 changes: 1 addition & 2 deletions net/sched/act_ipt.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
spin_lock(&ipt->tcf_lock);

ipt->tcf_tm.lastuse = jiffies;
ipt->tcf_bstats.bytes += qdisc_pkt_len(skb);
ipt->tcf_bstats.packets++;
bstats_update(&ipt->tcf_bstats, skb);

/* yes, we have to worry about both in and out dev
worry later - danger - this API seems to have changed
Expand Down
3 changes: 1 addition & 2 deletions net/sched/act_mirred.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,7 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a,

spin_lock(&m->tcf_lock);
m->tcf_tm.lastuse = jiffies;
m->tcf_bstats.bytes += qdisc_pkt_len(skb);
m->tcf_bstats.packets++;
bstats_update(&m->tcf_bstats, skb);

dev = m->tcfm_dev;
if (!dev) {
Expand Down
3 changes: 1 addition & 2 deletions net/sched/act_nat.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
egress = p->flags & TCA_NAT_FLAG_EGRESS;
action = p->tcf_action;

p->tcf_bstats.bytes += qdisc_pkt_len(skb);
p->tcf_bstats.packets++;
bstats_update(&p->tcf_bstats, skb);

spin_unlock(&p->tcf_lock);

Expand Down
3 changes: 1 addition & 2 deletions net/sched/act_pedit.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,7 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
bad:
p->tcf_qstats.overlimits++;
done:
p->tcf_bstats.bytes += qdisc_pkt_len(skb);
p->tcf_bstats.packets++;
bstats_update(&p->tcf_bstats, skb);
spin_unlock(&p->tcf_lock);
return p->tcf_action;
}
Expand Down
3 changes: 1 addition & 2 deletions net/sched/act_police.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,7 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a,

spin_lock(&police->tcf_lock);

police->tcf_bstats.bytes += qdisc_pkt_len(skb);
police->tcf_bstats.packets++;
bstats_update(&police->tcf_bstats, skb);

if (police->tcfp_ewma_rate &&
police->tcf_rate_est.bps >= police->tcfp_ewma_rate) {
Expand Down
3 changes: 1 addition & 2 deletions net/sched/act_simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result

spin_lock(&d->tcf_lock);
d->tcf_tm.lastuse = jiffies;
d->tcf_bstats.bytes += qdisc_pkt_len(skb);
d->tcf_bstats.packets++;
bstats_update(&d->tcf_bstats, skb);

/* print policy string followed by _ then packet count
* Example if this was the 3rd packet and the string was "hello"
Expand Down
3 changes: 1 addition & 2 deletions net/sched/act_skbedit.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ static int tcf_skbedit(struct sk_buff *skb, struct tc_action *a,

spin_lock(&d->tcf_lock);
d->tcf_tm.lastuse = jiffies;
d->tcf_bstats.bytes += qdisc_pkt_len(skb);
d->tcf_bstats.packets++;
bstats_update(&d->tcf_bstats, skb);

if (d->flags & SKBEDIT_F_PRIORITY)
skb->priority = d->priority;
Expand Down
6 changes: 2 additions & 4 deletions net/sched/sch_atm.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,10 +422,8 @@ drop: __maybe_unused
}
return ret;
}
sch->bstats.bytes += qdisc_pkt_len(skb);
sch->bstats.packets++;
flow->bstats.bytes += qdisc_pkt_len(skb);
flow->bstats.packets++;
qdisc_bstats_update(sch, skb);
bstats_update(&flow->bstats, skb);
/*
* Okay, this may seem weird. We pretend we've dropped the packet if
* it goes via ATM. The reason for this is that the outer qdisc
Expand Down
6 changes: 2 additions & 4 deletions net/sched/sch_cbq.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,7 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
ret = qdisc_enqueue(skb, cl->q);
if (ret == NET_XMIT_SUCCESS) {
sch->q.qlen++;
sch->bstats.packets++;
sch->bstats.bytes += qdisc_pkt_len(skb);
qdisc_bstats_update(sch, skb);
cbq_mark_toplevel(q, cl);
if (!cl->next_alive)
cbq_activate_class(cl);
Expand Down Expand Up @@ -650,8 +649,7 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child)
ret = qdisc_enqueue(skb, cl->q);
if (ret == NET_XMIT_SUCCESS) {
sch->q.qlen++;
sch->bstats.packets++;
sch->bstats.bytes += qdisc_pkt_len(skb);
qdisc_bstats_update(sch, skb);
if (!cl->next_alive)
cbq_activate_class(cl);
return 0;
Expand Down
8 changes: 2 additions & 6 deletions net/sched/sch_drr.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch)
{
struct drr_sched *q = qdisc_priv(sch);
struct drr_class *cl;
unsigned int len;
int err;

cl = drr_classify(skb, sch, &err);
Expand All @@ -362,7 +361,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch)
return err;
}

len = qdisc_pkt_len(skb);
err = qdisc_enqueue(skb, cl->qdisc);
if (unlikely(err != NET_XMIT_SUCCESS)) {
if (net_xmit_drop_count(err)) {
Expand All @@ -377,10 +375,8 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch)
cl->deficit = cl->quantum;
}

cl->bstats.packets++;
cl->bstats.bytes += len;
sch->bstats.packets++;
sch->bstats.bytes += len;
bstats_update(&cl->bstats, skb);
qdisc_bstats_update(sch, skb);

sch->q.qlen++;
return err;
Expand Down
3 changes: 1 addition & 2 deletions net/sched/sch_dsmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
return err;
}

sch->bstats.bytes += qdisc_pkt_len(skb);
sch->bstats.packets++;
qdisc_bstats_update(sch, skb);
sch->q.qlen++;

return NET_XMIT_SUCCESS;
Expand Down
6 changes: 2 additions & 4 deletions net/sched/sch_hfsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1599,10 +1599,8 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
if (cl->qdisc->q.qlen == 1)
set_active(cl, qdisc_pkt_len(skb));

cl->bstats.packets++;
cl->bstats.bytes += qdisc_pkt_len(skb);
sch->bstats.packets++;
sch->bstats.bytes += qdisc_pkt_len(skb);
bstats_update(&cl->bstats, skb);
qdisc_bstats_update(sch, skb);
sch->q.qlen++;

return NET_XMIT_SUCCESS;
Expand Down
17 changes: 6 additions & 11 deletions net/sched/sch_htb.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,15 +569,12 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
}
return ret;
} else {
cl->bstats.packets +=
skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
cl->bstats.bytes += qdisc_pkt_len(skb);
bstats_update(&cl->bstats, skb);
htb_activate(q, cl);
}

sch->q.qlen++;
sch->bstats.packets += skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
sch->bstats.bytes += qdisc_pkt_len(skb);
qdisc_bstats_update(sch, skb);
return NET_XMIT_SUCCESS;
}

Expand Down Expand Up @@ -648,12 +645,10 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
htb_add_to_wait_tree(q, cl, diff);
}

/* update byte stats except for leaves which are already updated */
if (cl->level) {
cl->bstats.bytes += bytes;
cl->bstats.packets += skb_is_gso(skb)?
skb_shinfo(skb)->gso_segs:1;
}
/* update basic stats except for leaves which are already updated */
if (cl->level)
bstats_update(&cl->bstats, skb);

cl = cl->parent;
}
}
Expand Down
3 changes: 1 addition & 2 deletions net/sched/sch_ingress.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ static int ingress_enqueue(struct sk_buff *skb, struct Qdisc *sch)

result = tc_classify(skb, p->filter_list, &res);

sch->bstats.packets++;
sch->bstats.bytes += qdisc_pkt_len(skb);
qdisc_bstats_update(sch, skb);
switch (result) {
case TC_ACT_SHOT:
result = TC_ACT_SHOT;
Expand Down
3 changes: 1 addition & 2 deletions net/sched/sch_multiq.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ multiq_enqueue(struct sk_buff *skb, struct Qdisc *sch)

ret = qdisc_enqueue(skb, qdisc);
if (ret == NET_XMIT_SUCCESS) {
sch->bstats.bytes += qdisc_pkt_len(skb);
sch->bstats.packets++;
qdisc_bstats_update(sch, skb);
sch->q.qlen++;
return NET_XMIT_SUCCESS;
}
Expand Down
6 changes: 2 additions & 4 deletions net/sched/sch_netem.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)

if (likely(ret == NET_XMIT_SUCCESS)) {
sch->q.qlen++;
sch->bstats.bytes += qdisc_pkt_len(skb);
sch->bstats.packets++;
qdisc_bstats_update(sch, skb);
} else if (net_xmit_drop_count(ret)) {
sch->qstats.drops++;
}
Expand Down Expand Up @@ -477,8 +476,7 @@ static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch)
__skb_queue_after(list, skb, nskb);

sch->qstats.backlog += qdisc_pkt_len(nskb);
sch->bstats.bytes += qdisc_pkt_len(nskb);
sch->bstats.packets++;
qdisc_bstats_update(sch, nskb);

return NET_XMIT_SUCCESS;
}
Expand Down
3 changes: 1 addition & 2 deletions net/sched/sch_prio.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)

ret = qdisc_enqueue(skb, qdisc);
if (ret == NET_XMIT_SUCCESS) {
sch->bstats.bytes += qdisc_pkt_len(skb);
sch->bstats.packets++;
qdisc_bstats_update(sch, skb);
sch->q.qlen++;
return NET_XMIT_SUCCESS;
}
Expand Down
3 changes: 1 addition & 2 deletions net/sched/sch_red.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc* sch)

ret = qdisc_enqueue(skb, child);
if (likely(ret == NET_XMIT_SUCCESS)) {
sch->bstats.bytes += qdisc_pkt_len(skb);
sch->bstats.packets++;
qdisc_bstats_update(sch, skb);
sch->q.qlen++;
} else if (net_xmit_drop_count(ret)) {
q->stats.pdrop++;
Expand Down
3 changes: 1 addition & 2 deletions net/sched/sch_sfq.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
slot->allot = q->scaled_quantum;
}
if (++sch->q.qlen <= q->limit) {
sch->bstats.bytes += qdisc_pkt_len(skb);
sch->bstats.packets++;
qdisc_bstats_update(sch, skb);
return NET_XMIT_SUCCESS;
}

Expand Down
3 changes: 1 addition & 2 deletions net/sched/sch_tbf.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch)
}

sch->q.qlen++;
sch->bstats.bytes += qdisc_pkt_len(skb);
sch->bstats.packets++;
qdisc_bstats_update(sch, skb);
return NET_XMIT_SUCCESS;
}

Expand Down
3 changes: 1 addition & 2 deletions net/sched/sch_teql.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc* sch)

if (q->q.qlen < dev->tx_queue_len) {
__skb_queue_tail(&q->q, skb);
sch->bstats.bytes += qdisc_pkt_len(skb);
sch->bstats.packets++;
qdisc_bstats_update(sch, skb);
return NET_XMIT_SUCCESS;
}

Expand Down

0 comments on commit bfe0d02

Please sign in to comment.