mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
bonding: convert unbalanced_load to per-cpu state
A later patch widens the bonding TLB tx counters from u32 to u64. The unbalanced_load counter sits in the transmit hot path, and cross-CPU synchronization of a u64 would introduce measurable overhead. Convert unbalanced_load to a per-cpu counter first so that the subsequent widening only touches per-cpu data local to each CPU. Introduce struct unbalanced_load_stats to hold the per-cpu counter, and move the aggregation into a helper, reset_unbalanced_load(), which sums all per-cpu instances. Use the delta of current total load vs variable prev_total_unbalanced to calculate the loading. Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org> Signed-off-by: Hangbin Liu <liuhangbin@kylinos.cn> Acked-by: Jay Vosburgh <jv@jvosburgh.net> Link: https://patch.msgid.link/20260831-bond_overflow-v6-1-ffb0ed1f7268@kylinos.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
d0ec95a8a4
commit
e147615635
|
|
@ -133,6 +133,10 @@ static int tlb_initialize(struct bonding *bond)
|
|||
if (!new_hashtbl)
|
||||
return -ENOMEM;
|
||||
|
||||
bond_info->unbalanced_load = alloc_percpu(struct unbalanced_load_stats);
|
||||
if (!bond_info->unbalanced_load)
|
||||
goto out;
|
||||
|
||||
spin_lock_bh(&bond->mode_lock);
|
||||
|
||||
bond_info->tx_hashtbl = new_hashtbl;
|
||||
|
|
@ -143,6 +147,10 @@ static int tlb_initialize(struct bonding *bond)
|
|||
spin_unlock_bh(&bond->mode_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
kfree(new_hashtbl);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Must be called only after all slaves have been released */
|
||||
|
|
@ -154,6 +162,8 @@ static void tlb_deinitialize(struct bonding *bond)
|
|||
|
||||
kfree(bond_info->tx_hashtbl);
|
||||
bond_info->tx_hashtbl = NULL;
|
||||
free_percpu(bond_info->unbalanced_load);
|
||||
bond_info->prev_total_unbalanced = 0;
|
||||
|
||||
spin_unlock_bh(&bond->mode_lock);
|
||||
}
|
||||
|
|
@ -1345,7 +1355,7 @@ static netdev_tx_t bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond,
|
|||
/* unbalanced or unassigned, send through primary */
|
||||
tx_slave = rcu_dereference(bond->curr_active_slave);
|
||||
if (bond->params.tlb_dynamic_lb)
|
||||
bond_info->unbalanced_load += skb->len;
|
||||
this_cpu_add(bond_info->unbalanced_load->tx_bytes, skb->len);
|
||||
}
|
||||
|
||||
if (tx_slave && bond_slave_can_tx(tx_slave)) {
|
||||
|
|
@ -1529,6 +1539,23 @@ netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
|
|||
return bond_do_alb_xmit(skb, bond, tx_slave);
|
||||
}
|
||||
|
||||
static u32 reset_unbalanced_load(struct alb_bond_info *bond_info)
|
||||
{
|
||||
struct unbalanced_load_stats *p;
|
||||
u32 delta, total_bytes = 0;
|
||||
int i;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
p = per_cpu_ptr(bond_info->unbalanced_load, i);
|
||||
total_bytes += READ_ONCE(p->tx_bytes);
|
||||
}
|
||||
|
||||
delta = total_bytes - bond_info->prev_total_unbalanced;
|
||||
bond_info->prev_total_unbalanced = total_bytes;
|
||||
|
||||
return delta / BOND_TLB_REBALANCE_INTERVAL;
|
||||
}
|
||||
|
||||
void bond_alb_monitor(struct work_struct *work)
|
||||
{
|
||||
struct bonding *bond = container_of(work, struct bonding,
|
||||
|
|
@ -1570,12 +1597,8 @@ void bond_alb_monitor(struct work_struct *work)
|
|||
if (atomic_read(&bond_info->tx_rebalance_counter) >= BOND_TLB_REBALANCE_TICKS) {
|
||||
bond_for_each_slave_rcu(bond, slave, iter) {
|
||||
tlb_clear_slave(bond, slave, 1);
|
||||
if (slave == rcu_access_pointer(bond->curr_active_slave)) {
|
||||
SLAVE_TLB_INFO(slave).load =
|
||||
bond_info->unbalanced_load /
|
||||
BOND_TLB_REBALANCE_INTERVAL;
|
||||
bond_info->unbalanced_load = 0;
|
||||
}
|
||||
if (slave == rcu_access_pointer(bond->curr_active_slave))
|
||||
SLAVE_TLB_INFO(slave).load = reset_unbalanced_load(bond_info);
|
||||
}
|
||||
atomic_set(&bond_info->tx_rebalance_counter, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,9 +123,14 @@ struct tlb_slave_info {
|
|||
*/
|
||||
};
|
||||
|
||||
struct unbalanced_load_stats {
|
||||
u32 tx_bytes;
|
||||
};
|
||||
|
||||
struct alb_bond_info {
|
||||
struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */
|
||||
u32 unbalanced_load;
|
||||
struct unbalanced_load_stats __percpu *unbalanced_load;
|
||||
u32 prev_total_unbalanced;
|
||||
atomic_t tx_rebalance_counter;
|
||||
int lp_counter;
|
||||
/* -------- rlb parameters -------- */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user