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.
context_tracking: New context tracking susbsystem
Create a new subsystem that probes on kernel boundaries to keep track of the transitions between level contexts with two basic initial contexts: user or kernel. This is an abstraction of some RCU code that use such tracking to implement its userspace extended quiescent state. We need to pull this up from RCU into this new level of indirection because this tracking is also going to be used to implement an "on demand" generic virtual cputime accounting. A necessary step to shutdown the tick while still accounting the cputime. Signed-off-by: Frederic Weisbecker <[email protected]> Cc: Andrew Morton <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Paul E. McKenney <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Steven Rostedt <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Li Zhong <[email protected]> Cc: Gilad Ben-Yossef <[email protected]> Reviewed-by: Steven Rostedt <[email protected]> [ paulmck: fix whitespace error and email address. ] Signed-off-by: Paul E. McKenney <[email protected]>
- Loading branch information
Showing
15 changed files
with
150 additions
and
108 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
15 changes: 7 additions & 8 deletions
15
arch/x86/include/asm/rcu.h → arch/x86/include/asm/context_tracking.h
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
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
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,18 @@ | ||
#ifndef _LINUX_CONTEXT_TRACKING_H | ||
#define _LINUX_CONTEXT_TRACKING_H | ||
|
||
#ifdef CONFIG_CONTEXT_TRACKING | ||
#include <linux/sched.h> | ||
|
||
extern void user_enter(void); | ||
extern void user_exit(void); | ||
extern void context_tracking_task_switch(struct task_struct *prev, | ||
struct task_struct *next); | ||
#else | ||
static inline void user_enter(void) { } | ||
static inline void user_exit(void) { } | ||
static inline void context_tracking_task_switch(struct task_struct *prev, | ||
struct task_struct *next) { } | ||
#endif /* !CONFIG_CONTEXT_TRACKING */ | ||
|
||
#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
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,83 @@ | ||
#include <linux/context_tracking.h> | ||
#include <linux/rcupdate.h> | ||
#include <linux/sched.h> | ||
#include <linux/percpu.h> | ||
#include <linux/hardirq.h> | ||
|
||
struct context_tracking { | ||
/* | ||
* When active is false, hooks are not set to | ||
* minimize overhead: TIF flags are cleared | ||
* and calls to user_enter/exit are ignored. This | ||
* may be further optimized using static keys. | ||
*/ | ||
bool active; | ||
enum { | ||
IN_KERNEL = 0, | ||
IN_USER, | ||
} state; | ||
}; | ||
|
||
static DEFINE_PER_CPU(struct context_tracking, context_tracking) = { | ||
#ifdef CONFIG_CONTEXT_TRACKING_FORCE | ||
.active = true, | ||
#endif | ||
}; | ||
|
||
void user_enter(void) | ||
{ | ||
unsigned long flags; | ||
|
||
/* | ||
* Some contexts may involve an exception occuring in an irq, | ||
* leading to that nesting: | ||
* rcu_irq_enter() rcu_user_exit() rcu_user_exit() rcu_irq_exit() | ||
* This would mess up the dyntick_nesting count though. And rcu_irq_*() | ||
* helpers are enough to protect RCU uses inside the exception. So | ||
* just return immediately if we detect we are in an IRQ. | ||
*/ | ||
if (in_interrupt()) | ||
return; | ||
|
||
WARN_ON_ONCE(!current->mm); | ||
|
||
local_irq_save(flags); | ||
if (__this_cpu_read(context_tracking.active) && | ||
__this_cpu_read(context_tracking.state) != IN_USER) { | ||
__this_cpu_write(context_tracking.state, IN_USER); | ||
rcu_user_enter(); | ||
} | ||
local_irq_restore(flags); | ||
} | ||
|
||
void user_exit(void) | ||
{ | ||
unsigned long flags; | ||
|
||
/* | ||
* Some contexts may involve an exception occuring in an irq, | ||
* leading to that nesting: | ||
* rcu_irq_enter() rcu_user_exit() rcu_user_exit() rcu_irq_exit() | ||
* This would mess up the dyntick_nesting count though. And rcu_irq_*() | ||
* helpers are enough to protect RCU uses inside the exception. So | ||
* just return immediately if we detect we are in an IRQ. | ||
*/ | ||
if (in_interrupt()) | ||
return; | ||
|
||
local_irq_save(flags); | ||
if (__this_cpu_read(context_tracking.state) == IN_USER) { | ||
__this_cpu_write(context_tracking.state, IN_KERNEL); | ||
rcu_user_exit(); | ||
} | ||
local_irq_restore(flags); | ||
} | ||
|
||
void context_tracking_task_switch(struct task_struct *prev, | ||
struct task_struct *next) | ||
{ | ||
if (__this_cpu_read(context_tracking.active)) { | ||
clear_tsk_thread_flag(prev, TIF_NOHZ); | ||
set_tsk_thread_flag(next, TIF_NOHZ); | ||
} | ||
} |
Oops, something went wrong.