[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20191014062919.rr56mj5uzyb7sj6r@linux-p48b>
Date: Sun, 13 Oct 2019 23:29:19 -0700
From: Davidlohr Bueso <dave@...olabs.net>
To: Manfred Spraul <manfred@...orfullife.com>
Cc: LKML <linux-kernel@...r.kernel.org>,
Waiman Long <longman@...hat.com>, 1vier1@....de,
Andrew Morton <akpm@...ux-foundation.org>,
Peter Zijlstra <peterz@...radead.org>,
Jonathan Corbet <corbet@....net>
Subject: Re: [PATCH 2/5] ipc/mqueue.c: Update/document memory barriers
On Fri, 11 Oct 2019, Manfred Spraul wrote:
>But you are right, there are two different scenarios:
>
>1) thread already in another wake_q, wakeup happens immediately after
>the cmpxchg_relaxed().
>
>This scenario is safe, due to the smp_mb__before_atomic() in wake_q_add()
>
>2) thread woken up but e.g. a timeout, see ->state=STATE_READY,
>returns to user space, calls sys_exit.
>
>This must not happen before get_task_struct acquired a reference.
>
>And this appears to be unsafe: get_task_struct() is refcount_inc(),
>which is refcount_inc_checked(), which is according to lib/refcount.c
>fully unordered.
>
>Thus: ->state=STATE_READY can execute before the refcount increase.
>
>Thus: ->state=STATE_READY needs a smp_store_release(), correct?
What if we did the reference count explicitly, and then just use
wake_q_add_safe()? That would avoid the extra barrier, __pipelined_op()
would become:
list_del();
get_task_struct();
wake_q_add_safe();
WRITE_ONCE(->state, STATE_READY);
Thanks,
Davidlohr
Powered by blists - more mailing lists