[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <ZGd+9CUBM+eWG5FR@shredder>
Date: Fri, 19 May 2023 16:51:48 +0300
From: Ido Schimmel <idosch@...dia.com>
To: Nikolay Aleksandrov <razor@...ckwall.org>
Cc: netdev@...r.kernel.org, bridge@...ts.linux-foundation.org,
davem@...emloft.net, kuba@...nel.org, pabeni@...hat.com,
edumazet@...gle.com, roopa@...dia.com, taras.chornyi@...ision.eu,
saeedm@...dia.com, leon@...nel.org, petrm@...dia.com,
vladimir.oltean@....com, claudiu.manoil@....com,
alexandre.belloni@...tlin.com, UNGLinuxDriver@...rochip.com,
jhs@...atatu.com, xiyou.wangcong@...il.com, jiri@...nulli.us,
taspelund@...dia.com
Subject: Re: [PATCH net-next 1/5] skbuff: bridge: Add layer 2 miss indication
On Thu, May 18, 2023 at 07:08:47PM +0300, Nikolay Aleksandrov wrote:
> On 18/05/2023 14:33, Ido Schimmel wrote:
> > diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
> > index fc17b9fd93e6..d8ab5890cbe6 100644
> > --- a/net/bridge/br_input.c
> > +++ b/net/bridge/br_input.c
> > @@ -334,6 +334,7 @@ static rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
> > return RX_HANDLER_CONSUMED;
> >
> > memset(skb->cb, 0, sizeof(struct br_input_skb_cb));
> > + skb->l2_miss = 0;
> >
> > p = br_port_get_rcu(skb->dev);
> > if (p->flags & BR_VLAN_TUNNEL)
>
> Overall looks good, only this part is a bit worrisome and needs some additional
> investigation because now we'll unconditionally dirty a cache line for every
> packet that is forwarded. Could you please check the effect with perf?
To eliminate it I tried the approach we discussed yesterday:
First, add the miss indication to the bridge's control block which is
zeroed for every skb entering the bridge:
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 2119729ded2b..bd5c18286a40 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -581,6 +581,7 @@ struct br_input_skb_cb {
#endif
u8 proxyarp_replied:1;
u8 src_port_isolated:1;
+ u8 miss:1; /* FDB or MDB lookup miss */
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
u8 vlan_filtered:1;
#endif
And set this bit upon misses instead of skb->l2_miss:
@@ -203,6 +205,8 @@ void br_flood(struct net_bridge *br, struct sk_buff *skb,
struct net_bridge_port *prev = NULL;
struct net_bridge_port *p;
+ BR_INPUT_SKB_CB(skb)->miss = 1;
+
list_for_each_entry_rcu(p, &br->port_list, list) {
/* Do not flood unicast traffic to ports that turn it off, nor
* other traffic if flood off, except for traffic we originate
@@ -295,6 +299,7 @@ void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
allow_mode_include = false;
} else {
p = NULL;
+ BR_INPUT_SKB_CB(skb)->miss = 1;
}
while (p || rp) {
Then copy it to skb->l2_miss at the very end where the cache line
containing this field is already written to:
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index 84d6dd5e5b1a..89f65564e338 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -50,6 +50,8 @@ int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb
br_switchdev_frame_set_offload_fwd_mark(skb);
+ skb->l2_miss = BR_INPUT_SKB_CB(skb)->miss;
+
dev_queue_xmit(skb);
return 0;
Also for locally received packets:
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index fc17b9fd93e6..274e55455b15 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -46,6 +46,8 @@ static int br_pass_frame_up(struct sk_buff *skb)
*/
br_switchdev_frame_unmark(skb);
+ skb->l2_miss = BR_INPUT_SKB_CB(skb)->miss;
+
/* Bridge is just like any other port. Make sure the
* packet is allowed except in promisc mode when someone
* may be running packet capture.
Ran these changes through the selftest and it seems to work.
WDYT?
Powered by blists - more mailing lists