Skip to content

Commit

Permalink
Merge tag 'core-rcu-2021-04-28' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/tip/tip

Pull RCU updates from Ingo Molnar:

 - Support for "N" as alias for last bit in bitmap parsing library (eg
   using syntax like "nohz_full=2-N")

 - kvfree_rcu updates

 - mm_dump_obj() updates. (One of these is to mm, but was suggested by
   Andrew Morton.)

 - RCU callback offloading update

 - Polling RCU grace-period interfaces

 - Realtime-related RCU updates

 - Tasks-RCU updates

 - Torture-test updates

 - Torture-test scripting updates

 - Miscellaneous fixes

* tag 'core-rcu-2021-04-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (77 commits)
  rcutorture: Test start_poll_synchronize_rcu() and poll_state_synchronize_rcu()
  rcu: Provide polling interfaces for Tiny RCU grace periods
  torture: Fix kvm.sh --datestamp regex check
  torture: Consolidate qemu-cmd duration editing into kvm-transform.sh
  torture: Print proper vmlinux path for kvm-again.sh runs
  torture: Make TORTURE_TRUST_MAKE available in kvm-again.sh environment
  torture: Make kvm-transform.sh update jitter commands
  torture: Add --duration argument to kvm-again.sh
  torture: Add kvm-again.sh to rerun a previous torture-test
  torture: Create a "batches" file for build reuse
  torture: De-capitalize TORTURE_SUITE
  torture: Make upper-case-only no-dot no-slash scenario names official
  torture: Rename SRCU-t and SRCU-u to avoid lowercase characters
  torture: Remove no-mpstat error message
  torture: Record kvm-test-1-run.sh and kvm-test-1-run-qemu.sh PIDs
  torture: Record jitter start/stop commands
  torture: Extract kvm-test-1-run-qemu.sh from kvm-test-1-run.sh
  torture: Record TORTURE_KCONFIG_GDB_ARG in qemu-cmd
  torture: Abstract jitter.sh start/stop into scripts
  rcu: Provide polling interfaces for Tree RCU grace periods
  ...
  • Loading branch information
torvalds committed Apr 28, 2021
2 parents 68a32ba + 120b566 commit 9a45da9
Show file tree
Hide file tree
Showing 54 changed files with 1,304 additions and 422 deletions.
2 changes: 1 addition & 1 deletion Documentation/RCU/RTFP.txt
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ Symposium on Distributed Computing}
'It's entirely possible that the current user could be replaced
by RCU and/or seqlocks, and we could get rid of brlocks entirely.'
.
Steve Hemminger responds by replacing them with RCU.
Stephen Hemminger responds by replacing them with RCU.
}
}

Expand Down
7 changes: 7 additions & 0 deletions Documentation/admin-guide/kernel-parameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ For example one can add to the command line following parameter:

where the final item represents CPUs 100,101,125,126,150,151,...

The value "N" can be used to represent the numerically last CPU on the system,
i.e "foo_cpus=16-N" would be equivalent to "16-31" on a 32 core system.

Keep in mind that "N" is dynamic, so if system changes cause the bitmap width
to change, such as less cores in the CPU list, then N and any ranges using N
will also change. Use the same on a small 4 core system, and "16-N" becomes
"16-3" and now the same boot input will be flagged as invalid (start > end).


This document may not be entirely up to date and comprehensive. The command
Expand Down
16 changes: 13 additions & 3 deletions Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4077,9 +4077,7 @@
see CONFIG_RAS_CEC help text.

rcu_nocbs= [KNL]
The argument is a cpu list, as described above,
except that the string "all" can be used to
specify every CPU on the system.
The argument is a cpu list, as described above.

In kernels built with CONFIG_RCU_NOCB_CPU=y, set
the specified list of CPUs to be no-callback CPUs.
Expand Down Expand Up @@ -4268,6 +4266,18 @@
rcuscale.kfree_rcu_test= [KNL]
Set to measure performance of kfree_rcu() flooding.

rcuscale.kfree_rcu_test_double= [KNL]
Test the double-argument variant of kfree_rcu().
If this parameter has the same value as
rcuscale.kfree_rcu_test_single, both the single-
and double-argument variants are tested.

rcuscale.kfree_rcu_test_single= [KNL]
Test the single-argument variant of kfree_rcu().
If this parameter has the same value as
rcuscale.kfree_rcu_test_double, both the single-
and double-argument variants are tested.

rcuscale.kfree_nthreads= [KNL]
The number of threads running loops of kfree_rcu().

Expand Down
4 changes: 4 additions & 0 deletions include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -3180,7 +3180,11 @@ unsigned long wp_shared_mapping_range(struct address_space *mapping,

extern int sysctl_nr_trim_pages;

#ifdef CONFIG_PRINTK
void mem_dump_obj(void *object);
#else
static inline void mem_dump_obj(void *object) {}
#endif

#endif /* __KERNEL__ */
#endif /* _LINUX_MM_H */
7 changes: 4 additions & 3 deletions include/linux/rcu_segcblist.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ struct rcu_cblist {
* | SEGCBLIST_KTHREAD_GP |
* | |
* | Kthreads handle callbacks holding nocb_lock, local rcu_core() stops |
* | handling callbacks. |
* | handling callbacks. Enable bypass queueing. |
* ----------------------------------------------------------------------------
*/

Expand All @@ -125,7 +125,7 @@ struct rcu_cblist {
* | SEGCBLIST_KTHREAD_GP |
* | |
* | CB/GP kthreads handle callbacks holding nocb_lock, local rcu_core() |
* | ignores callbacks. |
* | ignores callbacks. Bypass enqueue is enabled. |
* ----------------------------------------------------------------------------
* |
* v
Expand All @@ -134,7 +134,8 @@ struct rcu_cblist {
* | SEGCBLIST_KTHREAD_GP |
* | |
* | CB/GP kthreads and local rcu_core() handle callbacks concurrently |
* | holding nocb_lock. Wake up CB and GP kthreads if necessary. |
* | holding nocb_lock. Wake up CB and GP kthreads if necessary. Disable |
* | bypass enqueue. |
* ----------------------------------------------------------------------------
* |
* v
Expand Down
2 changes: 1 addition & 1 deletion include/linux/rculist_nulls.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ static inline void hlist_nulls_add_fake(struct hlist_nulls_node *n)
*
* The barrier() is needed to make sure compiler doesn't cache first element [1],
* as this loop can be restarted [2]
* [1] Documentation/core-api/atomic_ops.rst around line 114
* [1] Documentation/memory-barriers.txt around line 1533
* [2] Documentation/RCU/rculist_nulls.rst around line 146
*/
#define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member) \
Expand Down
2 changes: 1 addition & 1 deletion include/linux/rcupdate.h
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
* The BUILD_BUG_ON check must not involve any function calls, hence the
* checks are done in macros here.
*/
#define kfree_rcu kvfree_rcu
#define kfree_rcu(ptr, rhf...) kvfree_rcu(ptr, ## rhf)

/**
* kvfree_rcu() - kvfree an object after a grace period.
Expand Down
7 changes: 3 additions & 4 deletions include/linux/rcutiny.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
/* Never flag non-existent other CPUs! */
static inline bool rcu_eqs_special_set(int cpu) { return false; }

static inline unsigned long get_state_synchronize_rcu(void)
{
return 0;
}
unsigned long get_state_synchronize_rcu(void);
unsigned long start_poll_synchronize_rcu(void);
bool poll_state_synchronize_rcu(unsigned long oldstate);

static inline void cond_synchronize_rcu(unsigned long oldstate)
{
Expand Down
2 changes: 2 additions & 0 deletions include/linux/rcutree.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ void rcu_momentary_dyntick_idle(void);
void kfree_rcu_scheduler_running(void);
bool rcu_gp_might_be_stalled(void);
unsigned long get_state_synchronize_rcu(void);
unsigned long start_poll_synchronize_rcu(void);
bool poll_state_synchronize_rcu(unsigned long oldstate);
void cond_synchronize_rcu(unsigned long oldstate);

void rcu_idle_enter(void);
Expand Down
2 changes: 2 additions & 0 deletions include/linux/slab.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,10 @@ void kfree(const void *);
void kfree_sensitive(const void *);
size_t __ksize(const void *);
size_t ksize(const void *);
#ifdef CONFIG_PRINTK
bool kmem_valid_obj(void *object);
void kmem_dump_obj(void *object);
#endif

#ifdef CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR
void __check_heap_object(const void *ptr, unsigned long n, struct page *page,
Expand Down
2 changes: 1 addition & 1 deletion include/linux/vmalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms)
int register_vmap_purge_notifier(struct notifier_block *nb);
int unregister_vmap_purge_notifier(struct notifier_block *nb);

#ifdef CONFIG_MMU
#if defined(CONFIG_MMU) && defined(CONFIG_PRINTK)
bool vmalloc_dump_obj(void *object);
#else
static inline bool vmalloc_dump_obj(void *object) { return false; }
Expand Down
28 changes: 28 additions & 0 deletions include/trace/events/rcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,34 @@ TRACE_EVENT_RCU(rcu_fqs,
__entry->cpu, __entry->qsevent)
);

/*
* Tracepoint for RCU stall events. Takes a string identifying the RCU flavor
* and a string identifying which function detected the RCU stall as follows:
*
* "StallDetected": Scheduler-tick detects other CPU's stalls.
* "SelfDetected": Scheduler-tick detects a current CPU's stall.
* "ExpeditedStall": Expedited grace period detects stalls.
*/
TRACE_EVENT(rcu_stall_warning,

TP_PROTO(const char *rcuname, const char *msg),

TP_ARGS(rcuname, msg),

TP_STRUCT__entry(
__field(const char *, rcuname)
__field(const char *, msg)
),

TP_fast_assign(
__entry->rcuname = rcuname;
__entry->msg = msg;
),

TP_printk("%s %s",
__entry->rcuname, __entry->msg)
);

#endif /* #if defined(CONFIG_TREE_RCU) */

/*
Expand Down
3 changes: 1 addition & 2 deletions kernel/rcu/rcu_segcblist.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,7 @@ void rcu_segcblist_disable(struct rcu_segcblist *rsclp)
}

/*
* Mark the specified rcu_segcblist structure as offloaded. This
* structure must be empty.
* Mark the specified rcu_segcblist structure as offloaded.
*/
void rcu_segcblist_offload(struct rcu_segcblist *rsclp, bool offload)
{
Expand Down
15 changes: 14 additions & 1 deletion kernel/rcu/rcuscale.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,8 @@ rcu_scale_shutdown(void *arg)
torture_param(int, kfree_nthreads, -1, "Number of threads running loops of kfree_rcu().");
torture_param(int, kfree_alloc_num, 8000, "Number of allocations and frees done in an iteration.");
torture_param(int, kfree_loops, 10, "Number of loops doing kfree_alloc_num allocations and frees.");
torture_param(bool, kfree_rcu_test_double, false, "Do we run a kfree_rcu() double-argument scale test?");
torture_param(bool, kfree_rcu_test_single, false, "Do we run a kfree_rcu() single-argument scale test?");

static struct task_struct **kfree_reader_tasks;
static int kfree_nrealthreads;
Expand All @@ -644,10 +646,13 @@ kfree_scale_thread(void *arg)
struct kfree_obj *alloc_ptr;
u64 start_time, end_time;
long long mem_begin, mem_during = 0;
bool kfree_rcu_test_both;
DEFINE_TORTURE_RANDOM(tr);

VERBOSE_SCALEOUT_STRING("kfree_scale_thread task started");
set_cpus_allowed_ptr(current, cpumask_of(me % nr_cpu_ids));
set_user_nice(current, MAX_NICE);
kfree_rcu_test_both = (kfree_rcu_test_single == kfree_rcu_test_double);

start_time = ktime_get_mono_fast_ns();

Expand All @@ -670,7 +675,15 @@ kfree_scale_thread(void *arg)
if (!alloc_ptr)
return -ENOMEM;

kfree_rcu(alloc_ptr, rh);
// By default kfree_rcu_test_single and kfree_rcu_test_double are
// initialized to false. If both have the same value (false or true)
// both are randomly tested, otherwise only the one with value true
// is tested.
if ((kfree_rcu_test_single && !kfree_rcu_test_double) ||
(kfree_rcu_test_both && torture_random(&tr) & 0x800))
kfree_rcu(alloc_ptr);
else
kfree_rcu(alloc_ptr, rh);
}

cond_resched();
Expand Down
Loading

0 comments on commit 9a45da9

Please sign in to comment.