Commit 3a97e2ae authored by Jussi Maki's avatar Jussi Maki Committed by Zhengchao Shao
Browse files

net: bonding: Use per-cpu rr_tx_counter

mainline inclusion
from mainline-v5.14-rc1
commit 848ca918
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I7NDRB
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=848ca9182a7d25bb54955c3aab9a3a2742bf9678



----------------------------------------

The round-robin rr_tx_counter was shared across CPUs leading to
significant cache thrashing at high packet rates. This patch switches
the round-robin packet counter to use a per-cpu variable to decide
the destination slave.

On a test with 2x100Gbit ICE nic with pktgen_sample_04_many_flows.sh
(-s 64 -t 32) the tx rate was 19.6Mpps before and 22.3Mpps after
this patch.

"perf top -e cache_misses" before:
    12.31%  [bonding]       [k] bond_xmit_roundrobin_slave_get
    10.59%  [sch_fq_codel]  [k] fq_codel_dequeue
     9.34%  [kernel]        [k] skb_release_data
after:
    15.42%  [sch_fq_codel]  [k] fq_codel_dequeue
    10.06%  [kernel]        [k] __memset
     9.12%  [kernel]        [k] skb_release_data

Signed-off-by: default avatarJussi Maki <joamaki@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>

Conflicts:
	drivers/net/bonding/bond_main.c

Signed-off-by: default avatarZhengchao Shao <shaozhengchao@huawei.com>
parent 323ca2c2
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -4414,16 +4414,16 @@ static u32 bond_rr_gen_slave_id(struct bonding *bond)
		slave_id = prandom_u32();
		break;
	case 1:
		slave_id = bond->rr_tx_counter;
		slave_id = this_cpu_inc_return(*bond->rr_tx_counter);
		break;
	default:
		reciprocal_packets_per_slave =
			bond->params.reciprocal_packets_per_slave;
		slave_id = reciprocal_divide(bond->rr_tx_counter,
		slave_id = this_cpu_inc_return(*bond->rr_tx_counter);
		slave_id = reciprocal_divide(slave_id,
					     reciprocal_packets_per_slave);
		break;
	}
	bond->rr_tx_counter++;

	return slave_id;
}
@@ -5245,6 +5245,9 @@ static void bond_destructor(struct net_device *bond_dev)
	struct bonding *bond = netdev_priv(bond_dev);
	if (bond->wq)
		destroy_workqueue(bond->wq);

	if (bond->rr_tx_counter)
		free_percpu(bond->rr_tx_counter);
}

void bond_setup(struct net_device *bond_dev)
@@ -5744,6 +5747,15 @@ static int bond_init(struct net_device *bond_dev)
	if (!bond->wq)
		return -ENOMEM;

	if (BOND_MODE(bond) == BOND_MODE_ROUNDROBIN) {
		bond->rr_tx_counter = alloc_percpu(u32);
		if (!bond->rr_tx_counter) {
			destroy_workqueue(bond->wq);
			bond->wq = NULL;
			return -ENOMEM;
		}
	}

	spin_lock_init(&bond->stats_lock);
	netdev_lockdep_set_classes(bond_dev);

+1 −1
Original line number Diff line number Diff line
@@ -237,7 +237,7 @@ struct bonding {
	char     proc_file_name[IFNAMSIZ];
#endif /* CONFIG_PROC_FS */
	struct   list_head bond_list;
	u32      rr_tx_counter;
	u32 __percpu *rr_tx_counter;
	struct   ad_bond_info ad_info;
	struct   alb_bond_info alb_info;
	struct   bond_params params;