Skip to content

Commit cf392d1

Browse files
committed
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>
1 parent a724632 commit cf392d1

File tree

3 files changed

+318
-38
lines changed

3 files changed

+318
-38
lines changed

include/linux/cpuhotplug.h

Lines changed: 107 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ enum cpuhp_state {
9999

100100
int __cpuhp_setup_state(enum cpuhp_state state, const char *name, bool invoke,
101101
int (*startup)(unsigned int cpu),
102-
int (*teardown)(unsigned int cpu));
102+
int (*teardown)(unsigned int cpu), bool multi_instance);
103103

104104
/**
105105
* 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,
116116
int (*startup)(unsigned int cpu),
117117
int (*teardown)(unsigned int cpu))
118118
{
119-
return __cpuhp_setup_state(state, name, true, startup, teardown);
119+
return __cpuhp_setup_state(state, name, true, startup, teardown, false);
120120
}
121121

122122
/**
@@ -135,7 +135,66 @@ static inline int cpuhp_setup_state_nocalls(enum cpuhp_state state,
135135
int (*startup)(unsigned int cpu),
136136
int (*teardown)(unsigned int cpu))
137137
{
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+
*/
154+
static 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+
166+
int __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+
*/
179+
static 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+
*/
194+
static 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);
139198
}
140199

141200
void __cpuhp_remove_state(enum cpuhp_state state, bool invoke);
@@ -162,6 +221,51 @@ static inline void cpuhp_remove_state_nocalls(enum cpuhp_state state)
162221
__cpuhp_remove_state(state, false);
163222
}
164223

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+
*/
232+
static inline void cpuhp_remove_multi_state(enum cpuhp_state state)
233+
{
234+
__cpuhp_remove_state(state, false);
235+
}
236+
237+
int __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+
*/
249+
static 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+
*/
263+
static 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+
165269
#ifdef CONFIG_SMP
166270
void cpuhp_online_idle(enum cpuhp_state state);
167271
#else

include/trace/events/cpuhp.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,34 @@ TRACE_EVENT(cpuhp_enter,
3333
__entry->cpu, __entry->target, __entry->idx, __entry->fun)
3434
);
3535

36+
TRACE_EVENT(cpuhp_multi_enter,
37+
38+
TP_PROTO(unsigned int cpu,
39+
int target,
40+
int idx,
41+
int (*fun)(unsigned int, struct hlist_node *),
42+
struct hlist_node *node),
43+
44+
TP_ARGS(cpu, target, idx, fun, node),
45+
46+
TP_STRUCT__entry(
47+
__field( unsigned int, cpu )
48+
__field( int, target )
49+
__field( int, idx )
50+
__field( void *, fun )
51+
),
52+
53+
TP_fast_assign(
54+
__entry->cpu = cpu;
55+
__entry->target = target;
56+
__entry->idx = idx;
57+
__entry->fun = fun;
58+
),
59+
60+
TP_printk("cpu: %04u target: %3d step: %3d (%pf)",
61+
__entry->cpu, __entry->target, __entry->idx, __entry->fun)
62+
);
63+
3664
TRACE_EVENT(cpuhp_exit,
3765

3866
TP_PROTO(unsigned int cpu,

0 commit comments

Comments
 (0)