Waiman Long
e85fab7c4b
locking/rwsem: Prevent decrement of reader count before increment
...
[ Upstream commit a9e9bcb45b1525ba7aea26ed9441e8632aeeda58 ]
During my rwsem testing, it was found that after a down_read(), the
reader count may occasionally become 0 or even negative. Consequently,
a writer may steal the lock at that time and execute with the reader
in parallel thus breaking the mutual exclusion guarantee of the write
lock. In other words, both readers and writer can become rwsem owners
simultaneously.
The current reader wakeup code does it in one pass to clear waiter->task
and put them into wake_q before fully incrementing the reader count.
Once waiter->task is cleared, the corresponding reader may see it,
finish the critical section and do unlock to decrement the count before
the count is incremented. This is not a problem if there is only one
reader to wake up as the count has been pre-incremented by 1. It is
a problem if there are more than one readers to be woken up and writer
can steal the lock.
The wakeup was actually done in 2 passes before the following v4.9 commit:
70800c3c0c ("locking/rwsem: Scan the wait_list for readers only once")
To fix this problem, the wakeup is now done in two passes
again. In the first pass, we collect the readers and count them.
The reader count is then fully incremented. In the second pass, the
waiter->task is then cleared and they are put into wake_q to be woken
up later.
Signed-off-by: Waiman Long <longman@redhat.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: huang ying <huang.ying.caritas@gmail.com>
Fixes: 70800c3c0c ("locking/rwsem: Scan the wait_list for readers only once")
Link: http://lkml.kernel.org/r/20190428212557.13482-2-longman@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2019-05-21 18:48:55 +02:00
..
bpf
bpf: convert htab map to hlist_nulls
2019-05-16 19:43:40 +02:00
configs
config: android: enable CONFIG_SECCOMP
2016-10-11 15:06:32 -07:00
debug
kdb: use memmove instead of overlapping memcpy
2018-12-08 13:05:05 +01:00
events
perf/core: Restore mmap record type correctly
2019-04-20 09:07:46 +02:00
gcov
gcov: support GCC 7.1
2017-09-02 07:07:53 +02:00
irq
genirq: Prevent use-after-free and work list corruption
2019-05-10 17:52:10 +02:00
livepatch
livepatch/module: make TAINT_LIVEPATCH module-specific
2016-08-26 14:42:08 +02:00
locking
locking/rwsem: Prevent decrement of reader count before increment
2019-05-21 18:48:55 +02:00
power
PM / sleep: wakeup: Fix build error caused by missing SRCU support
2018-09-09 20:01:23 +02:00
printk
printk: Fix panic caused by passing log_buf_len to command line
2018-11-13 11:17:01 -08:00
rcu
rcu: Do RCU GP kthread self-wakeup from softirq and interrupt
2019-03-23 13:19:53 +01:00
sched
sched: Add sched_smt_active()
2019-05-14 19:19:36 +02:00
time
timer/debug: Change /proc/timer_stats from 0644 to 0600
2019-05-10 17:52:11 +02:00
trace
trace: Fix preempt_enable_no_resched() abuse
2019-05-02 09:32:00 +02:00
.gitignore
acct.c
kernel/acct.c: fix the acct->needcheck check in check_free_space()
2018-01-10 09:29:51 +01:00
async.c
kernel/async.c: revert "async: simplify lowest_in_progress()"
2018-02-17 13:21:18 +01:00
audit.c
audit: return on memory error to avoid null pointer dereference
2018-05-30 07:50:49 +02:00
audit.h
Merge branch 'stable-4.8' of git://git.infradead.org/users/pcmoore/audit
2016-07-29 17:54:17 -07:00
audit_fsnotify.c
audit_tree.c
audit: cleanup prune_tree_thread
2016-04-04 09:46:47 -04:00
audit_watch.c
audit: fix use-after-free in audit_add_watch
2018-09-26 08:36:37 +02:00
auditfilter.c
audit: allow not equal op for audit by executable
2018-08-03 07:55:25 +02:00
auditsc.c
audit: allow not equal op for audit by executable
2018-08-03 07:55:25 +02:00
backtracetest.c
bounds.c
kbuild: fix kernel/bounds.c 'W=1' warning
2018-11-13 11:16:57 -08:00
capability.c
ptrace: Capture the ptracer's creds not PT_PTRACE_CAP
2017-01-06 10:40:13 +01:00
cgroup.c
cgroup: Fix deadlock in cpu hotplug path
2018-10-13 09:18:56 +02:00
cgroup_freezer.c
cgroup_pids.c
cgroup/pids: remove spurious suspicious RCU usage warning
2017-03-26 13:05:58 +02:00
compat.c
configs.c
context_tracking.c
cpu.c
cpu/speculation: Add 'mitigations=' cmdline option
2019-05-14 19:19:41 +02:00
cpu_pm.c
cpuset.c
sched/cpuset/pm: Fix cpuset vs. suspend-resume bugs
2017-10-12 11:51:25 +02:00
crash_dump.c
cred.c
cred: Reject inodes with invalid ids in set_create_file_as()
2016-06-30 18:05:09 -05:00
delayacct.c
dma.c
elfcore.c
exec_domain.c
exit.c
kernel/exit.c: release ptraced tasks before zap_pid_ns_processes
2019-02-06 17:33:29 +01:00
extable.c
kernel/extable.c: mark core_kernel_text notrace
2017-07-21 07:42:21 +02:00
fork.c
fork: record start_time late
2019-01-13 10:03:51 +01:00
freezer.c
freezer, oom: check TIF_MEMDIE on the correct task
2016-07-28 16:07:41 -07:00
futex.c
futex: Ensure that futex address is aligned in handle_futex_death()
2019-03-27 14:13:03 +09:00
futex_compat.c
groups.c
kernel: make groups_sort calling a responsibility group_info allocators
2018-01-10 09:29:52 +01:00
hung_task.c
kernel: hung_task.c: disable on suspend
2019-04-20 09:07:52 +02:00
irq_work.c
jump_label.c
jump_label: Invoke jump_label_test() via early_initcall()
2017-12-14 09:28:24 +01:00
kallsyms.c
kcmp.c
Kconfig.freezer
Kconfig.hz
Kconfig.locks
Kconfig.preempt
kcov.c
kcov: ensure irq code sees a valid area
2018-08-03 07:55:12 +02:00
kexec.c
kexec: allow architectures to override boot mapping
2016-08-02 19:35:27 -04:00
kexec_core.c
objtool, x86: Add several functions and files to the objtool whitelist
2018-06-05 10:28:57 +02:00
kexec_file.c
kexec: fix double-free when failing to relocate the purgatory
2016-09-01 17:52:01 -07:00
kexec_internal.h
kmod.c
kprobes.c
kprobes: Fix error check when reusing optimized probes
2019-04-27 09:34:45 +02:00
ksysfs.c
kexec: add a kexec_crash_loaded() function
2016-08-02 19:35:30 -04:00
kthread.c
kthread, tracing: Don't expose half-written comm when creating kthreads
2018-08-03 07:55:12 +02:00
latencytop.c
Makefile
kernel/watchdog.c: move hardlockup detector to separate file
2017-06-17 06:41:57 +02:00
membarrier.c
Fix: Disable sys_membarrier when nohz_full is enabled
2017-03-12 06:41:45 +01:00
memremap.c
mm, devm_memremap_pages: kill mapping "System RAM" support
2019-01-13 10:03:51 +01:00
module-internal.h
module.c
module: exclude SHN_UNDEF symbols from kallsyms api
2018-10-03 17:01:48 -07:00
module_signing.c
KEYS: Move the point of trust determination to __key_link()
2016-04-11 22:43:43 +01:00
notifier.c
nsproxy.c
padata.c
padata: free correct variable
2017-05-20 14:28:40 +02:00
panic.c
panic: avoid deadlocks in re-entrant console drivers
2018-12-29 13:40:16 +01:00
params.c
pid.c
pidns: disable pid allocation if pid_ns_prepare_proc() is failed in alloc_pid()
2018-04-13 19:47:53 +02:00
pid_namespace.c
pid_ns: Sleep in TASK_INTERRUPTIBLE in zap_pid_ns_processes
2017-05-25 15:44:38 +02:00
profile.c
profile: Convert to hotplug state machine
2016-07-15 10:41:42 +02:00
ptrace.c
x86/speculation: Apply IBPB more strictly to avoid cross-process data leak
2019-05-14 19:19:34 +02:00
range.c
reboot.c
relay.c
kernel/relay.c: limit kmalloc size to KMALLOC_MAX_SIZE
2018-05-30 07:50:29 +02:00
resource.c
resource: fix integer overflow at reallocation
2018-04-24 09:34:09 +02:00
seccomp.c
seccomp: Move speculation migitation control to arch code
2018-05-22 16:58:02 +02:00
signal.c
signal: Restore the stop PTRACE_EVENT_EXIT
2019-02-20 10:18:33 +01:00
smp.c
cpu/hotplug: Fix SMT supported evaluation
2018-08-15 18:14:53 +02:00
smpboot.c
kthread/smpboot: do not park in kthread_create_on_cpu()
2016-10-11 15:06:33 -07:00
smpboot.h
softirq.c
Mark HI and TASKLET softirq synchronous
2018-08-15 18:14:42 +02:00
stacktrace.c
stacktrace, lockdep: Fix address, newline ugliness
2017-02-14 15:25:42 -08:00
stop_machine.c
stop_machine: Use raw spinlocks
2018-08-03 07:55:24 +02:00
sys.c
sys: don't hold uts_sem while accessing userspace memory
2018-09-09 20:01:24 +02:00
sys_ni.c
x86/pkeys: Fix pkeys build breakage for some non-x86 arches
2016-09-13 14:41:36 +02:00
sysctl.c
kernel/sysctl.c: fix out-of-bounds access when setting file-max
2019-04-27 09:34:47 +02:00
sysctl_binary.c
kernel/sysctl_binary.c: use generic UUID library
2016-05-20 17:58:30 -07:00
task_work.c
task_work: use READ_ONCE/lockless_dereference, avoid pi_lock if !task_works
2016-08-02 19:35:02 -04:00
taskstats.c
taskstats: fix the length of cgroupstats_cmd_get_policy
2016-11-03 16:55:58 -04:00
test_kprobes.c
torture.c
torture: Convert torture_shutdown() to hrtimer
2016-08-22 10:01:49 -07:00
tracepoint.c
tracepoint: Do not warn on ENOMEM
2018-05-09 09:50:20 +02:00
tsacct.c
ucount.c
kernel/ucount.c: mark user_header with kmemleak_ignore()
2017-06-17 06:41:51 +02:00
uid16.c
kernel: make groups_sort calling a responsibility group_info allocators
2018-01-10 09:29:52 +01:00
up.c
smp: Add function to execute a function synchronously on a CPU
2016-09-05 13:52:39 +02:00
user-return-notifier.c
user.c
user_namespace.c
userns: move user access out of the mutex
2018-09-09 20:01:24 +02:00
utsname.c
Merge branch 'nsfs-ioctls' into HEAD
2016-09-22 20:00:36 -05:00
utsname_sysctl.c
sys: don't hold uts_sem while accessing userspace memory
2018-09-09 20:01:24 +02:00
watchdog.c
kernel/watchdog: prevent false hardlockup on overloaded system
2017-06-17 06:41:57 +02:00
watchdog_hld.c
kernel/watchdog: prevent false hardlockup on overloaded system
2017-06-17 06:41:57 +02:00
workqueue.c
workqueue: use put_device() instead of kfree()
2018-05-30 07:50:36 +02:00
workqueue_internal.h
workqueue: Fix NULL pointer dereference
2017-11-15 15:53:17 +01:00