diff options
author | Ingo Molnar <mingo@kernel.org> | 2016-09-30 11:54:46 +0300 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-09-30 11:54:46 +0300 |
commit | 0b429e18c284af3e7a39f8ec44d95116c473fef8 (patch) | |
tree | 7957f57dc70c95a32f71896c9a526ca88b5517ad /net/ipv4/route.c | |
parent | d32cdbfb0ba319e44f75437afde868f7cafdc467 (diff) | |
parent | 53061afee43bc5041b67a45b6d793e7afdcf9ca7 (diff) | |
download | linux-0b429e18c284af3e7a39f8ec44d95116c473fef8.tar.xz |
Merge branch 'linus' into locking/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a1f2830d8110..b5b47a26d4ec 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -476,12 +476,18 @@ u32 ip_idents_reserve(u32 hash, int segs) atomic_t *p_id = ip_idents + hash % IP_IDENTS_SZ; u32 old = ACCESS_ONCE(*p_tstamp); u32 now = (u32)jiffies; - u32 delta = 0; + u32 new, delta = 0; if (old != now && cmpxchg(p_tstamp, old, now) == old) delta = prandom_u32_max(now - old); - return atomic_add_return(segs + delta, p_id) - segs; + /* Do not use atomic_add_return() as it makes UBSAN unhappy */ + do { + old = (u32)atomic_read(p_id); + new = old + delta + segs; + } while (atomic_cmpxchg(p_id, old, new) != old); + + return new - segs; } EXPORT_SYMBOL(ip_idents_reserve); |