diff options
-rw-r--r-- | include/net/sch_generic.h | 31 | ||||
-rw-r--r-- | net/core/gen_stats.c | 2 | ||||
-rw-r--r-- | net/sched/sch_generic.c | 13 |
3 files changed, 19 insertions, 27 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 9481f2c142e2..e7eb4aa6ccc9 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h | |||
@@ -51,7 +51,10 @@ struct qdisc_size_table { | |||
51 | struct qdisc_skb_head { | 51 | struct qdisc_skb_head { |
52 | struct sk_buff *head; | 52 | struct sk_buff *head; |
53 | struct sk_buff *tail; | 53 | struct sk_buff *tail; |
54 | __u32 qlen; | 54 | union { |
55 | u32 qlen; | ||
56 | atomic_t atomic_qlen; | ||
57 | }; | ||
55 | spinlock_t lock; | 58 | spinlock_t lock; |
56 | }; | 59 | }; |
57 | 60 | ||
@@ -408,27 +411,19 @@ static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz) | |||
408 | BUILD_BUG_ON(sizeof(qcb->data) < sz); | 411 | BUILD_BUG_ON(sizeof(qcb->data) < sz); |
409 | } | 412 | } |
410 | 413 | ||
411 | static inline int qdisc_qlen_cpu(const struct Qdisc *q) | ||
412 | { | ||
413 | return this_cpu_ptr(q->cpu_qstats)->qlen; | ||
414 | } | ||
415 | |||
416 | static inline int qdisc_qlen(const struct Qdisc *q) | 414 | static inline int qdisc_qlen(const struct Qdisc *q) |
417 | { | 415 | { |
418 | return q->q.qlen; | 416 | return q->q.qlen; |
419 | } | 417 | } |
420 | 418 | ||
421 | static inline int qdisc_qlen_sum(const struct Qdisc *q) | 419 | static inline u32 qdisc_qlen_sum(const struct Qdisc *q) |
422 | { | 420 | { |
423 | __u32 qlen = q->qstats.qlen; | 421 | u32 qlen = q->qstats.qlen; |
424 | int i; | ||
425 | 422 | ||
426 | if (q->flags & TCQ_F_NOLOCK) { | 423 | if (q->flags & TCQ_F_NOLOCK) |
427 | for_each_possible_cpu(i) | 424 | qlen += atomic_read(&q->q.atomic_qlen); |
428 | qlen += per_cpu_ptr(q->cpu_qstats, i)->qlen; | 425 | else |
429 | } else { | ||
430 | qlen += q->q.qlen; | 426 | qlen += q->q.qlen; |
431 | } | ||
432 | 427 | ||
433 | return qlen; | 428 | return qlen; |
434 | } | 429 | } |
@@ -825,14 +820,14 @@ static inline void qdisc_qstats_cpu_backlog_inc(struct Qdisc *sch, | |||
825 | this_cpu_add(sch->cpu_qstats->backlog, qdisc_pkt_len(skb)); | 820 | this_cpu_add(sch->cpu_qstats->backlog, qdisc_pkt_len(skb)); |
826 | } | 821 | } |
827 | 822 | ||
828 | static inline void qdisc_qstats_cpu_qlen_inc(struct Qdisc *sch) | 823 | static inline void qdisc_qstats_atomic_qlen_inc(struct Qdisc *sch) |
829 | { | 824 | { |
830 | this_cpu_inc(sch->cpu_qstats->qlen); | 825 | atomic_inc(&sch->q.atomic_qlen); |
831 | } | 826 | } |
832 | 827 | ||
833 | static inline void qdisc_qstats_cpu_qlen_dec(struct Qdisc *sch) | 828 | static inline void qdisc_qstats_atomic_qlen_dec(struct Qdisc *sch) |
834 | { | 829 | { |
835 | this_cpu_dec(sch->cpu_qstats->qlen); | 830 | atomic_dec(&sch->q.atomic_qlen); |
836 | } | 831 | } |
837 | 832 | ||
838 | static inline void qdisc_qstats_cpu_requeues_inc(struct Qdisc *sch) | 833 | static inline void qdisc_qstats_cpu_requeues_inc(struct Qdisc *sch) |
diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c index 9bf1b9ad1780..ac679f74ba47 100644 --- a/net/core/gen_stats.c +++ b/net/core/gen_stats.c | |||
@@ -291,7 +291,6 @@ __gnet_stats_copy_queue_cpu(struct gnet_stats_queue *qstats, | |||
291 | for_each_possible_cpu(i) { | 291 | for_each_possible_cpu(i) { |
292 | const struct gnet_stats_queue *qcpu = per_cpu_ptr(q, i); | 292 | const struct gnet_stats_queue *qcpu = per_cpu_ptr(q, i); |
293 | 293 | ||
294 | qstats->qlen = 0; | ||
295 | qstats->backlog += qcpu->backlog; | 294 | qstats->backlog += qcpu->backlog; |
296 | qstats->drops += qcpu->drops; | 295 | qstats->drops += qcpu->drops; |
297 | qstats->requeues += qcpu->requeues; | 296 | qstats->requeues += qcpu->requeues; |
@@ -307,7 +306,6 @@ void __gnet_stats_copy_queue(struct gnet_stats_queue *qstats, | |||
307 | if (cpu) { | 306 | if (cpu) { |
308 | __gnet_stats_copy_queue_cpu(qstats, cpu); | 307 | __gnet_stats_copy_queue_cpu(qstats, cpu); |
309 | } else { | 308 | } else { |
310 | qstats->qlen = q->qlen; | ||
311 | qstats->backlog = q->backlog; | 309 | qstats->backlog = q->backlog; |
312 | qstats->drops = q->drops; | 310 | qstats->drops = q->drops; |
313 | qstats->requeues = q->requeues; | 311 | qstats->requeues = q->requeues; |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 968a85fe4d4a..de31f2f3b973 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -68,7 +68,7 @@ static inline struct sk_buff *__skb_dequeue_bad_txq(struct Qdisc *q) | |||
68 | skb = __skb_dequeue(&q->skb_bad_txq); | 68 | skb = __skb_dequeue(&q->skb_bad_txq); |
69 | if (qdisc_is_percpu_stats(q)) { | 69 | if (qdisc_is_percpu_stats(q)) { |
70 | qdisc_qstats_cpu_backlog_dec(q, skb); | 70 | qdisc_qstats_cpu_backlog_dec(q, skb); |
71 | qdisc_qstats_cpu_qlen_dec(q); | 71 | qdisc_qstats_atomic_qlen_dec(q); |
72 | } else { | 72 | } else { |
73 | qdisc_qstats_backlog_dec(q, skb); | 73 | qdisc_qstats_backlog_dec(q, skb); |
74 | q->q.qlen--; | 74 | q->q.qlen--; |
@@ -108,7 +108,7 @@ static inline void qdisc_enqueue_skb_bad_txq(struct Qdisc *q, | |||
108 | 108 | ||
109 | if (qdisc_is_percpu_stats(q)) { | 109 | if (qdisc_is_percpu_stats(q)) { |
110 | qdisc_qstats_cpu_backlog_inc(q, skb); | 110 | qdisc_qstats_cpu_backlog_inc(q, skb); |
111 | qdisc_qstats_cpu_qlen_inc(q); | 111 | qdisc_qstats_atomic_qlen_inc(q); |
112 | } else { | 112 | } else { |
113 | qdisc_qstats_backlog_inc(q, skb); | 113 | qdisc_qstats_backlog_inc(q, skb); |
114 | q->q.qlen++; | 114 | q->q.qlen++; |
@@ -147,7 +147,7 @@ static inline int dev_requeue_skb_locked(struct sk_buff *skb, struct Qdisc *q) | |||
147 | 147 | ||
148 | qdisc_qstats_cpu_requeues_inc(q); | 148 | qdisc_qstats_cpu_requeues_inc(q); |
149 | qdisc_qstats_cpu_backlog_inc(q, skb); | 149 | qdisc_qstats_cpu_backlog_inc(q, skb); |
150 | qdisc_qstats_cpu_qlen_inc(q); | 150 | qdisc_qstats_atomic_qlen_inc(q); |
151 | 151 | ||
152 | skb = next; | 152 | skb = next; |
153 | } | 153 | } |
@@ -252,7 +252,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate, | |||
252 | skb = __skb_dequeue(&q->gso_skb); | 252 | skb = __skb_dequeue(&q->gso_skb); |
253 | if (qdisc_is_percpu_stats(q)) { | 253 | if (qdisc_is_percpu_stats(q)) { |
254 | qdisc_qstats_cpu_backlog_dec(q, skb); | 254 | qdisc_qstats_cpu_backlog_dec(q, skb); |
255 | qdisc_qstats_cpu_qlen_dec(q); | 255 | qdisc_qstats_atomic_qlen_dec(q); |
256 | } else { | 256 | } else { |
257 | qdisc_qstats_backlog_dec(q, skb); | 257 | qdisc_qstats_backlog_dec(q, skb); |
258 | q->q.qlen--; | 258 | q->q.qlen--; |
@@ -645,7 +645,7 @@ static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc, | |||
645 | if (unlikely(err)) | 645 | if (unlikely(err)) |
646 | return qdisc_drop_cpu(skb, qdisc, to_free); | 646 | return qdisc_drop_cpu(skb, qdisc, to_free); |
647 | 647 | ||
648 | qdisc_qstats_cpu_qlen_inc(qdisc); | 648 | qdisc_qstats_atomic_qlen_inc(qdisc); |
649 | /* Note: skb can not be used after skb_array_produce(), | 649 | /* Note: skb can not be used after skb_array_produce(), |
650 | * so we better not use qdisc_qstats_cpu_backlog_inc() | 650 | * so we better not use qdisc_qstats_cpu_backlog_inc() |
651 | */ | 651 | */ |
@@ -670,7 +670,7 @@ static struct sk_buff *pfifo_fast_dequeue(struct Qdisc *qdisc) | |||
670 | if (likely(skb)) { | 670 | if (likely(skb)) { |
671 | qdisc_qstats_cpu_backlog_dec(qdisc, skb); | 671 | qdisc_qstats_cpu_backlog_dec(qdisc, skb); |
672 | qdisc_bstats_cpu_update(qdisc, skb); | 672 | qdisc_bstats_cpu_update(qdisc, skb); |
673 | qdisc_qstats_cpu_qlen_dec(qdisc); | 673 | qdisc_qstats_atomic_qlen_dec(qdisc); |
674 | } | 674 | } |
675 | 675 | ||
676 | return skb; | 676 | return skb; |
@@ -714,7 +714,6 @@ static void pfifo_fast_reset(struct Qdisc *qdisc) | |||
714 | struct gnet_stats_queue *q = per_cpu_ptr(qdisc->cpu_qstats, i); | 714 | struct gnet_stats_queue *q = per_cpu_ptr(qdisc->cpu_qstats, i); |
715 | 715 | ||
716 | q->backlog = 0; | 716 | q->backlog = 0; |
717 | q->qlen = 0; | ||
718 | } | 717 | } |
719 | } | 718 | } |
720 | 719 | ||