[SRU][F:linux-bluefield][PATCH 2/5] net/sched: Extend qdisc control block with tc control block

Bodong Wang bodong at nvidia.com
Fri Jan 14 17:59:32 UTC 2022


You're right Tim. Should I send another version?
Sorry for the top posting, my email client has problem.


On 1/13/22 9:05 AM, Bodong Wang wrote:
> From: Paul Blakey <paulb at nvidia.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1957807
> 
> BPF layer extends the qdisc control block via struct bpf_skb_data_end 
> and because of that there is no more room to add variables to the 
> qdisc layer control block without going over the skb->cb size.
> 
> Extend the qdisc control block with a tc control block, and move all 
> tc related variables to there as a pre-step for extending the tc 
> control block with additional members.
> 
> Signed-off-by: Jakub Kicinski <kuba at kernel.org>
> Signed-off-by: Paul Blakey <paulb at nvidia.com> (cherry picked from 
> upstream commit f06d13d128fe59bf9004e74770f76e60b6687731)

Shouldn't this be commit ec624fe740b416fb68d536b37fb8eef46f90b5c2
("net/sched: Extend qdisc control block with tc control block") from linux-next ?

> Signed-off-by: Bodong Wang <bodong at nvidia.com>
> ---
>   include/net/pkt_sched.h   | 15 +++++++++++++++
>   include/net/sch_generic.h |  2 --
>   net/core/dev.c            |  8 ++++----
>   net/sched/act_ct.c        | 14 +++++++-------
>   net/sched/cls_api.c       |  6 ++++--
>   net/sched/cls_flower.c    |  3 ++-
>   net/sched/sch_frag.c      |  3 ++-
>   7 files changed, 34 insertions(+), 17 deletions(-)
> 
> diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 
> d1585b5..555083f 100644
> --- a/include/net/pkt_sched.h
> +++ b/include/net/pkt_sched.h
> @@ -174,4 +174,19 @@ struct tc_taprio_qopt_offload *taprio_offload_get(struct tc_taprio_qopt_offload
>   						  *offload);
>   void taprio_offload_free(struct tc_taprio_qopt_offload *offload);
>   
> +struct tc_skb_cb {
> +	struct qdisc_skb_cb qdisc_cb;
> +
> +	u16 mru;
> +	bool post_ct;
> +};
> +
> +static inline struct tc_skb_cb *tc_skb_cb(const struct sk_buff *skb) 
> +{
> +	struct tc_skb_cb *cb = (struct tc_skb_cb *)skb->cb;
> +
> +	BUILD_BUG_ON(sizeof(*cb) > sizeof_field(struct sk_buff, cb));
> +	return cb;
> +}
> +
>   #endif
> diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h 
> index d2111d3..4a29c1e 100644
> --- a/include/net/sch_generic.h
> +++ b/include/net/sch_generic.h
> @@ -425,8 +425,6 @@ struct qdisc_skb_cb {
>   	};
>   #define QDISC_CB_PRIV_LEN 20
>   	unsigned char		data[QDISC_CB_PRIV_LEN];
> -	u16			mru;
> -	bool			post_ct;
>   };
>   
>   typedef void tcf_chain_head_change_t(struct tcf_proto *tp_head, void 
> *priv); diff --git a/net/core/dev.c b/net/core/dev.c index 
> b08add0..4e57161 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -3506,8 +3506,8 @@ int dev_loopback_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
>   		return skb;
>   
>   	/* qdisc_skb_cb(skb)->pkt_len was already set by the caller. */
> -	qdisc_skb_cb(skb)->mru = 0;
> -	qdisc_skb_cb(skb)->post_ct = false;
> +	tc_skb_cb(skb)->mru = 0;
> +	tc_skb_cb(skb)->post_ct = false;
>   	mini_qdisc_bstats_cpu_update(miniq, skb);
>   
>   	switch (tcf_classify(skb, miniq->filter_list, &cl_res, false)) { @@ 
> -4597,8 +4597,8 @@ static __latent_entropy void net_tx_action(struct softirq_action *h)
>   	}
>   
>   	qdisc_skb_cb(skb)->pkt_len = skb->len;
> -	qdisc_skb_cb(skb)->mru = 0;
> -	qdisc_skb_cb(skb)->post_ct = false;
> +	tc_skb_cb(skb)->mru = 0;
> +	tc_skb_cb(skb)->post_ct = false;
>   	skb->tc_at_ingress = 1;
>   	mini_qdisc_bstats_cpu_update(miniq, skb);
>   
> diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c index 
> df6c4eb..d916c59 100644
> --- a/net/sched/act_ct.c
> +++ b/net/sched/act_ct.c
> @@ -683,10 +683,10 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
>   				   u8 family, u16 zone, bool *defrag)
>   {
>   	enum ip_conntrack_info ctinfo;
> -	struct qdisc_skb_cb cb;
>   	struct nf_conn *ct;
>   	int err = 0;
>   	bool frag;
> +	u16 mru;
>   
>   	/* Previously seen (loopback)? Ignore. */
>   	ct = nf_ct_get(skb, &ctinfo);
> @@ -701,7 +701,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
>   		return err;
>   
>   	skb_get(skb);
> -	cb = *qdisc_skb_cb(skb);
> +	mru = tc_skb_cb(skb)->mru;
>   
>   	if (family == NFPROTO_IPV4) {
>   		enum ip_defrag_users user = IP_DEFRAG_CONNTRACK_IN + zone; @@ 
> -715,7 +715,7 @@ static int tcf_ct_handle_fragments(struct net *net, 
> struct sk_buff *skb,
>   
>   		if (!err) {
>   			*defrag = true;
> -			cb.mru = IPCB(skb)->frag_max_size;
> +			mru = IPCB(skb)->frag_max_size;
>   		}
>   	} else { /* NFPROTO_IPV6 */
>   #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) @@ -728,7 +728,7 @@ static int 
> tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
>   
>   		if (!err) {
>   			*defrag = true;
> -			cb.mru = IP6CB(skb)->frag_max_size;
> +			mru = IP6CB(skb)->frag_max_size;
>   		}
>   #else
>   		err = -EOPNOTSUPP;
> @@ -737,7 +737,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
>   	}
>   
>   	if (err != -EINPROGRESS)
> -		*qdisc_skb_cb(skb) = cb;
> +		tc_skb_cb(skb)->mru = mru;
>   	skb_clear_hash(skb);
>   	skb->ignore_df = 1;
>   	return err;
> @@ -956,7 +956,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
>   	tcf_action_update_bstats(&c->common, skb);
>   
>   	if (clear) {
> -		qdisc_skb_cb(skb)->post_ct = false;
> +		tc_skb_cb(skb)->post_ct = false;
>   		ct = nf_ct_get(skb, &ctinfo);
>   		if (ct) {
>   			nf_conntrack_put(&ct->ct_general);
> @@ -1043,7 +1043,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
>   out_push:
>   	skb_push_rcsum(skb, nh_ofs);
>   
> -	qdisc_skb_cb(skb)->post_ct = true;
> +	tc_skb_cb(skb)->post_ct = true;
>   out_clear:
>   	if (defrag)
>   		qdisc_skb_cb(skb)->pkt_len = skb->len; diff --git 
> a/net/sched/cls_api.c b/net/sched/cls_api.c index c07cd36..535d243 
> 100644
> --- a/net/sched/cls_api.c
> +++ b/net/sched/cls_api.c
> @@ -1675,12 +1675,14 @@ int tcf_classify_ingress(struct sk_buff *skb,
>   
>   	/* If we missed on some chain */
>   	if (ret == TC_ACT_UNSPEC && last_executed_chain) {
> +		struct tc_skb_cb *cb = tc_skb_cb(skb);
> +
>   		ext = tc_skb_ext_alloc(skb);
>   		if (WARN_ON_ONCE(!ext))
>   			return TC_ACT_SHOT;
>   		ext->chain = last_executed_chain;
> -		ext->mru = qdisc_skb_cb(skb)->mru;
> -		ext->post_ct = qdisc_skb_cb(skb)->post_ct;
> +		ext->mru = cb->mru;
> +		ext->post_ct = cb->post_ct;
>   	}
>   
>   	return ret;
> diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 
> 6009f15..971b8d5 100644
> --- a/net/sched/cls_flower.c
> +++ b/net/sched/cls_flower.c
> @@ -19,6 +19,7 @@
>   
>   #include <net/sch_generic.h>
>   #include <net/pkt_cls.h>
> +#include <net/pkt_sched.h>
>   #include <net/ip.h>
>   #include <net/flow_dissector.h>
>   #include <net/geneve.h>
> @@ -305,7 +306,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
>   {
>   	struct cls_fl_head *head = rcu_dereference_bh(tp->root);
>   	struct fl_flow_key skb_mkey;
> -	bool post_ct = qdisc_skb_cb(skb)->post_ct;
> +	bool post_ct = tc_skb_cb(skb)->post_ct;
>   	struct fl_flow_key skb_key;
>   	struct fl_flow_mask *mask;
>   	struct cls_fl_filter *f;
> diff --git a/net/sched/sch_frag.c b/net/sched/sch_frag.c index 
> e1e77d3..6633530 100644
> --- a/net/sched/sch_frag.c
> +++ b/net/sched/sch_frag.c
> @@ -1,6 +1,7 @@
>   // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
>   #include <net/netlink.h>
>   #include <net/sch_generic.h>
> +#include <net/pkt_sched.h>
>   #include <net/dst.h>
>   #include <net/ip.h>
>   #include <net/ip6_fib.h>
> @@ -137,7 +138,7 @@ static int sch_fragment(struct net *net, struct 
> sk_buff *skb,
>   
>   int sch_frag_xmit_hook(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb))
>   {
> -	u16 mru = qdisc_skb_cb(skb)->mru;
> +	u16 mru = tc_skb_cb(skb)->mru;
>   	int err;
>   
>   	if (mru && skb->len > mru + skb->dev->hard_header_len)
> 

--
-----------
Tim Gardner
Canonical, Inc


More information about the kernel-team mailing list