Name

sk_has_sleeper — check if there are any waiting processes

Synopsis

int sk_has_sleeper (struct sock * sk);
 

Arguments

sk

socket

Description

Returns true if socket has waiting processes

The purpose of the sk_has_sleeper and sock_poll_wait is to wrap the memory barrier call. They were added due to the race found within the tcp code.

Consider following tcp code paths

CPU1 CPU2

sys_select receive packet ... ... __add_wait_queue update tp->rcv_nxt ... ... tp->rcv_nxt check sock_def_readable ... { schedule ... if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) wake_up_interruptible(sk->sk_sleep) ... }

The race for tcp fires when the __add_wait_queue changes done by CPU1 stay in its cache, and so does the tp->rcv_nxt update on CPU2 side. The CPU1 could then endup calling schedule and sleep forever if there are no more data on the socket.

The sk_has_sleeper is always called right after a call to read_lock, so we can use smp_mb__after_lock barrier.