Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net/sched: Export mq functions for reuse

To enable the cake_mq qdisc to reuse code from the mq qdisc, export a
bunch of functions from sch_mq. Split common functionality out from some
functions so it can be composed with other code, and export other
functions wholesale. To discourage wanton reuse, put the symbols into a
new NET_SCHED_INTERNAL namespace, and a sch_priv.h header file.

No functional change intended.

Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://patch.msgid.link/20260109-mq-cake-sub-qdisc-v8-1-8d613fece5d8@redhat.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Toke Høiland-Jørgensen and committed by
Paolo Abeni
8b27fd66 de746f8f

+77 -22
+1
MAINTAINERS
··· 25454 25454 S: Maintained 25455 25455 F: include/net/pkt_cls.h 25456 25456 F: include/net/pkt_sched.h 25457 + F: include/net/sch_priv.h 25457 25458 F: include/net/tc_act/ 25458 25459 F: include/uapi/linux/pkt_cls.h 25459 25460 F: include/uapi/linux/pkt_sched.h
+27
include/net/sch_priv.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __NET_SCHED_PRIV_H 3 + #define __NET_SCHED_PRIV_H 4 + 5 + #include <net/sch_generic.h> 6 + 7 + struct mq_sched { 8 + struct Qdisc **qdiscs; 9 + }; 10 + 11 + int mq_init_common(struct Qdisc *sch, struct nlattr *opt, 12 + struct netlink_ext_ack *extack, 13 + const struct Qdisc_ops *qdisc_ops); 14 + void mq_destroy_common(struct Qdisc *sch); 15 + void mq_attach(struct Qdisc *sch); 16 + void mq_dump_common(struct Qdisc *sch, struct sk_buff *skb); 17 + struct netdev_queue *mq_select_queue(struct Qdisc *sch, 18 + struct tcmsg *tcm); 19 + struct Qdisc *mq_leaf(struct Qdisc *sch, unsigned long cl); 20 + unsigned long mq_find(struct Qdisc *sch, u32 classid); 21 + int mq_dump_class(struct Qdisc *sch, unsigned long cl, 22 + struct sk_buff *skb, struct tcmsg *tcm); 23 + int mq_dump_class_stats(struct Qdisc *sch, unsigned long cl, 24 + struct gnet_dump *d); 25 + void mq_walk(struct Qdisc *sch, struct qdisc_walker *arg); 26 + 27 + #endif
+49 -22
net/sched/sch_mq.c
··· 15 15 #include <net/netlink.h> 16 16 #include <net/pkt_cls.h> 17 17 #include <net/pkt_sched.h> 18 - #include <net/sch_generic.h> 19 - 20 - struct mq_sched { 21 - struct Qdisc **qdiscs; 22 - }; 18 + #include <net/sch_priv.h> 23 19 24 20 static int mq_offload(struct Qdisc *sch, enum tc_mq_command cmd) 25 21 { ··· 45 49 return qdisc_offload_dump_helper(sch, TC_SETUP_QDISC_MQ, &opt); 46 50 } 47 51 48 - static void mq_destroy(struct Qdisc *sch) 52 + void mq_destroy_common(struct Qdisc *sch) 49 53 { 50 54 struct net_device *dev = qdisc_dev(sch); 51 55 struct mq_sched *priv = qdisc_priv(sch); 52 56 unsigned int ntx; 53 - 54 - mq_offload(sch, TC_MQ_DESTROY); 55 57 56 58 if (!priv->qdiscs) 57 59 return; ··· 57 63 qdisc_put(priv->qdiscs[ntx]); 58 64 kfree(priv->qdiscs); 59 65 } 66 + EXPORT_SYMBOL_NS_GPL(mq_destroy_common, "NET_SCHED_INTERNAL"); 60 67 61 - static int mq_init(struct Qdisc *sch, struct nlattr *opt, 62 - struct netlink_ext_ack *extack) 68 + static void mq_destroy(struct Qdisc *sch) 69 + { 70 + mq_offload(sch, TC_MQ_DESTROY); 71 + mq_destroy_common(sch); 72 + } 73 + 74 + int mq_init_common(struct Qdisc *sch, struct nlattr *opt, 75 + struct netlink_ext_ack *extack, 76 + const struct Qdisc_ops *qdisc_ops) 63 77 { 64 78 struct net_device *dev = qdisc_dev(sch); 65 79 struct mq_sched *priv = qdisc_priv(sch); ··· 89 87 90 88 for (ntx = 0; ntx < dev->num_tx_queues; ntx++) { 91 89 dev_queue = netdev_get_tx_queue(dev, ntx); 92 - qdisc = qdisc_create_dflt(dev_queue, get_default_qdisc_ops(dev, ntx), 90 + qdisc = qdisc_create_dflt(dev_queue, 91 + qdisc_ops ?: get_default_qdisc_ops(dev, ntx), 93 92 TC_H_MAKE(TC_H_MAJ(sch->handle), 94 93 TC_H_MIN(ntx + 1)), 95 94 extack); ··· 101 98 } 102 99 103 100 sch->flags |= TCQ_F_MQROOT; 101 + return 0; 102 + } 103 + EXPORT_SYMBOL_NS_GPL(mq_init_common, "NET_SCHED_INTERNAL"); 104 + 105 + static int mq_init(struct Qdisc *sch, struct nlattr *opt, 106 + struct netlink_ext_ack *extack) 107 + { 108 + int ret; 109 + 110 + ret = mq_init_common(sch, opt, extack, NULL); 111 + if (ret) 112 + return ret; 104 113 105 114 mq_offload(sch, TC_MQ_CREATE); 106 115 return 0; 107 116 } 108 117 109 - static void mq_attach(struct Qdisc *sch) 118 + void mq_attach(struct Qdisc *sch) 110 119 { 111 120 struct net_device *dev = qdisc_dev(sch); 112 121 struct mq_sched *priv = qdisc_priv(sch); ··· 139 124 kfree(priv->qdiscs); 140 125 priv->qdiscs = NULL; 141 126 } 127 + EXPORT_SYMBOL_NS_GPL(mq_attach, "NET_SCHED_INTERNAL"); 142 128 143 - static int mq_dump(struct Qdisc *sch, struct sk_buff *skb) 129 + void mq_dump_common(struct Qdisc *sch, struct sk_buff *skb) 144 130 { 145 131 struct net_device *dev = qdisc_dev(sch); 146 132 struct Qdisc *qdisc; ··· 168 152 169 153 spin_unlock_bh(qdisc_lock(qdisc)); 170 154 } 155 + } 156 + EXPORT_SYMBOL_NS_GPL(mq_dump_common, "NET_SCHED_INTERNAL"); 171 157 158 + static int mq_dump(struct Qdisc *sch, struct sk_buff *skb) 159 + { 160 + mq_dump_common(sch, skb); 172 161 return mq_offload_stats(sch); 173 162 } 174 163 ··· 187 166 return netdev_get_tx_queue(dev, ntx); 188 167 } 189 168 190 - static struct netdev_queue *mq_select_queue(struct Qdisc *sch, 191 - struct tcmsg *tcm) 169 + struct netdev_queue *mq_select_queue(struct Qdisc *sch, 170 + struct tcmsg *tcm) 192 171 { 193 172 return mq_queue_get(sch, TC_H_MIN(tcm->tcm_parent)); 194 173 } 174 + EXPORT_SYMBOL_NS_GPL(mq_select_queue, "NET_SCHED_INTERNAL"); 195 175 196 176 static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new, 197 177 struct Qdisc **old, struct netlink_ext_ack *extack) ··· 220 198 return 0; 221 199 } 222 200 223 - static struct Qdisc *mq_leaf(struct Qdisc *sch, unsigned long cl) 201 + struct Qdisc *mq_leaf(struct Qdisc *sch, unsigned long cl) 224 202 { 225 203 struct netdev_queue *dev_queue = mq_queue_get(sch, cl); 226 204 227 205 return rtnl_dereference(dev_queue->qdisc_sleeping); 228 206 } 207 + EXPORT_SYMBOL_NS_GPL(mq_leaf, "NET_SCHED_INTERNAL"); 229 208 230 - static unsigned long mq_find(struct Qdisc *sch, u32 classid) 209 + unsigned long mq_find(struct Qdisc *sch, u32 classid) 231 210 { 232 211 unsigned int ntx = TC_H_MIN(classid); 233 212 ··· 236 213 return 0; 237 214 return ntx; 238 215 } 216 + EXPORT_SYMBOL_NS_GPL(mq_find, "NET_SCHED_INTERNAL"); 239 217 240 - static int mq_dump_class(struct Qdisc *sch, unsigned long cl, 241 - struct sk_buff *skb, struct tcmsg *tcm) 218 + int mq_dump_class(struct Qdisc *sch, unsigned long cl, 219 + struct sk_buff *skb, struct tcmsg *tcm) 242 220 { 243 221 struct netdev_queue *dev_queue = mq_queue_get(sch, cl); 244 222 ··· 248 224 tcm->tcm_info = rtnl_dereference(dev_queue->qdisc_sleeping)->handle; 249 225 return 0; 250 226 } 227 + EXPORT_SYMBOL_NS_GPL(mq_dump_class, "NET_SCHED_INTERNAL"); 251 228 252 - static int mq_dump_class_stats(struct Qdisc *sch, unsigned long cl, 253 - struct gnet_dump *d) 229 + int mq_dump_class_stats(struct Qdisc *sch, unsigned long cl, 230 + struct gnet_dump *d) 254 231 { 255 232 struct netdev_queue *dev_queue = mq_queue_get(sch, cl); 256 233 ··· 261 236 return -1; 262 237 return 0; 263 238 } 239 + EXPORT_SYMBOL_NS_GPL(mq_dump_class_stats, "NET_SCHED_INTERNAL"); 264 240 265 - static void mq_walk(struct Qdisc *sch, struct qdisc_walker *arg) 241 + void mq_walk(struct Qdisc *sch, struct qdisc_walker *arg) 266 242 { 267 243 struct net_device *dev = qdisc_dev(sch); 268 244 unsigned int ntx; ··· 277 251 break; 278 252 } 279 253 } 254 + EXPORT_SYMBOL_NS_GPL(mq_walk, "NET_SCHED_INTERNAL"); 280 255 281 256 static const struct Qdisc_class_ops mq_class_ops = { 282 257 .select_queue = mq_select_queue,