mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: David Laight <David.Laight@ACULAB.COM>
To: 'Jann Horn' <jannh@google.com>, Waiman Long <longman@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>, Will Deacon <will@kernel.org>,
	Jonathan Corbet <corbet@lwn.net>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"linux-doc@vger.kernel.org" <linux-doc@vger.kernel.org>
Subject: RE: [PATCH] locking: Document that mutex_unlock() is non-atomic
Date: Fri, 1 Dec 2023 18:12:19 +0000	[thread overview]
Message-ID: <28b147c3d7354d1a8ff0b903da9b54f4@AcuMS.aculab.com> (raw)
In-Reply-To: <CAG48ez1a=VuEWwPTjcXFAwCyt9bRH-WzAfw0uP-qVu83kdxkZw@mail.gmail.com>

From: Jann Horn
> Sent: 01 December 2023 15:02
> 
> On Fri, Dec 1, 2023 at 1:33 AM Waiman Long <longman@redhat.com> wrote:
> > On 11/30/23 15:48, Jann Horn wrote:
> > > I have seen several cases of attempts to use mutex_unlock() to release an
> > > object such that the object can then be freed by another task.
> > > My understanding is that this is not safe because mutex_unlock(), in the
> > > MUTEX_FLAG_WAITERS && !MUTEX_FLAG_HANDOFF case, accesses the mutex
> > > structure after having marked it as unlocked; so mutex_unlock() requires
> > > its caller to ensure that the mutex stays alive until mutex_unlock()
> > > returns.
> > >
> > > If MUTEX_FLAG_WAITERS is set and there are real waiters, those waiters
> > > have to keep the mutex alive, I think; but we could have a spurious
> > > MUTEX_FLAG_WAITERS left if an interruptible/killable waiter bailed
> > > between the points where __mutex_unlock_slowpath() did the cmpxchg
> > > reading the flags and where it acquired the wait_lock.
> > >
> > > (With spinlocks, that kind of code pattern is allowed and, from what I
> > > remember, used in several places in the kernel.)
> > >
> > > If my understanding of this is correct, we should probably document this -
> > > I think such a semantic difference between mutexes and spinlocks is fairly
> > > unintuitive.
> >
> > Spinlocks are fair. So doing a lock/unlock sequence will make sure that
> > all the previously waiting waiters are done with the lock. Para-virtual
> > spinlocks, however, can be a bit unfair so doing a lock/unlock sequence
> > may not be enough to guarantee there is no waiter. The same is true for
> > mutex. Adding a spin_is_locked() or mutex_is_locked() check can make
> > sure that all the waiters are gone.
> 
> I think this pattern anyway only works when you're only trying to wait
> for the current holder of the lock, not tasks that are queued up on
> the lock as waiters - so a task initially holds a stable reference to
> some object, then acquires the object's lock, then drops the original
> reference, and then later drops the lock.
> You can see an example of such mutex usage (which is explicitly legal
> with userspace POSIX mutexes, but is forbidden with kernel mutexes) at
> the bottom of the POSIX manpage for pthread_mutex_destroy() at
> <https://pubs.opengroup.org/onlinepubs/007904875/functions/pthread_mutex_destroy.html>,
> in the section "Destroying Mutexes".

I don't understand at all what any of this is about.
You cannot de-initialise, free (etc) a mutex (or any other piece of
memory for that matter) if another thread can have a reference to it.
If some other code might be holding the mutex it also might be just
about to acquire it - you always need another lock of some kind to
ensure that doesn't happen.

IIRC pretty much the only time you need to acquire the mutex in the
free path is if locks are chained, eg:
	lock(table)
	entry = find_entry();
	lock(entry)
	unlock(table)
	...
	unlock(entry)

Then the free code has to:
	lock(table)
	remove_from_table(entry)
	lock(entry)
	unlock(entry)
	unlock(table)
	free(entry)

ISTR something about mutex_unlock() not being a full memory barrier.
But that is entirely different to this discussion.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

  parent reply	other threads:[~2023-12-01 18:12 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-30 20:48 Jann Horn
2023-11-30 21:53 ` Waiman Long
2023-11-30 22:24   ` Jann Horn
2023-11-30 23:56     ` Waiman Long
2023-12-01 10:33     ` [PATCH -v2] locking/mutex: " Ingo Molnar
2023-12-02  1:37       ` Bagas Sanjaya
2023-12-01 10:20   ` [PATCH] locking: " Ingo Molnar
2023-12-01  0:33 ` Waiman Long
2023-12-01 15:01   ` Jann Horn
     [not found]     ` <a9e19ad0-9a27-4885-a6ac-bebd3e997b02@redhat.com>
2023-12-01 16:03       ` Jann Horn
2023-12-01 18:12     ` David Laight [this message]
2023-12-01 18:18       ` Jann Horn
     [not found]         ` <1bcee696-d751-413c-a2ec-4a8480bae00b@redhat.com>
     [not found]           ` <780e652ff52044d4a213cacbd9276cf8@AcuMS.aculab.com>
2023-12-01 19:15             ` Waiman Long
2023-12-02 15:51               ` David Laight
2023-12-02 22:39                 ` Waiman Long
2023-12-01  9:10 ` Peter Zijlstra
2023-12-01 15:58   ` Jann Horn
2023-12-01 10:44 ` [tip: locking/core] locking/mutex: " tip-bot2 for Jann Horn
2023-12-01 12:18   ` Peter Zijlstra
2024-01-08  8:45     ` [PATCH] locking/mutex: Clarify that mutex_unlock(), and most other sleeping locks, cannot be used to reference-count objects Ingo Molnar
2024-01-08  9:00       ` [PATCH -v2] locking/mutex: Clarify that mutex_unlock(), and most other sleeping locks, can still use the lock object after it's unlocked Ingo Molnar
2024-01-08 15:28       ` [PATCH] locking/mutex: Clarify that mutex_unlock(), and most other sleeping locks, cannot be used to reference-count objects Jann Horn
2024-01-08  9:01     ` [tip: locking/core] locking/mutex: Clarify that mutex_unlock(), and most other sleeping locks, can still use the lock object after it's unlocked tip-bot2 for Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=28b147c3d7354d1a8ff0b903da9b54f4@AcuMS.aculab.com \
    --to=david.laight@aculab.com \
    --cc=corbet@lwn.net \
    --cc=jannh@google.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®