All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 net-next 0/3] net/sched: fix over mtu packet of defrag in
@ 2020-11-19 23:38 wenxu
  2020-11-19 23:38 ` [PATCH v3 net-next 1/3] net/sched: fix miss init the mru in qdisc_skb_cb wenxu
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: wenxu @ 2020-11-19 23:38 UTC (permalink / raw)
  To: kuba, marcelo.leitner, vladbu, jhs, xiyou.wangcong; +Cc: netdev

From: wenxu <wenxu@ucloud.cn>

Currently kernel tc subsystem can do conntrack in act_ct. But when several
fragment packets go through the act_ct, function tcf_ct_handle_fragments
will defrag the packets to a big one. But the last action will redirect
mirred to a device which maybe lead the reassembly big packet over the mtu
of target device.

The first patch fix miss init the qdisc_skb_cb->mru
The send one refactor the hanle of xmit in act_mirred and prepare for the
third one
The last one add implict packet fragment support to fix the over mtu for
defrag in act_ct.

wenxu (3):
  net/sched: fix miss init the mru in qdisc_skb_cb
  net/sched: act_mirred: refactor the handle of xmit
  net/sched: sch_frag: add generic packet fragment support.

 include/net/act_api.h     |   8 +++
 include/net/sch_generic.h |   5 +-
 net/core/dev.c            |   2 +
 net/sched/Makefile        |   1 +
 net/sched/act_api.c       |  44 ++++++++++++++
 net/sched/act_ct.c        |   7 +++
 net/sched/act_mirred.c    |  21 +++++--
 net/sched/sch_frag.c      | 150 ++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 228 insertions(+), 10 deletions(-)
 create mode 100644 net/sched/sch_frag.c

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 net-next 1/3] net/sched: fix miss init the mru in qdisc_skb_cb
  2020-11-19 23:38 [PATCH v3 net-next 0/3] net/sched: fix over mtu packet of defrag in wenxu
@ 2020-11-19 23:38 ` wenxu
  2020-11-19 23:38 ` [PATCH v3 net-next 2/3] net/sched: act_mirred: refactor the handle of xmit wenxu
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: wenxu @ 2020-11-19 23:38 UTC (permalink / raw)
  To: kuba, marcelo.leitner, vladbu, jhs, xiyou.wangcong; +Cc: netdev

From: wenxu <wenxu@ucloud.cn>

The mru in the qdisc_skb_cb should be init as 0. Only defrag packets in the
act_ct will set the value.

Fixes: 038ebb1a713d ("net/sched: act_ct: fix miss set mru for ovs after defrag in act_ct")
Signed-off-by: wenxu <wenxu@ucloud.cn>
---
v3: no change

 net/core/dev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/core/dev.c b/net/core/dev.c
index 60d325b..d0efa98 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3867,6 +3867,7 @@ 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;
 	mini_qdisc_bstats_cpu_update(miniq, skb);
 
 	switch (tcf_classify(skb, miniq->filter_list, &cl_res, false)) {
@@ -4954,6 +4955,7 @@ 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;
 	skb->tc_at_ingress = 1;
 	mini_qdisc_bstats_cpu_update(miniq, skb);
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 net-next 2/3] net/sched: act_mirred: refactor the handle of xmit
  2020-11-19 23:38 [PATCH v3 net-next 0/3] net/sched: fix over mtu packet of defrag in wenxu
  2020-11-19 23:38 ` [PATCH v3 net-next 1/3] net/sched: fix miss init the mru in qdisc_skb_cb wenxu
@ 2020-11-19 23:38 ` wenxu
  2020-11-19 23:38 ` [PATCH v3 net-next 3/3] net/sched: sch_frag: add generic packet fragment support wenxu
  2020-11-20 19:28 ` [PATCH v3 net-next 0/3] net/sched: fix over mtu packet of defrag in Cong Wang
  3 siblings, 0 replies; 9+ messages in thread
From: wenxu @ 2020-11-19 23:38 UTC (permalink / raw)
  To: kuba, marcelo.leitner, vladbu, jhs, xiyou.wangcong; +Cc: netdev

From: wenxu <wenxu@ucloud.cn>

This one is prepare for the next patch.

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
v3: no change

 include/net/sch_generic.h |  5 -----
 net/sched/act_mirred.c    | 21 +++++++++++++++------
 2 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index d8fd867..dd74f06 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -1281,9 +1281,4 @@ void mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc,
 void mini_qdisc_pair_block_init(struct mini_Qdisc_pair *miniqp,
 				struct tcf_block *block);
 
-static inline int skb_tc_reinsert(struct sk_buff *skb, struct tcf_result *res)
-{
-	return res->ingress ? netif_receive_skb(skb) : dev_queue_xmit(skb);
-}
-
 #endif
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index e24b7e2..17d0095 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -205,6 +205,18 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
 	return err;
 }
 
+static int tcf_mirred_forward(bool want_ingress, struct sk_buff *skb)
+{
+	int err;
+
+	if (!want_ingress)
+		err = dev_queue_xmit(skb);
+	else
+		err = netif_receive_skb(skb);
+
+	return err;
+}
+
 static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
 			  struct tcf_result *res)
 {
@@ -287,18 +299,15 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
 		/* let's the caller reinsert the packet, if possible */
 		if (use_reinsert) {
 			res->ingress = want_ingress;
-			if (skb_tc_reinsert(skb, res))
+			err = tcf_mirred_forward(res->ingress, skb);
+			if (err)
 				tcf_action_inc_overlimit_qstats(&m->common);
 			__this_cpu_dec(mirred_rec_level);
 			return TC_ACT_CONSUMED;
 		}
 	}
 
-	if (!want_ingress)
-		err = dev_queue_xmit(skb2);
-	else
-		err = netif_receive_skb(skb2);
-
+	err = tcf_mirred_forward(want_ingress, skb2);
 	if (err) {
 out:
 		tcf_action_inc_overlimit_qstats(&m->common);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 net-next 3/3] net/sched: sch_frag: add generic packet fragment support.
  2020-11-19 23:38 [PATCH v3 net-next 0/3] net/sched: fix over mtu packet of defrag in wenxu
  2020-11-19 23:38 ` [PATCH v3 net-next 1/3] net/sched: fix miss init the mru in qdisc_skb_cb wenxu
  2020-11-19 23:38 ` [PATCH v3 net-next 2/3] net/sched: act_mirred: refactor the handle of xmit wenxu
@ 2020-11-19 23:38 ` wenxu
  2020-11-24 19:24   ` Jakub Kicinski
  2020-11-20 19:28 ` [PATCH v3 net-next 0/3] net/sched: fix over mtu packet of defrag in Cong Wang
  3 siblings, 1 reply; 9+ messages in thread
From: wenxu @ 2020-11-19 23:38 UTC (permalink / raw)
  To: kuba, marcelo.leitner, vladbu, jhs, xiyou.wangcong; +Cc: netdev

From: wenxu <wenxu@ucloud.cn>

Currently kernel tc subsystem can do conntrack in cat_ct. But when several
fragment packets go through the act_ct, function tcf_ct_handle_fragments
will defrag the packets to a big one. But the last action will redirect
mirred to a device which maybe lead the reassembly big packet over the mtu
of target device.

This patch add support for a xmit hook to mirred, that gets executed before
xmiting the packet. Then, when act_ct gets loaded, it configs that hook.
The frag xmit hook maybe reused by other modules.

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
v2: make act_frag just buildin for tc core but not a module
    return an error code from tcf_fragment
    depends on INET for ip_do_fragment
v3: put the whole sch_frag.c under CONFIG_INET

 include/net/act_api.h     |   8 +++
 include/net/sch_generic.h |   2 +
 net/sched/Makefile        |   1 +
 net/sched/act_api.c       |  44 ++++++++++++++
 net/sched/act_ct.c        |   7 +++
 net/sched/act_mirred.c    |   2 +-
 net/sched/sch_frag.c      | 150 ++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 213 insertions(+), 1 deletion(-)
 create mode 100644 net/sched/sch_frag.c

diff --git a/include/net/act_api.h b/include/net/act_api.h
index 8721492..decb6de 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -239,6 +239,14 @@ int tcf_action_check_ctrlact(int action, struct tcf_proto *tp,
 			     struct netlink_ext_ack *newchain);
 struct tcf_chain *tcf_action_set_ctrlact(struct tc_action *a, int action,
 					 struct tcf_chain *newchain);
+
+typedef int xmit_hook_func(struct sk_buff *skb,
+			   int (*xmit)(struct sk_buff *skb));
+
+int tcf_dev_queue_xmit(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb));
+int tcf_set_xmit_hook(xmit_hook_func *xmit_hook);
+void tcf_clear_xmit_hook(void);
+
 #endif /* CONFIG_NET_CLS_ACT */
 
 static inline void tcf_action_stats_update(struct tc_action *a, u64 bytes,
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index dd74f06..162ed62 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -1281,4 +1281,6 @@ void mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc,
 void mini_qdisc_pair_block_init(struct mini_Qdisc_pair *miniqp,
 				struct tcf_block *block);
 
+int sch_frag_xmit_hook(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb));
+
 #endif
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 66bbf9a..dd14ef4 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -5,6 +5,7 @@
 
 obj-y	:= sch_generic.o sch_mq.o
 
+obj-$(CONFIG_INET)		+= sch_frag.o
 obj-$(CONFIG_NET_SCHED)		+= sch_api.o sch_blackhole.o
 obj-$(CONFIG_NET_CLS)		+= cls_api.o
 obj-$(CONFIG_NET_CLS_ACT)	+= act_api.o
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 60e1572..fbb35a8 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -22,6 +22,50 @@
 #include <net/act_api.h>
 #include <net/netlink.h>
 
+static xmit_hook_func __rcu *tcf_xmit_hook;
+static DEFINE_SPINLOCK(tcf_xmit_hook_lock);
+static u16 tcf_xmit_hook_count;
+
+int tcf_set_xmit_hook(xmit_hook_func *xmit_hook)
+{
+	spin_lock(&tcf_xmit_hook_lock);
+	if (!tcf_xmit_hook_count) {
+		rcu_assign_pointer(tcf_xmit_hook, xmit_hook);
+	} else if (xmit_hook != rcu_access_pointer(tcf_xmit_hook)) {
+		spin_unlock(&tcf_xmit_hook_lock);
+		return -EBUSY;
+	}
+
+	tcf_xmit_hook_count++;
+	spin_unlock(&tcf_xmit_hook_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(tcf_set_xmit_hook);
+
+void tcf_clear_xmit_hook(void)
+{
+	spin_lock(&tcf_xmit_hook_lock);
+	if (--tcf_xmit_hook_count == 0)
+		rcu_assign_pointer(tcf_xmit_hook, NULL);
+	spin_unlock(&tcf_xmit_hook_lock);
+
+	synchronize_rcu();
+}
+EXPORT_SYMBOL_GPL(tcf_clear_xmit_hook);
+
+int tcf_dev_queue_xmit(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb))
+{
+	xmit_hook_func *xmit_hook;
+
+	xmit_hook = rcu_dereference(tcf_xmit_hook);
+	if (xmit_hook)
+		return xmit_hook(skb, xmit);
+	else
+		return xmit(skb);
+}
+EXPORT_SYMBOL_GPL(tcf_dev_queue_xmit);
+
 static void tcf_action_goto_chain_exec(const struct tc_action *a,
 				       struct tcf_result *res)
 {
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index aba3cd8..f82dc65 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -1541,8 +1541,14 @@ static int __init ct_init_module(void)
 	if (err)
 		goto err_register;
 
+	err = tcf_set_xmit_hook(sch_frag_xmit_hook);
+	if (err)
+		goto err_action;
+
 	return 0;
 
+err_action:
+	tcf_unregister_action(&act_ct_ops, &ct_net_ops);
 err_register:
 	tcf_ct_flow_tables_uninit();
 err_tbl_init:
@@ -1552,6 +1558,7 @@ static int __init ct_init_module(void)
 
 static void __exit ct_cleanup_module(void)
 {
+	tcf_clear_xmit_hook();
 	tcf_unregister_action(&act_ct_ops, &ct_net_ops);
 	tcf_ct_flow_tables_uninit();
 	destroy_workqueue(act_ct_wq);
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index 17d0095..7153c67 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -210,7 +210,7 @@ static int tcf_mirred_forward(bool want_ingress, struct sk_buff *skb)
 	int err;
 
 	if (!want_ingress)
-		err = dev_queue_xmit(skb);
+		err = tcf_dev_queue_xmit(skb, dev_queue_xmit);
 	else
 		err = netif_receive_skb(skb);
 
diff --git a/net/sched/sch_frag.c b/net/sched/sch_frag.c
new file mode 100644
index 0000000..e1e77d3
--- /dev/null
+++ b/net/sched/sch_frag.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+#include <net/netlink.h>
+#include <net/sch_generic.h>
+#include <net/dst.h>
+#include <net/ip.h>
+#include <net/ip6_fib.h>
+
+struct sch_frag_data {
+	unsigned long dst;
+	struct qdisc_skb_cb cb;
+	__be16 inner_protocol;
+	u16 vlan_tci;
+	__be16 vlan_proto;
+	unsigned int l2_len;
+	u8 l2_data[VLAN_ETH_HLEN];
+	int (*xmit)(struct sk_buff *skb);
+};
+
+static DEFINE_PER_CPU(struct sch_frag_data, sch_frag_data_storage);
+
+static int sch_frag_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
+{
+	struct sch_frag_data *data = this_cpu_ptr(&sch_frag_data_storage);
+
+	if (skb_cow_head(skb, data->l2_len) < 0) {
+		kfree_skb(skb);
+		return -ENOMEM;
+	}
+
+	__skb_dst_copy(skb, data->dst);
+	*qdisc_skb_cb(skb) = data->cb;
+	skb->inner_protocol = data->inner_protocol;
+	if (data->vlan_tci & VLAN_CFI_MASK)
+		__vlan_hwaccel_put_tag(skb, data->vlan_proto,
+				       data->vlan_tci & ~VLAN_CFI_MASK);
+	else
+		__vlan_hwaccel_clear_tag(skb);
+
+	/* Reconstruct the MAC header.  */
+	skb_push(skb, data->l2_len);
+	memcpy(skb->data, &data->l2_data, data->l2_len);
+	skb_postpush_rcsum(skb, skb->data, data->l2_len);
+	skb_reset_mac_header(skb);
+
+	return data->xmit(skb);
+}
+
+static void sch_frag_prepare_frag(struct sk_buff *skb,
+				  int (*xmit)(struct sk_buff *skb))
+{
+	unsigned int hlen = skb_network_offset(skb);
+	struct sch_frag_data *data;
+
+	data = this_cpu_ptr(&sch_frag_data_storage);
+	data->dst = skb->_skb_refdst;
+	data->cb = *qdisc_skb_cb(skb);
+	data->xmit = xmit;
+	data->inner_protocol = skb->inner_protocol;
+	if (skb_vlan_tag_present(skb))
+		data->vlan_tci = skb_vlan_tag_get(skb) | VLAN_CFI_MASK;
+	else
+		data->vlan_tci = 0;
+	data->vlan_proto = skb->vlan_proto;
+	data->l2_len = hlen;
+	memcpy(&data->l2_data, skb->data, hlen);
+
+	memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
+	skb_pull(skb, hlen);
+}
+
+static unsigned int
+sch_frag_dst_get_mtu(const struct dst_entry *dst)
+{
+	return dst->dev->mtu;
+}
+
+static struct dst_ops sch_frag_dst_ops = {
+	.family = AF_UNSPEC,
+	.mtu = sch_frag_dst_get_mtu,
+};
+
+static int sch_fragment(struct net *net, struct sk_buff *skb,
+			u16 mru, int (*xmit)(struct sk_buff *skb))
+{
+	int ret = -1;
+
+	if (skb_network_offset(skb) > VLAN_ETH_HLEN) {
+		net_warn_ratelimited("L2 header too long to fragment\n");
+		goto err;
+	}
+
+	if (skb_protocol(skb, true) == htons(ETH_P_IP)) {
+		struct dst_entry sch_frag_dst;
+		unsigned long orig_dst;
+
+		sch_frag_prepare_frag(skb, xmit);
+		dst_init(&sch_frag_dst, &sch_frag_dst_ops, NULL, 1,
+			 DST_OBSOLETE_NONE, DST_NOCOUNT);
+		sch_frag_dst.dev = skb->dev;
+
+		orig_dst = skb->_skb_refdst;
+		skb_dst_set_noref(skb, &sch_frag_dst);
+		IPCB(skb)->frag_max_size = mru;
+
+		ret = ip_do_fragment(net, skb->sk, skb, sch_frag_xmit);
+		refdst_drop(orig_dst);
+	} else if (skb_protocol(skb, true) == htons(ETH_P_IPV6)) {
+		unsigned long orig_dst;
+		struct rt6_info sch_frag_rt;
+
+		sch_frag_prepare_frag(skb, xmit);
+		memset(&sch_frag_rt, 0, sizeof(sch_frag_rt));
+		dst_init(&sch_frag_rt.dst, &sch_frag_dst_ops, NULL, 1,
+			 DST_OBSOLETE_NONE, DST_NOCOUNT);
+		sch_frag_rt.dst.dev = skb->dev;
+
+		orig_dst = skb->_skb_refdst;
+		skb_dst_set_noref(skb, &sch_frag_rt.dst);
+		IP6CB(skb)->frag_max_size = mru;
+
+		ret = ipv6_stub->ipv6_fragment(net, skb->sk, skb,
+					       sch_frag_xmit);
+		refdst_drop(orig_dst);
+	} else {
+		net_warn_ratelimited("Fail frag %s: eth=%x, MRU=%d, MTU=%d\n",
+				     netdev_name(skb->dev),
+				     ntohs(skb_protocol(skb, true)), mru,
+				     skb->dev->mtu);
+		goto err;
+	}
+
+	return ret;
+err:
+	kfree_skb(skb);
+	return ret;
+}
+
+int sch_frag_xmit_hook(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb))
+{
+	u16 mru = qdisc_skb_cb(skb)->mru;
+	int err;
+
+	if (mru && skb->len > mru + skb->dev->hard_header_len)
+		err = sch_fragment(dev_net(skb->dev), skb, mru, xmit);
+	else
+		err = xmit(skb);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(sch_frag_xmit_hook);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 net-next 0/3] net/sched: fix over mtu packet of defrag in
  2020-11-19 23:38 [PATCH v3 net-next 0/3] net/sched: fix over mtu packet of defrag in wenxu
                   ` (2 preceding siblings ...)
  2020-11-19 23:38 ` [PATCH v3 net-next 3/3] net/sched: sch_frag: add generic packet fragment support wenxu
@ 2020-11-20 19:28 ` Cong Wang
  2020-11-21 14:39   ` Jamal Hadi Salim
  3 siblings, 1 reply; 9+ messages in thread
From: Cong Wang @ 2020-11-20 19:28 UTC (permalink / raw)
  To: wenxu
  Cc: Jakub Kicinski, Marcelo Ricardo Leitner, Vlad Buslov,
	Jamal Hadi Salim, Linux Kernel Network Developers

On Thu, Nov 19, 2020 at 3:39 PM <wenxu@ucloud.cn> wrote:
>
> From: wenxu <wenxu@ucloud.cn>
>
> Currently kernel tc subsystem can do conntrack in act_ct. But when several
> fragment packets go through the act_ct, function tcf_ct_handle_fragments
> will defrag the packets to a big one. But the last action will redirect
> mirred to a device which maybe lead the reassembly big packet over the mtu
> of target device.
>
> The first patch fix miss init the qdisc_skb_cb->mru
> The send one refactor the hanle of xmit in act_mirred and prepare for the
> third one
> The last one add implict packet fragment support to fix the over mtu for
> defrag in act_ct.

Overall it looks much better to me now, so:

Acked-by: Cong Wang <cong.wang@bytedance.com>

Thanks!

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 net-next 0/3] net/sched: fix over mtu packet of defrag in
  2020-11-20 19:28 ` [PATCH v3 net-next 0/3] net/sched: fix over mtu packet of defrag in Cong Wang
@ 2020-11-21 14:39   ` Jamal Hadi Salim
  0 siblings, 0 replies; 9+ messages in thread
From: Jamal Hadi Salim @ 2020-11-21 14:39 UTC (permalink / raw)
  To: Cong Wang, wenxu
  Cc: Jakub Kicinski, Marcelo Ricardo Leitner, Vlad Buslov,
	Linux Kernel Network Developers

On 2020-11-20 2:28 p.m., Cong Wang wrote:
> On Thu, Nov 19, 2020 at 3:39 PM <wenxu@ucloud.cn> wrote:
>>
>> From: wenxu <wenxu@ucloud.cn>
>>
>> Currently kernel tc subsystem can do conntrack in act_ct. But when several
>> fragment packets go through the act_ct, function tcf_ct_handle_fragments
>> will defrag the packets to a big one. But the last action will redirect
>> mirred to a device which maybe lead the reassembly big packet over the mtu
>> of target device.
>>
>> The first patch fix miss init the qdisc_skb_cb->mru
>> The send one refactor the hanle of xmit in act_mirred and prepare for the
>> third one
>> The last one add implict packet fragment support to fix the over mtu for
>> defrag in act_ct.
> 
> Overall it looks much better to me now, so:
> 
> Acked-by: Cong Wang <cong.wang@bytedance.com>

LGTM as well.

Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>

cheers,
jamal

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 net-next 3/3] net/sched: sch_frag: add generic packet fragment support.
  2020-11-19 23:38 ` [PATCH v3 net-next 3/3] net/sched: sch_frag: add generic packet fragment support wenxu
@ 2020-11-24 19:24   ` Jakub Kicinski
  2020-11-24 23:10     ` wenxu
  0 siblings, 1 reply; 9+ messages in thread
From: Jakub Kicinski @ 2020-11-24 19:24 UTC (permalink / raw)
  To: wenxu; +Cc: marcelo.leitner, vladbu, jhs, xiyou.wangcong, netdev

On Fri, 20 Nov 2020 07:38:36 +0800 wenxu@ucloud.cn wrote:
> +int tcf_dev_queue_xmit(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb))
> +{
> +	xmit_hook_func *xmit_hook;
> +
> +	xmit_hook = rcu_dereference(tcf_xmit_hook);
> +	if (xmit_hook)
> +		return xmit_hook(skb, xmit);
> +	else
> +		return xmit(skb);
> +}
> +EXPORT_SYMBOL_GPL(tcf_dev_queue_xmit);

I'm concerned about the performance impact of these indirect calls.

Did you check what code compiler will generate? What the impact with
retpolines enabled is going to be?

Now that sch_frag is no longer a module this could be simplified.

First of all - xmit_hook can only be sch_frag_xmit_hook, so please use
that directly. 

	if (READ_ONCE(tcf_xmit_hook_count)) 
		sch_frag_xmit_hook(...
	else
		dev_queue_xmit(...

The abstraction is costly and not necessary right now IMO.

Then probably the counter should be:

	u32 __read_mostly tcf_xmit_hook_count;

To avoid byte loads and having it be places in an unlucky cache line.

You could also make the helper a static inline in a header.


Unless I'm not giving the compiler enough credit and the performance
impact of this patch with retpolines on is indiscernible, but that'd
need to be proven by testing...

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 net-next 3/3] net/sched: sch_frag: add generic packet fragment support.
  2020-11-24 19:24   ` Jakub Kicinski
@ 2020-11-24 23:10     ` wenxu
  2020-11-25  0:02       ` Jakub Kicinski
  0 siblings, 1 reply; 9+ messages in thread
From: wenxu @ 2020-11-24 23:10 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: marcelo.leitner, vladbu, jhs, xiyou.wangcong, netdev


在 2020/11/25 3:24, Jakub Kicinski 写道:
> On Fri, 20 Nov 2020 07:38:36 +0800 wenxu@ucloud.cn wrote:
>> +int tcf_dev_queue_xmit(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb))
>> +{
>> +	xmit_hook_func *xmit_hook;
>> +
>> +	xmit_hook = rcu_dereference(tcf_xmit_hook);
>> +	if (xmit_hook)
>> +		return xmit_hook(skb, xmit);
>> +	else
>> +		return xmit(skb);
>> +}
>> +EXPORT_SYMBOL_GPL(tcf_dev_queue_xmit);
> I'm concerned about the performance impact of these indirect calls.
>
> Did you check what code compiler will generate? What the impact with
> retpolines enabled is going to be?
>
> Now that sch_frag is no longer a module this could be simplified.
>
> First of all - xmit_hook can only be sch_frag_xmit_hook, so please use
> that directly. 
>
> 	if (READ_ONCE(tcf_xmit_hook_count)) 
> 		sch_frag_xmit_hook(...
> 	else
> 		dev_queue_xmit(...
>
> The abstraction is costly and not necessary right now IMO.
>
> Then probably the counter should be:
>
> 	u32 __read_mostly tcf_xmit_hook_count;
>
> To avoid byte loads and having it be places in an unlucky cache line.
Maybe a static key replace  tcf_xmit_hook_count is more simplified?

DEFINE_STATIC_KEY_FALSE(tcf_xmit_hook_in_use);


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 net-next 3/3] net/sched: sch_frag: add generic packet fragment support.
  2020-11-24 23:10     ` wenxu
@ 2020-11-25  0:02       ` Jakub Kicinski
  0 siblings, 0 replies; 9+ messages in thread
From: Jakub Kicinski @ 2020-11-25  0:02 UTC (permalink / raw)
  To: wenxu; +Cc: marcelo.leitner, vladbu, jhs, xiyou.wangcong, netdev

On Wed, 25 Nov 2020 07:10:43 +0800 wenxu wrote:
> 在 2020/11/25 3:24, Jakub Kicinski 写道:
> > On Fri, 20 Nov 2020 07:38:36 +0800 wenxu@ucloud.cn wrote:  
> >> +int tcf_dev_queue_xmit(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb))
> >> +{
> >> +	xmit_hook_func *xmit_hook;
> >> +
> >> +	xmit_hook = rcu_dereference(tcf_xmit_hook);
> >> +	if (xmit_hook)
> >> +		return xmit_hook(skb, xmit);
> >> +	else
> >> +		return xmit(skb);
> >> +}
> >> +EXPORT_SYMBOL_GPL(tcf_dev_queue_xmit);  
> > I'm concerned about the performance impact of these indirect calls.
> >
> > Did you check what code compiler will generate? What the impact with
> > retpolines enabled is going to be?
> >
> > Now that sch_frag is no longer a module this could be simplified.
> >
> > First of all - xmit_hook can only be sch_frag_xmit_hook, so please use
> > that directly. 
> >
> > 	if (READ_ONCE(tcf_xmit_hook_count)) 
> > 		sch_frag_xmit_hook(...
> > 	else
> > 		dev_queue_xmit(...
> >
> > The abstraction is costly and not necessary right now IMO.
> >
> > Then probably the counter should be:
> >
> > 	u32 __read_mostly tcf_xmit_hook_count;
> >
> > To avoid byte loads and having it be places in an unlucky cache line.  
> Maybe a static key replace  tcf_xmit_hook_count is more simplified?
> 
> DEFINE_STATIC_KEY_FALSE(tcf_xmit_hook_in_use);

I wasn't sure if static key would work with the module (mirred being a
module) but thinking about it again, if tcf_dev_queue_xmit() is not an
static inline but a normal function, it should work. Sounds good!

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-11-25  0:02 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-19 23:38 [PATCH v3 net-next 0/3] net/sched: fix over mtu packet of defrag in wenxu
2020-11-19 23:38 ` [PATCH v3 net-next 1/3] net/sched: fix miss init the mru in qdisc_skb_cb wenxu
2020-11-19 23:38 ` [PATCH v3 net-next 2/3] net/sched: act_mirred: refactor the handle of xmit wenxu
2020-11-19 23:38 ` [PATCH v3 net-next 3/3] net/sched: sch_frag: add generic packet fragment support wenxu
2020-11-24 19:24   ` Jakub Kicinski
2020-11-24 23:10     ` wenxu
2020-11-25  0:02       ` Jakub Kicinski
2020-11-20 19:28 ` [PATCH v3 net-next 0/3] net/sched: fix over mtu packet of defrag in Cong Wang
2020-11-21 14:39   ` Jamal Hadi Salim

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.