Skip to content

Commit be8c3a9

Browse files
Nils Hoppmannroxanan1996
authored andcommitted
net/smc: Fix pos miscalculation in statistics
BugLink: https://bugs.launchpad.net/bugs/2039575 SMC_STAT_PAYLOAD_SUB(_smc_stats, _tech, key, _len, _rc) will calculate wrong bucket positions for payloads of exactly 4096 bytes and (1 << (m + 12)) bytes, with m == SMC_BUF_MAX - 1. Intended bucket distribution: Assume l == size of payload, m == SMC_BUF_MAX - 1. Bucket 0 : 0 < l <= 2^13 Bucket n, 1 <= n <= m-1 : 2^(n+12) < l <= 2^(n+13) Bucket m : l > 2^(m+12) Current solution: _pos = fls64((l) >> 13) [...] _pos = (_pos < m) ? ((l == 1 << (_pos + 12)) ? _pos - 1 : _pos) : m For l == 4096, _pos == -1, but should be _pos == 0. For l == (1 << (m + 12)), _pos == m, but should be _pos == m - 1. In order to avoid special treatment of these corner cases, the calculation is adjusted. The new solution first subtracts the length by one, and then calculates the correct bucket by shifting accordingly, i.e. _pos = fls64((l - 1) >> 13), l > 0. This not only fixes the issues named above, but also makes the whole bucket assignment easier to follow. Same is done for SMC_STAT_RMB_SIZE_SUB(_smc_stats, _tech, k, _len), where the calculation of the bucket position is similar to the one named above. Fixes: e0e4b8f ("net/smc: Add SMC statistics support") Suggested-by: Halil Pasic <[email protected]> Signed-off-by: Nils Hoppmann <[email protected]> Reviewed-by: Halil Pasic <[email protected]> Reviewed-by: Wenjia Zhang <[email protected]> Reviewed-by: Dust Li <[email protected]> Signed-off-by: David S. Miller <[email protected]> (cherry picked from commit a950a59) Signed-off-by: Frank Heimes <[email protected]> Acked-by: Stefan Bader <[email protected]> Acked-by: Roxana Nicolescu <[email protected]> Signed-off-by: Roxana Nicolescu <[email protected]>
1 parent 69a4d99 commit be8c3a9

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

net/smc/smc_stats.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,14 @@ do { \
9292
typeof(_smc_stats) stats = (_smc_stats); \
9393
typeof(_tech) t = (_tech); \
9494
typeof(_len) l = (_len); \
95-
int _pos = fls64((l) >> 13); \
95+
int _pos; \
9696
typeof(_rc) r = (_rc); \
9797
int m = SMC_BUF_MAX - 1; \
9898
this_cpu_inc((*stats).smc[t].key ## _cnt); \
99-
if (r <= 0) \
99+
if (r <= 0 || l <= 0) \
100100
break; \
101-
_pos = (_pos < m) ? ((l == 1 << (_pos + 12)) ? _pos - 1 : _pos) : m; \
101+
_pos = fls64((l - 1) >> 13); \
102+
_pos = (_pos <= m) ? _pos : m; \
102103
this_cpu_inc((*stats).smc[t].key ## _pd.buf[_pos]); \
103104
this_cpu_add((*stats).smc[t].key ## _bytes, r); \
104105
} \
@@ -138,9 +139,12 @@ while (0)
138139
do { \
139140
typeof(_len) _l = (_len); \
140141
typeof(_tech) t = (_tech); \
141-
int _pos = fls((_l) >> 13); \
142+
int _pos; \
142143
int m = SMC_BUF_MAX - 1; \
143-
_pos = (_pos < m) ? ((_l == 1 << (_pos + 12)) ? _pos - 1 : _pos) : m; \
144+
if (_l <= 0) \
145+
break; \
146+
_pos = fls((_l - 1) >> 13); \
147+
_pos = (_pos <= m) ? _pos : m; \
144148
this_cpu_inc((*(_smc_stats)).smc[t].k ## _rmbsize.buf[_pos]); \
145149
} \
146150
while (0)

0 commit comments

Comments
 (0)