Skip to content

Commit d16a8c3

Browse files
committed
tracing: Wait for preempt irq delay thread to finish
Running on a slower machine, it is possible that the preempt delay kernel thread may still be executing if the module was immediately removed after added, and this can cause the kernel to crash as the kernel thread might be executing after its code has been removed. There's no reason that the caller of the code shouldn't just wait for the delay thread to finish, as the thread can also be created by a trigger in the sysfs code, which also has the same issues. Link: http://lore.kernel.org/r/[email protected] Cc: [email protected] Fixes: 7939372 ("lib: Add module for testing preemptoff/irqsoff latency tracers") Reported-by: Xiao Yang <[email protected]> Reviewed-by: Xiao Yang <[email protected]> Reviewed-by: Joel Fernandes <[email protected]> Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent 5b4dcd2 commit d16a8c3

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

kernel/trace/preemptirq_delay_test.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,22 +113,42 @@ static int preemptirq_delay_run(void *data)
113113

114114
for (i = 0; i < s; i++)
115115
(testfuncs[i])(i);
116+
117+
set_current_state(TASK_INTERRUPTIBLE);
118+
while (!kthread_should_stop()) {
119+
schedule();
120+
set_current_state(TASK_INTERRUPTIBLE);
121+
}
122+
123+
__set_current_state(TASK_RUNNING);
124+
116125
return 0;
117126
}
118127

119-
static struct task_struct *preemptirq_start_test(void)
128+
static int preemptirq_run_test(void)
120129
{
130+
struct task_struct *task;
131+
121132
char task_name[50];
122133

123134
snprintf(task_name, sizeof(task_name), "%s_test", test_mode);
124-
return kthread_run(preemptirq_delay_run, NULL, task_name);
135+
task = kthread_run(preemptirq_delay_run, NULL, task_name);
136+
if (IS_ERR(task))
137+
return PTR_ERR(task);
138+
if (task)
139+
kthread_stop(task);
140+
return 0;
125141
}
126142

127143

128144
static ssize_t trigger_store(struct kobject *kobj, struct kobj_attribute *attr,
129145
const char *buf, size_t count)
130146
{
131-
preemptirq_start_test();
147+
ssize_t ret;
148+
149+
ret = preemptirq_run_test();
150+
if (ret)
151+
return ret;
132152
return count;
133153
}
134154

@@ -148,11 +168,9 @@ static struct kobject *preemptirq_delay_kobj;
148168

149169
static int __init preemptirq_delay_init(void)
150170
{
151-
struct task_struct *test_task;
152171
int retval;
153172

154-
test_task = preemptirq_start_test();
155-
retval = PTR_ERR_OR_ZERO(test_task);
173+
retval = preemptirq_run_test();
156174
if (retval != 0)
157175
return retval;
158176

0 commit comments

Comments
 (0)