aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2016-08-12 13:49:39 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-09-02 14:05:05 -0400
commitcf392d10b69e6e6c57ceea48b347a2ab1a4b75b2 (patch)
tree45d917264300caaab4eede4ab32b10f75bd8e4c2 /include/linux
parenta724632ca0c84b494875e9367e07e29472c139ba (diff)
cpu/hotplug: Add multi instance support
This patch adds the ability for a given state to have multiple instances. Until now all states have a single instance and the startup / teardown callback use global variables. A few drivers need to perform a the same callbacks on multiple "instances". Currently we have three drivers in tree which all have a global list which they iterate over. With multi instance they support don't need their private list and the functionality has been moved into core code. Plus we hold the hotplug lock in core so no cpus comes/goes while instances are registered and we do rollback in error case :) Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Will Deacon <will.deacon@arm.com> Cc: rt@linutronix.de Link: http://lkml.kernel.org/r/1471024183-12666-3-git-send-email-bigeasy@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/cpuhotplug.h110
1 files changed, 107 insertions, 3 deletions
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 242bf530edfc..dcfe619171b4 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -99,7 +99,7 @@ enum cpuhp_state {
99 99
100int __cpuhp_setup_state(enum cpuhp_state state, const char *name, bool invoke, 100int __cpuhp_setup_state(enum cpuhp_state state, const char *name, bool invoke,
101 int (*startup)(unsigned int cpu), 101 int (*startup)(unsigned int cpu),
102 int (*teardown)(unsigned int cpu)); 102 int (*teardown)(unsigned int cpu), bool multi_instance);
103 103
104/** 104/**
105 * cpuhp_setup_state - Setup hotplug state callbacks with calling the callbacks 105 * cpuhp_setup_state - Setup hotplug state callbacks with calling the callbacks
@@ -116,7 +116,7 @@ static inline int cpuhp_setup_state(enum cpuhp_state state,
116 int (*startup)(unsigned int cpu), 116 int (*startup)(unsigned int cpu),
117 int (*teardown)(unsigned int cpu)) 117 int (*teardown)(unsigned int cpu))
118{ 118{
119 return __cpuhp_setup_state(state, name, true, startup, teardown); 119 return __cpuhp_setup_state(state, name, true, startup, teardown, false);
120} 120}
121 121
122/** 122/**
@@ -135,7 +135,66 @@ static inline int cpuhp_setup_state_nocalls(enum cpuhp_state state,
135 int (*startup)(unsigned int cpu), 135 int (*startup)(unsigned int cpu),
136 int (*teardown)(unsigned int cpu)) 136 int (*teardown)(unsigned int cpu))
137{ 137{
138 return __cpuhp_setup_state(state, name, false, startup, teardown); 138 return __cpuhp_setup_state(state, name, false, startup, teardown,
139 false);
140}
141
142/**
143 * cpuhp_setup_state_multi - Add callbacks for multi state
144 * @state: The state for which the calls are installed
145 * @name: Name of the callback.
146 * @startup: startup callback function
147 * @teardown: teardown callback function
148 *
149 * Sets the internal multi_instance flag and prepares a state to work as a multi
150 * instance callback. No callbacks are invoked at this point. The callbacks are
151 * invoked once an instance for this state are registered via
152 * @cpuhp_state_add_instance or @cpuhp_state_add_instance_nocalls.
153 */
154static inline int cpuhp_setup_state_multi(enum cpuhp_state state,
155 const char *name,
156 int (*startup)(unsigned int cpu,
157 struct hlist_node *node),
158 int (*teardown)(unsigned int cpu,
159 struct hlist_node *node))
160{
161 return __cpuhp_setup_state(state, name, false,
162 (void *) startup,
163 (void *) teardown, true);
164}
165
166int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node,
167 bool invoke);
168
169/**
170 * cpuhp_state_add_instance - Add an instance for a state and invoke startup
171 * callback.
172 * @state: The state for which the instance is installed
173 * @node: The node for this individual state.
174 *
175 * Installs the instance for the @state and invokes the startup callback on
176 * the present cpus which have already reached the @state. The @state must have
177 * been earlier marked as multi-instance by @cpuhp_setup_state_multi.
178 */
179static inline int cpuhp_state_add_instance(enum cpuhp_state state,
180 struct hlist_node *node)
181{
182 return __cpuhp_state_add_instance(state, node, true);
183}
184
185/**
186 * cpuhp_state_add_instance_nocalls - Add an instance for a state without
187 * invoking the startup callback.
188 * @state: The state for which the instance is installed
189 * @node: The node for this individual state.
190 *
191 * Installs the instance for the @state The @state must have been earlier
192 * marked as multi-instance by @cpuhp_setup_state_multi.
193 */
194static inline int cpuhp_state_add_instance_nocalls(enum cpuhp_state state,
195 struct hlist_node *node)
196{
197 return __cpuhp_state_add_instance(state, node, false);
139} 198}
140 199
141void __cpuhp_remove_state(enum cpuhp_state state, bool invoke); 200void __cpuhp_remove_state(enum cpuhp_state state, bool invoke);
@@ -162,6 +221,51 @@ static inline void cpuhp_remove_state_nocalls(enum cpuhp_state state)
162 __cpuhp_remove_state(state, false); 221 __cpuhp_remove_state(state, false);
163} 222}
164 223
224/**
225 * cpuhp_remove_multi_state - Remove hotplug multi state callback
226 * @state: The state for which the calls are removed
227 *
228 * Removes the callback functions from a multi state. This is the reverse of
229 * cpuhp_setup_state_multi(). All instances should have been removed before
230 * invoking this function.
231 */
232static inline void cpuhp_remove_multi_state(enum cpuhp_state state)
233{
234 __cpuhp_remove_state(state, false);
235}
236
237int __cpuhp_state_remove_instance(enum cpuhp_state state,
238 struct hlist_node *node, bool invoke);
239
240/**
241 * cpuhp_state_remove_instance - Remove hotplug instance from state and invoke
242 * the teardown callback
243 * @state: The state from which the instance is removed
244 * @node: The node for this individual state.
245 *
246 * Removes the instance and invokes the teardown callback on the present cpus
247 * which have already reached the @state.
248 */
249static inline int cpuhp_state_remove_instance(enum cpuhp_state state,
250 struct hlist_node *node)
251{
252 return __cpuhp_state_remove_instance(state, node, true);
253}
254
255/**
256 * cpuhp_state_remove_instance_nocalls - Remove hotplug instance from state
257 * without invoking the reatdown callback
258 * @state: The state from which the instance is removed
259 * @node: The node for this individual state.
260 *
261 * Removes the instance without invoking the teardown callback.
262 */
263static inline int cpuhp_state_remove_instance_nocalls(enum cpuhp_state state,
264 struct hlist_node *node)
265{
266 return __cpuhp_state_remove_instance(state, node, false);
267}
268
165#ifdef CONFIG_SMP 269#ifdef CONFIG_SMP
166void cpuhp_online_idle(enum cpuhp_state state); 270void cpuhp_online_idle(enum cpuhp_state state);
167#else 271#else