forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
srcu: Introduce CLASSIC_SRCU Kconfig option
The TREE_SRCU rewrite is large and a bit on the non-simple side, so this commit helps reduce risk by allowing the old v4.11 SRCU algorithm to be selected using a new CLASSIC_SRCU Kconfig option that depends on RCU_EXPERT. The default is to use the new TREE_SRCU and TINY_SRCU algorithms, in order to help get these the testing that they need. However, if your users do not require the update-side scalability that is to be provided by TREE_SRCU, select RCU_EXPERT and then CLASSIC_SRCU to revert back to the old classic SRCU algorithm. Signed-off-by: Paul E. McKenney <[email protected]>
- Loading branch information
Showing
7 changed files
with
934 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
* 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 <[email protected]> | ||
*/ | ||
|
||
#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); | ||
unsigned long srcu_batches_completed(struct srcu_struct *sp); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.