tree: https://github.com/congwang/linux.git sch_bpf head: a656e8aec8755a26268ca54b6fce76969dda9c2e commit: a656e8aec8755a26268ca54b6fce76969dda9c2e [2/2] sch_bpf: draft config: ia64-allmodconfig (attached as .config) compiler: ia64-linux-gcc (GCC) 10.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/congwang/linux/commit/a656e8aec8755a26268ca54b6fce76969dda9c2e git remote add congwang https://github.com/congwang/linux.git git fetch --no-tags congwang sch_bpf git checkout a656e8aec8755a26268ca54b6fce76969dda9c2e # save the attached .config to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross O=build_dir ARCH=ia64 SHELL=/bin/bash net/sched/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All error/warnings (new ones prefixed by >>): net/sched/sch_bpf.c: In function 'sch_bpf_dump': >> net/sched/sch_bpf.c:103:39: error: 'TCA_SCH_BPF_ENQUEUE_PROG_TAG' undeclared (first use in this function); did you mean 'TCA_SCH_BPF_ENQUEUE_PROG_ID'? 103 | TCA_SCH_BPF_ENQUEUE_PROG_ID, TCA_SCH_BPF_ENQUEUE_PROG_TAG)) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ | TCA_SCH_BPF_ENQUEUE_PROG_ID net/sched/sch_bpf.c:103:39: note: each undeclared identifier is reported only once for each function it appears in >> net/sched/sch_bpf.c:106:39: error: 'TCA_SCH_BPF_DEQUEUE_PROG_TAG' undeclared (first use in this function); did you mean 'TCA_SCH_BPF_DEQUEUE_PROG_ID'? 106 | TCA_SCH_BPF_DEQUEUE_PROG_ID, TCA_SCH_BPF_DEQUEUE_PROG_TAG)) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ | TCA_SCH_BPF_DEQUEUE_PROG_ID net/sched/sch_bpf.c: In function 'sch_bpf_classify': >> net/sched/sch_bpf.c:135:9: error: 'tcf' undeclared (first use in this function) 135 | while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) >= 0) { | ^~~ net/sched/sch_bpf.c:129:20: warning: unused variable 'filter' [-Wunused-variable] 129 | struct tcf_proto *filter; | ^~~~~~ net/sched/sch_bpf.c:128:24: warning: unused variable 'q' [-Wunused-variable] 128 | struct sch_bpf_qdisc *q = qdisc_priv(sch); | ^ In file included from include/linux/rbtree.h:22, from include/linux/mm_types.h:10, from include/linux/buildid.h:5, from include/linux/module.h:14, from net/sched/sch_bpf.c:7: net/sched/sch_bpf.c: In function 'sch_bpf_enqueue': >> include/linux/rcupdate.h:389:9: error: invalid type argument of unary '*' (have 'struct sch_bpf_prog') 389 | typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \ | ^ include/linux/rcupdate.h:528:2: note: in expansion of macro '__rcu_dereference_check' 528 | __rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu) | ^~~~~~~~~~~~~~~~~~~~~~~ include/linux/rcupdate.h:596:28: note: in expansion of macro 'rcu_dereference_check' 596 | #define rcu_dereference(p) rcu_dereference_check(p, 0) | ^~~~~~~~~~~~~~~~~~~~~ net/sched/sch_bpf.c:173:13: note: in expansion of macro 'rcu_dereference' 173 | enqueue = rcu_dereference(q->enqueue_prog); | ^~~~~~~~~~~~~~~ include/linux/rcupdate.h:389:35: error: invalid type argument of unary '*' (have 'struct sch_bpf_prog') 389 | typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \ | ^ include/linux/rcupdate.h:528:2: note: in expansion of macro '__rcu_dereference_check' 528 | __rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu) | ^~~~~~~~~~~~~~~~~~~~~~~ include/linux/rcupdate.h:596:28: note: in expansion of macro 'rcu_dereference_check' 596 | #define rcu_dereference(p) rcu_dereference_check(p, 0) | ^~~~~~~~~~~~~~~~~~~~~ net/sched/sch_bpf.c:173:13: note: in expansion of macro 'rcu_dereference' 173 | enqueue = rcu_dereference(q->enqueue_prog); | ^~~~~~~~~~~~~~~ include/linux/rcupdate.h:392:11: error: invalid type argument of unary '*' (have 'struct sch_bpf_prog') 392 | ((typeof(*p) __force __kernel *)(________p1)); \ | ^ include/linux/rcupdate.h:528:2: note: in expansion of macro '__rcu_dereference_check' 528 | __rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu) | ^~~~~~~~~~~~~~~~~~~~~~~ include/linux/rcupdate.h:596:28: note: in expansion of macro 'rcu_dereference_check' 596 | #define rcu_dereference(p) rcu_dereference_check(p, 0) | ^~~~~~~~~~~~~~~~~~~~~ net/sched/sch_bpf.c:173:13: note: in expansion of macro 'rcu_dereference' 173 | enqueue = rcu_dereference(q->enqueue_prog); | ^~~~~~~~~~~~~~~ >> net/sched/sch_bpf.c:190:8: error: 'ret' undeclared (first use in this function); did you mean 'res'? 190 | if ((ret = qdisc_enqueue(skb, cl->qdisc, | ^~~ | res >> net/sched/sch_bpf.c:200:20: error: passing argument 2 of 'pq_push' from incompatible pointer type [-Werror=incompatible-pointer-types] 200 | pq_push(&cl->pq, &skb->rbnode); | ^~~~~~~~~~~~ | | | struct rb_node * In file included from net/sched/sch_bpf.c:18: include/linux/priority_queue.h:29:66: note: expected 'struct pq_node *' but argument is of type 'struct rb_node *' 29 | static inline void pq_push(struct pq_root *root, struct pq_node *node) | ~~~~~~~~~~~~~~~~^~~~ In file included from include/linux/rbtree.h:22, from include/linux/mm_types.h:10, from include/linux/buildid.h:5, from include/linux/module.h:14, from net/sched/sch_bpf.c:7: net/sched/sch_bpf.c: In function 'sch_bpf_dequeue': >> include/linux/rcupdate.h:389:9: error: invalid type argument of unary '*' (have 'struct sch_bpf_prog') 389 | typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \ | ^ include/linux/rcupdate.h:528:2: note: in expansion of macro '__rcu_dereference_check' 528 | __rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu) | ^~~~~~~~~~~~~~~~~~~~~~~ include/linux/rcupdate.h:596:28: note: in expansion of macro 'rcu_dereference_check' 596 | #define rcu_dereference(p) rcu_dereference_check(p, 0) | ^~~~~~~~~~~~~~~~~~~~~ net/sched/sch_bpf.c:218:12: note: in expansion of macro 'rcu_dereference' 218 | dequeue = rcu_dereference(q->dequeue_prog); | ^~~~~~~~~~~~~~~ include/linux/rcupdate.h:389:35: error: invalid type argument of unary '*' (have 'struct sch_bpf_prog') 389 | typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \ | ^ include/linux/rcupdate.h:528:2: note: in expansion of macro '__rcu_dereference_check' 528 | __rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu) | ^~~~~~~~~~~~~~~~~~~~~~~ include/linux/rcupdate.h:596:28: note: in expansion of macro 'rcu_dereference_check' 596 | #define rcu_dereference(p) rcu_dereference_check(p, 0) | ^~~~~~~~~~~~~~~~~~~~~ net/sched/sch_bpf.c:218:12: note: in expansion of macro 'rcu_dereference' 218 | dequeue = rcu_dereference(q->dequeue_prog); | ^~~~~~~~~~~~~~~ include/linux/rcupdate.h:392:11: error: invalid type argument of unary '*' (have 'struct sch_bpf_prog') 392 | ((typeof(*p) __force __kernel *)(________p1)); \ | ^ include/linux/rcupdate.h:528:2: note: in expansion of macro '__rcu_dereference_check' 528 | __rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu) | ^~~~~~~~~~~~~~~~~~~~~~~ include/linux/rcupdate.h:596:28: note: in expansion of macro 'rcu_dereference_check' 596 | #define rcu_dereference(p) rcu_dereference_check(p, 0) | ^~~~~~~~~~~~~~~~~~~~~ net/sched/sch_bpf.c:218:12: note: in expansion of macro 'rcu_dereference' 218 | dequeue = rcu_dereference(q->dequeue_prog); | ^~~~~~~~~~~~~~~ >> net/sched/sch_bpf.c:219:28: error: 'skb' undeclared (first use in this function) 219 | bpf_compute_data_pointers(skb); | ^~~ >> net/sched/sch_bpf.c:230:11: error: assignment to 'struct sk_buff *' from incompatible pointer type 'struct pq_node *' [-Werror=incompatible-pointer-types] 230 | ctx.skb = pq_pop(&cl->pq); | ^ >> net/sched/sch_bpf.c:236:13: error: 'SCH_BPF_RET_OK' undeclared (first use in this function) 236 | if (res == SCH_BPF_RET_OK) { | ^~~~~~~~~~~~~~ >> net/sched/sch_bpf.c:238:20: error: 'SCH_BPF_RET_REQUEUE' undeclared (first use in this function) 238 | } else if (res == SCH_BPF_RET_REQUEUE) { | ^~~~~~~~~~~~~~~~~~~ net/sched/sch_bpf.c:240:20: error: passing argument 2 of 'pq_push' from incompatible pointer type [-Werror=incompatible-pointer-types] 240 | pq_push(&cl->pq, &ctx.skb->rbnode); | ^~~~~~~~~~~~~~~~ | | | struct rb_node * In file included from net/sched/sch_bpf.c:18: include/linux/priority_queue.h:29:66: note: expected 'struct pq_node *' but argument is of type 'struct rb_node *' 29 | static inline void pq_push(struct pq_root *root, struct pq_node *node) | ~~~~~~~~~~~~~~~~^~~~ net/sched/sch_bpf.c: In function 'sch_bpf_search': >> net/sched/sch_bpf.c:283:37: warning: passing argument 1 of 'sch_bpf_find' makes pointer from integer without a cast [-Wint-conversion] 283 | return (unsigned long)sch_bpf_find(handle, sch); | ^~~~~~ | | | u32 {aka unsigned int} net/sched/sch_bpf.c:115:57: note: expected 'struct Qdisc *' but argument is of type 'u32' {aka 'unsigned int'} 115 | static struct sch_bpf_class *sch_bpf_find(struct Qdisc *sch, u32 classid) | ~~~~~~~~~~~~~~^~~ >> net/sched/sch_bpf.c:283:45: warning: passing argument 2 of 'sch_bpf_find' makes integer from pointer without a cast [-Wint-conversion] 283 | return (unsigned long)sch_bpf_find(handle, sch); | ^~~ | | | struct Qdisc * net/sched/sch_bpf.c:115:66: note: expected 'u32' {aka 'unsigned int'} but argument is of type 'struct Qdisc *' 115 | static struct sch_bpf_class *sch_bpf_find(struct Qdisc *sch, u32 classid) | ~~~~^~~~~~~ net/sched/sch_bpf.c: At top level: >> net/sched/sch_bpf.c:297:3: error: 'TCA_SCH_BPF_ENQUEUE_PROG_FD' undeclared here (not in a function); did you mean 'TCA_SCH_BPF_ENQUEUE_PROG_ID'? 297 | [TCA_SCH_BPF_ENQUEUE_PROG_FD] = { .type = NLA_U32 }, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ | TCA_SCH_BPF_ENQUEUE_PROG_ID >> net/sched/sch_bpf.c:297:3: error: array index in initializer not of integer type net/sched/sch_bpf.c:297:3: note: (near initialization for 'sch_bpf_policy') >> net/sched/sch_bpf.c:300:3: error: 'TCA_SCH_BPF_DEQUEUE_PROG_FD' undeclared here (not in a function); did you mean 'TCA_SCH_BPF_DEQUEUE_PROG_ID'? 300 | [TCA_SCH_BPF_DEQUEUE_PROG_FD] = { .type = NLA_U32 }, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ | TCA_SCH_BPF_DEQUEUE_PROG_ID net/sched/sch_bpf.c:300:3: error: array index in initializer not of integer type net/sched/sch_bpf.c:300:3: note: (near initialization for 'sch_bpf_policy') net/sched/sch_bpf.c: In function 'bpf_init_prog': >> net/sched/sch_bpf.c:313:33: error: 'BPF_PROG_TYPE_SCHED_SCH' undeclared (first use in this function); did you mean 'BPF_PROG_TYPE_SCHED_ACT'? 313 | fp = bpf_prog_get_type(bpf_fd, BPF_PROG_TYPE_SCHED_SCH); | ^~~~~~~~~~~~~~~~~~~~~~~ | BPF_PROG_TYPE_SCHED_ACT net/sched/sch_bpf.c: At top level: net/sched/sch_bpf.c:330:8: error: return type defaults to 'int' [-Werror=return-type] 330 | static bpf_cleanup_prog(struct sch_bpf_prog *prog) | ^~~~~~~~~~~~~~~~ net/sched/sch_bpf.c: In function 'sch_bpf_change': >> net/sched/sch_bpf.c:353:11: error: incompatible type for argument 2 of 'bpf_init_prog' 353 | opt[TCA_SCH_BPF_ENQUEUE_PROG_NAME], &q->enqueue_prog); | ~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | struct nlattr net/sched/sch_bpf.c:305:60: note: expected 'struct nlattr *' but argument is of type 'struct nlattr' 305 | static int bpf_init_prog(struct nlattr *fd, struct nlattr *name, struct sch_bpf_prog *prog) | ~~~~~~~~~~~~~~~^~~~ net/sched/sch_bpf.c:357:11: error: incompatible type for argument 2 of 'bpf_init_prog' 357 | opt[TCA_SCH_BPF_DEQUEUE_PROG_NAME], &q->dequeue_prog); | ~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | struct nlattr net/sched/sch_bpf.c:305:60: note: expected 'struct nlattr *' but argument is of type 'struct nlattr' 305 | static int bpf_init_prog(struct nlattr *fd, struct nlattr *name, struct sch_bpf_prog *prog) | ~~~~~~~~~~~~~~~^~~~ net/sched/sch_bpf.c:342:6: warning: unused variable 'gen_flags' [-Wunused-variable] 342 | u32 gen_flags = 0; | ^~~~~~~~~ net/sched/sch_bpf.c: In function 'sch_bpf_init': >> net/sched/sch_bpf.c:387:3: error: 'err' undeclared (first use in this function) 387 | err = sch_bpf_change(sch, opt, extack); | ^~~ net/sched/sch_bpf.c: In function 'sch_bpf_change_class': net/sched/sch_bpf.c:427:3: error: 'err' undeclared (first use in this function) 427 | err = -ENOBUFS; | ^~~ >> net/sched/sch_bpf.c:430:4: error: label 'failure' used but not defined 430 | goto failure; | ^~~~ net/sched/sch_bpf.c:423:60: warning: unused variable 'parent' [-Wunused-variable] 423 | struct sch_bpf_class *cl = (struct sch_bpf_class *)*arg, *parent; | ^~~~~~ net/sched/sch_bpf.c: In function 'sch_bpf_delete': net/sched/sch_bpf.c:449:1: error: no return statement in function returning non-void [-Werror=return-type] 449 | } | ^ net/sched/sch_bpf.c: At top level: net/sched/sch_bpf.c:480:13: error: initialization of 'int (*)(struct Qdisc *, long unsigned int, struct netlink_ext_ack *)' from incompatible pointer type 'int (*)(struct Qdisc *, long unsigned int)' [-Werror=incompatible-pointer-types] 480 | .delete = sch_bpf_delete, | ^~~~~~~~~~~~~~ net/sched/sch_bpf.c:480:13: note: (near initialization for 'sch_bpf_class_ops.delete') net/sched/sch_bpf.c:484:11: error: 'sch_bpf_dump_class' undeclared here (not in a function); did you mean 'sch_bpf_dump_prog'? 484 | .dump = sch_bpf_dump_class, | ^~~~~~~~~~~~~~~~~~ | sch_bpf_dump_prog net/sched/sch_bpf.c:485:16: error: 'sch_bpf_dump_class_stats' undeclared here (not in a function) 485 | .dump_stats = sch_bpf_dump_class_stats, | ^~~~~~~~~~~~~~~~~~~~~~~~ net/sched/sch_bpf.c:497:12: error: 'sch_bpf_reset' undeclared here (not in a function); did you mean 'sch_bpf_delete'? 497 | .reset = sch_bpf_reset, | ^~~~~~~~~~~~~ | sch_bpf_delete net/sched/sch_bpf.c:501:16: error: 'sch_bpf_dump_stats' undeclared here (not in a function); did you mean 'sch_bpf_dump_prog'? 501 | .dump_stats = sch_bpf_dump_stats, | ^~~~~~~~~~~~~~~~~~ | sch_bpf_dump_prog net/sched/sch_bpf.c:505:19: error: conflicting types for 'sch_bpf_init' 505 | static int __init sch_bpf_init(void) | ^~~~~~~~~~~~ net/sched/sch_bpf.c:381:12: note: previous definition of 'sch_bpf_init' was here 381 | static int sch_bpf_init(struct Qdisc *sch, struct nlattr *opt, | ^~~~~~~~~~~~ In file included from net/sched/sch_bpf.c:7: include/linux/module.h:133:6: warning: 'init_module' alias between functions of incompatible types 'int(void)' and 'int(struct Qdisc *, struct nlattr *, struct netlink_ext_ack *)' [-Wattribute-alias=] 133 | int init_module(void) __copy(initfn) \ | ^~~~~~~~~~~ net/sched/sch_bpf.c:515:1: note: in expansion of macro 'module_init' 515 | module_init(sch_bpf_init) | ^~~~~~~~~~~ net/sched/sch_bpf.c:381:12: note: aliased declaration here 381 | static int sch_bpf_init(struct Qdisc *sch, struct nlattr *opt, | ^~~~~~~~~~~~ In file included from net/sched/sch_bpf.c:7: include/linux/module.h:133:6: error: section of alias 'init_module' must match section of its target 133 | int init_module(void) __copy(initfn) \ | ^~~~~~~~~~~ net/sched/sch_bpf.c:515:1: note: in expansion of macro 'module_init' 515 | module_init(sch_bpf_init) | ^~~~~~~~~~~ cc1: some warnings being treated as errors vim +103 net/sched/sch_bpf.c 92 93 static int sch_bpf_dump(struct Qdisc *sch, struct sk_buff *skb) 94 { 95 struct sch_bpf_qdisc *q = qdisc_priv(sch); 96 struct nlattr *opts; 97 98 opts = nla_nest_start_noflag(skb, TCA_OPTIONS); 99 if (opts == NULL) 100 goto nla_put_failure; 101 102 if (sch_bpf_dump_prog(&q->enqueue_prog, skb, TCA_SCH_BPF_ENQUEUE_PROG_NAME, > 103 TCA_SCH_BPF_ENQUEUE_PROG_ID, TCA_SCH_BPF_ENQUEUE_PROG_TAG)) 104 goto nla_put_failure; 105 if (sch_bpf_dump_prog(&q->dequeue_prog, skb, TCA_SCH_BPF_DEQUEUE_PROG_NAME, > 106 TCA_SCH_BPF_DEQUEUE_PROG_ID, TCA_SCH_BPF_DEQUEUE_PROG_TAG)) 107 goto nla_put_failure; 108 109 return nla_nest_end(skb, opts); 110 111 nla_put_failure: 112 return -1; 113 } 114 115 static struct sch_bpf_class *sch_bpf_find(struct Qdisc *sch, u32 classid) 116 { 117 struct sch_bpf_qdisc *q = qdisc_priv(sch); 118 struct Qdisc_class_common *clc; 119 120 clc = qdisc_class_find(&q->clhash, classid); 121 if (clc == NULL) 122 return NULL; 123 return container_of(clc, struct sch_bpf_class, common); 124 } 125 126 static struct sch_bpf_class *sch_bpf_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) 127 { 128 struct sch_bpf_qdisc *q = qdisc_priv(sch); 129 struct tcf_proto *filter; 130 struct sch_bpf_class *cl; 131 struct tcf_result res; 132 int result; 133 134 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > 135 while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) >= 0) { 136 #ifdef CONFIG_NET_CLS_ACT 137 switch (result) { 138 case TC_ACT_QUEUED: 139 case TC_ACT_STOLEN: 140 case TC_ACT_TRAP: 141 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; 142 fallthrough; 143 case TC_ACT_SHOT: 144 return NULL; 145 } 146 #endif 147 cl = (void *)res.class; 148 if (!cl) { 149 cl = sch_bpf_find(sch, res.classid); 150 if (!cl) 151 break; 152 } 153 154 tcf = rcu_dereference_bh(cl->filter_list); 155 } 156 157 return cl; 158 } 159 160 static int sch_bpf_enqueue(struct sk_buff *skb, struct Qdisc *sch, 161 struct sk_buff **to_free) 162 { 163 struct sch_bpf_qdisc *q = qdisc_priv(sch); 164 unsigned int len = qdisc_pkt_len(skb); 165 struct sch_bpf_ctx ctx = {}; 166 struct sch_bpf_class *cl; 167 int res; 168 169 cl = sch_bpf_classify(skb, sch, &res); 170 if (!cl) { 171 struct bpf_prog *enqueue; 172 173 enqueue = rcu_dereference(q->enqueue_prog); 174 bpf_compute_data_pointers(skb); 175 176 ctx.skb = skb; 177 ctx.nr_classes = q->clhash.hashelems; 178 ctx.nr_packets = sch->q.qlen; 179 res = BPF_PROG_RUN(enqueue, &ctx); 180 cl = sch_bpf_find(sch, ctx.classid); 181 if (!cl) { 182 if (res & __NET_XMIT_BYPASS) 183 qdisc_qstats_drop(sch); 184 __qdisc_drop(skb, to_free); 185 return res; 186 } 187 } 188 189 if (cl->qdisc) { > 190 if ((ret = qdisc_enqueue(skb, cl->qdisc, 191 to_free)) != NET_XMIT_SUCCESS) { 192 if (net_xmit_drop_count(ret)) { 193 qdisc_qstats_drop(sch); 194 cl->drops++; 195 } 196 return ret; 197 } 198 } else { 199 sch_bpf_skb_cb(skb)->rank = ctx.rank; > 200 pq_push(&cl->pq, &skb->rbnode); 201 } 202 203 sch->qstats.backlog += len; 204 sch->q.qlen++; 205 return res; 206 } 207 208 static struct sk_buff *sch_bpf_dequeue(struct Qdisc *sch) 209 { 210 struct sch_bpf_qdisc *q = qdisc_priv(sch); 211 struct sch_bpf_ctx ctx = {}; 212 struct sk_buff *ret = NULL; 213 struct bpf_prog *dequeue; 214 struct sch_bpf_class *cl; 215 struct pq_node *flow; 216 int res; 217 218 dequeue = rcu_dereference(q->dequeue_prog); > 219 bpf_compute_data_pointers(skb); 220 221 flow = pq_pop(&q->flows); 222 if (!flow) 223 return NULL; 224 225 cl = container_of(flow, struct sch_bpf_class, node); 226 if (cl->qdisc) { 227 ctx.skb = cl->qdisc->dequeue(cl->qdisc); 228 ctx.classid = cl->common.classid; 229 } else { > 230 ctx.skb = pq_pop(&cl->pq); 231 ctx.classid = cl->rank; 232 } 233 ctx.nr_classes = q->clhash.hashelems; 234 ctx.nr_packets = sch->q.qlen; 235 res = BPF_PROG_RUN(dequeue, &ctx); > 236 if (res == SCH_BPF_RET_OK) { 237 ret = ctx.skb; > 238 } else if (res == SCH_BPF_RET_REQUEUE) { 239 sch_bpf_skb_cb(ctx.skb)->rank = ctx.rank; 240 pq_push(&cl->pq, &ctx.skb->rbnode); 241 ret = NULL; 242 } else { 243 kfree_skb(ctx.skb); 244 ret = NULL; 245 } 246 247 cl->rank = ctx.classid; 248 if (pq_top(&cl->pq)) { 249 pq_push(&q->flows, &cl->node); 250 } 251 return ret; 252 } 253 254 static struct Qdisc *sch_bpf_leaf(struct Qdisc *sch, unsigned long arg) 255 { 256 struct sch_bpf_class *cl = (struct sch_bpf_class *)arg; 257 258 return cl->qdisc; 259 } 260 261 static int sch_bpf_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, 262 struct Qdisc **old, struct netlink_ext_ack *extack) 263 { 264 struct sch_bpf_class *cl = (struct sch_bpf_class *)arg; 265 266 if (new) 267 *old = qdisc_replace(sch, new, &cl->qdisc); 268 return 0; 269 } 270 271 static unsigned long sch_bpf_bind(struct Qdisc *sch, unsigned long parent, 272 u32 classid) 273 { 274 return 0; 275 } 276 277 static void sch_bpf_unbind(struct Qdisc *q, unsigned long cl) 278 { 279 } 280 281 static unsigned long sch_bpf_search(struct Qdisc *sch, u32 handle) 282 { > 283 return (unsigned long)sch_bpf_find(handle, sch); 284 } 285 286 static struct tcf_block *sch_bpf_tcf_block(struct Qdisc *sch, unsigned long cl, 287 struct netlink_ext_ack *extack) 288 { 289 struct sch_bpf_qdisc *q = qdisc_priv(sch); 290 291 if (cl) 292 return NULL; 293 return q->block; 294 } 295 296 static const struct nla_policy sch_bpf_policy[TCA_SCH_BPF_MAX + 1] = { > 297 [TCA_SCH_BPF_ENQUEUE_PROG_FD] = { .type = NLA_U32 }, 298 [TCA_SCH_BPF_ENQUEUE_PROG_NAME] = { .type = NLA_NUL_STRING, 299 .len = ACT_BPF_NAME_LEN }, > 300 [TCA_SCH_BPF_DEQUEUE_PROG_FD] = { .type = NLA_U32 }, 301 [TCA_SCH_BPF_DEQUEUE_PROG_NAME] = { .type = NLA_NUL_STRING, 302 .len = ACT_BPF_NAME_LEN }, 303 }; 304 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org