Skip to content

Commit 848ca91

Browse files
joamakidavem330
authored andcommitted
net: bonding: Use per-cpu rr_tx_counter
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: Jussi Maki <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b8f6b05 commit 848ca91

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

drivers/net/bonding/bond_main.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4202,16 +4202,16 @@ static u32 bond_rr_gen_slave_id(struct bonding *bond)
42024202
slave_id = prandom_u32();
42034203
break;
42044204
case 1:
4205-
slave_id = bond->rr_tx_counter;
4205+
slave_id = this_cpu_inc_return(*bond->rr_tx_counter);
42064206
break;
42074207
default:
42084208
reciprocal_packets_per_slave =
42094209
bond->params.reciprocal_packets_per_slave;
4210-
slave_id = reciprocal_divide(bond->rr_tx_counter,
4210+
slave_id = this_cpu_inc_return(*bond->rr_tx_counter);
4211+
slave_id = reciprocal_divide(slave_id,
42114212
reciprocal_packets_per_slave);
42124213
break;
42134214
}
4214-
bond->rr_tx_counter++;
42154215

42164216
return slave_id;
42174217
}
@@ -4852,6 +4852,9 @@ static void bond_destructor(struct net_device *bond_dev)
48524852

48534853
if (bond->wq)
48544854
destroy_workqueue(bond->wq);
4855+
4856+
if (bond->rr_tx_counter)
4857+
free_percpu(bond->rr_tx_counter);
48554858
}
48564859

48574860
void bond_setup(struct net_device *bond_dev)
@@ -5350,6 +5353,15 @@ static int bond_init(struct net_device *bond_dev)
53505353
if (!bond->wq)
53515354
return -ENOMEM;
53525355

5356+
if (BOND_MODE(bond) == BOND_MODE_ROUNDROBIN) {
5357+
bond->rr_tx_counter = alloc_percpu(u32);
5358+
if (!bond->rr_tx_counter) {
5359+
destroy_workqueue(bond->wq);
5360+
bond->wq = NULL;
5361+
return -ENOMEM;
5362+
}
5363+
}
5364+
53535365
spin_lock_init(&bond->stats_lock);
53545366
netdev_lockdep_set_classes(bond_dev);
53555367

include/net/bonding.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ struct bonding {
232232
char proc_file_name[IFNAMSIZ];
233233
#endif /* CONFIG_PROC_FS */
234234
struct list_head bond_list;
235-
u32 rr_tx_counter;
235+
u32 __percpu *rr_tx_counter;
236236
struct ad_bond_info ad_info;
237237
struct alb_bond_info alb_info;
238238
struct bond_params params;

0 commit comments

Comments
 (0)