kernel-hacking-2024-linux-s.../kernel/sched
Eric Biggers 42288cb44c wait: add wake_up_pollfree()
Several ->poll() implementations are special in that they use a
waitqueue whose lifetime is the current task, rather than the struct
file as is normally the case.  This is okay for blocking polls, since a
blocking poll occurs within one task; however, non-blocking polls
require another solution.  This solution is for the queue to be cleared
before it is freed, using 'wake_up_poll(wq, EPOLLHUP | POLLFREE);'.

However, that has a bug: wake_up_poll() calls __wake_up() with
nr_exclusive=1.  Therefore, if there are multiple "exclusive" waiters,
and the wakeup function for the first one returns a positive value, only
that one will be called.  That's *not* what's needed for POLLFREE;
POLLFREE is special in that it really needs to wake up everyone.

Considering the three non-blocking poll systems:

- io_uring poll doesn't handle POLLFREE at all, so it is broken anyway.

- aio poll is unaffected, since it doesn't support exclusive waits.
  However, that's fragile, as someone could add this feature later.

- epoll doesn't appear to be broken by this, since its wakeup function
  returns 0 when it sees POLLFREE.  But this is fragile.

Although there is a workaround (see epoll), it's better to define a
function which always sends POLLFREE to all waiters.  Add such a
function.  Also make it verify that the queue really becomes empty after
all waiters have been woken up.

Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20211209010455.42744-2-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
2021-12-09 10:49:56 -08:00
..
autogroup.c sched/fair: Prevent dead task groups from regaining cfs_rq's 2021-11-11 13:09:33 +01:00
autogroup.h
clock.c
completion.c
core.c sched/uclamp: Fix rq->uclamp_max not set on first enqueue 2021-12-04 10:56:18 +01:00
core_sched.c kernel.sys.v5.16 2021-11-10 16:10:47 -08:00
cpuacct.c
cpudeadline.c
cpudeadline.h
cpufreq.c
cpufreq_schedutil.c
cpupri.c
cpupri.h
cputime.c sched/cputime: Fix getrusage(RUSAGE_THREAD) with nohz_full 2021-12-02 15:08:22 +01:00
deadline.c sched/dl: Support schedstats for deadline sched class 2021-10-05 15:51:53 +02:00
debug.c sched: Fix DEBUG && !SCHEDSTATS warn 2021-10-06 10:30:57 +02:00
fair.c sched/fair: Prevent dead task groups from regaining cfs_rq's 2021-11-11 13:09:33 +01:00
features.h sched: Disable TTWU_QUEUE on RT 2021-10-05 15:52:12 +02:00
idle.c
isolation.c
loadavg.c
Makefile sched: Disable -Wunused-but-set-variable 2021-10-15 11:25:15 +02:00
membarrier.c
pelt.c
pelt.h
psi.c
rt.c sched/fair: Prevent dead task groups from regaining cfs_rq's 2021-11-11 13:09:33 +01:00
sched-pelt.h
sched.h sched/fair: Prevent dead task groups from regaining cfs_rq's 2021-11-11 13:09:33 +01:00
smp.h
stats.c sched: Introduce task block time in schedstats 2021-10-05 15:51:48 +02:00
stats.h sched: Make schedstats helpers independent of fair sched class 2021-10-05 15:51:47 +02:00
stop_task.c sched: Make struct sched_statistics independent of fair sched class 2021-10-05 15:51:45 +02:00
swait.c
topology.c Merge branch 'akpm' (patches from Andrew) 2021-11-06 14:08:17 -07:00
wait.c wait: add wake_up_pollfree() 2021-12-09 10:49:56 -08:00
wait_bit.c