Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 30b0594a authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-bridge-convert-bool-options-to-bits'



Nikolay Aleksandrov says:

====================
net: bridge: convert bool options to bits

A lot of boolean bridge options have been added around the net_bridge
structure resulting in holes and more importantly different cache lines
that need to be fetched in the fast path. This set moves all of those
to bits in a bitfield which resides in a hot cache line thus reducing
the size of net_bridge, the number of holes and the number of cache
lines needed for the fast path.
The set is also sent in preparation for new boolean options to avoid
spreading them in the structure and making new holes.
One nice side-effect is that we avoid potential race conditions by using
the bitops since some of the options were bits being directly set in
parallel risking hard to debug issues (has_ipv6_addr).

Before:
 size: 1184, holes: 8, sum holes: 30
After:
 size: 1160, holes: 3, sum holes: 7

Patch 01 is a trivial style fix
Patch 02 adds the new options bitfield and converts the vlan boolean
         options to bits
Patches 03-08 convert the rest of the boolean options to bits
Patch 09 re-arranges a few fields in net_bridge to further reduce size

v2: patch 09: remove the comment about offload_fwd_mark in net_bridge and
    leave it where it is now, thanks to Ido for spotting it
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 37ac5db6 35750b0b
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -175,6 +175,22 @@ static struct notifier_block br_switchdev_notifier = {
	.notifier_call = br_switchdev_event,
};

void br_opt_toggle(struct net_bridge *br, enum net_bridge_opts opt, bool on)
{
	bool cur = !!br_opt_get(br, opt);

	br_debug(br, "toggle option: %d state: %d -> %d\n",
		 opt, cur, on);

	if (cur == on)
		return;

	if (on)
		set_bit(opt, &br->options);
	else
		clear_bit(opt, &br->options);
}

static void __net_exit br_net_exit(struct net *net)
{
	struct net_device *dev;
+8 −5
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ void br_recalculate_neigh_suppress_enabled(struct net_bridge *br)
		}
	}

	br->neigh_suppress_enabled = neigh_suppress;
	br_opt_toggle(br, BROPT_NEIGH_SUPPRESS_ENABLED, neigh_suppress);
}

#if IS_ENABLED(CONFIG_INET)
@@ -155,7 +155,7 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
	    ipv4_is_multicast(tip))
		return;

	if (br->neigh_suppress_enabled) {
	if (br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED)) {
		if (p && (p->flags & BR_NEIGH_SUPPRESS))
			return;
		if (ipv4_is_zeronet(sip) || sip == tip) {
@@ -175,7 +175,8 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
			return;
	}

	if (br->neigh_suppress_enabled && br_is_local_ip(vlandev, tip)) {
	if (br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) &&
	    br_is_local_ip(vlandev, tip)) {
		/* its our local ip, so don't proxy reply
		 * and don't forward to neigh suppress ports
		 */
@@ -213,7 +214,8 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
			/* If we have replied or as long as we know the
			 * mac, indicate to arp replied
			 */
			if (replied || br->neigh_suppress_enabled)
			if (replied ||
			    br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED))
				BR_INPUT_SKB_CB(skb)->proxyarp_replied = true;
		}

@@ -460,7 +462,8 @@ void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br,
			 * mac, indicate to NEIGH_SUPPRESS ports that we
			 * have replied
			 */
			if (replied || br->neigh_suppress_enabled)
			if (replied ||
			    br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED))
				BR_INPUT_SKB_CB(skb)->proxyarp_replied = true;
		}
		neigh_release(n);
+3 −3
Original line number Diff line number Diff line
@@ -67,11 +67,11 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
	if (IS_ENABLED(CONFIG_INET) &&
	    (eth->h_proto == htons(ETH_P_ARP) ||
	     eth->h_proto == htons(ETH_P_RARP)) &&
	    br->neigh_suppress_enabled) {
	    br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED)) {
		br_do_proxy_suppress_arp(skb, br, vid, NULL);
	} else if (IS_ENABLED(CONFIG_IPV6) &&
		   skb->protocol == htons(ETH_P_IPV6) &&
		   br->neigh_suppress_enabled &&
		   br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) &&
		   pskb_may_pull(skb, sizeof(struct ipv6hdr) +
				 sizeof(struct nd_msg)) &&
		   ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) {
@@ -228,7 +228,7 @@ static int br_change_mtu(struct net_device *dev, int new_mtu)
	dev->mtu = new_mtu;

	/* this flag will be cleared if the MTU was automatically adjusted */
	br->mtu_set_by_user = true;
	br_opt_toggle(br, BROPT_MTU_SET_BY_USER, true);
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
	/* remember the MTU in the rtable for PMTU */
	dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu);
+2 −2
Original line number Diff line number Diff line
@@ -508,14 +508,14 @@ void br_mtu_auto_adjust(struct net_bridge *br)
	ASSERT_RTNL();

	/* if the bridge MTU was manually configured don't mess with it */
	if (br->mtu_set_by_user)
	if (br_opt_get(br, BROPT_MTU_SET_BY_USER))
		return;

	/* change to the minimum MTU and clear the flag which was set by
	 * the bridge ndo_change_mtu callback
	 */
	dev_set_mtu(br->dev, br_mtu_min(br));
	br->mtu_set_by_user = false;
	br_opt_toggle(br, BROPT_MTU_SET_BY_USER, false);
}

static void br_set_gso_limits(struct net_bridge *br)
+1 −1
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
		br_do_proxy_suppress_arp(skb, br, vid, p);
	} else if (IS_ENABLED(CONFIG_IPV6) &&
		   skb->protocol == htons(ETH_P_IPV6) &&
		   br->neigh_suppress_enabled &&
		   br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) &&
		   pskb_may_pull(skb, sizeof(struct ipv6hdr) +
				 sizeof(struct nd_msg)) &&
		   ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) {
Loading