mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
srcu: Remove Classic SRCU
Classic SRCU was only ever intended to be a fallback in case of issues with Tree/Tiny SRCU, and the latter two are doing quite well in testing. This commit therefore removes Classic SRCU. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
This commit is contained in:
@@ -60,8 +60,6 @@ int init_srcu_struct(struct srcu_struct *sp);
|
|||||||
#include <linux/srcutiny.h>
|
#include <linux/srcutiny.h>
|
||||||
#elif defined(CONFIG_TREE_SRCU)
|
#elif defined(CONFIG_TREE_SRCU)
|
||||||
#include <linux/srcutree.h>
|
#include <linux/srcutree.h>
|
||||||
#elif defined(CONFIG_CLASSIC_SRCU)
|
|
||||||
#include <linux/srcuclassic.h>
|
|
||||||
#elif defined(CONFIG_SRCU)
|
#elif defined(CONFIG_SRCU)
|
||||||
#error "Unknown SRCU implementation specified to kernel configuration"
|
#error "Unknown SRCU implementation specified to kernel configuration"
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -1,100 +0,0 @@
|
|||||||
/*
|
|
||||||
* Sleepable Read-Copy Update mechanism for mutual exclusion,
|
|
||||||
* classic v4.11 variant.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, you can access it online at
|
|
||||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
|
||||||
*
|
|
||||||
* Copyright (C) IBM Corporation, 2017
|
|
||||||
*
|
|
||||||
* Author: Paul McKenney <paulmck@us.ibm.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LINUX_SRCU_CLASSIC_H
|
|
||||||
#define _LINUX_SRCU_CLASSIC_H
|
|
||||||
|
|
||||||
struct srcu_array {
|
|
||||||
unsigned long lock_count[2];
|
|
||||||
unsigned long unlock_count[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rcu_batch {
|
|
||||||
struct rcu_head *head, **tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define RCU_BATCH_INIT(name) { NULL, &(name.head) }
|
|
||||||
|
|
||||||
struct srcu_struct {
|
|
||||||
unsigned long completed;
|
|
||||||
struct srcu_array __percpu *per_cpu_ref;
|
|
||||||
spinlock_t queue_lock; /* protect ->batch_queue, ->running */
|
|
||||||
bool running;
|
|
||||||
/* callbacks just queued */
|
|
||||||
struct rcu_batch batch_queue;
|
|
||||||
/* callbacks try to do the first check_zero */
|
|
||||||
struct rcu_batch batch_check0;
|
|
||||||
/* callbacks done with the first check_zero and the flip */
|
|
||||||
struct rcu_batch batch_check1;
|
|
||||||
struct rcu_batch batch_done;
|
|
||||||
struct delayed_work work;
|
|
||||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
||||||
struct lockdep_map dep_map;
|
|
||||||
#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
|
|
||||||
};
|
|
||||||
|
|
||||||
void process_srcu(struct work_struct *work);
|
|
||||||
|
|
||||||
#define __SRCU_STRUCT_INIT(name) \
|
|
||||||
{ \
|
|
||||||
.completed = -300, \
|
|
||||||
.per_cpu_ref = &name##_srcu_array, \
|
|
||||||
.queue_lock = __SPIN_LOCK_UNLOCKED(name.queue_lock), \
|
|
||||||
.running = false, \
|
|
||||||
.batch_queue = RCU_BATCH_INIT(name.batch_queue), \
|
|
||||||
.batch_check0 = RCU_BATCH_INIT(name.batch_check0), \
|
|
||||||
.batch_check1 = RCU_BATCH_INIT(name.batch_check1), \
|
|
||||||
.batch_done = RCU_BATCH_INIT(name.batch_done), \
|
|
||||||
.work = __DELAYED_WORK_INITIALIZER(name.work, process_srcu, 0),\
|
|
||||||
__SRCU_DEP_MAP_INIT(name) \
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Define and initialize a srcu struct at build time.
|
|
||||||
* Do -not- call init_srcu_struct() nor cleanup_srcu_struct() on it.
|
|
||||||
*
|
|
||||||
* Note that although DEFINE_STATIC_SRCU() hides the name from other
|
|
||||||
* files, the per-CPU variable rules nevertheless require that the
|
|
||||||
* chosen name be globally unique. These rules also prohibit use of
|
|
||||||
* DEFINE_STATIC_SRCU() within a function. If these rules are too
|
|
||||||
* restrictive, declare the srcu_struct manually. For example, in
|
|
||||||
* each file:
|
|
||||||
*
|
|
||||||
* static struct srcu_struct my_srcu;
|
|
||||||
*
|
|
||||||
* Then, before the first use of each my_srcu, manually initialize it:
|
|
||||||
*
|
|
||||||
* init_srcu_struct(&my_srcu);
|
|
||||||
*
|
|
||||||
* See include/linux/percpu-defs.h for the rules on per-CPU variables.
|
|
||||||
*/
|
|
||||||
#define __DEFINE_SRCU(name, is_static) \
|
|
||||||
static DEFINE_PER_CPU(struct srcu_array, name##_srcu_array);\
|
|
||||||
is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name)
|
|
||||||
#define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */)
|
|
||||||
#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static)
|
|
||||||
|
|
||||||
void synchronize_srcu_expedited(struct srcu_struct *sp);
|
|
||||||
void srcu_barrier(struct srcu_struct *sp);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
+2
-19
@@ -526,32 +526,15 @@ config SRCU
|
|||||||
permits arbitrary sleeping or blocking within RCU read-side critical
|
permits arbitrary sleeping or blocking within RCU read-side critical
|
||||||
sections.
|
sections.
|
||||||
|
|
||||||
config CLASSIC_SRCU
|
|
||||||
bool "Use v4.11 classic SRCU implementation"
|
|
||||||
default n
|
|
||||||
depends on RCU_EXPERT && SRCU
|
|
||||||
help
|
|
||||||
This option selects the traditional well-tested classic SRCU
|
|
||||||
implementation from v4.11, as might be desired for enterprise
|
|
||||||
Linux distributions. Without this option, the shiny new
|
|
||||||
Tiny SRCU and Tree SRCU implementations are used instead.
|
|
||||||
At some point, it is hoped that Tiny SRCU and Tree SRCU
|
|
||||||
will accumulate enough test time and confidence to allow
|
|
||||||
Classic SRCU to be dropped entirely.
|
|
||||||
|
|
||||||
Say Y if you need a rock-solid SRCU.
|
|
||||||
|
|
||||||
Say N if you would like help test Tree SRCU.
|
|
||||||
|
|
||||||
config TINY_SRCU
|
config TINY_SRCU
|
||||||
bool
|
bool
|
||||||
default y if SRCU && TINY_RCU && !CLASSIC_SRCU
|
default y if SRCU && TINY_RCU
|
||||||
help
|
help
|
||||||
This option selects the single-CPU non-preemptible version of SRCU.
|
This option selects the single-CPU non-preemptible version of SRCU.
|
||||||
|
|
||||||
config TREE_SRCU
|
config TREE_SRCU
|
||||||
bool
|
bool
|
||||||
default y if SRCU && !TINY_RCU && !CLASSIC_SRCU
|
default y if SRCU && !TINY_RCU
|
||||||
help
|
help
|
||||||
This option selects the full-fledged version of SRCU.
|
This option selects the full-fledged version of SRCU.
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
KCOV_INSTRUMENT := n
|
KCOV_INSTRUMENT := n
|
||||||
|
|
||||||
obj-y += update.o sync.o
|
obj-y += update.o sync.o
|
||||||
obj-$(CONFIG_CLASSIC_SRCU) += srcu.o
|
|
||||||
obj-$(CONFIG_TREE_SRCU) += srcutree.o
|
obj-$(CONFIG_TREE_SRCU) += srcutree.o
|
||||||
obj-$(CONFIG_TINY_SRCU) += srcutiny.o
|
obj-$(CONFIG_TINY_SRCU) += srcutiny.o
|
||||||
obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
|
obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
|
||||||
|
|||||||
@@ -457,22 +457,6 @@ void srcutorture_get_gp_data(enum rcutorture_type test_type,
|
|||||||
struct srcu_struct *sp, int *flags,
|
struct srcu_struct *sp, int *flags,
|
||||||
unsigned long *gpnum, unsigned long *completed);
|
unsigned long *gpnum, unsigned long *completed);
|
||||||
|
|
||||||
#elif defined(CONFIG_CLASSIC_SRCU)
|
|
||||||
|
|
||||||
static inline void srcutorture_get_gp_data(enum rcutorture_type test_type,
|
|
||||||
struct srcu_struct *sp, int *flags,
|
|
||||||
unsigned long *gpnum,
|
|
||||||
unsigned long *completed)
|
|
||||||
{
|
|
||||||
if (test_type != SRCU_FLAVOR)
|
|
||||||
return;
|
|
||||||
*flags = 0;
|
|
||||||
*completed = sp->completed;
|
|
||||||
*gpnum = *completed;
|
|
||||||
if (sp->batch_queue.head || sp->batch_check0.head || sp->batch_check1.head)
|
|
||||||
(*gpnum)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_TINY_RCU
|
#ifdef CONFIG_TINY_RCU
|
||||||
|
|||||||
@@ -564,31 +564,19 @@ static void srcu_torture_stats(void)
|
|||||||
int __maybe_unused cpu;
|
int __maybe_unused cpu;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
#if defined(CONFIG_TREE_SRCU) || defined(CONFIG_CLASSIC_SRCU)
|
|
||||||
#ifdef CONFIG_TREE_SRCU
|
#ifdef CONFIG_TREE_SRCU
|
||||||
idx = srcu_ctlp->srcu_idx & 0x1;
|
idx = srcu_ctlp->srcu_idx & 0x1;
|
||||||
#else /* #ifdef CONFIG_TREE_SRCU */
|
|
||||||
idx = srcu_ctlp->completed & 0x1;
|
|
||||||
#endif /* #else #ifdef CONFIG_TREE_SRCU */
|
|
||||||
pr_alert("%s%s Tree SRCU per-CPU(idx=%d):",
|
pr_alert("%s%s Tree SRCU per-CPU(idx=%d):",
|
||||||
torture_type, TORTURE_FLAG, idx);
|
torture_type, TORTURE_FLAG, idx);
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
unsigned long l0, l1;
|
unsigned long l0, l1;
|
||||||
unsigned long u0, u1;
|
unsigned long u0, u1;
|
||||||
long c0, c1;
|
long c0, c1;
|
||||||
#ifdef CONFIG_TREE_SRCU
|
|
||||||
struct srcu_data *counts;
|
struct srcu_data *counts;
|
||||||
|
|
||||||
counts = per_cpu_ptr(srcu_ctlp->sda, cpu);
|
counts = per_cpu_ptr(srcu_ctlp->sda, cpu);
|
||||||
u0 = counts->srcu_unlock_count[!idx];
|
u0 = counts->srcu_unlock_count[!idx];
|
||||||
u1 = counts->srcu_unlock_count[idx];
|
u1 = counts->srcu_unlock_count[idx];
|
||||||
#else /* #ifdef CONFIG_TREE_SRCU */
|
|
||||||
struct srcu_array *counts;
|
|
||||||
|
|
||||||
counts = per_cpu_ptr(srcu_ctlp->per_cpu_ref, cpu);
|
|
||||||
u0 = counts->unlock_count[!idx];
|
|
||||||
u1 = counts->unlock_count[idx];
|
|
||||||
#endif /* #else #ifdef CONFIG_TREE_SRCU */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure that a lock is always counted if the corresponding
|
* Make sure that a lock is always counted if the corresponding
|
||||||
@@ -596,13 +584,8 @@ static void srcu_torture_stats(void)
|
|||||||
*/
|
*/
|
||||||
smp_rmb();
|
smp_rmb();
|
||||||
|
|
||||||
#ifdef CONFIG_TREE_SRCU
|
|
||||||
l0 = counts->srcu_lock_count[!idx];
|
l0 = counts->srcu_lock_count[!idx];
|
||||||
l1 = counts->srcu_lock_count[idx];
|
l1 = counts->srcu_lock_count[idx];
|
||||||
#else /* #ifdef CONFIG_TREE_SRCU */
|
|
||||||
l0 = counts->lock_count[!idx];
|
|
||||||
l1 = counts->lock_count[idx];
|
|
||||||
#endif /* #else #ifdef CONFIG_TREE_SRCU */
|
|
||||||
|
|
||||||
c0 = l0 - u0;
|
c0 = l0 - u0;
|
||||||
c1 = l1 - u1;
|
c1 = l1 - u1;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,6 @@ TREE06
|
|||||||
TREE07
|
TREE07
|
||||||
TREE08
|
TREE08
|
||||||
TREE09
|
TREE09
|
||||||
SRCU-C
|
|
||||||
SRCU-N
|
SRCU-N
|
||||||
SRCU-P
|
SRCU-P
|
||||||
SRCU-t
|
SRCU-t
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
CONFIG_RCU_TRACE=n
|
|
||||||
CONFIG_SMP=y
|
|
||||||
CONFIG_NR_CPUS=3
|
|
||||||
CONFIG_HOTPLUG_CPU=y
|
|
||||||
CONFIG_RCU_EXPERT=y
|
|
||||||
CONFIG_CLASSIC_SRCU=y
|
|
||||||
CONFIG_PREEMPT_NONE=n
|
|
||||||
CONFIG_PREEMPT_VOLUNTARY=n
|
|
||||||
CONFIG_PREEMPT=y
|
|
||||||
CONFIG_DEBUG_LOCK_ALLOC=y
|
|
||||||
CONFIG_PROVE_LOCKING=y
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
CONFIG_SMP=y
|
|
||||||
CONFIG_HZ_PERIODIC=n
|
|
||||||
CONFIG_NO_HZ_IDLE=y
|
|
||||||
CONFIG_NO_HZ_FULL=n
|
|
||||||
CONFIG_RCU_FAST_NO_HZ=n
|
|
||||||
CONFIG_HOTPLUG_CPU=n
|
|
||||||
CONFIG_SUSPEND=n
|
|
||||||
CONFIG_HIBERNATION=n
|
|
||||||
CONFIG_RCU_NOCB_CPU=n
|
|
||||||
CONFIG_DEBUG_LOCK_ALLOC=n
|
|
||||||
CONFIG_PROVE_LOCKING=n
|
|
||||||
CONFIG_RCU_BOOST=n
|
|
||||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
|
||||||
CONFIG_RCU_EXPERT=y
|
|
||||||
CONFIG_RCU_TRACE=y
|
|
||||||
CONFIG_CLASSIC_SRCU=y
|
|
||||||
Reference in New Issue
Block a user