Skip to content

Commit

Permalink
net: sched: implement qstat helper routines
Browse files Browse the repository at this point in the history
This adds helpers to manipulate qstats logic and replaces locations
that touch the counters directly. This simplifies future patches
to push qstats onto per cpu counters.

Signed-off-by: John Fastabend <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
jrfastab authored and davem330 committed Sep 30, 2014
1 parent 22e0f8b commit 25331d6
Show file tree
Hide file tree
Showing 25 changed files with 108 additions and 81 deletions.
39 changes: 33 additions & 6 deletions include/net/sch_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,38 @@ static inline void qdisc_bstats_update(struct Qdisc *sch,
bstats_update(&sch->bstats, skb);
}

static inline void qdisc_qstats_backlog_dec(struct Qdisc *sch,
const struct sk_buff *skb)
{
sch->qstats.backlog -= qdisc_pkt_len(skb);
}

static inline void qdisc_qstats_backlog_inc(struct Qdisc *sch,
const struct sk_buff *skb)
{
sch->qstats.backlog += qdisc_pkt_len(skb);
}

static inline void __qdisc_qstats_drop(struct Qdisc *sch, int count)
{
sch->qstats.drops += count;
}

static inline void qdisc_qstats_drop(struct Qdisc *sch)
{
sch->qstats.drops++;
}

static inline void qdisc_qstats_overlimit(struct Qdisc *sch)
{
sch->qstats.overlimits++;
}

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_qstats_backlog_inc(sch, skb);

return NET_XMIT_SUCCESS;
}
Expand All @@ -541,7 +568,7 @@ static inline struct sk_buff *__qdisc_dequeue_head(struct Qdisc *sch,
struct sk_buff *skb = __skb_dequeue(list);

if (likely(skb != NULL)) {
sch->qstats.backlog -= qdisc_pkt_len(skb);
qdisc_qstats_backlog_dec(sch, skb);
qdisc_bstats_update(sch, skb);
}

Expand All @@ -560,7 +587,7 @@ static inline unsigned int __qdisc_queue_drop_head(struct Qdisc *sch,

if (likely(skb != NULL)) {
unsigned int len = qdisc_pkt_len(skb);
sch->qstats.backlog -= len;
qdisc_qstats_backlog_dec(sch, skb);
kfree_skb(skb);
return len;
}
Expand All @@ -579,7 +606,7 @@ static inline struct sk_buff *__qdisc_dequeue_tail(struct Qdisc *sch,
struct sk_buff *skb = __skb_dequeue_tail(list);

if (likely(skb != NULL))
sch->qstats.backlog -= qdisc_pkt_len(skb);
qdisc_qstats_backlog_dec(sch, skb);

return skb;
}
Expand Down Expand Up @@ -661,14 +688,14 @@ static inline unsigned int qdisc_queue_drop(struct Qdisc *sch)
static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch)
{
kfree_skb(skb);
sch->qstats.drops++;
qdisc_qstats_drop(sch);

return NET_XMIT_DROP;
}

static inline int qdisc_reshape_fail(struct sk_buff *skb, struct Qdisc *sch)
{
sch->qstats.drops++;
qdisc_qstats_drop(sch);

#ifdef CONFIG_NET_CLS_ACT
if (sch->reshape_fail == NULL || sch->reshape_fail(skb, sch))
Expand Down
2 changes: 1 addition & 1 deletion net/sched/sch_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
cops->put(sch, cl);
}
sch->q.qlen -= n;
sch->qstats.drops += drops;
__qdisc_qstats_drop(sch, drops);
}
}
EXPORT_SYMBOL(qdisc_tree_decrease_qlen);
Expand Down
2 changes: 1 addition & 1 deletion net/sched/sch_atm.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
if (ret != NET_XMIT_SUCCESS) {
drop: __maybe_unused
if (net_xmit_drop_count(ret)) {
sch->qstats.drops++;
qdisc_qstats_drop(sch);
if (flow)
flow->qstats.drops++;
}
Expand Down
10 changes: 5 additions & 5 deletions net/sched/sch_cbq.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
#endif
if (cl == NULL) {
if (ret & __NET_XMIT_BYPASS)
sch->qstats.drops++;
qdisc_qstats_drop(sch);
kfree_skb(skb);
return ret;
}
Expand All @@ -395,7 +395,7 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
}

if (net_xmit_drop_count(ret)) {
sch->qstats.drops++;
qdisc_qstats_drop(sch);
cbq_mark_toplevel(q, cl);
cl->qstats.drops++;
}
Expand Down Expand Up @@ -650,11 +650,11 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child)
return 0;
}
if (net_xmit_drop_count(ret))
sch->qstats.drops++;
qdisc_qstats_drop(sch);
return 0;
}

sch->qstats.drops++;
qdisc_qstats_drop(sch);
return -1;
}
#endif
Expand Down Expand Up @@ -995,7 +995,7 @@ cbq_dequeue(struct Qdisc *sch)
*/

if (sch->q.qlen) {
sch->qstats.overlimits++;
qdisc_qstats_overlimit(sch);
if (q->wd_expires)
qdisc_watchdog_schedule(&q->watchdog,
now + q->wd_expires);
Expand Down
14 changes: 7 additions & 7 deletions net/sched/sch_choke.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ static void choke_drop_by_idx(struct Qdisc *sch, unsigned int idx)
if (idx == q->tail)
choke_zap_tail_holes(q);

sch->qstats.backlog -= qdisc_pkt_len(skb);
qdisc_qstats_backlog_dec(sch, skb);
qdisc_drop(skb, sch);
qdisc_tree_decrease_qlen(sch, 1);
--sch->q.qlen;
Expand Down Expand Up @@ -302,7 +302,7 @@ static int choke_enqueue(struct sk_buff *skb, struct Qdisc *sch)
if (q->vars.qavg > p->qth_max) {
q->vars.qcount = -1;

sch->qstats.overlimits++;
qdisc_qstats_overlimit(sch);
if (use_harddrop(q) || !use_ecn(q) ||
!INET_ECN_set_ce(skb)) {
q->stats.forced_drop++;
Expand All @@ -315,7 +315,7 @@ static int choke_enqueue(struct sk_buff *skb, struct Qdisc *sch)
q->vars.qcount = 0;
q->vars.qR = red_random(p);

sch->qstats.overlimits++;
qdisc_qstats_overlimit(sch);
if (!use_ecn(q) || !INET_ECN_set_ce(skb)) {
q->stats.prob_drop++;
goto congestion_drop;
Expand All @@ -332,7 +332,7 @@ static int choke_enqueue(struct sk_buff *skb, struct Qdisc *sch)
q->tab[q->tail] = skb;
q->tail = (q->tail + 1) & q->tab_mask;
++sch->q.qlen;
sch->qstats.backlog += qdisc_pkt_len(skb);
qdisc_qstats_backlog_inc(sch, skb);
return NET_XMIT_SUCCESS;
}

Expand All @@ -345,7 +345,7 @@ static int choke_enqueue(struct sk_buff *skb, struct Qdisc *sch)

other_drop:
if (ret & __NET_XMIT_BYPASS)
sch->qstats.drops++;
qdisc_qstats_drop(sch);
kfree_skb(skb);
return ret;
}
Expand All @@ -365,7 +365,7 @@ static struct sk_buff *choke_dequeue(struct Qdisc *sch)
q->tab[q->head] = NULL;
choke_zap_head_holes(q);
--sch->q.qlen;
sch->qstats.backlog -= qdisc_pkt_len(skb);
qdisc_qstats_backlog_dec(sch, skb);
qdisc_bstats_update(sch, skb);

return skb;
Expand Down Expand Up @@ -460,7 +460,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)
ntab[tail++] = skb;
continue;
}
sch->qstats.backlog -= qdisc_pkt_len(skb);
qdisc_qstats_backlog_dec(sch, skb);
--sch->q.qlen;
qdisc_drop(skb, sch);
}
Expand Down
2 changes: 1 addition & 1 deletion net/sched/sch_codel.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ static int codel_change(struct Qdisc *sch, struct nlattr *opt)
while (sch->q.qlen > sch->limit) {
struct sk_buff *skb = __skb_dequeue(&sch->q);

sch->qstats.backlog -= qdisc_pkt_len(skb);
qdisc_qstats_backlog_dec(sch, skb);
qdisc_drop(skb, sch);
}
qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen);
Expand Down
4 changes: 2 additions & 2 deletions net/sched/sch_drr.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch)
cl = drr_classify(skb, sch, &err);
if (cl == NULL) {
if (err & __NET_XMIT_BYPASS)
sch->qstats.drops++;
qdisc_qstats_drop(sch);
kfree_skb(skb);
return err;
}
Expand All @@ -369,7 +369,7 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch)
if (unlikely(err != NET_XMIT_SUCCESS)) {
if (net_xmit_drop_count(err)) {
cl->qstats.drops++;
sch->qstats.drops++;
qdisc_qstats_drop(sch);
}
return err;
}
Expand Down
2 changes: 1 addition & 1 deletion net/sched/sch_dsmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
err = qdisc_enqueue(skb, p->q);
if (err != NET_XMIT_SUCCESS) {
if (net_xmit_drop_count(err))
sch->qstats.drops++;
qdisc_qstats_drop(sch);
return err;
}

Expand Down
2 changes: 1 addition & 1 deletion net/sched/sch_fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch)

/* queue full, remove one skb to fulfill the limit */
__qdisc_queue_drop_head(sch, &sch->q);
sch->qstats.drops++;
qdisc_qstats_drop(sch);
qdisc_enqueue_tail(skb, sch);

return NET_XMIT_CN;
Expand Down
4 changes: 2 additions & 2 deletions net/sched/sch_fq.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ static struct sk_buff *fq_dequeue_head(struct Qdisc *sch, struct fq_flow *flow)
flow->head = skb->next;
skb->next = NULL;
flow->qlen--;
sch->qstats.backlog -= qdisc_pkt_len(skb);
qdisc_qstats_backlog_dec(sch, skb);
sch->q.qlen--;
}
return skb;
Expand Down Expand Up @@ -371,7 +371,7 @@ static int fq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
f->qlen++;
if (skb_is_retransmit(skb))
q->stat_tcp_retrans++;
sch->qstats.backlog += qdisc_pkt_len(skb);
qdisc_qstats_backlog_inc(sch, skb);
if (fq_flow_is_detached(f)) {
fq_flow_add_tail(&q->new_flows, f);
if (time_after(jiffies, f->age + q->flow_refill_delay))
Expand Down
8 changes: 4 additions & 4 deletions net/sched/sch_fq_codel.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ static unsigned int fq_codel_drop(struct Qdisc *sch)
q->backlogs[idx] -= len;
kfree_skb(skb);
sch->q.qlen--;
sch->qstats.drops++;
sch->qstats.backlog -= len;
qdisc_qstats_drop(sch);
qdisc_qstats_backlog_dec(sch, skb);
flow->dropped++;
return idx;
}
Expand All @@ -180,7 +180,7 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch)
idx = fq_codel_classify(skb, sch, &ret);
if (idx == 0) {
if (ret & __NET_XMIT_BYPASS)
sch->qstats.drops++;
qdisc_qstats_drop(sch);
kfree_skb(skb);
return ret;
}
Expand All @@ -190,7 +190,7 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch)
flow = &q->flows[idx];
flow_queue_add(flow, skb);
q->backlogs[idx] += qdisc_pkt_len(skb);
sch->qstats.backlog += qdisc_pkt_len(skb);
qdisc_qstats_backlog_inc(sch, skb);

if (list_empty(&flow->flowchain)) {
list_add_tail(&flow->flowchain, &q->new_flows);
Expand Down
4 changes: 2 additions & 2 deletions net/sched/sch_gred.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ static int gred_enqueue(struct sk_buff *skb, struct Qdisc *sch)
break;

case RED_PROB_MARK:
sch->qstats.overlimits++;
qdisc_qstats_overlimit(sch);
if (!gred_use_ecn(t) || !INET_ECN_set_ce(skb)) {
q->stats.prob_drop++;
goto congestion_drop;
Expand All @@ -219,7 +219,7 @@ static int gred_enqueue(struct sk_buff *skb, struct Qdisc *sch)
break;

case RED_HARD_MARK:
sch->qstats.overlimits++;
qdisc_qstats_overlimit(sch);
if (gred_use_harddrop(t) || !gred_use_ecn(t) ||
!INET_ECN_set_ce(skb)) {
q->stats.forced_drop++;
Expand Down
8 changes: 4 additions & 4 deletions net/sched/sch_hfsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1591,7 +1591,7 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
cl = hfsc_classify(skb, sch, &err);
if (cl == NULL) {
if (err & __NET_XMIT_BYPASS)
sch->qstats.drops++;
qdisc_qstats_drop(sch);
kfree_skb(skb);
return err;
}
Expand All @@ -1600,7 +1600,7 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
if (unlikely(err != NET_XMIT_SUCCESS)) {
if (net_xmit_drop_count(err)) {
cl->qstats.drops++;
sch->qstats.drops++;
qdisc_qstats_drop(sch);
}
return err;
}
Expand Down Expand Up @@ -1643,7 +1643,7 @@ hfsc_dequeue(struct Qdisc *sch)
*/
cl = vttree_get_minvt(&q->root, cur_time);
if (cl == NULL) {
sch->qstats.overlimits++;
qdisc_qstats_overlimit(sch);
hfsc_schedule_watchdog(sch);
return NULL;
}
Expand Down Expand Up @@ -1698,7 +1698,7 @@ hfsc_drop(struct Qdisc *sch)
list_move_tail(&cl->dlist, &q->droplist);
}
cl->qstats.drops++;
sch->qstats.drops++;
qdisc_qstats_drop(sch);
sch->q.qlen--;
return len;
}
Expand Down
8 changes: 4 additions & 4 deletions net/sched/sch_hhf.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,8 @@ static unsigned int hhf_drop(struct Qdisc *sch)
struct sk_buff *skb = dequeue_head(bucket);

sch->q.qlen--;
sch->qstats.drops++;
sch->qstats.backlog -= qdisc_pkt_len(skb);
qdisc_qstats_drop(sch);
qdisc_qstats_backlog_dec(sch, skb);
kfree_skb(skb);
}

Expand All @@ -395,7 +395,7 @@ static int hhf_enqueue(struct sk_buff *skb, struct Qdisc *sch)

bucket = &q->buckets[idx];
bucket_add(bucket, skb);
sch->qstats.backlog += qdisc_pkt_len(skb);
qdisc_qstats_backlog_inc(sch, skb);

if (list_empty(&bucket->bucketchain)) {
unsigned int weight;
Expand Down Expand Up @@ -457,7 +457,7 @@ static struct sk_buff *hhf_dequeue(struct Qdisc *sch)
if (bucket->head) {
skb = dequeue_head(bucket);
sch->q.qlen--;
sch->qstats.backlog -= qdisc_pkt_len(skb);
qdisc_qstats_backlog_dec(sch, skb);
}

if (!skb) {
Expand Down
Loading

0 comments on commit 25331d6

Please sign in to comment.