Skip to content

Commit

Permalink
Merge branches 'fixes.2024.12.14a', 'rcutorture.2024.12.14a', 'srcu.2…
Browse files Browse the repository at this point in the history
…024.12.14a' and 'torture-test.2024.12.14a' into rcu-merge.2024.12.14a

fixes.2024.12.14a: RCU fixes
rcutorture.2024.12.14a: Torture-test updates
srcu.2024.12.14a: SRCU updates
torture-test.2024.12.14a: Adding an extra test, fixes
  • Loading branch information
Uladzislau Rezki (Sony) committed Dec 14, 2024
4 parents 8f6f163 + 0fef924 + 45c7c67 + 6ca774f commit 4b5c220
Show file tree
Hide file tree
Showing 13 changed files with 410 additions and 70 deletions.
90 changes: 89 additions & 1 deletion Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5362,7 +5362,42 @@

rcutorture.gp_cond= [KNL]
Use conditional/asynchronous update-side
primitives, if available.
normal-grace-period primitives, if available.

rcutorture.gp_cond_exp= [KNL]
Use conditional/asynchronous update-side
expedited-grace-period primitives, if available.

rcutorture.gp_cond_full= [KNL]
Use conditional/asynchronous update-side
normal-grace-period primitives that also take
concurrent expedited grace periods into account,
if available.

rcutorture.gp_cond_exp_full= [KNL]
Use conditional/asynchronous update-side
expedited-grace-period primitives that also take
concurrent normal grace periods into account,
if available.

rcutorture.gp_cond_wi= [KNL]
Nominal wait interval for normal conditional
grace periods (specified by rcutorture's
gp_cond and gp_cond_full module parameters),
in microseconds. The actual wait interval will
be randomly selected to nanosecond granularity up
to this wait interval. Defaults to 16 jiffies,
for example, 16,000 microseconds on a system
with HZ=1000.

rcutorture.gp_cond_wi_exp= [KNL]
Nominal wait interval for expedited conditional
grace periods (specified by rcutorture's
gp_cond_exp and gp_cond_exp_full module
parameters), in microseconds. The actual wait
interval will be randomly selected to nanosecond
granularity up to this wait interval. Defaults to
128 microseconds.

rcutorture.gp_exp= [KNL]
Use expedited update-side primitives, if available.
Expand All @@ -5371,6 +5406,43 @@
Use normal (non-expedited) asynchronous
update-side primitives, if available.

rcutorture.gp_poll= [KNL]
Use polled update-side normal-grace-period
primitives, if available.

rcutorture.gp_poll_exp= [KNL]
Use polled update-side expedited-grace-period
primitives, if available.

rcutorture.gp_poll_full= [KNL]
Use polled update-side normal-grace-period
primitives that also take concurrent expedited
grace periods into account, if available.

rcutorture.gp_poll_exp_full= [KNL]
Use polled update-side expedited-grace-period
primitives that also take concurrent normal
grace periods into account, if available.

rcutorture.gp_poll_wi= [KNL]
Nominal wait interval for normal conditional
grace periods (specified by rcutorture's
gp_poll and gp_poll_full module parameters),
in microseconds. The actual wait interval will
be randomly selected to nanosecond granularity up
to this wait interval. Defaults to 16 jiffies,
for example, 16,000 microseconds on a system
with HZ=1000.

rcutorture.gp_poll_wi_exp= [KNL]
Nominal wait interval for expedited conditional
grace periods (specified by rcutorture's
gp_poll_exp and gp_poll_exp_full module
parameters), in microseconds. The actual wait
interval will be randomly selected to nanosecond
granularity up to this wait interval. Defaults to
128 microseconds.

rcutorture.gp_sync= [KNL]
Use normal (non-expedited) synchronous
update-side primitives, if available. If all
Expand Down Expand Up @@ -5424,6 +5496,22 @@
Set time (jiffies) between CPU-hotplug operations,
or zero to disable CPU-hotplug testing.

rcutorture.preempt_duration= [KNL]
Set duration (in milliseconds) of preemptions
by a high-priority FIFO real-time task. Set to
zero (the default) to disable. The CPUs to
preempt are selected randomly from the set that
are online at a given point in time. Races with
CPUs going offline are ignored, with that attempt
at preemption skipped.

rcutorture.preempt_interval= [KNL]
Set interval (in milliseconds, defaulting to one
second) between preemptions by a high-priority
FIFO real-time task. This delay is mediated
by an hrtimer and is further fuzzed to avoid
inadvertent synchronizations.

rcutorture.read_exit_burst= [KNL]
The number of times in a given read-then-exit
episode that a set of read-then-exit kthreads
Expand Down
11 changes: 11 additions & 0 deletions include/linux/rcupdate_wait.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,15 @@ static inline void cond_resched_rcu(void)
#endif
}

// Has the current task blocked within its current RCU read-side
// critical section?
static inline bool has_rcu_reader_blocked(void)
{
#ifdef CONFIG_PREEMPT_RCU
return !list_empty(&current->rcu_node_entry);
#else
return false;
#endif
}

#endif /* _LINUX_SCHED_RCUPDATE_WAIT_H */
21 changes: 14 additions & 7 deletions include/linux/srcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ int init_srcu_struct(struct srcu_struct *ssp);
#define __SRCU_DEP_MAP_INIT(srcu_name)
#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */

/* Values for SRCU Tree srcu_data ->srcu_reader_flavor, but also used by rcutorture. */
#define SRCU_READ_FLAVOR_NORMAL 0x1 // srcu_read_lock().
#define SRCU_READ_FLAVOR_NMI 0x2 // srcu_read_lock_nmisafe().
#define SRCU_READ_FLAVOR_LITE 0x4 // srcu_read_lock_lite().
#define SRCU_READ_FLAVOR_ALL 0x7 // All of the above.

#ifdef CONFIG_TINY_SRCU
#include <linux/srcutiny.h>
#elif defined(CONFIG_TREE_SRCU)
Expand Down Expand Up @@ -232,13 +238,14 @@ static inline int srcu_read_lock_held(const struct srcu_struct *ssp)
* a mutex that is held elsewhere while calling synchronize_srcu() or
* synchronize_srcu_expedited().
*
* The return value from srcu_read_lock() must be passed unaltered
* to the matching srcu_read_unlock(). Note that srcu_read_lock() and
* the matching srcu_read_unlock() must occur in the same context, for
* example, it is illegal to invoke srcu_read_unlock() in an irq handler
* if the matching srcu_read_lock() was invoked in process context. Or,
* for that matter to invoke srcu_read_unlock() from one task and the
* matching srcu_read_lock() from another.
* The return value from srcu_read_lock() is guaranteed to be
* non-negative. This value must be passed unaltered to the matching
* srcu_read_unlock(). Note that srcu_read_lock() and the matching
* srcu_read_unlock() must occur in the same context, for example, it is
* illegal to invoke srcu_read_unlock() in an irq handler if the matching
* srcu_read_lock() was invoked in process context. Or, for that matter to
* invoke srcu_read_unlock() from one task and the matching srcu_read_lock()
* from another.
*/
static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
{
Expand Down
8 changes: 2 additions & 6 deletions include/linux/srcutree.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct srcu_data {
atomic_long_t srcu_lock_count[2]; /* Locks per CPU. */
atomic_long_t srcu_unlock_count[2]; /* Unlocks per CPU. */
int srcu_reader_flavor; /* Reader flavor for srcu_struct structure? */
/* Values: SRCU_READ_FLAVOR_.* */

/* Update-side state. */
spinlock_t __private lock ____cacheline_internodealigned_in_smp;
Expand All @@ -43,11 +44,6 @@ struct srcu_data {
struct srcu_struct *ssp;
};

/* Values for ->srcu_reader_flavor. */
#define SRCU_READ_FLAVOR_NORMAL 0x1 // srcu_read_lock().
#define SRCU_READ_FLAVOR_NMI 0x2 // srcu_read_lock_nmisafe().
#define SRCU_READ_FLAVOR_LITE 0x4 // srcu_read_lock_lite().

/*
* Node in SRCU combining tree, similar in function to rcu_data.
*/
Expand Down Expand Up @@ -258,7 +254,7 @@ static inline void srcu_check_read_flavor_lite(struct srcu_struct *ssp)
if (likely(READ_ONCE(sdp->srcu_reader_flavor) & SRCU_READ_FLAVOR_LITE))
return;

// Note that the cmpxchg() in srcu_check_read_flavor() is fully ordered.
// Note that the cmpxchg() in __srcu_check_read_flavor() is fully ordered.
__srcu_check_read_flavor(ssp, SRCU_READ_FLAVOR_LITE);
}

Expand Down
2 changes: 1 addition & 1 deletion include/linux/torture.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ void _torture_stop_kthread(char *m, struct task_struct **tp);
#endif

#if IS_ENABLED(CONFIG_RCU_TORTURE_TEST) || IS_MODULE(CONFIG_RCU_TORTURE_TEST) || IS_ENABLED(CONFIG_LOCK_TORTURE_TEST) || IS_MODULE(CONFIG_LOCK_TORTURE_TEST)
long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask);
long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask, bool dowarn);
#endif

#endif /* __LINUX_TORTURE_H */
6 changes: 3 additions & 3 deletions kernel/locking/locktorture.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static const struct kernel_param_ops lt_bind_ops = {
module_param_cb(bind_readers, &lt_bind_ops, &bind_readers, 0644);
module_param_cb(bind_writers, &lt_bind_ops, &bind_writers, 0644);

long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask);
long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask, bool dowarn);

static struct task_struct *stats_task;
static struct task_struct **writer_tasks;
Expand Down Expand Up @@ -1358,7 +1358,7 @@ static int __init lock_torture_init(void)
if (torture_init_error(firsterr))
goto unwind;
if (cpumask_nonempty(bind_writers))
torture_sched_setaffinity(writer_tasks[i]->pid, bind_writers);
torture_sched_setaffinity(writer_tasks[i]->pid, bind_writers, true);

create_reader:
if (cxt.cur_ops->readlock == NULL || (j >= cxt.nrealreaders_stress))
Expand All @@ -1369,7 +1369,7 @@ static int __init lock_torture_init(void)
if (torture_init_error(firsterr))
goto unwind;
if (cpumask_nonempty(bind_readers))
torture_sched_setaffinity(reader_tasks[j]->pid, bind_readers);
torture_sched_setaffinity(reader_tasks[j]->pid, bind_readers, true);
}
if (stat_interval > 0) {
firsterr = torture_create_kthread(lock_torture_stats, NULL,
Expand Down
31 changes: 31 additions & 0 deletions kernel/rcu/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,37 @@ config RCU_TORTURE_TEST
Say M if you want the RCU torture tests to build as a module.
Say N if you are unsure.

config RCU_TORTURE_TEST_CHK_RDR_STATE
tristate "Check rcutorture reader state"
depends on RCU_TORTURE_TEST
default n
help
This option causes rcutorture to check the desired rcutorture
reader state for each segment against the actual context.
Note that PREEMPT_COUNT must be enabled if the preempt-disabled
and bh-disabled checks are to take effect, and that PREEMPT_RCU
must be enabled for the RCU-nesting checks to take effect.
These checks add overhead, and this Kconfig options is therefore
disabled by default.

Say Y here if you want rcutorture reader contexts checked.
Say N if you are unsure.

config RCU_TORTURE_TEST_LOG_CPU
tristate "Log CPU for rcutorture failures"
depends on RCU_TORTURE_TEST
default n
help
This option causes rcutorture to decorate each entry of its
log of failure/close-call rcutorture reader segments with the
number of the CPU that the reader was running on at the time.
This information can be useful, but it does incur additional
overhead, overhead that can make both failures and close calls
less probable.

Say Y here if you want CPU IDs logged.
Say N if you are unsure.

config RCU_REF_SCALE_TEST
tristate "Scalability tests for read-side synchronization (RCU and others)"
depends on DEBUG_KERNEL
Expand Down
Loading

0 comments on commit 4b5c220

Please sign in to comment.