On 11/11, Peter Zijlstra wrote:
>
> On Wed, Nov 11, 2015 at 05:39:40PM +0800, Boqun Feng wrote:
>
> > Just be curious, should spin_unlock_wait() semantically be an ACQUIRE?
>
> I did wonder the same thing, it would simplify a number of things if
> this were so.

Yes, me too.

Sometimes I even think it should have both ACQUIRE + RELEASE semantics.
IOW, it should be "equivalent" to spin_lock() + spin_unlock().

Consider this code:

        object_t *object;
        spinlock_t lock;

        void update(void)
        {
                object_t *o;

                spin_lock(&lock);
                o = READ_ONCE(object);
                if (o) {
                        BUG_ON(o->dead);
                        do_something(o);
                }
                spin_unlock(&lock);
        }

        void destroy(void) // can be called only once, can't race with itself
        {
                object_t *o;

                o = object;
                object = NULL;

                /*
                 * pairs with lock/ACQUIRE. The next update() must see
                 * object == NULL after spin_lock();
                 */
                smp_mb();

                spin_unlock_wait(&lock);

                /*
                 * pairs with unlock/RELEASE. The previous update() has
                 * already passed BUG_ON(o->dead).
                 *
                 * (Yes, yes, in this particular case it is not needed,
                 *  we can rely on the control dependency).
                 */
                smp_mb();

                o->dead = true;
        }

I believe the code above is correct and it needs the barriers on both sides.

If it is wrong, then task_work_run() is buggy: it relies on mb() implied by
cmpxchg() before spin_unlock_wait() the same way: the next task_work_cancel()
should see the result of our cmpxchg(), it must not try to read work->next or
work->func.

Hmm. Not sure I really understand what I am trying to say... Perhaps in fact
I mean that unlock_wait() should be removed because it is too subtle for me ;)

Oleg.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to