aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/sch_generic.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/sch_generic.h')
-rw-r--r--include/net/sch_generic.h76
1 files changed, 69 insertions, 7 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index dad558bc06fa..3c8728aaab4e 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -23,11 +23,17 @@ struct qdisc_rate_table {
23}; 23};
24 24
25enum qdisc_state_t { 25enum qdisc_state_t {
26 __QDISC_STATE_RUNNING,
27 __QDISC_STATE_SCHED, 26 __QDISC_STATE_SCHED,
28 __QDISC_STATE_DEACTIVATED, 27 __QDISC_STATE_DEACTIVATED,
29}; 28};
30 29
30/*
31 * following bits are only changed while qdisc lock is held
32 */
33enum qdisc___state_t {
34 __QDISC___STATE_RUNNING,
35};
36
31struct qdisc_size_table { 37struct qdisc_size_table {
32 struct list_head list; 38 struct list_head list;
33 struct tc_sizespec szopts; 39 struct tc_sizespec szopts;
@@ -72,9 +78,27 @@ struct Qdisc {
72 unsigned long state; 78 unsigned long state;
73 struct sk_buff_head q; 79 struct sk_buff_head q;
74 struct gnet_stats_basic_packed bstats; 80 struct gnet_stats_basic_packed bstats;
81 unsigned long __state;
75 struct gnet_stats_queue qstats; 82 struct gnet_stats_queue qstats;
83 struct rcu_head rcu_head;
84 spinlock_t busylock;
76}; 85};
77 86
87static inline bool qdisc_is_running(struct Qdisc *qdisc)
88{
89 return test_bit(__QDISC___STATE_RUNNING, &qdisc->__state);
90}
91
92static inline bool qdisc_run_begin(struct Qdisc *qdisc)
93{
94 return !__test_and_set_bit(__QDISC___STATE_RUNNING, &qdisc->__state);
95}
96
97static inline void qdisc_run_end(struct Qdisc *qdisc)
98{
99 __clear_bit(__QDISC___STATE_RUNNING, &qdisc->__state);
100}
101
78struct Qdisc_class_ops { 102struct Qdisc_class_ops {
79 /* Child qdisc manipulation */ 103 /* Child qdisc manipulation */
80 struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *); 104 struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *);
@@ -312,12 +336,24 @@ extern void qdisc_calculate_pkt_len(struct sk_buff *skb,
312extern void tcf_destroy(struct tcf_proto *tp); 336extern void tcf_destroy(struct tcf_proto *tp);
313extern void tcf_destroy_chain(struct tcf_proto **fl); 337extern void tcf_destroy_chain(struct tcf_proto **fl);
314 338
315/* Reset all TX qdiscs of a device. */ 339/* Reset all TX qdiscs greater then index of a device. */
340static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i)
341{
342 struct Qdisc *qdisc;
343
344 for (; i < dev->num_tx_queues; i++) {
345 qdisc = netdev_get_tx_queue(dev, i)->qdisc;
346 if (qdisc) {
347 spin_lock_bh(qdisc_lock(qdisc));
348 qdisc_reset(qdisc);
349 spin_unlock_bh(qdisc_lock(qdisc));
350 }
351 }
352}
353
316static inline void qdisc_reset_all_tx(struct net_device *dev) 354static inline void qdisc_reset_all_tx(struct net_device *dev)
317{ 355{
318 unsigned int i; 356 qdisc_reset_all_tx_gt(dev, 0);
319 for (i = 0; i < dev->num_tx_queues; i++)
320 qdisc_reset(netdev_get_tx_queue(dev, i)->qdisc);
321} 357}
322 358
323/* Are all TX queues of the device empty? */ 359/* Are all TX queues of the device empty? */
@@ -427,6 +463,25 @@ static inline struct sk_buff *qdisc_dequeue_head(struct Qdisc *sch)
427 return __qdisc_dequeue_head(sch, &sch->q); 463 return __qdisc_dequeue_head(sch, &sch->q);
428} 464}
429 465
466static inline unsigned int __qdisc_queue_drop_head(struct Qdisc *sch,
467 struct sk_buff_head *list)
468{
469 struct sk_buff *skb = __qdisc_dequeue_head(sch, list);
470
471 if (likely(skb != NULL)) {
472 unsigned int len = qdisc_pkt_len(skb);
473 kfree_skb(skb);
474 return len;
475 }
476
477 return 0;
478}
479
480static inline unsigned int qdisc_queue_drop_head(struct Qdisc *sch)
481{
482 return __qdisc_queue_drop_head(sch, &sch->q);
483}
484
430static inline struct sk_buff *__qdisc_dequeue_tail(struct Qdisc *sch, 485static inline struct sk_buff *__qdisc_dequeue_tail(struct Qdisc *sch,
431 struct sk_buff_head *list) 486 struct sk_buff_head *list)
432{ 487{
@@ -551,9 +606,16 @@ static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen)
551} 606}
552 607
553#ifdef CONFIG_NET_CLS_ACT 608#ifdef CONFIG_NET_CLS_ACT
554static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask) 609static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask,
610 int action)
555{ 611{
556 struct sk_buff *n = skb_clone(skb, gfp_mask); 612 struct sk_buff *n;
613
614 if ((action == TC_ACT_STOLEN || action == TC_ACT_QUEUED) &&
615 !skb_shared(skb))
616 n = skb_get(skb);
617 else
618 n = skb_clone(skb, gfp_mask);
557 619
558 if (n) { 620 if (n) {
559 n->tc_verd = SET_TC_VERD(n->tc_verd, 0); 621 n->tc_verd = SET_TC_VERD(n->tc_verd, 0);