rcutorture and documentation patches for 3.6
Subsystems (2)
cover rcutorture and documentation patches for 3.6
Hello!
This patch series updates documentation and rcutorture:
1. Update documentation to allow for the new call_srcu() and
srcu_barrier() functions.
2. Fix ordering of the torture_ops list.
3. Make rcutorture actually test the new srcu_barrier() function.
4. Fix synchronization of the kthreads testing the various
rcu_barrier() functions.
5. Fix an incorrect (and quite confusing) message in rcutorture.
6. Make rcutorture's fakewriters occasionally invoke the appropriate
rcu_barrier() function so that we test concurrent rcu_barrier() calls.
Thanx, Paul
b/Documentation/RCU/checklist.txt | 39 ++++++++++++++++++------------------- b/Documentation/RCU/rcubarrier.txt | 6 +++-- b/Documentation/RCU/torture.txt | 9 ++++++++ b/Documentation/RCU/whatisRCU.txt | 6 ++--- b/kernel/rcutorture.c | 4 +-- kernel/rcutorture.c | 32 ++++++++++++++++++++++++------ 6 files changed, 64 insertions(+), 32 deletions(-)
PATCH 1/6 rcu: Update documentation to cover call_srcu() and srcu_barrier().
From: "Paul E. McKenney" <[email protected]>
The advent of call_srcu() and srcu_barrier() obsoleted some of the documentation, so this commit brings that up to date.
--- Documentation/RCU/checklist.txt | 39 +++++++++++++++++++------------------ Documentation/RCU/rcubarrier.txt | 6 +++- Documentation/RCU/torture.txt | 9 ++++++++ Documentation/RCU/whatisRCU.txt | 6 ++-- 4 files changed, 36 insertions(+), 24 deletions(-)
Documentation/RCU/checklist.txt +20 -19
@@ -162,9 +162,9 @@ over a rather long period of time, but improvements are always welcome! when publicizing a pointer to a structure that can be traversed by an RCU read-side critical section. -5. If call_rcu(), or a related primitive such as call_rcu_bh() or - call_rcu_sched(), is used, the callback function must be - written to be called from softirq context. In particular, +5. If call_rcu(), or a related primitive such as call_rcu_bh(), + call_rcu_sched(), or call_srcu() is used, the callback function + must be written to be called from softirq context. In particular, it cannot block. 6. Since synchronize_rcu() can block, it cannot be called from
@@ -202,11 +202,12 @@ over a rather long period of time, but improvements are always welcome! updater uses call_rcu_sched() or synchronize_sched(), then the corresponding readers must disable preemption, possibly by calling rcu_read_lock_sched() and rcu_read_unlock_sched(). - If the updater uses synchronize_srcu(), the the corresponding - readers must use srcu_read_lock() and srcu_read_unlock(), - and with the same srcu_struct. The rules for the expedited - primitives are the same as for their non-expedited counterparts. - Mixing things up will result in confusion and broken kernels. + If the updater uses synchronize_srcu() or call_srcu(), + the the corresponding readers must use srcu_read_lock() and + srcu_read_unlock(), and with the same srcu_struct. The rules for + the expedited primitives are the same as for their non-expedited + counterparts. Mixing things up will result in confusion and + broken kernels. One exception to this rule: rcu_read_lock() and rcu_read_unlock() may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh()
@@ -333,14 +334,14 @@ over a rather long period of time, but improvements are always welcome! victim CPU from ever going offline.) 14. SRCU (srcu_read_lock(), srcu_read_unlock(), srcu_dereference(), - synchronize_srcu(), and synchronize_srcu_expedited()) may only - be invoked from process context. Unlike other forms of RCU, it - -is- permissible to block in an SRCU read-side critical section - (demarked by srcu_read_lock() and srcu_read_unlock()), hence the - "SRCU": "sleepable RCU". Please note that if you don't need - to sleep in read-side critical sections, you should be using - RCU rather than SRCU, because RCU is almost always faster and - easier to use than is SRCU. + synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu()) + may only be invoked from process context. Unlike other forms of + RCU, it -is- permissible to block in an SRCU read-side critical + section (demarked by srcu_read_lock() and srcu_read_unlock()), + hence the "SRCU": "sleepable RCU". Please note that if you + don't need to sleep in read-side critical sections, you should be + using RCU rather than SRCU, because RCU is almost always faster + and easier to use than is SRCU. If you need to enter your read-side critical section in a hardirq or exception handler, and then exit that same read-side
@@ -353,8 +354,8 @@ over a rather long period of time, but improvements are always welcome! cleanup_srcu_struct(). These are passed a "struct srcu_struct" that defines the scope of a given SRCU domain. Once initialized, the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock() - synchronize_srcu(), and synchronize_srcu_expedited(). A given - synchronize_srcu() waits only for SRCU read-side critical + synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu(). + A given synchronize_srcu() waits only for SRCU read-side critical sections governed by srcu_read_lock() and srcu_read_unlock() calls that have been passed the same srcu_struct. This property is what makes sleeping read-side critical sections tolerable --
@@ -374,7 +375,7 @@ over a rather long period of time, but improvements are always welcome! requiring SRCU's read-side deadlock immunity or low read-side realtime latency. - Note that, rcu_assign_pointer() relates to SRCU just as they do + Note that, rcu_assign_pointer() relates to SRCU just as it does to other forms of RCU. 15. The whole point of call_rcu(), synchronize_rcu(), and friends
Documentation/RCU/rcubarrier.txt +4 -2
@@ -261,8 +261,10 @@ Answers to Quick Quizzes Quick Quiz #1: Why is there no srcu_barrier()? -Answer: Since there is no call_srcu(), there can be no outstanding SRCU - callbacks. Therefore, there is no need to wait for them. +Answer: There really is an srcu_barrier() now that there is a call_srcu(). + Before call_srcu(), there were no SRCU callbacks, and there was + therefore no need to wait for them, and therefore there was + no srcu_barrier(). Quick Quiz #2: Is there any other situation where rcu_barrier() might be required?
Documentation/RCU/torture.txt +9 -0
@@ -174,11 +174,20 @@ torture_type The type of RCU to test, with string values as follows: and synchronize_rcu_bh_expedited(). "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(). + "srcu_raw": srcu_read_lock_raw(), srcu_read_unlock_raw(), + and call_srcu(). + + "srcu_raw_sync": srcu_read_lock_raw(), srcu_read_unlock_raw(), + and synchronize_srcu(). + "sched": preempt_disable(), preempt_enable(), and call_rcu_sched().
Documentation/RCU/whatisRCU.txt +3 -3
@@ -833,9 +833,9 @@ sched: Critical sections Grace period Barrier SRCU: Critical sections Grace period Barrier - srcu_read_lock synchronize_srcu N/A - srcu_read_unlock synchronize_srcu_expedited - srcu_read_lock_raw + srcu_read_lock synchronize_srcu srcu_barrier + srcu_read_unlock call_srcu + srcu_read_lock_raw synchronize_srcu_expedited srcu_read_unlock_raw srcu_dereference
Signature · 1 line
1.7.8
PATCH 2/6 rcu: Rationalize ordering of torture_ops list
From: "Paul E. McKenney" <[email protected]>
Move the raw SRCU interfaces out of the middle of the normal SRCU interfaces.
--- kernel/rcutorture.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
kernel/rcutorture.c +2 -2
@@ -1908,8 +1908,8 @@ rcu_torture_init(void)static struct rcu_torture_ops *torture_ops[] = { &rcu_ops, &rcu_sync_ops, &rcu_expedited_ops, &rcu_bh_ops, &rcu_bh_sync_ops, &rcu_bh_expedited_ops, - &srcu_ops, &srcu_sync_ops, &srcu_raw_ops, - &srcu_raw_sync_ops, &srcu_expedited_ops, + &srcu_ops, &srcu_sync_ops, &srcu_expedited_ops, + &srcu_raw_ops, &srcu_raw_sync_ops, &sched_ops, &sched_sync_ops, &sched_expedited_ops, };mutex_lock (&fullstop_mutex);
Signature · 1 line
1.7.8
Re: [PATCH tip/core/rcu 2/6] rcu: Rationalize ordering of torture_ops list
Quoted 6 lines · Paul E. McKenney
From: "Paul E. McKenney" <[email protected]>
Move the raw SRCU interfaces out of the middle of the normal SRCU interfaces.
Signed-off-by Paul E. McKenney <[email protected]>
Quoted 22 lines
--- kernel/rcutorture.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)kernel/rcutorture.c +2
-2@@ -1908,8 +1908,8 @@ rcu_torture_init(void)static struct rcu_torture_ops *torture_ops[] = { &rcu_ops, &rcu_sync_ops, &rcu_expedited_ops, &rcu_bh_ops, &rcu_bh_sync_ops, &rcu_bh_expedited_ops, - &srcu_ops, &srcu_sync_ops, &srcu_raw_ops, - &srcu_raw_sync_ops, &srcu_expedited_ops, + &srcu_ops, &srcu_sync_ops, &srcu_expedited_ops, + &srcu_raw_ops, &srcu_raw_sync_ops, &sched_ops, &sched_sync_ops, &sched_expedited_ops, };mutex_lock (&fullstop_mutex);Signature · 1 line
1.7.8
PATCH 3/6 rcu: Test srcu_barrier() from rcutorture test suite
In reply to Paul E. McKenneyFrom: "Paul E. McKenney" <[email protected]>
SRCU now has a call_srcu() and an srcu_barrier(), but rcutorture does not test srcu_barrier(). This commit adds the machinery to allow rcutorture's existing rcu_barrier() tests to apply to SRCU.
--- kernel/rcutorture.c | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-)
kernel/rcutorture.c +13 -2
@@ -635,6 +635,17 @@ static void srcu_torture_synchronize(void)synchronize_srcu (&srcu_ctl); } +static void srcu_torture_call (struct rcu_head *head, +void (*func)(struct rcu_head *head)) +{ +call_srcu (&srcu_ctl, head, func); +} + +static void srcu_torture_barrier (void ) +{ +srcu_barrier (&srcu_ctl); +} +static int srcu_torture_stats (char *page) {int cnt =0 ;
@@ -661,8 +672,8 @@ static struct rcu_torture_ops srcu_ops = { .completed = srcu_torture_completed, .deferred_free = srcu_torture_deferred_free, .sync = srcu_torture_synchronize, - .call = NULL, - .cb_barrier = NULL, + .call = srcu_torture_call, + .cb_barrier = srcu_torture_barrier, .stats = srcu_torture_stats, .name = "srcu" };
Signature · 1 line
1.7.8
Re: [PATCH tip/core/rcu 3/6] rcu: Test srcu_barrier() from rcutorture test suite
Quoted 7 lines · Paul E. McKenney
From: "Paul E. McKenney" <[email protected]>
SRCU now has a
call_srcu()and ansrcu_barrier(), but rcutorture does not testsrcu_barrier(). This commit adds the machinery to allow rcutorture's existingrcu_barrier()tests to apply to SRCU.Signed-off-by Paul E. McKenney <[email protected]>
This commit message suggests that the commit only adds support for testing srcu_barrier, but it adds both call_srcu and srcu_barrier. You might want to wordsmith it a bit:
SRCU now has a call_srcu() and an srcu_barrier(), but rcutorture does not test them. This commit adds the machinery to allow rcutorture's existing tests for call_rcu() and rcu_barrier() to apply to the SRCU equivalents.
With that change:
Quoted 40 lines
--- kernel/rcutorture.c | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-)kernel/rcutorture.c +13
-2@@ -635,6 +635,17 @@ static void srcu_torture_synchronize(void)synchronize_srcu (&srcu_ctl); } +static void srcu_torture_call (struct rcu_head *head, +void (*func)(struct rcu_head *head)) +{ +call_srcu (&srcu_ctl, head, func); +} + +static void srcu_torture_barrier (void ) +{ +srcu_barrier (&srcu_ctl); +} +static int srcu_torture_stats (char *page) {int cnt =0 ;@@ -661,8 +672,8 @@ static struct rcu_torture_ops srcu_ops = { .completed = srcu_torture_completed, .deferred_free = srcu_torture_deferred_free, .sync = srcu_torture_synchronize, - .call = NULL, - .cb_barrier = NULL, + .call = srcu_torture_call, + .cb_barrier = srcu_torture_barrier, .stats = srcu_torture_stats, .name = "srcu" };Signature · 1 line
1.7.8
PATCH 4/6 rcu: Fix bug in rcu_barrier() torture test
In reply to Paul E. McKenneyFrom: "Paul E. McKenney" <[email protected]>
The child threads in the rcu_torture_barrier_cbs() are improperly synchronized, which can cause the rcu_barrier() tests to hang. The failure mode is as follows:
1. CPU 0 running in rcu_torture_barrier() sets barrier_cbs_count
to n_barrier_cbs.
2. CPU 1 running in rcu_torture_barrier_cbs() wakes up, posts
its RCU callback, and atomically decrements barrier_cbs_count. Because barrier_cbs_count is not zero, it does not do the wake_up().
3. CPU 2 running in rcu_torture_barrier_cbs() wakes up, but
finds that barrier_cbs_count is not equal to n_barrier_cbs, and so returns to sleep.
4. The value of barrier_cbs_count therefore never reaches zero,
which causes the test to hang.
This commit therefore uses a phase variable to coordinate the test, preventing this scenario from occurring.
--- kernel/rcutorture.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)
kernel/rcutorture.c +7 -2
@@ -206,6 +206,7 @@ static unsigned long boost_starttime; /* jiffies of next boost test start. */DEFINE_MUTEX (boost_mutex);/* protect setting boost_starttime */ /* and boost task create/destroy. */ static atomic_t barrier_cbs_count;/* Barrier callbacks registered. */ +static bool barrier_phase;/* Test phase. */ static atomic_t barrier_cbs_invoked;/* Barrier callbacks invoked. */ static wait_queue_head_t *barrier_cbs_wq;/* Coordinate barrier testing. */ static DECLARE_WAIT_QUEUE_HEAD (barrier_wq);
@@ -1642,6 +1643,7 @@ void rcu_torture_barrier_cbf(struct rcu_head *rcu)static int rcu_torture_barrier_cbs (void *arg) {long myid = (long )arg; +bool lastphase =0 ;struct rcu_head rcu;init_rcu_head_on_stack (&rcu);
@@ -1649,9 +1651,11 @@ static int rcu_torture_barrier_cbs(void *arg)set_user_nice (current,19 ); do { wait_event(barrier_cbs_wq[myid], - atomic_read(&barrier_cbs_count) == n_barrier_cbs || + barrier_phase != lastphase || kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP); + lastphase = barrier_phase; + smp_mb(); if (kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP) break; cur_ops->call(&rcu, rcu_torture_barrier_cbf);
@@ -1676,7 +1680,8 @@ static int rcu_torture_barrier(void *arg) do { atomic_set(&barrier_cbs_invoked, 0); atomic_set(&barrier_cbs_count, n_barrier_cbs); - /* wake_up() path contains the required barriers. */ + smp_mb(); + barrier_phase = !barrier_phase; for (i = 0; i < n_barrier_cbs; i++) wake_up(&barrier_cbs_wq[i]); wait_event(barrier_wq,
Signature · 1 line
1.7.8
Mathieu Desnoyers
reviewerRe: [PATCH tip/core/rcu 4/6] rcu: Fix bug in rcu_barrier() torture test
* Paul E. McKenney ([email protected]) wrote:
[...]
Quoted 9 lines
kernel/rcutorture.c +1
-0@@ -1642,6 +1643,7 @@ void rcu_torture_barrier_cbf(struct rcu_head *rcu)static int rcu_torture_barrier_cbs (void *arg) {long myid = (long )arg; +bool lastphase =0 ;struct rcu_head rcu;init_rcu_head_on_stack (&rcu);
kernel/rcutorture.c static int rcu_torture_barrier_cbs(void *arg) · line 1658
Quoted 9 lines
kernel/rcutorture.c +3
-1@@ -1649,9 +1651,11 @@ static int rcu_torture_barrier_cbs(void *arg)set_user_nice (current,19 ); do { wait_event(barrier_cbs_wq[myid], - atomic_read(&barrier_cbs_count) == n_barrier_cbs || + barrier_phase != lastphase || kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP); + lastphase = barrier_phase; + smp_mb();
Hi Paul,
Documenting this barrier, and the barrier below, along with the variable accesses they order, would appear to be a good idea, especially since the bug this is correcting was caused by the lack of appropriate smp_mb().
Thanks,
Mathieu
Quoted 16 lines
kernel/rcutorture.c +2
-1if (kthread_should_stop () || fullstop !=FULLSTOP_DONTSTOP )break ; cur_ops->call (&rcu, rcu_torture_barrier_cbf);@@ -1676,7 +1680,8 @@ static int rcu_torture_barrier(void *arg) do { atomic_set(&barrier_cbs_invoked, 0); atomic_set(&barrier_cbs_count, n_barrier_cbs); - /* wake_up() path contains the required barriers. */ + smp_mb(); + barrier_phase = !barrier_phase; for (i = 0; i < n_barrier_cbs; i++) wake_up(&barrier_cbs_wq[i]); wait_event(barrier_wq,Signature · 1 line
1.7.8
Signature · 4 lines
Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com
Re: [PATCH tip/core/rcu 4/6] rcu: Fix bug in rcu_barrier() torture test
Quoted 23 lines · Mathieu Desnoyers
* Paul E. McKenney ([email protected]) wrote:
[...]Quoted 9 lines
kernel/rcutorture.c +1
-0@@ -1642,6 +1643,7 @@ void rcu_torture_barrier_cbf(struct rcu_head *rcu)static int rcu_torture_barrier_cbs (void *arg) {long myid = (long )arg; +bool lastphase =0 ;struct rcu_head rcu;init_rcu_head_on_stack (&rcu);kernel/rcutorture.c static int rcu_torture_barrier_cbs(void *arg) · line 1658
Quoted 9 lines
kernel/rcutorture.c +3
-1@@ -1649,9 +1651,11 @@ static int rcu_torture_barrier_cbs(void *arg)set_user_nice (current,19 ); do { wait_event(barrier_cbs_wq[myid], - atomic_read(&barrier_cbs_count) == n_barrier_cbs || + barrier_phase != lastphase || kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP); + lastphase = barrier_phase; + smp_mb();Hi Paul,
Quoted 4 lines
Documenting this barrier, and the barrier below, along with the variable accesses they order, would appear to be a good idea, especially since the bug this is correcting was caused by the lack of appropriate
smp_mb().
Fair point, even in rcutorture. Or maybe especially in rcutorture...
Will fix!
Thanx, Paul
Quoted 27 lines
Thanks,
Mathieu
Quoted 16 lines
kernel/rcutorture.c +2
-1if (kthread_should_stop () || fullstop !=FULLSTOP_DONTSTOP )break ; cur_ops->call (&rcu, rcu_torture_barrier_cbf);@@ -1676,7 +1680,8 @@ static int rcu_torture_barrier(void *arg) do { atomic_set(&barrier_cbs_invoked, 0); atomic_set(&barrier_cbs_count, n_barrier_cbs); - /* wake_up() path contains the required barriers. */ + smp_mb(); + barrier_phase = !barrier_phase; for (i = 0; i < n_barrier_cbs; i++) wake_up(&barrier_cbs_wq[i]); wait_event(barrier_wq,Signature · 1 line
1.7.8Signature · 4 lines
Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com
PATCH 5/6 rcu: Fix diagnostic-printk typo in rcutorture
In reply to Paul E. McKenneyFrom: "Paul E. McKenney" <[email protected]>
The rcu_torture_barrier() function has a copy-and-paste typo in the string passed to rcutorture_shutdown_absorb(), which this commit fixes.
--- kernel/rcutorture.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
kernel/rcutorture.c +1 -1
@@ -1700,7 +1700,7 @@ static int rcu_torture_barrier(void *arg)schedule_timeout_interruptible (HZ /10 ); }while (!kthread_should_stop () && fullstop ==FULLSTOP_DONTSTOP );VERBOSE_PRINTK_STRING ("rcu_torture_barrier task stopping" ); -rcutorture_shutdown_absorb ("rcu_torture_barrier_cbs" ); +rcutorture_shutdown_absorb ("rcu_torture_barrier" );while (!kthread_should_stop ())schedule_timeout_interruptible (1 );return 0 ;
Signature · 1 line
1.7.8
Re: [PATCH tip/core/rcu 5/6] rcu: Fix diagnostic-printk typo in rcutorture
Quoted 7 lines · Paul E. McKenney
From: "Paul E. McKenney" <[email protected]>
The
rcu_torture_barrier()function has a copy-and-paste typo in the string passed torcutorture_shutdown_absorb(), which this commit fixes.Signed-off-by Paul E. McKenney <[email protected]>Signed-off-by Paul E. McKenney <[email protected]>
Quoted 20 lines
--- kernel/rcutorture.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)kernel/rcutorture.c +1
-1@@ -1700,7 +1700,7 @@ static int rcu_torture_barrier(void *arg)schedule_timeout_interruptible (HZ /10 ); }while (!kthread_should_stop () && fullstop ==FULLSTOP_DONTSTOP );VERBOSE_PRINTK_STRING ("rcu_torture_barrier task stopping" ); -rcutorture_shutdown_absorb ("rcu_torture_barrier_cbs" ); +rcutorture_shutdown_absorb ("rcu_torture_barrier" );while (!kthread_should_stop ())schedule_timeout_interruptible (1 );return 0 ;Signature · 1 line
1.7.8
PATCH 6/6 rcu: Make rcutorture fakewriters invoke rcu_barrier()
In reply to Paul E. McKenneyFrom: "Paul E. McKenney" <[email protected]>
The current rcutorture rcu_barrier() testing never intentionally runs more than one instance of rcu_barrier() at a given time. This fails to test the the shiny new concurrency features of rcu_barrier(). This commit therefore modifies the rcutorture fakewriter kthread to randomly invoke rcu_barrier() rather than the usual synchronize_rcu().
--- kernel/rcutorture.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
kernel/rcutorture.c +5 -1
@@ -1025,7 +1025,11 @@ rcu_torture_fakewriter(void *arg)do {schedule_timeout_uninterruptible (1 +rcu_random (&rand)%10 );udelay (rcu_random (&rand) &0x3ff ); - cur_ops->sync (); +if (cur_ops->cb_barrier !=NULL && +rcu_random (&rand) % (NR_CPUS *8 ) ==0 ) + cur_ops->cb_barrier (); +else + cur_ops->sync ();rcu_stutter_wait ("rcu_torture_fakewriter" ); }while (!kthread_should_stop () && fullstop ==FULLSTOP_DONTSTOP );
Signature · 1 line
1.7.8
Josh Triplett
maintainerRe: [PATCH tip/core/rcu 6/6] rcu: Make rcutorture fakewriters invoke rcu_barrier()
Quoted 19 lines · Paul E. McKenney
From: "Paul E. McKenney" <[email protected]>
The current rcutorture
rcu_barrier()testing never intentionally runs more than one instance ofrcu_barrier()at a given time. This fails to test the the shiny new concurrency features ofrcu_barrier(). This commit therefore modifies the rcutorture fakewriter kthread to randomly invokercu_barrier()rather than the usualsynchronize_rcu().Signed-off-by Paul E. McKenney <[email protected]>Signed-off-by Paul E. McKenney <[email protected]>--- kernel/rcutorture.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)kernel/rcutorture.c +0
-0
kernel/rcutorture.c rcu_torture_fakewriter(void *arg) · line 1029
Quoted 6 lines
kernel/rcutorture.c +2
-1@@ -1025,7 +1025,11 @@ rcu_torture_fakewriter(void *arg) do { schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10); udelay(rcu_random(&rand) & 0x3ff); - cur_ops->sync(); + if (cur_ops->cb_barrier != NULL && + rcu_random(&rand) % (NR_CPUS * 8) == 0)
NR_CPUS seems like an odd choice here. I assume you want to control for having many rcu_torture_fakewriter threads, and aim for the same average rate of barrier calls across the whole set of threads regardless of the number of threads. However, NR_CPUS does not accurately reflect either the number of fakewriter threads (which a user can set arbitrarily) or the number of CPUs currently on the system (since NR_CPUS represents the compile-time limit). I'd suggest changing this to use the actual number of fakewriter threads, which rcutorture knows at start time.
- Josh Triplett
Re: [PATCH tip/core/rcu 6/6] rcu: Make rcutorture fakewriters invoke rcu_barrier()
Quoted 27 lines · Josh Triplett
Quoted 19 lines · Paul E. McKenney
From: "Paul E. McKenney" <[email protected]>
The current rcutorture
rcu_barrier()testing never intentionally runs more than one instance ofrcu_barrier()at a given time. This fails to test the the shiny new concurrency features ofrcu_barrier(). This commit therefore modifies the rcutorture fakewriter kthread to randomly invokercu_barrier()rather than the usualsynchronize_rcu().Signed-off-by Paul E. McKenney <[email protected]>Signed-off-by Paul E. McKenney <[email protected]>--- kernel/rcutorture.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)kernel/rcutorture.c +0
-0kernel/rcutorture.c rcu_torture_fakewriter(void *arg) · line 1029
Quoted 6 lines
kernel/rcutorture.c +2
-1@@ -1025,7 +1025,11 @@ rcu_torture_fakewriter(void *arg) do { schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10); udelay(rcu_random(&rand) & 0x3ff); - cur_ops->sync(); + if (cur_ops->cb_barrier != NULL && + rcu_random(&rand) % (NR_CPUS * 8) == 0)
Quoted 8 lines
NR_CPUSseems like an odd choice here. I assume you want to control for having manyrcu_torture_fakewriterthreads, and aim for the same average rate of barrier calls across the whole set of threads regardless of the number of threads. However,NR_CPUSdoes not accurately reflect either the number of fakewriter threads (which a user can set arbitrarily) or the number of CPUs currently on the system (sinceNR_CPUSrepresents the compile-time limit). I'd suggest changing this to use the actual number of fakewriter threads, which rcutorture knows at start time.
Indeed, this should use the number of online CPUs. Which should be easy to compute, will fix.
Also will fix the commit message as suggested, and apply your reviewed-bys as specified.
Thanx, Paul
Josh Triplett
maintainerRe: [PATCH tip/core/rcu 6/6] rcu: Make rcutorture fakewriters invoke rcu_barrier()
Quoted 37 lines · Paul E. McKenney
Quoted 27 lines · Josh Triplett
Quoted 19 lines · Paul E. McKenney
From: "Paul E. McKenney" <[email protected]>
The current rcutorture
rcu_barrier()testing never intentionally runs more than one instance ofrcu_barrier()at a given time. This fails to test the the shiny new concurrency features ofrcu_barrier(). This commit therefore modifies the rcutorture fakewriter kthread to randomly invokercu_barrier()rather than the usualsynchronize_rcu().Signed-off-by Paul E. McKenney <[email protected]>Signed-off-by Paul E. McKenney <[email protected]>--- kernel/rcutorture.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)kernel/rcutorture.c +0
-0kernel/rcutorture.c rcu_torture_fakewriter(void *arg) · line 1029
Quoted 6 lines
kernel/rcutorture.c +2
-1@@ -1025,7 +1025,11 @@ rcu_torture_fakewriter(void *arg) do { schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10); udelay(rcu_random(&rand) & 0x3ff); - cur_ops->sync(); + if (cur_ops->cb_barrier != NULL && + rcu_random(&rand) % (NR_CPUS * 8) == 0)Quoted 8 lines
NR_CPUSseems like an odd choice here. I assume you want to control for having manyrcu_torture_fakewriterthreads, and aim for the same average rate of barrier calls across the whole set of threads regardless of the number of threads. However,NR_CPUSdoes not accurately reflect either the number of fakewriter threads (which a user can set arbitrarily) or the number of CPUs currently on the system (sinceNR_CPUSrepresents the compile-time limit). I'd suggest changing this to use the actual number of fakewriter threads, which rcutorture knows at start time.
Quoted 2 lines
Indeed, this should use the number of online CPUs. Which should be easy to compute, will fix.
I'd suggest using nfakewriters instead.
- Josh Triplett
Re: [PATCH tip/core/rcu 6/6] rcu: Make rcutorture fakewriters invoke rcu_barrier()
Quoted 38 lines · Josh Triplett
Quoted 37 lines · Paul E. McKenney
Quoted 35 lines · Josh Triplett
Quoted 19 lines · Paul E. McKenney
From: "Paul E. McKenney" <[email protected]>
The current rcutorture
rcu_barrier()testing never intentionally runs more than one instance ofrcu_barrier()at a given time. This fails to test the the shiny new concurrency features ofrcu_barrier(). This commit therefore modifies the rcutorture fakewriter kthread to randomly invokercu_barrier()rather than the usualsynchronize_rcu().Signed-off-by Paul E. McKenney <[email protected]>Signed-off-by Paul E. McKenney <[email protected]>--- kernel/rcutorture.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)kernel/rcutorture.c +0
-0kernel/rcutorture.c rcu_torture_fakewriter(void *arg) · line 1029
Quoted 6 lines
kernel/rcutorture.c +2
-1@@ -1025,7 +1025,11 @@ rcu_torture_fakewriter(void *arg) do { schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10); udelay(rcu_random(&rand) & 0x3ff); - cur_ops->sync(); + if (cur_ops->cb_barrier != NULL && + rcu_random(&rand) % (NR_CPUS * 8) == 0)
NR_CPUSseems like an odd choice here. I assume you want to control for having manyrcu_torture_fakewriterthreads, and aim for the same average rate of barrier calls across the whole set of threads regardless of the number of threads. However,NR_CPUSdoes not accurately reflect either the number of fakewriter threads (which a user can set arbitrarily) or the number of CPUs currently on the system (sinceNR_CPUSrepresents the compile-time limit). I'd suggest changing this to use the actual number of fakewriter threads, which rcutorture knows at start time.
Quoted 4 lines
Quoted 2 lines
Indeed, this should use the number of online CPUs. Which should be easy to compute, will fix.
I'd suggest using nfakewriters instead.
Right... Fixed, thank you!!!
Thanx, Paul
Josh Triplett
maintainerRe: [PATCH tip/core/rcu 1/6] rcu: Update documentation to cover call_srcu() and srcu_barrier().
In reply to Paul E. McKenneyDocumentation/RCU/rcubarrier.txt Answers to Quick Quizzes · line 267
Quoted 12 lines · Paul E. McKenney
Documentation/RCU/rcubarrier.txt +4
-2@@ -261,8 +261,10 @@ Answers to Quick Quizzes Quick Quiz #1: Why is there no srcu_barrier()? -Answer: Since there is no call_srcu(), there can be no outstanding SRCU - callbacks. Therefore, there is no need to wait for them. +Answer: There really is an srcu_barrier() now that there is a call_srcu(). + Before call_srcu(), there were no SRCU callbacks, and there was + therefore no need to wait for them, and therefore there was + no srcu_barrier().
I don't think it makes sense to leave this question in its current form and just change the answer. It seems like a trick question now. :)
I'd suggest just dropping the question and renumbering the remaining questions.
- Josh Triplett
Re: [PATCH tip/core/rcu 1/6] rcu: Update documentation to cover call_srcu() and srcu_barrier().
Quoted 17 lines · Josh Triplett
Documentation/RCU/rcubarrier.txt Answers to Quick Quizzes · line 267
Quoted 12 lines · Paul E. McKenney
Documentation/RCU/rcubarrier.txt +4
-2@@ -261,8 +261,10 @@ Answers to Quick Quizzes Quick Quiz #1: Why is there no srcu_barrier()? -Answer: Since there is no call_srcu(), there can be no outstanding SRCU - callbacks. Therefore, there is no need to wait for them. +Answer: There really is an srcu_barrier() now that there is a call_srcu(). + Before call_srcu(), there were no SRCU callbacks, and there was + therefore no need to wait for them, and therefore there was + no srcu_barrier().I don't think it makes sense to leave this question in its current form and just change the answer. It seems like a trick question now. :)
Quoted 2 lines
I'd suggest just dropping the question and renumbering the remaining questions.
But I -like- trick questions!!! ;-)
I will nevertheless update as suggested.
Thanx, Paul