Skip to content

Commit 3b3ae88

Browse files
borkmanndavem330
authored andcommitted
net: sched: consolidate tc_classify{,_compat}
For classifiers getting invoked via tc_classify(), we always need an extra function call into tc_classify_compat(), as both are being exported as symbols and tc_classify() itself doesn't do much except handling of reclassifications when tp->classify() returned with TC_ACT_RECLASSIFY. CBQ and ATM are the only qdiscs that directly call into tc_classify_compat(), all others use tc_classify(). When tc actions are being configured out in the kernel, tc_classify() effectively does nothing besides delegating. We could spare this layer and consolidate both functions. pktgen on single CPU constantly pushing skbs directly into the netif_receive_skb() path with a dummy classifier on ingress qdisc attached, improves slightly from 22.3Mpps to 23.1Mpps. Signed-off-by: Daniel Borkmann <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent fe21882 commit 3b3ae88

File tree

16 files changed

+40
-47
lines changed

16 files changed

+40
-47
lines changed

include/net/pkt_sched.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,8 @@ static inline void qdisc_run(struct Qdisc *q)
110110
__qdisc_run(q);
111111
}
112112

113-
int tc_classify_compat(struct sk_buff *skb, const struct tcf_proto *tp,
114-
struct tcf_result *res);
115113
int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
116-
struct tcf_result *res);
114+
struct tcf_result *res, bool compat_mode);
117115

118116
static inline __be16 tc_skb_protocol(const struct sk_buff *skb)
119117
{

net/core/dev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3657,7 +3657,7 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb,
36573657
skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_INGRESS);
36583658
qdisc_bstats_cpu_update(cl->q, skb);
36593659

3660-
switch (tc_classify(skb, cl, &cl_res)) {
3660+
switch (tc_classify(skb, cl, &cl_res, false)) {
36613661
case TC_ACT_OK:
36623662
case TC_ACT_RECLASSIFY:
36633663
skb->tc_index = TC_H_MIN(cl_res.classid);

net/sched/sch_api.c

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,51 +1806,46 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
18061806
* to this qdisc, (optionally) tests for protocol and asks
18071807
* specific classifiers.
18081808
*/
1809-
int tc_classify_compat(struct sk_buff *skb, const struct tcf_proto *tp,
1810-
struct tcf_result *res)
1809+
int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
1810+
struct tcf_result *res, bool compat_mode)
18111811
{
18121812
__be16 protocol = tc_skb_protocol(skb);
1813-
int err;
1813+
#ifdef CONFIG_NET_CLS_ACT
1814+
const struct tcf_proto *old_tp = tp;
1815+
int limit = 0;
18141816

1817+
reclassify:
1818+
#endif
18151819
for (; tp; tp = rcu_dereference_bh(tp->next)) {
1820+
int err;
1821+
18161822
if (tp->protocol != protocol &&
18171823
tp->protocol != htons(ETH_P_ALL))
18181824
continue;
1819-
err = tp->classify(skb, tp, res);
18201825

1826+
err = tp->classify(skb, tp, res);
1827+
#ifdef CONFIG_NET_CLS_ACT
1828+
if (unlikely(err == TC_ACT_RECLASSIFY &&
1829+
!compat_mode))
1830+
goto reset;
1831+
#endif
18211832
if (err >= 0)
18221833
return err;
18231834
}
1824-
return -1;
1825-
}
1826-
EXPORT_SYMBOL(tc_classify_compat);
18271835

1828-
int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
1829-
struct tcf_result *res)
1830-
{
1831-
int err = 0;
1832-
#ifdef CONFIG_NET_CLS_ACT
1833-
const struct tcf_proto *otp = tp;
1834-
int limit = 0;
1835-
reclassify:
1836-
#endif
1837-
1838-
err = tc_classify_compat(skb, tp, res);
1836+
return -1;
18391837
#ifdef CONFIG_NET_CLS_ACT
1840-
if (err == TC_ACT_RECLASSIFY) {
1841-
tp = otp;
1842-
1843-
if (unlikely(limit++ >= MAX_REC_LOOP)) {
1844-
net_notice_ratelimited("%s: packet reclassify loop rule prio %u protocol %02x\n",
1845-
tp->q->ops->id,
1846-
tp->prio & 0xffff,
1847-
ntohs(tp->protocol));
1848-
return TC_ACT_SHOT;
1849-
}
1850-
goto reclassify;
1838+
reset:
1839+
if (unlikely(limit++ >= MAX_REC_LOOP)) {
1840+
net_notice_ratelimited("%s: reclassify loop, rule prio %u, "
1841+
"protocol %02x\n", tp->q->ops->id,
1842+
tp->prio & 0xffff, ntohs(tp->protocol));
1843+
return TC_ACT_SHOT;
18511844
}
1845+
1846+
tp = old_tp;
1847+
goto reclassify;
18521848
#endif
1853-
return err;
18541849
}
18551850
EXPORT_SYMBOL(tc_classify);
18561851

net/sched/sch_atm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
375375
list_for_each_entry(flow, &p->flows, list) {
376376
fl = rcu_dereference_bh(flow->filter_list);
377377
if (fl) {
378-
result = tc_classify_compat(skb, fl, &res);
378+
result = tc_classify(skb, fl, &res, true);
379379
if (result < 0)
380380
continue;
381381
flow = (struct atm_flow_data *)res.class;

net/sched/sch_cbq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
240240
/*
241241
* Step 2+n. Apply classifier.
242242
*/
243-
result = tc_classify_compat(skb, fl, &res);
243+
result = tc_classify(skb, fl, &res, true);
244244
if (!fl || result < 0)
245245
goto fallback;
246246

net/sched/sch_choke.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ static bool choke_classify(struct sk_buff *skb,
201201
int result;
202202

203203
fl = rcu_dereference_bh(q->filter_list);
204-
result = tc_classify(skb, fl, &res);
204+
result = tc_classify(skb, fl, &res, false);
205205
if (result >= 0) {
206206
#ifdef CONFIG_NET_CLS_ACT
207207
switch (result) {

net/sched/sch_drr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ static struct drr_class *drr_classify(struct sk_buff *skb, struct Qdisc *sch,
331331

332332
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
333333
fl = rcu_dereference_bh(q->filter_list);
334-
result = tc_classify(skb, fl, &res);
334+
result = tc_classify(skb, fl, &res, false);
335335
if (result >= 0) {
336336
#ifdef CONFIG_NET_CLS_ACT
337337
switch (result) {

net/sched/sch_dsmark.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
230230
else {
231231
struct tcf_result res;
232232
struct tcf_proto *fl = rcu_dereference_bh(p->filter_list);
233-
int result = tc_classify(skb, fl, &res);
233+
int result = tc_classify(skb, fl, &res, false);
234234

235235
pr_debug("result %d class 0x%04x\n", result, res.classid);
236236

net/sched/sch_fq_codel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static unsigned int fq_codel_classify(struct sk_buff *skb, struct Qdisc *sch,
9292
return fq_codel_hash(q, skb) + 1;
9393

9494
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
95-
result = tc_classify(skb, filter, &res);
95+
result = tc_classify(skb, filter, &res, false);
9696
if (result >= 0) {
9797
#ifdef CONFIG_NET_CLS_ACT
9898
switch (result) {

net/sched/sch_hfsc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1165,7 +1165,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
11651165
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
11661166
head = &q->root;
11671167
tcf = rcu_dereference_bh(q->root.filter_list);
1168-
while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
1168+
while (tcf && (result = tc_classify(skb, tcf, &res, false)) >= 0) {
11691169
#ifdef CONFIG_NET_CLS_ACT
11701170
switch (result) {
11711171
case TC_ACT_QUEUED:

net/sched/sch_htb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch,
229229
}
230230

231231
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
232-
while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
232+
while (tcf && (result = tc_classify(skb, tcf, &res, false)) >= 0) {
233233
#ifdef CONFIG_NET_CLS_ACT
234234
switch (result) {
235235
case TC_ACT_QUEUED:

net/sched/sch_multiq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ multiq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
4646
int err;
4747

4848
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
49-
err = tc_classify(skb, fl, &res);
49+
err = tc_classify(skb, fl, &res, false);
5050
#ifdef CONFIG_NET_CLS_ACT
5151
switch (err) {
5252
case TC_ACT_STOLEN:

net/sched/sch_prio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
4242
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
4343
if (TC_H_MAJ(skb->priority) != sch->handle) {
4444
fl = rcu_dereference_bh(q->filter_list);
45-
err = tc_classify(skb, fl, &res);
45+
err = tc_classify(skb, fl, &res, false);
4646
#ifdef CONFIG_NET_CLS_ACT
4747
switch (err) {
4848
case TC_ACT_STOLEN:

net/sched/sch_qfq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ static struct qfq_class *qfq_classify(struct sk_buff *skb, struct Qdisc *sch,
717717

718718
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
719719
fl = rcu_dereference_bh(q->filter_list);
720-
result = tc_classify(skb, fl, &res);
720+
result = tc_classify(skb, fl, &res, false);
721721
if (result >= 0) {
722722
#ifdef CONFIG_NET_CLS_ACT
723723
switch (result) {

net/sched/sch_sfb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ static bool sfb_classify(struct sk_buff *skb, struct tcf_proto *fl,
258258
struct tcf_result res;
259259
int result;
260260

261-
result = tc_classify(skb, fl, &res);
261+
result = tc_classify(skb, fl, &res, false);
262262
if (result >= 0) {
263263
#ifdef CONFIG_NET_CLS_ACT
264264
switch (result) {

net/sched/sch_sfq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
179179
return sfq_hash(q, skb) + 1;
180180

181181
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
182-
result = tc_classify(skb, fl, &res);
182+
result = tc_classify(skb, fl, &res, false);
183183
if (result >= 0) {
184184
#ifdef CONFIG_NET_CLS_ACT
185185
switch (result) {

0 commit comments

Comments
 (0)