diff options
Diffstat (limited to 'include/net/sch_generic.h')
-rw-r--r-- | include/net/sch_generic.h | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 433604bb3fe8..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 | ||
25 | enum qdisc_state_t { | 25 | enum 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 | */ | ||
33 | enum qdisc___state_t { | ||
34 | __QDISC___STATE_RUNNING, | ||
35 | }; | ||
36 | |||
31 | struct qdisc_size_table { | 37 | struct qdisc_size_table { |
32 | struct list_head list; | 38 | struct list_head list; |
33 | struct tc_sizespec szopts; | 39 | struct tc_sizespec szopts; |
@@ -72,10 +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; |
76 | struct rcu_head rcu_head; | 83 | struct rcu_head rcu_head; |
84 | spinlock_t busylock; | ||
77 | }; | 85 | }; |
78 | 86 | ||
87 | static inline bool qdisc_is_running(struct Qdisc *qdisc) | ||
88 | { | ||
89 | return test_bit(__QDISC___STATE_RUNNING, &qdisc->__state); | ||
90 | } | ||
91 | |||
92 | static inline bool qdisc_run_begin(struct Qdisc *qdisc) | ||
93 | { | ||
94 | return !__test_and_set_bit(__QDISC___STATE_RUNNING, &qdisc->__state); | ||
95 | } | ||
96 | |||
97 | static inline void qdisc_run_end(struct Qdisc *qdisc) | ||
98 | { | ||
99 | __clear_bit(__QDISC___STATE_RUNNING, &qdisc->__state); | ||
100 | } | ||
101 | |||
79 | struct Qdisc_class_ops { | 102 | struct Qdisc_class_ops { |
80 | /* Child qdisc manipulation */ | 103 | /* Child qdisc manipulation */ |
81 | struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *); | 104 | struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *); |
@@ -583,9 +606,16 @@ static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen) | |||
583 | } | 606 | } |
584 | 607 | ||
585 | #ifdef CONFIG_NET_CLS_ACT | 608 | #ifdef CONFIG_NET_CLS_ACT |
586 | static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask) | 609 | static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask, |
610 | int action) | ||
587 | { | 611 | { |
588 | 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); | ||
589 | 619 | ||
590 | if (n) { | 620 | if (n) { |
591 | n->tc_verd = SET_TC_VERD(n->tc_verd, 0); | 621 | n->tc_verd = SET_TC_VERD(n->tc_verd, 0); |