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.

unix: Improve locking scheme in unix_show_fdinfo()

After switching to TCP_ESTABLISHED or TCP_LISTEN sk_state, alive SOCK_STREAM
and SOCK_SEQPACKET sockets can't change it anymore (since commit 3ff8bff704f4
"unix: Fix race in SOCK_SEQPACKET's unix_dgram_sendmsg()").

Thus, we do not need to take lock here.

Signed-off-by: Kirill Tkhai <tkhai@ya.ru>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Kirill Tkhai and committed by
David S. Miller
b27401a3 40ea3ee2

+10 -10
+10 -10
net/unix/af_unix.c
··· 807 807 static void unix_show_fdinfo(struct seq_file *m, struct socket *sock) 808 808 { 809 809 struct sock *sk = sock->sk; 810 + unsigned char s_state; 810 811 struct unix_sock *u; 811 - int nr_fds; 812 + int nr_fds = 0; 812 813 813 814 if (sk) { 815 + s_state = READ_ONCE(sk->sk_state); 814 816 u = unix_sk(sk); 815 - if (sock->type == SOCK_DGRAM) { 816 - nr_fds = atomic_read(&u->scm_stat.nr_fds); 817 - goto out_print; 818 - } 819 817 820 - unix_state_lock(sk); 821 - if (sk->sk_state != TCP_LISTEN) 818 + /* SOCK_STREAM and SOCK_SEQPACKET sockets never change their 819 + * sk_state after switching to TCP_ESTABLISHED or TCP_LISTEN. 820 + * SOCK_DGRAM is ordinary. So, no lock is needed. 821 + */ 822 + if (sock->type == SOCK_DGRAM || s_state == TCP_ESTABLISHED) 822 823 nr_fds = atomic_read(&u->scm_stat.nr_fds); 823 - else 824 + else if (s_state == TCP_LISTEN) 824 825 nr_fds = unix_count_nr_fds(sk); 825 - unix_state_unlock(sk); 826 - out_print: 826 + 827 827 seq_printf(m, "scm_fds: %u\n", nr_fds); 828 828 } 829 829 }