diff options
author | Rik van Riel <riel@redhat.com> | 2015-02-10 15:27:50 -0500 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2015-03-09 10:42:52 -0400 |
commit | 3aab4f50bff89bdea5066a05d4f3c5fa25bc37c7 (patch) | |
tree | bb83901091481a72fbd5327718e8cbb079a91d3e /kernel/context_tracking.c | |
parent | c467ea763fd5d8795b7d1b5a78eb94b6ad8f66ad (diff) |
context_tracking: Generalize context tracking APIs to support user and guest
Generalize the context tracking APIs to support various nature of
contexts. This is performed by splitting out the mechanism from
context_tracking_user_enter and context_tracking_user_exit into
context_tracking_enter and context_tracking_exit.
The nature of the context we track is now detailed in a ctx_state
parameter pushed to these APIs, allowing the same functions to not just
track kernel <> user space switching, but also kernel <> guest transitions.
But leave the old functions in order to avoid breaking ARM, which calls
these functions from assembler code, and cannot easily use C enum
parameters.
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Rik van Riel <riel@redhat.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will deacon <will.deacon@arm.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Luiz Capitulino <lcapitulino@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'kernel/context_tracking.c')
-rw-r--r-- | kernel/context_tracking.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c index 8ad53c9d38b6..17715d811b71 100644 --- a/kernel/context_tracking.c +++ b/kernel/context_tracking.c | |||
@@ -39,15 +39,15 @@ void context_tracking_cpu_set(int cpu) | |||
39 | } | 39 | } |
40 | 40 | ||
41 | /** | 41 | /** |
42 | * context_tracking_user_enter - Inform the context tracking that the CPU is going to | 42 | * context_tracking_enter - Inform the context tracking that the CPU is going |
43 | * enter userspace mode. | 43 | * enter user or guest space mode. |
44 | * | 44 | * |
45 | * This function must be called right before we switch from the kernel | 45 | * This function must be called right before we switch from the kernel |
46 | * to userspace, when it's guaranteed the remaining kernel instructions | 46 | * to user or guest space, when it's guaranteed the remaining kernel |
47 | * to execute won't use any RCU read side critical section because this | 47 | * instructions to execute won't use any RCU read side critical section |
48 | * function sets RCU in extended quiescent state. | 48 | * because this function sets RCU in extended quiescent state. |
49 | */ | 49 | */ |
50 | void context_tracking_user_enter(void) | 50 | void context_tracking_enter(enum ctx_state state) |
51 | { | 51 | { |
52 | unsigned long flags; | 52 | unsigned long flags; |
53 | 53 | ||
@@ -75,7 +75,7 @@ void context_tracking_user_enter(void) | |||
75 | WARN_ON_ONCE(!current->mm); | 75 | WARN_ON_ONCE(!current->mm); |
76 | 76 | ||
77 | local_irq_save(flags); | 77 | local_irq_save(flags); |
78 | if ( __this_cpu_read(context_tracking.state) != CONTEXT_USER) { | 78 | if ( __this_cpu_read(context_tracking.state) != state) { |
79 | if (__this_cpu_read(context_tracking.active)) { | 79 | if (__this_cpu_read(context_tracking.active)) { |
80 | trace_user_enter(0); | 80 | trace_user_enter(0); |
81 | /* | 81 | /* |
@@ -101,24 +101,31 @@ void context_tracking_user_enter(void) | |||
101 | * OTOH we can spare the calls to vtime and RCU when context_tracking.active | 101 | * OTOH we can spare the calls to vtime and RCU when context_tracking.active |
102 | * is false because we know that CPU is not tickless. | 102 | * is false because we know that CPU is not tickless. |
103 | */ | 103 | */ |
104 | __this_cpu_write(context_tracking.state, CONTEXT_USER); | 104 | __this_cpu_write(context_tracking.state, state); |
105 | } | 105 | } |
106 | local_irq_restore(flags); | 106 | local_irq_restore(flags); |
107 | } | 107 | } |
108 | NOKPROBE_SYMBOL(context_tracking_enter); | ||
109 | |||
110 | void context_tracking_user_enter(void) | ||
111 | { | ||
112 | context_tracking_enter(CONTEXT_USER); | ||
113 | } | ||
108 | NOKPROBE_SYMBOL(context_tracking_user_enter); | 114 | NOKPROBE_SYMBOL(context_tracking_user_enter); |
109 | 115 | ||
110 | /** | 116 | /** |
111 | * context_tracking_user_exit - Inform the context tracking that the CPU is | 117 | * context_tracking_exit - Inform the context tracking that the CPU is |
112 | * exiting userspace mode and entering the kernel. | 118 | * exiting user or guest mode and entering the kernel. |
113 | * | 119 | * |
114 | * This function must be called after we entered the kernel from userspace | 120 | * This function must be called after we entered the kernel from user or |
115 | * before any use of RCU read side critical section. This potentially include | 121 | * guest space before any use of RCU read side critical section. This |
116 | * any high level kernel code like syscalls, exceptions, signal handling, etc... | 122 | * potentially include any high level kernel code like syscalls, exceptions, |
123 | * signal handling, etc... | ||
117 | * | 124 | * |
118 | * This call supports re-entrancy. This way it can be called from any exception | 125 | * This call supports re-entrancy. This way it can be called from any exception |
119 | * handler without needing to know if we came from userspace or not. | 126 | * handler without needing to know if we came from userspace or not. |
120 | */ | 127 | */ |
121 | void context_tracking_user_exit(void) | 128 | void context_tracking_exit(enum ctx_state state) |
122 | { | 129 | { |
123 | unsigned long flags; | 130 | unsigned long flags; |
124 | 131 | ||
@@ -129,7 +136,7 @@ void context_tracking_user_exit(void) | |||
129 | return; | 136 | return; |
130 | 137 | ||
131 | local_irq_save(flags); | 138 | local_irq_save(flags); |
132 | if (__this_cpu_read(context_tracking.state) == CONTEXT_USER) { | 139 | if (__this_cpu_read(context_tracking.state) == state) { |
133 | if (__this_cpu_read(context_tracking.active)) { | 140 | if (__this_cpu_read(context_tracking.active)) { |
134 | /* | 141 | /* |
135 | * We are going to run code that may use RCU. Inform | 142 | * We are going to run code that may use RCU. Inform |
@@ -143,6 +150,12 @@ void context_tracking_user_exit(void) | |||
143 | } | 150 | } |
144 | local_irq_restore(flags); | 151 | local_irq_restore(flags); |
145 | } | 152 | } |
153 | NOKPROBE_SYMBOL(context_tracking_exit); | ||
154 | |||
155 | void context_tracking_user_exit(void) | ||
156 | { | ||
157 | context_tracking_exit(CONTEXT_USER); | ||
158 | } | ||
146 | NOKPROBE_SYMBOL(context_tracking_user_exit); | 159 | NOKPROBE_SYMBOL(context_tracking_user_exit); |
147 | 160 | ||
148 | /** | 161 | /** |