Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1277120

Re: net: Generalise wq_has_sleeper helper

From Peter Zijlstra <peterz@infradead.org>
Newsgroups linux.kernel
Subject Re: net: Generalise wq_has_sleeper helper
Date 2015-11-25 10:20 +0100
Message-ID <qyEp3-4c9-7@gated-at.bofh.it> (permalink)
References <qmJXd-1GX-31@gated-at.bofh.it> <qtAcq-11f-13@gated-at.bofh.it> <qyeNX-3YZ-1@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


On Tue, Nov 24, 2015 at 01:54:23PM +0800, Herbert Xu wrote:
> diff --git a/include/linux/wait.h b/include/linux/wait.h
> index 1e1bf9f..bd1157f 100644
> --- a/include/linux/wait.h
> +++ b/include/linux/wait.h
> @@ -107,6 +107,50 @@ static inline int waitqueue_active(wait_queue_head_t *q)
>  	return !list_empty(&q->task_list);
>  }
>  
> +/**
> + * wq_has_sleeper - check if there are any waiting processes
> + * @wq: wait queue head
> + *
> + * Returns true if wq has waiting processes
> + *
> + * The purpose of the wq_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               rcu_read_lock();
> + *                          wq = rcu_dereference(sk->sk_wq);
> + *                          if (wq && waitqueue_active(&wq->wait))
> + *                              wake_up_interruptible(&wq->wait)
> + *                          ...
> + *                       }
> + *
> + * 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.
> + *

Would be easier to refer to the comment that now adorns
waitqueue_active().

> + */
> +static inline bool wq_has_sleeper(wait_queue_head_t *wq)
> +{
> +	/* We need to be sure we are in sync with the

broken comment style.

> +	 * add_wait_queue modifications to the wait queue.
> +	 *
> +	 * This memory barrier should be paired with one on the
> +	 * waiting side.
> +	 */
> +	smp_mb();
> +	return waitqueue_active(wq);
> +}
> +
>  extern void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
>  extern void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);
>  extern void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

net: Generalise wq_has_sleeper helper Herbert Xu <herbert@gondor.apana.org.au> - 2015-11-24 07:00 +0100
  Re: net: Generalise wq_has_sleeper helper David Miller <davem@davemloft.net> - 2015-11-24 22:40 +0100
    Re: net: Generalise wq_has_sleeper helper Herbert Xu <herbert@gondor.apana.org.au> - 2015-11-25 02:20 +0100
  Re: net: Generalise wq_has_sleeper helper Peter Zijlstra <peterz@infradead.org> - 2015-11-25 10:20 +0100
    Re: net: Generalise wq_has_sleeper helper David Miller <davem@davemloft.net> - 2015-11-25 17:40 +0100
      [PATCH v2] net: Generalise wq_has_sleeper helper Herbert Xu <herbert@gondor.apana.org.au> - 2015-11-26 07:00 +0100

csiph-web