mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
To: Waiman Long <longman@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,  Will Deacon <will@kernel.org>,
	Boqun Feng <boqun@kernel.org>,
	linux-kernel@vger.kernel.org,
	 "David Hildenbrand (Arm)" <david@kernel.org>
Subject: Re: [PATCH] locking/rwsem: don't let a read lock steal from a queued writer
Date: Sat, 7 Nov 2026 19:28:52 +0000	[thread overview]
Message-ID: <au92oUJyEnth8b9E@gremlin> (raw)
In-Reply-To: <98a82cda-e363-449e-9b2b-8432f8fdcc3a@redhat.com>

On Thu, Nov 05, 2026 at 11:55:37PM -0500, Waiman Long wrote:
>
> On 11/5/26 3:24 PM, Lorenzo Stoakes (ARM) wrote:
> > Since commit 1a728dff855a ("locking/rwsem: Enable reader optimistic lock
> > stealing"), a racing read lock can steal an rwsem from under a queued
> > writer whose handoff timeout hasn't expired yet.
> >
> > This is most problematic when an rwsem read lock is released then
> > reacquired in order to relieve lock contention, as instead it will simply
> > have the lock handed right back to it ahead of the intended beneficiary.
> >
> > Naturally, this behaviour rather defeats the object of doing this kind of
> > thing, so this is less than ideal.
>
> If there is only one reader doing this release and then acquire operation,
> it will leave its task_struct value in the owner field. So we can check if
> the owner field  to determine if we should skip the lock stealing operation.

That seems like it's overfitted the problem though? And would cede to read locks
also, no?

The intent is to prevent starvation of write locks, which seems like a
worthwhile goal not only in the case of dropping an rwsem to relieve contention.

>
> Something like
>
> diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c
> index b9c180ac1eee..1f0fffd75c18 100644
> --- a/kernel/locking/rwsem.c
> +++ b/kernel/locking/rwsem.c
> @@ -1019,15 +1019,17 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem,
> long count, unsigned int stat
>         long adjustment = -RWSEM_READER_BIAS;
>         long rcnt = (count >> RWSEM_READER_SHIFT);
>         struct rwsem_waiter waiter, *first;
> +       long owner = atomic_long_read(&sem->owner);
>         DEFINE_WAKE_Q(wake_q);
>
>         /*
>          * To prevent a constant stream of readers from starving a sleeping
>          * writer, don't attempt optimistic lock stealing if the lock is
> -        * very likely owned by readers.
> +        * very likely owned by readers or when the current task is the
> +        * previous owning reader.
>          */
> -       if ((atomic_long_read(&sem->owner) & RWSEM_READER_OWNED) &&
> -           (rcnt > 1) && !(count & RWSEM_WRITER_LOCKED))
> +       if ((owner & RWSEM_READER_OWNED) && ((rcnt > 1) ||
> +           (current == (struct task_struct *)(owner &
> ~RWSEM_OWNER_FLAGS_MASK))))

Actually the RWSEM_WRITER_LOCKED here is redundant given the block below, I
did think about removing it...

And could probably avoid that open-coded expression with
rwsem_owner_flags() I think?

Anyway, it seems this code would be redundant with CONFIG_DEBUG_RWSEMS or
CONFIG_DETECT_HUNG_TASK_BLOCKER, both of which implement code for
rwsem_clear_reader_owned() which is called when a read lock is dropped.

That would mean any kernel with those set would not get the required
behaviour, which is unexpected behaviour, so I think this is out anyway.

>                 goto queue;
>
>         /*
>
> ------------------------------------------------------------------------------------------------------------------------
>
> Will this help?

I think in general the original patch is more useful in that it expressly
prefers a first-in-the-queue writer to an incoming reader.

>
> Cheers,
> Longman
>

--
Cheers, Lorenzo

      reply	other threads:[~2026-11-07 19:28 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05 20:24 Lorenzo Stoakes (ARM)
2026-11-06  4:55 ` Waiman Long
2026-11-07 19:28   ` Lorenzo Stoakes (ARM) [this message]

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=au92oUJyEnth8b9E@gremlin \
    --to=ljs@kernel.org \
    --cc=boqun@kernel.org \
    --cc=david@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®