Skip to content

Commit 1db4948

Browse files
Peter ZijlstraKAGA-KOKO
Peter Zijlstra
authored andcommitted
smp/hotplug: Hotplug state fail injection
Add a sysfs file to one-time fail a specific state. This can be used to test the state rollback code paths. Something like this (hotplug-up.sh): #!/bin/bash echo 0 > /debug/sched_debug echo 1 > /debug/tracing/events/cpuhp/enable ALL_STATES=`cat /sys/devices/system/cpu/hotplug/states | cut -d':' -f1` STATES=${1:-$ALL_STATES} for state in $STATES do echo 0 > /sys/devices/system/cpu/cpu1/online echo 0 > /debug/tracing/trace echo Fail state: $state echo $state > /sys/devices/system/cpu/cpu1/hotplug/fail cat /sys/devices/system/cpu/cpu1/hotplug/fail echo 1 > /sys/devices/system/cpu/cpu1/online cat /debug/tracing/trace > hotfail-${state}.trace sleep 1 done Can be used to test for all possible rollback (barring multi-instance) scenarios on CPU-up, CPU-down is a trivial modification of the above. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent 5ebe774 commit 1db4948

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

include/linux/cpuhotplug.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
*/
2323

2424
enum cpuhp_state {
25-
CPUHP_OFFLINE,
25+
CPUHP_INVALID = -1,
26+
CPUHP_OFFLINE = 0,
2627
CPUHP_CREATE_THREADS,
2728
CPUHP_PERF_PREPARE,
2829
CPUHP_PERF_X86_PREPARE,

kernel/cpu.c

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
struct cpuhp_cpu_state {
5353
enum cpuhp_state state;
5454
enum cpuhp_state target;
55+
enum cpuhp_state fail;
5556
#ifdef CONFIG_SMP
5657
struct task_struct *thread;
5758
bool should_run;
@@ -67,7 +68,9 @@ struct cpuhp_cpu_state {
6768
#endif
6869
};
6970

70-
static DEFINE_PER_CPU(struct cpuhp_cpu_state, cpuhp_state);
71+
static DEFINE_PER_CPU(struct cpuhp_cpu_state, cpuhp_state) = {
72+
.fail = CPUHP_INVALID,
73+
};
7174

7275
#if defined(CONFIG_LOCKDEP) && defined(CONFIG_SMP)
7376
static struct lockdep_map cpuhp_state_up_map =
@@ -160,6 +163,15 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
160163
int (*cb)(unsigned int cpu);
161164
int ret, cnt;
162165

166+
if (st->fail == state) {
167+
st->fail = CPUHP_INVALID;
168+
169+
if (!(bringup ? step->startup.single : step->teardown.single))
170+
return 0;
171+
172+
return -EAGAIN;
173+
}
174+
163175
if (!step->multi_instance) {
164176
WARN_ON_ONCE(lastp && *lastp);
165177
cb = bringup ? step->startup.single : step->teardown.single;
@@ -1805,9 +1817,55 @@ static ssize_t show_cpuhp_target(struct device *dev,
18051817
}
18061818
static DEVICE_ATTR(target, 0644, show_cpuhp_target, write_cpuhp_target);
18071819

1820+
1821+
static ssize_t write_cpuhp_fail(struct device *dev,
1822+
struct device_attribute *attr,
1823+
const char *buf, size_t count)
1824+
{
1825+
struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
1826+
struct cpuhp_step *sp;
1827+
int fail, ret;
1828+
1829+
ret = kstrtoint(buf, 10, &fail);
1830+
if (ret)
1831+
return ret;
1832+
1833+
/*
1834+
* Cannot fail STARTING/DYING callbacks.
1835+
*/
1836+
if (cpuhp_is_atomic_state(fail))
1837+
return -EINVAL;
1838+
1839+
/*
1840+
* Cannot fail anything that doesn't have callbacks.
1841+
*/
1842+
mutex_lock(&cpuhp_state_mutex);
1843+
sp = cpuhp_get_step(fail);
1844+
if (!sp->startup.single && !sp->teardown.single)
1845+
ret = -EINVAL;
1846+
mutex_unlock(&cpuhp_state_mutex);
1847+
if (ret)
1848+
return ret;
1849+
1850+
st->fail = fail;
1851+
1852+
return count;
1853+
}
1854+
1855+
static ssize_t show_cpuhp_fail(struct device *dev,
1856+
struct device_attribute *attr, char *buf)
1857+
{
1858+
struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
1859+
1860+
return sprintf(buf, "%d\n", st->fail);
1861+
}
1862+
1863+
static DEVICE_ATTR(fail, 0644, show_cpuhp_fail, write_cpuhp_fail);
1864+
18081865
static struct attribute *cpuhp_cpu_attrs[] = {
18091866
&dev_attr_state.attr,
18101867
&dev_attr_target.attr,
1868+
&dev_attr_fail.attr,
18111869
NULL
18121870
};
18131871

0 commit comments

Comments
 (0)