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

net: sched: introduce ingress/egress block index attributes for qdisc

Introduce two new attributes to be used for qdisc creation and dumping.
One for ingress block, one for egress block. Introduce a set of ops that
qdisc which supports block sharing would implement.

Passing block indexes in qdisc change is not supported yet and it is
checked and forbidded.

In future, these attributes are to be reused for specifying block
indexes for classes as well. As of this moment however, it is not
supported so a check is in place to forbid it.

Suggested-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jiri Pirko and committed by
David S. Miller
d47a6b0e 7960d1da

+69
+7
include/net/sch_generic.h
··· 204 204 int (*dump)(struct Qdisc *, struct sk_buff *); 205 205 int (*dump_stats)(struct Qdisc *, struct gnet_dump *); 206 206 207 + void (*ingress_block_set)(struct Qdisc *sch, 208 + u32 block_index); 209 + void (*egress_block_set)(struct Qdisc *sch, 210 + u32 block_index); 211 + u32 (*ingress_block_get)(struct Qdisc *sch); 212 + u32 (*egress_block_get)(struct Qdisc *sch); 213 + 207 214 struct module *owner; 208 215 }; 209 216
+2
include/uapi/linux/rtnetlink.h
··· 568 568 TCA_DUMP_INVISIBLE, 569 569 TCA_CHAIN, 570 570 TCA_HW_OFFLOAD, 571 + TCA_INGRESS_BLOCK, 572 + TCA_EGRESS_BLOCK, 571 573 __TCA_MAX 572 574 }; 573 575
+60
net/sched/sch_api.c
··· 791 791 unsigned char *b = skb_tail_pointer(skb); 792 792 struct gnet_dump d; 793 793 struct qdisc_size_table *stab; 794 + u32 block_index; 794 795 __u32 qlen; 795 796 796 797 cond_resched(); ··· 808 807 tcm->tcm_info = refcount_read(&q->refcnt); 809 808 if (nla_put_string(skb, TCA_KIND, q->ops->id)) 810 809 goto nla_put_failure; 810 + if (q->ops->ingress_block_get) { 811 + block_index = q->ops->ingress_block_get(q); 812 + if (block_index && 813 + nla_put_u32(skb, TCA_INGRESS_BLOCK, block_index)) 814 + goto nla_put_failure; 815 + } 816 + if (q->ops->egress_block_get) { 817 + block_index = q->ops->egress_block_get(q); 818 + if (block_index && 819 + nla_put_u32(skb, TCA_EGRESS_BLOCK, block_index)) 820 + goto nla_put_failure; 821 + } 811 822 if (q->ops->dump && q->ops->dump(q, skb) < 0) 812 823 goto nla_put_failure; 813 824 if (nla_put_u8(skb, TCA_HW_OFFLOAD, !!(q->flags & TCQ_F_OFFLOADED))) ··· 1007 994 return err; 1008 995 } 1009 996 997 + static int qdisc_block_indexes_set(struct Qdisc *sch, struct nlattr **tca, 998 + struct netlink_ext_ack *extack) 999 + { 1000 + u32 block_index; 1001 + 1002 + if (tca[TCA_INGRESS_BLOCK]) { 1003 + block_index = nla_get_u32(tca[TCA_INGRESS_BLOCK]); 1004 + 1005 + if (!block_index) { 1006 + NL_SET_ERR_MSG(extack, "Ingress block index cannot be 0"); 1007 + return -EINVAL; 1008 + } 1009 + if (!sch->ops->ingress_block_set) { 1010 + NL_SET_ERR_MSG(extack, "Ingress block sharing is not supported"); 1011 + return -EOPNOTSUPP; 1012 + } 1013 + sch->ops->ingress_block_set(sch, block_index); 1014 + } 1015 + if (tca[TCA_EGRESS_BLOCK]) { 1016 + block_index = nla_get_u32(tca[TCA_EGRESS_BLOCK]); 1017 + 1018 + if (!block_index) { 1019 + NL_SET_ERR_MSG(extack, "Egress block index cannot be 0"); 1020 + return -EINVAL; 1021 + } 1022 + if (!sch->ops->egress_block_set) { 1023 + NL_SET_ERR_MSG(extack, "Egress block sharing is not supported"); 1024 + return -EOPNOTSUPP; 1025 + } 1026 + sch->ops->egress_block_set(sch, block_index); 1027 + } 1028 + return 0; 1029 + } 1030 + 1010 1031 /* lockdep annotation is needed for ingress; egress gets it only for name */ 1011 1032 static struct lock_class_key qdisc_tx_lock; 1012 1033 static struct lock_class_key qdisc_rx_lock; ··· 1135 1088 netdev_info(dev, "Caught tx_queue_len zero misconfig\n"); 1136 1089 } 1137 1090 1091 + err = qdisc_block_indexes_set(sch, tca, extack); 1092 + if (err) 1093 + goto err_out3; 1094 + 1138 1095 if (ops->init) { 1139 1096 err = ops->init(sch, tca[TCA_OPTIONS], extack); 1140 1097 if (err != 0) ··· 1219 1168 if (!sch->ops->change) { 1220 1169 NL_SET_ERR_MSG(extack, "Change operation not supported by specified qdisc"); 1221 1170 return -EINVAL; 1171 + } 1172 + if (tca[TCA_INGRESS_BLOCK] || tca[TCA_EGRESS_BLOCK]) { 1173 + NL_SET_ERR_MSG(extack, "Change of blocks is not supported"); 1174 + return -EOPNOTSUPP; 1222 1175 } 1223 1176 err = sch->ops->change(sch, tca[TCA_OPTIONS], extack); 1224 1177 if (err) ··· 1947 1892 err = -EINVAL; 1948 1893 goto out; 1949 1894 } 1895 + } 1896 + 1897 + if (tca[TCA_INGRESS_BLOCK] || tca[TCA_EGRESS_BLOCK]) { 1898 + NL_SET_ERR_MSG(extack, "Shared blocks are not supported for classes"); 1899 + return -EOPNOTSUPP; 1950 1900 } 1951 1901 1952 1902 new_cl = cl;