[RFC PATCH 00/12] FUTEX_PING: A stealable futex using Proxy Execution.

Suleiman Souhlal posted 12 patches 1 week ago
include/linux/futex.h            |  22 +
include/linux/futex_types.h      |   1 +
include/linux/sched.h            |  53 ++-
include/uapi/linux/futex.h       |   3 +
init/init_task.c                 |   1 +
kernel/fork.c                    |   3 +-
kernel/futex/Makefile            |   2 +-
kernel/futex/core.c              | 102 ++++-
kernel/futex/futex.h             |  27 +-
kernel/futex/pi.c                | 132 +++---
kernel/futex/ping.c              | 707 +++++++++++++++++++++++++++++++
kernel/futex/syscalls.c          |   6 +
kernel/locking/mutex.c           |   8 +-
kernel/sched/core.c              |  69 ++-
kernel/sched/sched.h             |   2 +-
tools/testing/futex/Makefile     |  13 +
tools/testing/futex/ping_bench.c | 428 +++++++++++++++++++
17 files changed, 1484 insertions(+), 95 deletions(-)
create mode 100644 kernel/futex/ping.c
create mode 100644 tools/testing/futex/Makefile
create mode 100644 tools/testing/futex/ping_bench.c
[RFC PATCH 00/12] FUTEX_PING: A stealable futex using Proxy Execution.
Posted by Suleiman Souhlal 1 week ago
Hello,

This patch series adds a new type of PI futexes, PI Next Generation,
or PING (name coined by Steven Rostedt) (but other name suggestions
are welcome!), that differs from classic PI futexes in that they can
be stolen from the top waiter, and use Proxy Execution instead of
rtmutexes internally. 

The reason to allow the futexes to be stolen is that with classic PI
futex's strict handoff to the top waiter, new contending lockers are
now forced to wait in queue, which means that any locking operation
now becomes a scheduling event. With stealing, a contending locker has
the chance of taking the lock without blocking. The longer wait time
of blocked tasks can be mitigated by forcing the lock to be handed
off to them in a way that can't be stolen, when they've been stolen
from too much, to ensure they don't get starved.

The use of Proxy Execution lets us also get Priority Inheritance for
for fair tasks, which PI futexes don't really allow.


PING futexes are used similarly to FUTEX_*_PI, where the owner is
expected to write its TID in the futex.

The main user-visible difference with regular PI futexes is that the
kernel is allowed to set the FUTEX_WAITERS bit with an empty TID.
This is to allow for a new locker to steal the lock from the top
waiter, which is supposed to improve performance in workloads that
don't need strict RT handling.
The user is also allowed to notice that the futex is unlocked but
has waiters, and steal it without going to the kernel.

An example of how they're meant to be used:
Lock:
        static __thread pid_t tid = gettid();
        uint32_t oldval = 0;
        if (atomic_compare_exchange_strong(ftx, &oldval, tid)
                return;
        oldval = FUTEX_WAITERS;
        // The user could also spin here a bit.
        if (atomic_compare_exchange_strong(ftx, &oldval,
            tid | FUTEX_WAITERS))
                return;
        if (futex(ftx, FUTEX_LOCK_PING, 0, NULL) != 0)
                err(1, "FUTEX_LOCK_PING");

Unlock:
        static __thread pid_t tid = gettid();
        uint32_t oldval = tid;
        if (atomic_compare_exchange_strong(ftx, &oldval, 0))
                return;
        if (futex(ftx, FUTEX_UNLOCK_PING, 0, NULL) != 0)
                err(1, "FUTEX_UNLOCK_PING");


Why did we opt for a new futex type instead of making PI futexes
and rtmutex use Proxy Execution?

PI futexes have strict rtmutex semantics, which while important
for RT workloads, could also potentially result in performance
penalties in workloads where maintaining those semantics isn't
as important. Since we don't want to break existing applications,
creating a new futex type seems appropriate.
Making a new futex type also lets us change the user interface a bit,
to allow for userspace stealing.

We do hope to eventually enable rtmutexes to use Proxy Execution
but the rtmutex wait_lock and pi_lock ordering is backwards for
Proxy Execution, so a potentially complicated rework might be needed
before rtmutexes can use it.
In the meantime, Proxy Execution boosting and rtmutex boosting
can continue to coexist.


Some features of PING futexes:
- Uses Proxy Execution.
- Optimistic spinning (can also be done in userspace, similarly to
  FUTEX_WAIT futexes).
- Allows for userspace stealing.
- Starvation prevention with handoff.


Some performance numbers (lock acquisition time, in nsec, lower is better):
(The numbers were kindly gathered by John on a machine with 11th Gen
Intel(R) Core(TM) i5.)
(How PING performs compared to PI and FUTEX_WAIT seems to vary a lot
based on hardware and ping_bench parameters, and the results look a
bit more impressive on my device :-), but I did not include them since
they are based on an older kernel version.)

With all fair tasks:
"ping_bench -a -w 50000 -s 1000 -t 16"

x FUTEX_PING
+ FUTEX_PI
* glibc pthread_mutex_t (using FUTEX_WAIT)
    N      Mean    Stddev     Min     25p     50p     75p     Max
x 159984  214377.3 859183.23      21   13703   15580   75343 1.15e+07
+ 159984 240690.75 23090.391  234635  237833  239962  241565 1.07e+06
Difference at 95.0% confidence
      26313.4 +/- 4211.65 [22101.8 30525.1]
      12.274363% +/- 1.9646%
      (z 12.2454 p-val 1.77893e-34 crit val 1.95996 se 2148.84)
* 159984 203941.44  14257763      17      20      21      21 1.21e+09
No difference proven at 95.0% confidence
      (z -0.292232 p-val 0.770109 crit val 1.95996 se 35710.9)

With priority inversions with a RT foreground task:
"ping_bench -t 8 -b 16 -r 1 -p -w 10000 -S 500"

x FUTEX_PING
+ FUTEX_PI
* glibc pthread_mutex_t (using FUTEX_WAIT)
    N      Mean    Stddev     Min     25p     50p     75p     Max
x 9999 615.55326 3387.2647      21      50      52      54 8.2e+04
+ 9999 701.18222 3450.3964      21      49      52      53 3.34e+04
No difference proven at 95.0% confidence
      (z 1.77087 p-val 0.0765815 crit val 1.95996 se 48.354)
* 9999 205935.36 2881211.5      24      53      54      55 1.24e+08
Difference at 95.0% confidence
      205320 +/- 56473.6 [148846 261793]
      33355.327862% +/- 9174.44%
      (z 7.1258 p-val 1.03486e-12 crit val 1.95996 se 28813.6)


The patches apply on top of Linus' HEAD.

Any feedback is welcome!


Suleiman Souhlal (12):
  sched: Abstract task_struct->blocked_on by locking primitive.
  futex: Switch PI futex to use p->pi_futex_lock instead of p->pi_lock.
  futex: Add "ping" parameter to pi_state management functions and
    export them.
  futex: Introduce stealable PI futex, FUTEX_*_PING.
  futex: Implement exit_ping_state_list().
  futex: Address aborting from futex_lock_ping() while owning
    ping_state.
  futex: Make FUTEX_*_PING use Proxy Execution.
  futex: Implement PING futex handoff.
  futex: Wake up donor in PING futex unlock.
  futex: Optimistic spinning for PING futexes.
  futex: Allow userspace stealing for PING futexes.
  tools/testing/futex: Add ping_bench, a tool for benchmarking futexes.

 include/linux/futex.h            |  22 +
 include/linux/futex_types.h      |   1 +
 include/linux/sched.h            |  53 ++-
 include/uapi/linux/futex.h       |   3 +
 init/init_task.c                 |   1 +
 kernel/fork.c                    |   3 +-
 kernel/futex/Makefile            |   2 +-
 kernel/futex/core.c              | 102 ++++-
 kernel/futex/futex.h             |  27 +-
 kernel/futex/pi.c                | 132 +++---
 kernel/futex/ping.c              | 707 +++++++++++++++++++++++++++++++
 kernel/futex/syscalls.c          |   6 +
 kernel/locking/mutex.c           |   8 +-
 kernel/sched/core.c              |  69 ++-
 kernel/sched/sched.h             |   2 +-
 tools/testing/futex/Makefile     |  13 +
 tools/testing/futex/ping_bench.c | 428 +++++++++++++++++++
 17 files changed, 1484 insertions(+), 95 deletions(-)
 create mode 100644 kernel/futex/ping.c
 create mode 100644 tools/testing/futex/Makefile
 create mode 100644 tools/testing/futex/ping_bench.c

-- 
2.55.0.1082.g2b9226bbc0-goog
Re: [RFC PATCH 00/12] FUTEX_PING: A stealable futex using Proxy Execution.
Posted by Peter Zijlstra 1 week ago
On Thu, Sep 17, 2026 at 04:33:24AM +0000, Suleiman Souhlal wrote:
> Hello,
> 
> This patch series adds a new type of PI futexes, PI Next Generation,
> or PING (name coined by Steven Rostedt) (but other name suggestions
> are welcome!), that differs from classic PI futexes in that they can
> be stolen from the top waiter, and use Proxy Execution instead of
> rtmutexes internally. 
> 
> The reason to allow the futexes to be stolen is that with classic PI
> futex's strict handoff to the top waiter, new contending lockers are
> now forced to wait in queue, which means that any locking operation
> now becomes a scheduling event. With stealing, a contending locker has
> the chance of taking the lock without blocking. The longer wait time
> of blocked tasks can be mitigated by forcing the lock to be handed
> off to them in a way that can't be stolen, when they've been stolen
> from too much, to ensure they don't get starved.
> 
> The use of Proxy Execution lets us also get Priority Inheritance for
> for fair tasks, which PI futexes don't really allow.

https://patch.msgid.link/1490204338-1856-1-git-send-email-longman%40redhat.com

Also, the goal is to eventually delete rt_mutex and have it be the
normal mutex, in which case the existing FUTEX_*_PI things will
automagically work.

So I'm thinking all of this is way premature.
Re: [RFC PATCH 00/12] FUTEX_PING: A stealable futex using Proxy Execution.
Posted by Suleiman Souhlal 6 days, 20 hours ago
On Thu, Sep 17, 2026 at 5:58 PM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Thu, Sep 17, 2026 at 04:33:24AM +0000, Suleiman Souhlal wrote:
> > Hello,
> >
> > This patch series adds a new type of PI futexes, PI Next Generation,
> > or PING (name coined by Steven Rostedt) (but other name suggestions
> > are welcome!), that differs from classic PI futexes in that they can
> > be stolen from the top waiter, and use Proxy Execution instead of
> > rtmutexes internally.
> >
> > The reason to allow the futexes to be stolen is that with classic PI
> > futex's strict handoff to the top waiter, new contending lockers are
> > now forced to wait in queue, which means that any locking operation
> > now becomes a scheduling event. With stealing, a contending locker has
> > the chance of taking the lock without blocking. The longer wait time
> > of blocked tasks can be mitigated by forcing the lock to be handed
> > off to them in a way that can't be stolen, when they've been stolen
> > from too much, to ensure they don't get starved.
> >
> > The use of Proxy Execution lets us also get Priority Inheritance for
> > for fair tasks, which PI futexes don't really allow.
>
> https://patch.msgid.link/1490204338-1856-1-git-send-email-longman%40redhat.com

I was not aware of this, thanks!
It actually seems very similar to this patchset (but much better written).
The main functional differences that I can see from a cursory look are
that on unlock it doesn't preserve the waiters bit, while PING does,
and that TP futex also supports userspace rwlocks, unlike PING.
And of course the fact that PING also uses Proxy Execution.
So now I know that I'm not completely crazy for wanting this. :-)

>
> Also, the goal is to eventually delete rt_mutex and have it be the
> normal mutex, in which case the existing FUTEX_*_PI things will
> automagically work.

I considered using a mutex but I was under the impression that some RT
workloads really want strict RT handling such that the highest
priority RT task always has to take the lock before any other
contender, which mutex doesn't currently allow. For these workloads,
the existing rtmutex behavior of handing off the lock to the top
waiter is desirable.

Other workloads still have RT tasks, but are ok with slightly less
strict handling, as long as RT tasks still get serviced reasonably
fast (so they still want priority inheritance, but are ok with the
occasional case where a fair task steals the lock from the RT top
waiter).
I suspect Android is in this later bucket, so for them using a mutex
as it's currently implemented would be ok. But others might not be.
On the other hand, the current rtmutex behavior would not be desirable
for users like Android, due to the performance with fair tasks that
Steven brings up in his reply.

These different needs are why I wanted to add a new futex type.
But maybe the different needs could be selected through a CONFIG
option, but with the same user API (FUTEX_*_PI)?

I also had some other probably not insurmountable minor issues, like
the fact that we probably wouldn't want to get kernel lockdep warnings
for userspace deadlocks.

-- Suleiman
Re: [RFC PATCH 00/12] FUTEX_PING: A stealable futex using Proxy Execution.
Posted by Peter Zijlstra 6 days, 18 hours ago
On Fri, Sep 18, 2026 at 03:07:56PM +0900, Suleiman Souhlal wrote:
> On Thu, Sep 17, 2026 at 5:58 PM Peter Zijlstra <peterz@infradead.org> wrote:
> >
> > On Thu, Sep 17, 2026 at 04:33:24AM +0000, Suleiman Souhlal wrote:
> > > Hello,
> > >
> > > This patch series adds a new type of PI futexes, PI Next Generation,
> > > or PING (name coined by Steven Rostedt) (but other name suggestions
> > > are welcome!), that differs from classic PI futexes in that they can
> > > be stolen from the top waiter, and use Proxy Execution instead of
> > > rtmutexes internally.
> > >
> > > The reason to allow the futexes to be stolen is that with classic PI
> > > futex's strict handoff to the top waiter, new contending lockers are
> > > now forced to wait in queue, which means that any locking operation
> > > now becomes a scheduling event. With stealing, a contending locker has
> > > the chance of taking the lock without blocking. The longer wait time
> > > of blocked tasks can be mitigated by forcing the lock to be handed
> > > off to them in a way that can't be stolen, when they've been stolen
> > > from too much, to ensure they don't get starved.
> > >
> > > The use of Proxy Execution lets us also get Priority Inheritance for
> > > for fair tasks, which PI futexes don't really allow.
> >
> > https://patch.msgid.link/1490204338-1856-1-git-send-email-longman%40redhat.com
> 
> I was not aware of this, thanks!
> It actually seems very similar to this patchset (but much better written).
> The main functional differences that I can see from a cursory look are
> that on unlock it doesn't preserve the waiters bit, while PING does,
> and that TP futex also supports userspace rwlocks, unlike PING.
> And of course the fact that PING also uses Proxy Execution.
> So now I know that I'm not completely crazy for wanting this. :-)

Well, you all seem to be in violent disagreement with yourself. On the
one hand you call your feature Priority Inheritance Next-Gen, while at
the same time you're arguing you do NOT in fact want the strictness of
PI/RT.

You cannot have it both ways.


But yes, FUTEX_LOCK/FUTEX_UNLOCK is desirable for a fair number of
reasons, and Waiman's earlier attempt basically died because neither
Thomas nor me found time to do a proper review :-(

One of the very few things that I remember being annoyed with is that it
did handoff in the futex code, while mutex_unlock() already has this.
But other than it being a annoyance, I never had enough time to dig in
to understand if this was fixable or not.

Anyway, back then the motivation for FUTEX_LOCK was to get optimistic
spinning for 'free' by using mutex, much like how FUTEX_LOCK_PI uses
rt_mutex. These days, you'd get proxy exec as well.

But like I mentioned elsewhere, the whole futex/proxy thing needs a
deadlock detector, something we don't really need for in-kernel code,
since it is a hard requirement for kernel code not to have lock cycles
(barring ww_mutex, which will resolve them etc.). But we cannot trust
userspace to play nice.

Doing it at schedule() time is very much not ideal, this is something
much better done at block time, not least because it is the ideal
context to return -EDEADLK, but also because you but the cost of
verifying it in the right context.
Re: [RFC PATCH 00/12] FUTEX_PING: A stealable futex using Proxy Execution.
Posted by John Stultz 1 week ago
On Thu, Sep 17, 2026 at 1:58 AM Peter Zijlstra <peterz@infradead.org> wrote:
> On Thu, Sep 17, 2026 at 04:33:24AM +0000, Suleiman Souhlal wrote:
> >
> > This patch series adds a new type of PI futexes, PI Next Generation,
> > or PING (name coined by Steven Rostedt) (but other name suggestions
> > are welcome!), that differs from classic PI futexes in that they can
> > be stolen from the top waiter, and use Proxy Execution instead of
> > rtmutexes internally.
> >
> > The reason to allow the futexes to be stolen is that with classic PI
> > futex's strict handoff to the top waiter, new contending lockers are
> > now forced to wait in queue, which means that any locking operation
> > now becomes a scheduling event. With stealing, a contending locker has
> > the chance of taking the lock without blocking. The longer wait time
> > of blocked tasks can be mitigated by forcing the lock to be handed
> > off to them in a way that can't be stolen, when they've been stolen
> > from too much, to ensure they don't get starved.
> >
> > The use of Proxy Execution lets us also get Priority Inheritance for
> > for fair tasks, which PI futexes don't really allow.
>
> https://patch.msgid.link/1490204338-1856-1-git-send-email-longman%40redhat.com

Thanks for that reference! I'm sure we can learn a lot from that series.
(I do like the straightforward FUTEX_LOCK/UNLOCK over the PING name here :)

> Also, the goal is to eventually delete rt_mutex and have it be the
> normal mutex, in which case the existing FUTEX_*_PI things will
> automagically work.

Indeed, moving rt_mutexes to proxy is a goal.  Though the performance
concerns from FUTEX_*_PI have to do with the semantics it (and
rt_mutex) promises: strict RT prio order handoff - esentially FIFO for
SCHED_NORMAL.  Not so much the mechanism it uses for boosting.

That's why it seems a new FUTEX op is needed. Since we 1) need to
communicate the owner to the kernel 2) want different semantics for
lock-handoff and stealing.

Even when we get to moving rt_mutexes to proxy, it seems to me we're
likely going to have to keep the rt_mutex itself (even if the PI
boosting is proxy based) as a distinguisher, since the users likely
desire the strict semantics (or at least we will need to add some
behavior flags to the mutex struct so it can still satisfy those
semantics).

> So I'm thinking all of this is way premature.

So it is just an initial RFC, and we are looking for input.

But there is a strong appetite to solve this, as we're already seeing
vendors doing less ideal things, like passing who the waiter thinks
the owner is (racy) in via unused fields of FUTEX_WAIT, so that
out-of-tree custom scheduler boosting can (temporarily - as again it
can be wrong) try to get that owner to release the lock. The longer we
go without a usable upstream solution, the more entrenched these less
ideal solutions become.

thanks
-john
Re: [RFC PATCH 00/12] FUTEX_PING: A stealable futex using Proxy Execution.
Posted by Peter Zijlstra 6 days, 18 hours ago
On Thu, Sep 17, 2026 at 10:53:47AM -0700, John Stultz wrote:

> > Also, the goal is to eventually delete rt_mutex and have it be the
> > normal mutex, in which case the existing FUTEX_*_PI things will
> > automagically work.
> 
> Indeed, moving rt_mutexes to proxy is a goal.  Though the performance
> concerns from FUTEX_*_PI have to do with the semantics it (and
> rt_mutex) promises: strict RT prio order handoff - esentially FIFO for
> SCHED_NORMAL.  Not so much the mechanism it uses for boosting.

Yeah, mutex will probably need to grow a few feature when doing that.

> That's why it seems a new FUTEX op is needed. Since we 1) need to
> communicate the owner to the kernel 2) want different semantics for
> lock-handoff and stealing.

So I'm not convinced. One could argue the strict requirements are
dependent on the scheduling class, not the lock type. It should be
feasible to make stealing behaviour depend on the lock owner or waiter
class for instance.

> > So I'm thinking all of this is way premature.
> 
> So it is just an initial RFC, and we are looking for input.
> 
> But there is a strong appetite to solve this, as we're already seeing
> vendors doing less ideal things, like passing who the waiter thinks
> the owner is (racy) in via unused fields of FUTEX_WAIT, so that
> out-of-tree custom scheduler boosting can (temporarily - as again it
> can be wrong) try to get that owner to release the lock. The longer we
> go without a usable upstream solution, the more entrenched these less
> ideal solutions become.

So this does sound a little like blackmail. If vendors want this, then
vendors had better help out upstream. If vendors don't give a toss about
upstream, then why should I give a flying fuck about them?

It is then on Google to tell vendors to put up or shut up. Just tell em
their hacks are no longer allowed once we have something upstream. Break
their toys and tell em to kindly go cry in the corner.

So no, we don't rush this.
Re: [RFC PATCH 00/12] FUTEX_PING: A stealable futex using Proxy Execution.
Posted by Steven Rostedt 1 week ago
On Thu, 17 Sep 2026 10:53:47 -0700
John Stultz <jstultz@google.com> wrote:

> Indeed, moving rt_mutexes to proxy is a goal.  Though the performance
> concerns from FUTEX_*_PI have to do with the semantics it (and
> rt_mutex) promises: strict RT prio order handoff - esentially FIFO for
> SCHED_NORMAL.  Not so much the mechanism it uses for boosting.

I started working on this while still at Google on the
ChromeOS/Android-on-chrome team. The biggest issue we found with
FUTEX_PI was that it forced all users of it to be fair. Even
SCHED_OTHER which did not even benefit from the PI code. The result, it
killed performance, and nobody wanted to use it.

What I recommended was to have a new futex to allow SCHED_OTHER tasks
to be unfair (just like rt_mutex is in PREEMPT_RT), and also to allow
more to be done in user space and not require every contention to go
into the kernel.

We had a test (Suleiman, can you share that test) which emulated the
code in Chrome and by switching to FUTEX_PI the performance dropped by
a large percentage (I don't recall the actual numbers but I posted them
internally at Google). By switching SCHED_OTHER to be non fair (that
is, when the lock was released, if the next waiting task was
SCHED_OTHER, and the new SCHED_OTHER task coming in could steal the
lock), and the performance almost went back to what normal FUTEX had (I
was assuming that going into the kernel on all contention was the cause
of not getting closer to normal FUTEX). That alone was a big
improvement over FUTEX_PI.

There was talk about changing FUTEX_PI to allow SCHED_OTHER to be
unfair and to steal, but that would change the semantics of it and
there may be some application that requires FUTEX_PI to be fair for all
tasks, even SCHED_OTHER. This is when we decided that we need a new
FUTEX_PI (new generation, which I coined FUTEX_PING, but kinda of a
joke so feel free to change), so that we could change the semantics
without breaking backward compatibility of applications requiring the
current behavior of FUTEX_PI.

But FUTEX_PI requires all contention to be handled in the kernel, where
as we can get even more performance if we could change it to allow the
SCHED_OTHER case (which can steal the lock) to be handled in user space.

I haven't looked at Suleiman's code yet (I'm currently traveling and
don't have time until after Oct 10th). But I would expect this new
futex to keep RT tasks being fair. Otherwise no RT task will use it.

In summary, the motivation of this patch was that we had a few RT tasks
suffering from priority inversion from hundreds of SCHED_OTHER tasks
over a shared mutex. The problem was, if we switched it to FUTEX_PI,
the few RT tasks would perform correctly, but the slowdown from the
hundreds of SCHED_OTHER tasks made it a show stopper. The goal was to
have a futex that allowed nice PI with RT tasks, but still allowed
SCHED_OTHER being unfair and stealing from each other.

-- Steve
Re: [RFC PATCH 00/12] FUTEX_PING: A stealable futex using Proxy Execution.
Posted by Suleiman Souhlal 6 days, 20 hours ago
On Fri, Sep 18, 2026 at 3:51 AM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Thu, 17 Sep 2026 10:53:47 -0700
> John Stultz <jstultz@google.com> wrote:
>
> > Indeed, moving rt_mutexes to proxy is a goal.  Though the performance
> > concerns from FUTEX_*_PI have to do with the semantics it (and
> > rt_mutex) promises: strict RT prio order handoff - esentially FIFO for
> > SCHED_NORMAL.  Not so much the mechanism it uses for boosting.
>
> I started working on this while still at Google on the
> ChromeOS/Android-on-chrome team. The biggest issue we found with
> FUTEX_PI was that it forced all users of it to be fair. Even
> SCHED_OTHER which did not even benefit from the PI code. The result, it
> killed performance, and nobody wanted to use it.
>
> What I recommended was to have a new futex to allow SCHED_OTHER tasks
> to be unfair (just like rt_mutex is in PREEMPT_RT), and also to allow
> more to be done in user space and not require every contention to go
> into the kernel.
>
> We had a test (Suleiman, can you share that test) which emulated the
> code in Chrome and by switching to FUTEX_PI the performance dropped by
> a large percentage (I don't recall the actual numbers but I posted them
> internally at Google). By switching SCHED_OTHER to be non fair (that
> is, when the lock was released, if the next waiting task was
> SCHED_OTHER, and the new SCHED_OTHER task coming in could steal the
> lock), and the performance almost went back to what normal FUTEX had (I
> was assuming that going into the kernel on all contention was the cause
> of not getting closer to normal FUTEX). That alone was a big
> improvement over FUTEX_PI.

Your test is here: https://rostedt.org/private/lock-test.c
Your PING implementation is here:
https://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git/log/?h=ping/test

>
> There was talk about changing FUTEX_PI to allow SCHED_OTHER to be
> unfair and to steal, but that would change the semantics of it and
> there may be some application that requires FUTEX_PI to be fair for all
> tasks, even SCHED_OTHER. This is when we decided that we need a new
> FUTEX_PI (new generation, which I coined FUTEX_PING, but kinda of a
> joke so feel free to change), so that we could change the semantics
> without breaking backward compatibility of applications requiring the
> current behavior of FUTEX_PI.
>
> But FUTEX_PI requires all contention to be handled in the kernel, where
> as we can get even more performance if we could change it to allow the
> SCHED_OTHER case (which can steal the lock) to be handled in user space.
>
> I haven't looked at Suleiman's code yet (I'm currently traveling and
> don't have time until after Oct 10th). But I would expect this new
> futex to keep RT tasks being fair. Otherwise no RT task will use it.

Currently, my implementation allows a fair task to steal from an RT
blocking task.
However, I think that we could easily change it.

I suspect that for our use case, we are ok with fair tasks
occasionally stealing from RT tasks.

>
> In summary, the motivation of this patch was that we had a few RT tasks
> suffering from priority inversion from hundreds of SCHED_OTHER tasks
> over a shared mutex. The problem was, if we switched it to FUTEX_PI,
> the few RT tasks would perform correctly, but the slowdown from the
> hundreds of SCHED_OTHER tasks made it a show stopper. The goal was to
> have a futex that allowed nice PI with RT tasks, but still allowed
> SCHED_OTHER being unfair and stealing from each other.

I agree with everything you've said, but I should also add that we
would also like PI behavior between fair tasks, not just when RT tasks
are present, because priority inversions can still occur between fair
tasks. For example when using sched group shares.
The existing rtmutex based PI futexes can't address those, as far as I can tell.
This is why I opted for a whole new implementation rather than your
initial prototype that still used rtmutexes.

-- Suleiman