diff mbox series

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

Message ID 1642089942-11876-3-git-send-email-bodong@nvidia.com
State New
Headers show
Series Fix ct_state nat matching and nat action not being executed | expand

Commit Message

Bodong Wang Jan. 13, 2022, 4:05 p.m. UTC
From: Paul Blakey <paulb@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@kernel.org>
Signed-off-by: Paul Blakey <paulb@nvidia.com>
(cherry picked from upstream commit f06d13d128fe59bf9004e74770f76e60b6687731)
Signed-off-by: Bodong Wang <bodong@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(-)

Comments

Tim Gardner Jan. 14, 2022, 3:06 p.m. UTC | #1
On 1/13/22 9:05 AM, Bodong Wang wrote:
> From: Paul Blakey <paulb@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@kernel.org>
> Signed-off-by: Paul Blakey <paulb@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@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)
>
Bodong Wang Jan. 14, 2022, 5:59 p.m. UTC | #2
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@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@kernel.org>
> Signed-off-by: Paul Blakey <paulb@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@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
Tim Gardner Jan. 14, 2022, 6:48 p.m. UTC | #3
On 1/14/22 10:59 AM, Bodong Wang wrote:
> You're right Tim. Should I send another version?
> Sorry for the top posting, my email client has problem.
> 
> 

Yes - please NAK this thread, start a new thread with 'v2' in the 
subject. The NAK indicates to the stable team to not spend any time 
reviewing this patch set. Also remember to describe what your v2 changes 
are in the cover letter.

rtg
diff mbox series

Patch

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)