mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 14:12:06 +00:00
net_sched: factorize qdisc stats handling
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 <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f1593d2298
commit
bfe0d0298f
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -426,10 +426,18 @@ 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)
|
||||
{
|
||||
sch->bstats.bytes += len;
|
||||
sch->bstats.packets++;
|
||||
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)
|
||||
{
|
||||
bstats_update(&sch->bstats, skb);
|
||||
}
|
||||
|
||||
static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,
|
||||
@ -437,7 +445,7 @@ static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,
|
||||
{
|
||||
__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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
@ -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;
|
||||
|
@ -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);
|
||||
@ -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)) {
|
||||
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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++;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user