Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: use try_cmpxchg() in lock_sock_nested()

Add a fast path in lock_sock_nested(), to avoid acquiring
the socket spinlock only to set @owned to one:

spin_lock_bh(&sk->sk_lock.slock);
if (unlikely(sock_owned_by_user_nocheck(sk)))
__lock_sock(sk);
sk->sk_lock.owned = 1;
spin_unlock_bh(&sk->sk_lock.slock);

On x86_64 compiler generates something quite efficient:

00000000000077c0 <lock_sock_nested>:
77c0: f3 0f 1e fa endbr64
77c4: e8 00 00 00 00 call __fentry__
77c9: b9 01 00 00 00 mov $0x1,%ecx
77ce: 31 c0 xor %eax,%eax
77d0: f0 48 0f b1 8f 48 01 00 00 lock cmpxchg %rcx,0x148(%rdi)
77d9: 75 06 jne slow_path
77db: 2e e9 00 00 00 00 cs jmp __x86_return_thunk-0x4
slow_path: ...

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
Link: https://patch.msgid.link/20260226021215.1764237-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
5151ec54 b99ccb37

+20 -2
+7 -2
include/net/sock.h
··· 81 81 * mini-semaphore synchronizes multiple users amongst themselves. 82 82 */ 83 83 typedef struct { 84 - spinlock_t slock; 85 - int owned; 84 + union { 85 + struct slock_owned { 86 + int owned; 87 + spinlock_t slock; 88 + }; 89 + long combined; 90 + }; 86 91 wait_queue_head_t wq; 87 92 /* 88 93 * We express the mutex-alike socket_lock semantics
+13
net/core/sock.c
··· 3780 3780 mutex_acquire(&sk->sk_lock.dep_map, subclass, 0, _RET_IP_); 3781 3781 3782 3782 might_sleep(); 3783 + #ifdef CONFIG_64BIT 3784 + if (sizeof(struct slock_owned) == sizeof(long)) { 3785 + socket_lock_t tmp, old; 3786 + 3787 + tmp.slock = __SPIN_LOCK_UNLOCKED(tmp.slock); 3788 + tmp.owned = 1; 3789 + old.slock = __SPIN_LOCK_UNLOCKED(old.slock); 3790 + old.owned = 0; 3791 + if (likely(try_cmpxchg(&sk->sk_lock.combined, 3792 + &old.combined, tmp.combined))) 3793 + return; 3794 + } 3795 + #endif 3783 3796 spin_lock_bh(&sk->sk_lock.slock); 3784 3797 if (unlikely(sock_owned_by_user_nocheck(sk))) 3785 3798 __lock_sock(sk);