Root/target/linux/generic/patches-2.6.31/260-extend_pfifo_fast.patch

1--- a/net/sched/sch_generic.c
2+++ b/net/sched/sch_generic.c
3@@ -391,16 +391,50 @@ static const u8 prio2band[TC_PRIO_MAX+1]
4 
5 #define PFIFO_FAST_BANDS 3
6 
7+struct pfifo_fast_sched_data {
8+ struct tcf_proto *filter_list;
9+ struct sk_buff_head list[PFIFO_FAST_BANDS];
10+};
11+
12 static inline struct sk_buff_head *prio2list(struct sk_buff *skb,
13                          struct Qdisc *qdisc)
14 {
15- struct sk_buff_head *list = qdisc_priv(qdisc);
16+ struct pfifo_fast_sched_data *q = qdisc_priv(qdisc);
17+ struct sk_buff_head *list = q->list;
18     return list + prio2band[skb->priority & TC_PRIO_MAX];
19 }
20 
21+static int pfifo_fast_filter(struct sk_buff *skb, struct Qdisc* qdisc)
22+{
23+#ifdef CONFIG_NET_CLS_ACT
24+ struct pfifo_fast_sched_data *q = qdisc_priv(qdisc);
25+ int result = 0, ret = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
26+ struct tcf_result res;
27+
28+ if (q->filter_list != NULL)
29+ result = tc_classify(skb, q->filter_list, &res);
30+ if (result >= 0) {
31+ switch (result) {
32+ case TC_ACT_STOLEN:
33+ case TC_ACT_QUEUED:
34+ ret = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
35+ case TC_ACT_SHOT:
36+ kfree_skb(skb);
37+ return ret;
38+ }
39+ }
40+#endif
41+ return 0;
42+}
43+
44 static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
45 {
46     struct sk_buff_head *list = prio2list(skb, qdisc);
47+ int ret;
48+
49+ ret = pfifo_fast_filter(skb, qdisc);
50+ if (ret)
51+ return ret;
52 
53     if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
54         qdisc->q.qlen++;
55@@ -412,8 +446,9 @@ static int pfifo_fast_enqueue(struct sk_
56 
57 static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc)
58 {
59+ struct pfifo_fast_sched_data *q = qdisc_priv(qdisc);
60+ struct sk_buff_head *list = q->list;
61     int prio;
62- struct sk_buff_head *list = qdisc_priv(qdisc);
63 
64     for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
65         if (!skb_queue_empty(list + prio)) {
66@@ -440,8 +475,9 @@ static struct sk_buff *pfifo_fast_peek(s
67 
68 static void pfifo_fast_reset(struct Qdisc* qdisc)
69 {
70+ struct pfifo_fast_sched_data *q = qdisc_priv(qdisc);
71+ struct sk_buff_head *list = q->list;
72     int prio;
73- struct sk_buff_head *list = qdisc_priv(qdisc);
74 
75     for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
76         __qdisc_reset_queue(qdisc, list + prio);
77@@ -464,8 +500,9 @@ nla_put_failure:
78 
79 static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
80 {
81+ struct pfifo_fast_sched_data *q = qdisc_priv(qdisc);
82+ struct sk_buff_head *list = q->list;
83     int prio;
84- struct sk_buff_head *list = qdisc_priv(qdisc);
85 
86     for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
87         skb_queue_head_init(list + prio);
88@@ -473,9 +510,36 @@ static int pfifo_fast_init(struct Qdisc
89     return 0;
90 }
91 
92+static int pfifo_fast_change_class(struct Qdisc *qdisc, u32 classid, u32 parentid,
93+ struct nlattr **tca, unsigned long *arg)
94+{
95+ return -EOPNOTSUPP;
96+}
97+
98+static unsigned long pfifo_fast_get(struct Qdisc *qdisc, u32 classid)
99+{
100+ return 0;
101+}
102+
103+static struct tcf_proto **pfifo_fast_find_tcf(struct Qdisc *qdisc, unsigned long cl)
104+{
105+ struct pfifo_fast_sched_data *q = qdisc_priv(qdisc);
106+
107+ if (cl)
108+ return NULL;
109+ return &q->filter_list;
110+}
111+
112+static const struct Qdisc_class_ops pfifo_fast_class_ops = {
113+ .get = pfifo_fast_get,
114+ .change = pfifo_fast_change_class,
115+ .tcf_chain = pfifo_fast_find_tcf,
116+};
117+
118 static struct Qdisc_ops pfifo_fast_ops __read_mostly = {
119     .id = "pfifo_fast",
120- .priv_size = PFIFO_FAST_BANDS * sizeof(struct sk_buff_head),
121+ .cl_ops = &pfifo_fast_class_ops,
122+ .priv_size = sizeof(struct pfifo_fast_sched_data),
123     .enqueue = pfifo_fast_enqueue,
124     .dequeue = pfifo_fast_dequeue,
125     .peek = pfifo_fast_peek,
126@@ -757,3 +821,18 @@ void dev_shutdown(struct net_device *dev
127     shutdown_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc);
128     WARN_ON(timer_pending(&dev->watchdog_timer));
129 }
130+
131+#ifdef CONFIG_NET_SCHED
132+static int __init sch_generic_init(void)
133+{
134+ return register_qdisc(&pfifo_fast_ops);
135+}
136+
137+static void __exit sch_generic_exit(void)
138+{
139+ unregister_qdisc(&pfifo_fast_ops);
140+}
141+
142+module_init(sch_generic_init)
143+module_exit(sch_generic_exit)
144+#endif
145

Archive Download this file



interactive