Commit 48766a58 authored by Tung Nguyen's avatar Tung Nguyen Committed by David S. Miller

tipc: improve function tipc_wait_for_rcvmsg()

This commit replaces schedule_timeout() with wait_woken()
in function tipc_wait_for_rcvmsg(). wait_woken() uses
memory barriers in its implementation to avoid potential
race condition when putting a process into sleeping state
and then waking it up.
Acked-by: default avatarYing Xue <ying.xue@windriver.com>
Acked-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarTung Nguyen <tung.q.nguyen@dektech.com.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 223b7329
...@@ -1677,7 +1677,7 @@ static void tipc_sk_send_ack(struct tipc_sock *tsk) ...@@ -1677,7 +1677,7 @@ static void tipc_sk_send_ack(struct tipc_sock *tsk)
static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
DEFINE_WAIT(wait); DEFINE_WAIT_FUNC(wait, woken_wake_function);
long timeo = *timeop; long timeo = *timeop;
int err = sock_error(sk); int err = sock_error(sk);
...@@ -1685,15 +1685,17 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) ...@@ -1685,15 +1685,17 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
return err; return err;
for (;;) { for (;;) {
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
if (timeo && skb_queue_empty(&sk->sk_receive_queue)) { if (timeo && skb_queue_empty(&sk->sk_receive_queue)) {
if (sk->sk_shutdown & RCV_SHUTDOWN) { if (sk->sk_shutdown & RCV_SHUTDOWN) {
err = -ENOTCONN; err = -ENOTCONN;
break; break;
} }
add_wait_queue(sk_sleep(sk), &wait);
release_sock(sk); release_sock(sk);
timeo = schedule_timeout(timeo); timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
sched_annotate_sleep();
lock_sock(sk); lock_sock(sk);
remove_wait_queue(sk_sleep(sk), &wait);
} }
err = 0; err = 0;
if (!skb_queue_empty(&sk->sk_receive_queue)) if (!skb_queue_empty(&sk->sk_receive_queue))
...@@ -1709,7 +1711,6 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) ...@@ -1709,7 +1711,6 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
if (err) if (err)
break; break;
} }
finish_wait(sk_sleep(sk), &wait);
*timeop = timeo; *timeop = timeo;
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment