summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorHangbin Liu <liuhangbin@kylinos.cn>2026-08-31 09:51:00 +0800
committerJakub Kicinski <kuba@kernel.org>2026-09-02 18:17:47 -0700
commit4cef95f72bbd0d5edb232143751251717efb5928 (patch)
treee5261b273ebdf3c0b75c4fd78281f1982f55b43e /include
parente14761563588281909beaef0a4b5d1b735c7404c (diff)
bonding: fix u32 overflow in compute_gap()
The TLB load-tracking fields tx_bytes, load_history, load, and unbalanced_load are all u32. At sustained throughput above ~3.2 Gbit/s over the 10-second rebalance interval the byte counters wrap, causing compute_gap() to produce incorrect gap values and mis-select slaves. Such speeds are common on modern NICs under heavy traffic. Widen these fields to u64. Use u64_stats_sync to protect the per-cpu unbalanced_load_stats against tearing on 32-bit architectures, and div_u64() for the 64-bit divisions. The tx_bytes and load_history are protected in spin_lock. Also protect the slave load writing in bond_alb_monitor() with spin_lock in case of tear on 32-bit. For compute_gap(), we still use s64 arithmetic throughout, so we can preserve the existing calculation logic. This order of magnitude is sufficiently large, there is no need to worry about overflow for now. Detected by AI code review. Cc: stable+noautosel@kernel.org # never worked 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-2-ffb0ed1f7268@kylinos.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include')
-rw-r--r--include/net/bond_alb.h11
1 files changed, 6 insertions, 5 deletions
diff --git a/include/net/bond_alb.h b/include/net/bond_alb.h
index 6fb09b4fc7e2..32f1981033e4 100644
--- a/include/net/bond_alb.h
+++ b/include/net/bond_alb.h
@@ -57,12 +57,12 @@ struct tlb_client_info {
* packets to a Client that the Hash function
* gave this entry index.
*/
- u32 tx_bytes; /* Each Client accumulates the BytesTx that
+ u64 tx_bytes; /* Each Client accumulates the BytesTx that
* were transmitted to it, and after each
* CallBack the LoadHistory is divided
* by the balance interval
*/
- u32 load_history; /* This field contains the amount of Bytes
+ u64 load_history; /* This field contains the amount of Bytes
* that were transmitted to this client by
* the server on the previous balance
* interval in Bps.
@@ -118,19 +118,20 @@ struct tlb_slave_info {
* are the entries that were assigned to use this
* slave for transmit.
*/
- u32 load; /* Each slave sums the loadHistory of all clients
+ u64 load; /* Each slave sums the loadHistory of all clients
* assigned to it
*/
};
struct unbalanced_load_stats {
- u32 tx_bytes;
+ u64_stats_t tx_bytes;
+ struct u64_stats_sync syncp;
};
struct alb_bond_info {
struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */
struct unbalanced_load_stats __percpu *unbalanced_load;
- u32 prev_total_unbalanced;
+ u64 prev_total_unbalanced;
atomic_t tx_rebalance_counter;
int lp_counter;
/* -------- rlb parameters -------- */