RCU changes for v4.4
Subsystems (12)
Linus,
Please pull the latest core-rcu-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-rcu-for-linus
# HEAD: b33e18f61bd18227a456016a77b1a968f5bc1d65 fs/writeback, rcu: Don't use list_entry_rcu() for pointer offsetting in bdi_split_work_to_wbs()
The main changes in this cycle were:
- Improvements to expedited grace periods. (Paul E. McKenney)
- Performance improvements to and locktorture tests for percpu-rwsem. (Oleg Nesterov, Paul E. McKenney)
- Torture-test changes. (Paul E. McKenney, Davidlohr Bueso)
- Documentation updates. (Paul E. McKenney)
- Miscellaneous fixes. (Paul E. McKenney, Boqun Feng, Oleg Nesterov, Patrick Marlier)
Thanks,
Ingo
------------------>
Boqun Feng (3):
rcu: Use rcu_callback_t in call_rcu*() and friends
rcu: Use call_rcu_func_t to replace explicit type equivalents
rcu: Don't disable preemption for Tiny and Tree RCU readers
Davidlohr Bueso (2):
sched: Export sched_setscheduler_nocheck
locktorture: Support rtmutex torturing
Jason A. Donenfeld (1):
documentation: Correct doc to use rcu_dereference_protected
Oleg Nesterov (9):
rcu: Create rcu_sync infrastructure
rcu_sync: Simplify rcu_sync using new rcu_sync_ops structure
rcu_sync: Add CONFIG_PROVE_RCU checks
rcu_sync: Introduce rcu_sync_dtor()
locking/percpu-rwsem: Make percpu_free_rwsem() after kzalloc() safe locking/percpu-rwsem: Make use of the rcu_sync infrastructure locking/percpu-rwsem: Fix the comments outdated by rcu_sync locking/percpu-rwsem: Clean up the lockdep annotations in percpu_down_read()
rcu_sync: Cleanup the CONFIG_PROVE_RCU checks
Patrick Marlier (1):
rculist: Make list_entry_rcu() use lockless_dereference()
Paul E. McKenney (36):
rcu: Use rsp->expedited_wq instead of sync_rcu_preempt_exp_wq
rcu: Move rcu_report_exp_rnp() to allow consolidation
rcu: Consolidate tree setup for synchronize_rcu_expedited()
rcu: Use single-stage IPI algorithm for RCU expedited grace period
rcu: Move synchronize_sched_expedited() to combining tree
rcu: Rename qs_pending to core_needs_qs
rcu: Invert passed_quiesce and rename to cpu_no_qs
rcu: Make ->cpu_no_qs be a union for aggregate OR
rcu: Eliminate panic when silly boot-time fanout specified
rcu: Add online/offline info to stall warning message
rcu: Move preemption disabling out of __srcu_read_lock()
rcu: Correct comment for values of ->gp_state field
rcu: Add rcu_pointer_handoff()
rcu: Remove deprecated rcu_lockdep_assert()
rculist: Use WRITE_ONCE() when deleting from reader-visible list
documentation: No acquire/release for RCU readers
documentation: Call out slow consoles as cause of stall warnings
documentation: Catch up list of torture_type options
documentation: Add lockless_dereference() locking/percpu-rwsem: Export symbols for locktorture
locktorture: Add torture tests for percpu_rwsem
torture: Consolidate cond_resched_rcu_qs() into stutter_wait()
rcutorture: Fix module unwind when bad torture_type specified
rcutorture: Fix unused-function warning for torturing_tasks()
torture: Forgive non-plural arguments
locktorture: Fix module unwind when bad torture_type specified
rcu: Switch synchronize_sched_expedited() to IPI
rcu: Stop silencing lockdep false positive for expedited grace periods
rcu: Stop excluding CPU hotplug in synchronize_sched_expedited()
cpu: Remove try_get_online_cpus()
rcu: Prepare for consolidating expedited CPU selection
rcu: Consolidate expedited CPU selection
rcu: Add online/offline info to expedited stall warning message
rcu: Add tasks to expedited stall-warning messages
rcu: Enable stall warnings for synchronize_rcu_expedited()
rcu: Better hotplug handling for synchronize_sched_expedited()
Petr Mladek (1):
rcu: Finish folding ->fqs_state into ->gp_state
Tejun Heo (1):
fs/writeback, rcu: Don't use list_entry_rcu() for pointer offsetting in bdi_split_work_to_wbs()
Documentation/RCU/stallwarn.txt | 7 + Documentation/RCU/torture.txt | 39 +- Documentation/RCU/trace.txt | 32 +- Documentation/RCU/whatisRCU.txt | 6 +- Documentation/kernel-parameters.txt | 9 +- Documentation/locking/locktorture.txt | 3 + Documentation/memory-barriers.txt | 12 +- fs/fs-writeback.c | 4 +- include/linux/cpu.h | 2 - include/linux/list.h | 5 +- include/linux/list_bl.h | 5 +- include/linux/list_nulls.h | 3 +- include/linux/percpu-rwsem.h | 3 +- include/linux/rcu_sync.h | 86 ++++ include/linux/rculist.h | 5 +- include/linux/rcupdate.h | 59 +-- include/linux/rcutiny.h | 3 +- include/linux/rcutree.h | 2 +- include/linux/sched.h | 10 +- include/linux/srcu.h | 5 +- kernel/cpu.c | 13 - kernel/exit.c | 2 + kernel/locking/locktorture.c | 164 ++++++- kernel/locking/percpu-rwsem.c | 90 ++-- kernel/rcu/Makefile | 2 +- kernel/rcu/rcutorture.c | 16 +- kernel/rcu/srcu.c | 4 +- kernel/rcu/sync.c | 223 +++++++++ kernel/rcu/tiny.c | 8 +- kernel/rcu/tree.c | 512 ++++++++++++++++----- kernel/rcu/tree.h | 69 ++- kernel/rcu/tree_plugin.h | 437 ++++++++++-------- kernel/rcu/tree_trace.c | 10 +- kernel/rcu/update.c | 2 +- kernel/sched/core.c | 1 + kernel/torture.c | 1 + tools/testing/selftests/rcutorture/bin/kvm.sh | 6 +- .../selftests/rcutorture/configs/lock/CFLIST | 4 +- .../selftests/rcutorture/configs/lock/LOCK05 | 6 + .../selftests/rcutorture/configs/lock/LOCK05.boot | 1 + .../selftests/rcutorture/configs/lock/LOCK06 | 6 + .../selftests/rcutorture/configs/lock/LOCK06.boot | 1 + 42 files changed, 1333 insertions(+), 545 deletions(-) create mode 100644 include/linux/rcu_sync.h create mode 100644 kernel/rcu/sync.c create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK05 create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK05.boot create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK06 create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK06.boot
Documentation/RCU/stallwarn.txt +7 -0
@@ -205,6 +205,13 @@ o For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the behavior, you might need to replace some of the cond_resched() calls with calls to cond_resched_rcu_qs(). +o Booting Linux using a console connection that is too slow to + keep up with the boot-time console-message rate. For example, + a 115Kbaud serial console can be -way- too slow to keep up + with boot-time message rates, and will frequently result in + RCU CPU stall warning messages. Especially if you have added + debug printk()s. + o Anything that prevents RCU's grace-period kthreads from running. This can result in the "All QSes seen" console-log message. This message will include information on when the kthread last
Documentation/RCU/torture.txt +13 -26
@@ -166,40 +166,27 @@ test_no_idle_hz Whether or not to test the ability of RCU to operate in torture_type The type of RCU to test, with string values as follows: - "rcu": rcu_read_lock(), rcu_read_unlock() and call_rcu(). - - "rcu_sync": rcu_read_lock(), rcu_read_unlock(), and - synchronize_rcu(). - - "rcu_expedited": rcu_read_lock(), rcu_read_unlock(), and - synchronize_rcu_expedited(). + "rcu": rcu_read_lock(), rcu_read_unlock() and call_rcu(), + along with expedited, synchronous, and polling + variants. "rcu_bh": rcu_read_lock_bh(), rcu_read_unlock_bh(), and - call_rcu_bh(). - - "rcu_bh_sync": rcu_read_lock_bh(), rcu_read_unlock_bh(), - and synchronize_rcu_bh(). + call_rcu_bh(), along with expedited and synchronous + variants. - "rcu_bh_expedited": rcu_read_lock_bh(), rcu_read_unlock_bh(), - and synchronize_rcu_bh_expedited(). + "rcu_busted": This tests an intentionally incorrect version + of RCU in order to help test rcutorture itself. "srcu": srcu_read_lock(), srcu_read_unlock() and - call_srcu(). - - "srcu_sync": srcu_read_lock(), srcu_read_unlock() and - synchronize_srcu(). - - "srcu_expedited": srcu_read_lock(), srcu_read_unlock() and - synchronize_srcu_expedited(). + call_srcu(), along with expedited and + synchronous variants. "sched": preempt_disable(), preempt_enable(), and - call_rcu_sched(). - - "sched_sync": preempt_disable(), preempt_enable(), and - synchronize_sched(). + call_rcu_sched(), along with expedited, + synchronous, and polling variants. - "sched_expedited": preempt_disable(), preempt_enable(), and - synchronize_sched_expedited(). + "tasks": voluntary context switch and call_rcu_tasks(), + along with expedited and synchronous variants. Defaults to "rcu".
Documentation/RCU/trace.txt +16 -16
@@ -56,14 +56,14 @@ Within each flavor directory (rcu/rcu_bh, rcu/rcu_sched, and possibly The output of "cat rcu/rcu_preempt/rcudata" looks as follows: - 0!c=30455 g=30456 pq=1/0 qp=1 dt=126535/140000000000000/0 df=2002 of=4 ql=0/0 qs=N... b=10 ci=74572 nci=0 co=1131 ca=716 - 1!c=30719 g=30720 pq=1/0 qp=0 dt=132007/140000000000000/0 df=1874 of=10 ql=0/0 qs=N... b=10 ci=123209 nci=0 co=685 ca=982 - 2!c=30150 g=30151 pq=1/1 qp=1 dt=138537/140000000000000/0 df=1707 of=8 ql=0/0 qs=N... b=10 ci=80132 nci=0 co=1328 ca=1458 - 3 c=31249 g=31250 pq=1/1 qp=0 dt=107255/140000000000000/0 df=1749 of=6 ql=0/450 qs=NRW. b=10 ci=151700 nci=0 co=509 ca=622 - 4!c=29502 g=29503 pq=1/0 qp=1 dt=83647/140000000000000/0 df=965 of=5 ql=0/0 qs=N... b=10 ci=65643 nci=0 co=1373 ca=1521 - 5 c=31201 g=31202 pq=1/0 qp=1 dt=70422/0/0 df=535 of=7 ql=0/0 qs=.... b=10 ci=58500 nci=0 co=764 ca=698 - 6!c=30253 g=30254 pq=1/0 qp=1 dt=95363/140000000000000/0 df=780 of=5 ql=0/0 qs=N... b=10 ci=100607 nci=0 co=1414 ca=1353 - 7 c=31178 g=31178 pq=1/0 qp=0 dt=91536/0/0 df=547 of=4 ql=0/0 qs=.... b=10 ci=109819 nci=0 co=1115 ca=969 + 0!c=30455 g=30456 cnq=1/0:1 dt=126535/140000000000000/0 df=2002 of=4 ql=0/0 qs=N... b=10 ci=74572 nci=0 co=1131 ca=716 + 1!c=30719 g=30720 cnq=1/0:0 dt=132007/140000000000000/0 df=1874 of=10 ql=0/0 qs=N... b=10 ci=123209 nci=0 co=685 ca=982 + 2!c=30150 g=30151 cnq=1/1:1 dt=138537/140000000000000/0 df=1707 of=8 ql=0/0 qs=N... b=10 ci=80132 nci=0 co=1328 ca=1458 + 3 c=31249 g=31250 cnq=1/1:0 dt=107255/140000000000000/0 df=1749 of=6 ql=0/450 qs=NRW. b=10 ci=151700 nci=0 co=509 ca=622 + 4!c=29502 g=29503 cnq=1/0:1 dt=83647/140000000000000/0 df=965 of=5 ql=0/0 qs=N... b=10 ci=65643 nci=0 co=1373 ca=1521 + 5 c=31201 g=31202 cnq=1/0:1 dt=70422/0/0 df=535 of=7 ql=0/0 qs=.... b=10 ci=58500 nci=0 co=764 ca=698 + 6!c=30253 g=30254 cnq=1/0:1 dt=95363/140000000000000/0 df=780 of=5 ql=0/0 qs=N... b=10 ci=100607 nci=0 co=1414 ca=1353 + 7 c=31178 g=31178 cnq=1/0:0 dt=91536/0/0 df=547 of=4 ql=0/0 qs=.... b=10 ci=109819 nci=0 co=1115 ca=969 This file has one line per CPU, or eight for this 8-CPU system. The fields are as follows:
@@ -188,14 +188,14 @@ o "ca" is the number of RCU callbacks that have been adopted by this Kernels compiled with CONFIG_RCU_BOOST=y display the following from /debug/rcu/rcu_preempt/rcudata: - 0!c=12865 g=12866 pq=1/0 qp=1 dt=83113/140000000000000/0 df=288 of=11 ql=0/0 qs=N... kt=0/O ktl=944 b=10 ci=60709 nci=0 co=748 ca=871 - 1 c=14407 g=14408 pq=1/0 qp=0 dt=100679/140000000000000/0 df=378 of=7 ql=0/119 qs=NRW. kt=0/W ktl=9b6 b=10 ci=109740 nci=0 co=589 ca=485 - 2 c=14407 g=14408 pq=1/0 qp=0 dt=105486/0/0 df=90 of=9 ql=0/89 qs=NRW. kt=0/W ktl=c0c b=10 ci=83113 nci=0 co=533 ca=490 - 3 c=14407 g=14408 pq=1/0 qp=0 dt=107138/0/0 df=142 of=8 ql=0/188 qs=NRW. kt=0/W ktl=b96 b=10 ci=121114 nci=0 co=426 ca=290 - 4 c=14405 g=14406 pq=1/0 qp=1 dt=50238/0/0 df=706 of=7 ql=0/0 qs=.... kt=0/W ktl=812 b=10 ci=34929 nci=0 co=643 ca=114 - 5!c=14168 g=14169 pq=1/0 qp=0 dt=45465/140000000000000/0 df=161 of=11 ql=0/0 qs=N... kt=0/O ktl=b4d b=10 ci=47712 nci=0 co=677 ca=722 - 6 c=14404 g=14405 pq=1/0 qp=0 dt=59454/0/0 df=94 of=6 ql=0/0 qs=.... kt=0/W ktl=e57 b=10 ci=55597 nci=0 co=701 ca=811 - 7 c=14407 g=14408 pq=1/0 qp=1 dt=68850/0/0 df=31 of=8 ql=0/0 qs=.... kt=0/W ktl=14bd b=10 ci=77475 nci=0 co=508 ca=1042 + 0!c=12865 g=12866 cnq=1/0:1 dt=83113/140000000000000/0 df=288 of=11 ql=0/0 qs=N... kt=0/O ktl=944 b=10 ci=60709 nci=0 co=748 ca=871 + 1 c=14407 g=14408 cnq=1/0:0 dt=100679/140000000000000/0 df=378 of=7 ql=0/119 qs=NRW. kt=0/W ktl=9b6 b=10 ci=109740 nci=0 co=589 ca=485 + 2 c=14407 g=14408 cnq=1/0:0 dt=105486/0/0 df=90 of=9 ql=0/89 qs=NRW. kt=0/W ktl=c0c b=10 ci=83113 nci=0 co=533 ca=490 + 3 c=14407 g=14408 cnq=1/0:0 dt=107138/0/0 df=142 of=8 ql=0/188 qs=NRW. kt=0/W ktl=b96 b=10 ci=121114 nci=0 co=426 ca=290 + 4 c=14405 g=14406 cnq=1/0:1 dt=50238/0/0 df=706 of=7 ql=0/0 qs=.... kt=0/W ktl=812 b=10 ci=34929 nci=0 co=643 ca=114 + 5!c=14168 g=14169 cnq=1/0:0 dt=45465/140000000000000/0 df=161 of=11 ql=0/0 qs=N... kt=0/O ktl=b4d b=10 ci=47712 nci=0 co=677 ca=722 + 6 c=14404 g=14405 cnq=1/0:0 dt=59454/0/0 df=94 of=6 ql=0/0 qs=.... kt=0/W ktl=e57 b=10 ci=55597 nci=0 co=701 ca=811 + 7 c=14407 g=14408 cnq=1/0:1 dt=68850/0/0 df=31 of=8 ql=0/0 qs=.... kt=0/W ktl=14bd b=10 ci=77475 nci=0 co=508 ca=1042 This is similar to the output discussed above, but contains the following additional fields:
Documentation/RCU/whatisRCU.txt +3 -3
@@ -364,7 +364,7 @@ uses of RCU may be found in listRCU.txt, arrayRCU.txt, and NMI-RCU.txt. }; DEFINE_SPINLOCK(foo_mutex); - struct foo *gbl_foo; + struct foo __rcu *gbl_foo; /* * Create a new struct foo that is the same as the one currently
@@ -386,7 +386,7 @@ uses of RCU may be found in listRCU.txt, arrayRCU.txt, and NMI-RCU.txt. new_fp = kmalloc(sizeof(*new_fp), GFP_KERNEL); spin_lock(&foo_mutex); - old_fp = gbl_foo; + old_fp = rcu_dereference_protected(gbl_foo, lockdep_is_held(&foo_mutex)); *new_fp = *old_fp; new_fp->a = new_a; rcu_assign_pointer(gbl_foo, new_fp);
@@ -487,7 +487,7 @@ so the function is not permitted to block. The foo struct needs to new_fp = kmalloc(sizeof(*new_fp), GFP_KERNEL); spin_lock(&foo_mutex); - old_fp = gbl_foo; + old_fp = rcu_dereference_protected(gbl_foo, lockdep_is_held(&foo_mutex)); *new_fp = *old_fp; new_fp->a = new_a; rcu_assign_pointer(gbl_foo, new_fp);
Documentation/kernel-parameters.txt +6 -3
@@ -3074,9 +3074,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. cache-to-cache transfer latencies. rcutree.rcu_fanout_leaf= [KNL] - Increase the number of CPUs assigned to each - leaf rcu_node structure. Useful for very large - systems. + Change the number of CPUs assigned to each + leaf rcu_node structure. Useful for very + large systems, which will choose the value 64, + and for NUMA systems with large remote-access + latencies, which will choose a value aligned + with the appropriate hardware boundaries. rcutree.jiffies_till_sched_qs= [KNL] Set required age in jiffies for a
Documentation/locking/locktorture.txt +3 -0
@@ -52,6 +52,9 @@ torture_type Type of lock to torture. By default, only spinlocks will o "mutex_lock": mutex_lock() and mutex_unlock() pairs. + o "rtmutex_lock": rtmutex_lock() and rtmutex_unlock() + pairs. Kernel must have CONFIG_RT_MUTEX=y. + o "rwsem_lock": read/write down() and up() semaphore pairs. torture_runnable Start locktorture at boot time in the case where the
Documentation/memory-barriers.txt +11 -1
@@ -1710,6 +1710,17 @@ CPU from reordering them. operations" subsection for information on where to use these. + (*) lockless_dereference(); + This can be thought of as a pointer-fetch wrapper around the + smp_read_barrier_depends() data-dependency barrier. + + This is also similar to rcu_dereference(), but in cases where + object lifetime is handled by some mechanism other than RCU, for + example, when the objects removed only when the system goes down. + In addition, lockless_dereference() is used in some data structures + that can be used both with and without RCU. + + (*) dma_wmb(); (*) dma_rmb();
@@ -1789,7 +1800,6 @@ ACQUIRING FUNCTIONS (*) mutexes (*) semaphores (*) R/W semaphores - (*) RCU In all cases there are variants on "ACQUIRE" operations and "RELEASE" operations for each construct. These operations all imply certain barriers:
fs/fs-writeback.c +2 -2
@@ -779,8 +779,8 @@ static void bdi_split_work_to_wbs(struct backing_dev_info *bdi, bool skip_if_busy) {struct bdi_writeback *last_wb =NULL ; -struct bdi_writeback *wb =list_entry_rcu (&bdi->wb_list, - struct bdi_writeback, bdi_node); +struct bdi_writeback *wb =list_entry (&bdi->wb_list, + struct bdi_writeback, bdi_node);might_sleep (); restart:
include/linux/cpu.h +0 -2
@@ -228,7 +228,6 @@ extern struct bus_type cpu_subsys;extern void cpu_hotplug_begin (void );extern void cpu_hotplug_done (void );extern void get_online_cpus (void ); -extern bool try_get_online_cpus (void );extern void put_online_cpus (void );extern void cpu_hotplug_disable (void );extern void cpu_hotplug_enable (void );
@@ -246,7 +245,6 @@ int cpu_down(unsigned int cpu);static inline void cpu_hotplug_begin (void ) {}static inline void cpu_hotplug_done (void ) {}#define get_online_cpus () do { } while (0) -#define try_get_online_cpus () true#define put_online_cpus () do { } while (0)#define cpu_hotplug_disable () do { } while (0)#define cpu_hotplug_enable () do { } while (0)
include/linux/list.h +3 -2
@@ -87,7 +87,7 @@ static inline void list_add_tail(struct list_head *new, struct list_head *head)static inline void __list_del (struct list_head * prev,struct list_head * next) { next->prev = prev; - prev->next = next; +WRITE_ONCE (prev->next, next); }/**
@@ -615,7 +615,8 @@ static inline void __hlist_del(struct hlist_node *n) {struct hlist_node *next = n->next;struct hlist_node **pprev = n->pprev; - *pprev = next; + +WRITE_ONCE (*pprev, next);if (next) next->pprev = pprev; }
include/linux/list_bl.h +3 -2
@@ -93,9 +93,10 @@ static inline void __hlist_bl_del(struct hlist_bl_node *n)LIST_BL_BUG_ON ((unsigned long )n &LIST_BL_LOCKMASK );/* pprev may be `first`, so be careful not to lose the lock bit */ - *pprev = (struct hlist_bl_node *) +WRITE_ONCE (*pprev, + (struct hlist_bl_node *) ((unsigned long )next | - ((unsigned long )*pprev &LIST_BL_LOCKMASK )); + ((unsigned long )*pprev &LIST_BL_LOCKMASK )));if (next) next->pprev = pprev; }
include/linux/list_nulls.h +2 -1
@@ -76,7 +76,8 @@ static inline void __hlist_nulls_del(struct hlist_nulls_node *n) {struct hlist_nulls_node *next = n->next;struct hlist_nulls_node **pprev = n->pprev; - *pprev = next; + +WRITE_ONCE (*pprev, next);if (!is_a_nulls (next)) next->pprev = pprev; }
include/linux/percpu-rwsem.h +2 -1
@@ -5,11 +5,12 @@#include <linux/rwsem.h> #include <linux/percpu.h> #include <linux/wait.h> +#include <linux/rcu_sync.h> #include <linux/lockdep.h> struct percpu_rw_semaphore { +struct rcu_sync rss;unsigned int __percpu *fast_read_ctr; -atomic_t write_ctr;struct rw_semaphore rw_sem;atomic_t slow_read_ctr;wait_queue_head_t write_waitq;
include/linux/rcu_sync.h new file +86 -0
86 lines not on this page · raw message
include/linux/rculist.h +1 -4
@@ -247,10 +247,7 @@ static inline void list_splice_init_rcu(struct list_head *list,* primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock(). */ #define list_entry_rcu (ptr, type, member) \ -({ \ - typeof(*ptr) __rcu *__ptr = (typeof(*ptr) __rcu __force *)ptr; \ - container_of((typeof(ptr))rcu_dereference_raw(__ptr), type, member); \ -}) + container_of(lockless_dereference(ptr), type, member)/** * Where are list_empty_rcu() and list_first_entry_rcu()?
include/linux/rcupdate.h +31 -28
120 lines not on this page · raw message
include/linux/rcutiny.h +2 -1
@@ -83,7 +83,7 @@ static inline void synchronize_sched_expedited(void) }static inline void kfree_call_rcu (struct rcu_head *head, -void (*func)(struct rcu_head *rcu)) +rcu_callback_t func) {call_rcu (head, func); }
@@ -216,6 +216,7 @@ static inline bool rcu_is_watching(void)static inline void rcu_all_qs (void ) { +barrier ();/* Avoid RCU read-side critical sections leaking across. */ }#endif /* __LINUX_RCUTINY_H */
include/linux/rcutree.h +1 -1
@@ -48,7 +48,7 @@ void synchronize_rcu_bh(void);void synchronize_sched_expedited (void );void synchronize_rcu_expedited (void ); -void kfree_call_rcu (struct rcu_head *head,void (*func)(struct rcu_head *rcu)); +void kfree_call_rcu (struct rcu_head *head,rcu_callback_t func);/** * synchronize_rcu_bh_expedited - Brute-force RCU-bh grace period
include/linux/sched.h +6 -4
@@ -1342,10 +1342,12 @@ struct sched_dl_entity {union rcu_special {struct { -bool blocked; -bool need_qs; - } b; -short s; +u8 blocked; +u8 need_qs; +u8 exp_need_qs; +u8 pad;/* Otherwise the compiler can store garbage here. */ + } b;/* Bits. */ +u32 s;/* Set of bits. */ };struct rcu_node ;
include/linux/srcu.h +4 -1
@@ -215,8 +215,11 @@ static inline int srcu_read_lock_held(struct srcu_struct *sp)*/ static inline int srcu_read_lock (struct srcu_struct *sp)__acquires (sp) { -int retval =__srcu_read_lock (sp); +int retval; +preempt_disable (); + retval =__srcu_read_lock (sp); +preempt_enable ();rcu_lock_acquire (&(sp)->dep_map);return retval; }
kernel/cpu.c +0 -13
@@ -102,19 +102,6 @@ void get_online_cpus(void) }EXPORT_SYMBOL_GPL (get_online_cpus); -bool try_get_online_cpus (void ) -{ -if (cpu_hotplug.active_writer == current) -return true; -if (!mutex_trylock (&cpu_hotplug.lock)) -return false; -cpuhp_lock_acquire_tryread (); -atomic_inc (&cpu_hotplug.refcount); -mutex_unlock (&cpu_hotplug.lock); -return true; -} -EXPORT_SYMBOL_GPL (try_get_online_cpus); -void put_online_cpus (void ) {int refcount;
kernel/exit.c +2 -0
@@ -761,7 +761,9 @@ void do_exit(long code)*/ flush_ptrace_hw_breakpoint (tsk); +TASKS_RCU (preempt_disable ());TASKS_RCU (tasks_rcu_i =__srcu_read_lock (&tasks_rcu_exit_srcu)); +TASKS_RCU (preempt_enable ());exit_notify (tsk, group_dead);proc_exit_connector (tsk);#ifdef CONFIG_NUMA
kernel/locking/locktorture.c +159 -5
281 lines not on this page · raw message
kernel/locking/percpu-rwsem.c +35 -55
156 lines not on this page · raw message
kernel/rcu/Makefile +1 -1
@@ -1,4 +1,4 @@ -obj-y += update.o +obj-y += update.o sync.o obj-$(CONFIG_SRCU) += srcu.o obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o obj-$(CONFIG_TREE_RCU) += tree.o
kernel/rcu/rcutorture.c +7 -9
@@ -252,7 +252,7 @@ struct rcu_torture_ops {void (*exp_sync)(void );unsigned long (*get_state)(void );void (*cond_sync)(unsigned long oldstate); -void (*call)(struct rcu_head *head,void (*func)(struct rcu_head *rcu)); +call_rcu_func_t call;void (*cb_barrier)(void );void (*fqs)(void );void (*stats)(void );
@@ -448,7 +448,7 @@ static void synchronize_rcu_busted(void) }static void -call_rcu_busted (struct rcu_head *head,void (*func)(struct rcu_head *rcu)) +call_rcu_busted (struct rcu_head *head,rcu_callback_t func) {/* This is a deliberate bug for testing purposes only! */ func (head);
@@ -523,7 +523,7 @@ static void srcu_torture_synchronize(void) }static void srcu_torture_call (struct rcu_head *head, -void (*func)(struct rcu_head *head)) +rcu_callback_t func) {call_srcu (srcu_ctlp, head, func); }
@@ -695,7 +695,7 @@ static bool __maybe_unused torturing_tasks(void)#define RCUTORTURE_TASKS_OPS -static bool torturing_tasks (void ) +static bool __maybe_unused torturing_tasks (void ) {return false; }
@@ -768,7 +768,6 @@ static int rcu_torture_boost(void *arg) } call_rcu_time = jiffies; } -cond_resched_rcu_qs ();stutter_wait ("rcu_torture_boost" );if (torture_must_stop ()) goto checkwait;
@@ -1208,7 +1207,6 @@ rcu_torture_reader(void *arg)__this_cpu_inc (rcu_torture_batch[completed]);preempt_enable (); cur_ops->readunlock (idx); -cond_resched_rcu_qs ();stutter_wait ("rcu_torture_reader" ); }while (!torture_must_stop ());if (irqreader && cur_ops->irq_capable) {
@@ -1742,15 +1740,15 @@ rcu_torture_init(void)for (i =0 ; i <ARRAY_SIZE (torture_ops); i++)pr_alert (" %s" , torture_ops[i]->name);pr_alert ("\n" ); -torture_init_end (); -return -EINVAL ; + firsterr = -EINVAL ; + goto unwind; }if (cur_ops->fqs ==NULL && fqs_duration !=0 ) {pr_alert ("rcu-torture: ->fqs NULL and non-zero fqs_duration, fqs disabled.\n" ); fqs_duration =0 ; }if (cur_ops->init) - cur_ops->init ();/* no "goto unwind" prior to this point!!! */ + cur_ops->init ();if (nreaders >=0 ) { nrealreaders = nreaders;
kernel/rcu/srcu.c +1 -3
@@ -298,11 +298,9 @@ int __srcu_read_lock(struct srcu_struct *sp)int idx; idx =READ_ONCE (sp->completed) &0x1 ; -preempt_disable ();__this_cpu_inc (sp->per_cpu_ref->c[idx]);smp_mb ();/* B */ /* Avoid leaking the critical section. */ __this_cpu_inc (sp->per_cpu_ref->seq[idx]); -preempt_enable ();return idx; }EXPORT_SYMBOL_GPL (__srcu_read_lock);
@@ -387,7 +385,7 @@ static void srcu_flip(struct srcu_struct *sp)* srcu_struct structure. */ void call_srcu (struct srcu_struct *sp,struct rcu_head *head, -void (*func)(struct rcu_head *head)) +rcu_callback_t func) {unsigned long flags;
kernel/rcu/sync.c new file +223 -0
223 lines not on this page · raw message
kernel/rcu/tiny.c +4 -4
@@ -44,7 +44,7 @@ struct rcu_ctrlblk;static void __rcu_process_callbacks (struct rcu_ctrlblk *rcp);static void rcu_process_callbacks (struct softirq_action *unused);static void __call_rcu (struct rcu_head *head, -void (*func)(struct rcu_head *rcu), +rcu_callback_t func,struct rcu_ctrlblk *rcp);#include "tiny_plugin.h"
@@ -203,7 +203,7 @@ EXPORT_SYMBOL_GPL(synchronize_sched);* Helper function for call_rcu() and call_rcu_bh(). */ static void __call_rcu (struct rcu_head *head, -void (*func)(struct rcu_head *rcu), +rcu_callback_t func,struct rcu_ctrlblk *rcp) {unsigned long flags;
@@ -229,7 +229,7 @@ static void __call_rcu(struct rcu_head *head,* period. But since we have but one CPU, that would be after any * quiescent state. */ -void call_rcu_sched (struct rcu_head *head,void (*func)(struct rcu_head *rcu)) +void call_rcu_sched (struct rcu_head *head,rcu_callback_t func) {__call_rcu (head, func, &rcu_sched_ctrlblk); }
@@ -239,7 +239,7 @@ EXPORT_SYMBOL_GPL(call_rcu_sched);* Post an RCU bottom-half callback to be invoked after any subsequent * quiescent state. */ -void call_rcu_bh (struct rcu_head *head,void (*func)(struct rcu_head *rcu)) +void call_rcu_bh (struct rcu_head *head,rcu_callback_t func) {__call_rcu (head, func, &rcu_bh_ctrlblk); }
kernel/rcu/tree.c +396 -116
814 lines not on this page · raw message
kernel/rcu/tree.h +34 -35
169 lines not on this page · raw message
kernel/rcu/tree_plugin.h +241 -196
562 lines not on this page · raw message
kernel/rcu/tree_trace.c +5 -5
@@ -117,13 +117,13 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)if (!rdp->beenonline)return ; -seq_printf (m,"%3d%cc=%ld g=%ld pq=%d/%d qp=%d" , +seq_printf (m,"%3d%cc=%ld g=%ld cnq=%d/%d:%d" , rdp->cpu,cpu_is_offline (rdp->cpu) ?'!' :' ' ,ulong2long (rdp->completed),ulong2long (rdp->gpnum), - rdp->passed_quiesce, + rdp->cpu_no_qs.b.norm, rdp->rcu_qs_ctr_snap ==per_cpu (rcu_qs_ctr, rdp->cpu), - rdp->qs_pending); + rdp->core_needs_qs); seq_printf(m, " dt=%d/%llx/%d df=%lu", atomic_read(&rdp->dynticks->dynticks), rdp->dynticks->dynticks_nesting,
@@ -268,7 +268,7 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp) gpnum = rsp->gpnum;seq_printf (m,"c=%ld g=%ld s=%d jfq=%ld j=%x " ,ulong2long (rsp->completed),ulong2long (gpnum), - rsp->fqs_state, + rsp->gp_state, (long )(rsp->jiffies_force_qs - jiffies), (int )(jiffies &0xffff )); seq_printf(m, "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld/%ld\n",
@@ -361,7 +361,7 @@ static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp)cpu_is_offline (rdp->cpu) ?'!' :' ' , rdp->n_rcu_pending);seq_printf (m,"qsp=%ld rpq=%ld cbr=%ld cng=%ld " , - rdp->n_rp_qs_pending, + rdp->n_rp_core_needs_qs, rdp->n_rp_report_qs, rdp->n_rp_cb_ready, rdp->n_rp_cpu_needs_gp);
kernel/rcu/update.c +1 -1
@@ -534,7 +534,7 @@ static void rcu_spawn_tasks_kthread(void);* Post an RCU-tasks callback. First call must be from process context * after the scheduler if fully operational. */ -void call_rcu_tasks (struct rcu_head *rhp,void (*func)(struct rcu_head *rhp)) +void call_rcu_tasks (struct rcu_head *rhp,rcu_callback_t func) {unsigned long flags;bool needwake;
kernel/sched/core.c +1 -0
@@ -4029,6 +4029,7 @@ int sched_setscheduler_nocheck(struct task_struct *p, int policy, {return _sched_setscheduler (p, policy, param, false); } +EXPORT_SYMBOL_GPL (sched_setscheduler_nocheck);static int do_sched_setscheduler (pid_t pid,int policy,struct sched_param __user *param)
kernel/torture.c +1 -0
@@ -523,6 +523,7 @@ static int stutter;*/ void stutter_wait (const char *title) { +cond_resched_rcu_qs ();while (READ_ONCE (stutter_pause_test) || (torture_runnable && !READ_ONCE (*torture_runnable))) {if (stutter_pause_test)
tools/testing/selftests/rcutorture/bin/kvm.sh +3 -3
@@ -75,7 +75,7 @@ usage () { while test $# -gt 0 do case "$1" in - --bootargs) + --bootargs|--bootarg) checkarg --bootargs "(list of kernel boot arguments)" "$#" "$2" '.*' '^--' TORTURE_BOOTARGS="$2" shift
@@ -88,7 +88,7 @@ do --buildonly) TORTURE_BUILDONLY=1 ;; - --configs) + --configs|--config) checkarg --configs "(list of config files)" "$#" "$2" '^[^/]*$' '^--' configs="$2" shift
@@ -134,7 +134,7 @@ do --no-initrd) TORTURE_INITRD=""; export TORTURE_INITRD ;; - --qemu-args) + --qemu-args|--qemu-arg) checkarg --qemu-args "-qemu args" $# "$2" '^-' '^error' TORTURE_QEMU_ARG="$2" shift
tools/testing/selftests/rcutorture/configs/lock/CFLIST +3 -1
@@ -1,4 +1,6 @@ LOCK01 LOCK02 LOCK03 -LOCK04 +LOCK04 +LOCK05 +LOCK06
tools/testing/selftests/rcutorture/configs/lock/LOCK05 new file +6 -0
@@ -0,0 +1,6 @@ +CONFIG_SMP=y +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +CONFIG_PREEMPT_NONE=n +CONFIG_PREEMPT_VOLUNTARY=n +CONFIG_PREEMPT=y
tools/testing/selftests/rcutorture/configs/lock/LOCK05.boot new file +1 -0
@@ -0,0 +1 @@ +locktorture.torture_type=rtmutex_lock
tools/testing/selftests/rcutorture/configs/lock/LOCK06 new file +6 -0
@@ -0,0 +1,6 @@ +CONFIG_SMP=y +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +CONFIG_PREEMPT_NONE=n +CONFIG_PREEMPT_VOLUNTARY=n +CONFIG_PREEMPT=y
tools/testing/selftests/rcutorture/configs/lock/LOCK06.boot new file +1 -0
@@ -0,0 +1 @@ +locktorture.torture_type=percpu_rwsem_lock