Skip to content

Commit 42a20f8

Browse files
keesPeter Zijlstra
authored and
Peter Zijlstra
committed
sched: Add wrapper for get_wchan() to keep task blocked
Having a stable wchan means the process must be blocked and for it to stay that way while performing stack unwinding. Suggested-by: Peter Zijlstra <[email protected]> Signed-off-by: Kees Cook <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Acked-by: Geert Uytterhoeven <[email protected]> Acked-by: Russell King (Oracle) <[email protected]> [arm] Tested-by: Mark Rutland <[email protected]> [arm64] Link: https://lkml.kernel.org/r/[email protected]
1 parent bc9bbb8 commit 42a20f8

File tree

50 files changed

+80
-112
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+80
-112
lines changed

arch/alpha/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
4242
struct task_struct;
4343
extern void release_thread(struct task_struct *);
4444

45-
unsigned long get_wchan(struct task_struct *p);
45+
unsigned long __get_wchan(struct task_struct *p);
4646

4747
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
4848

arch/alpha/kernel/process.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,12 +376,11 @@ thread_saved_pc(struct task_struct *t)
376376
}
377377

378378
unsigned long
379-
get_wchan(struct task_struct *p)
379+
__get_wchan(struct task_struct *p)
380380
{
381381
unsigned long schedule_frame;
382382
unsigned long pc;
383-
if (!p || p == current || task_is_running(p))
384-
return 0;
383+
385384
/*
386385
* This one depends on the frame size of schedule(). Do a
387386
* "disass schedule" in gdb to find the frame size. Also, the

arch/arc/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ struct task_struct;
7070
extern void start_thread(struct pt_regs * regs, unsigned long pc,
7171
unsigned long usp);
7272

73-
extern unsigned int get_wchan(struct task_struct *p);
73+
extern unsigned int __get_wchan(struct task_struct *p);
7474

7575
#endif /* !__ASSEMBLY__ */
7676

arch/arc/kernel/stacktrace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* = specifics of data structs where trace is saved(CONFIG_STACKTRACE etc)
1616
*
1717
* vineetg: March 2009
18-
* -Implemented correct versions of thread_saved_pc() and get_wchan()
18+
* -Implemented correct versions of thread_saved_pc() and __get_wchan()
1919
*
2020
* rajeshwarr: 2008
2121
* -Initial implementation
@@ -248,7 +248,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
248248
* Of course just returning schedule( ) would be pointless so unwind until
249249
* the function is not in schedular code
250250
*/
251-
unsigned int get_wchan(struct task_struct *tsk)
251+
unsigned int __get_wchan(struct task_struct *tsk)
252252
{
253253
return arc_unwind_core(tsk, NULL, __get_first_nonsched, NULL);
254254
}

arch/arm/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ struct task_struct;
8484
/* Free all resources held by a thread. */
8585
extern void release_thread(struct task_struct *);
8686

87-
unsigned long get_wchan(struct task_struct *p);
87+
unsigned long __get_wchan(struct task_struct *p);
8888

8989
#define task_pt_regs(p) \
9090
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)

arch/arm/kernel/process.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,11 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
276276
return 0;
277277
}
278278

279-
unsigned long get_wchan(struct task_struct *p)
279+
unsigned long __get_wchan(struct task_struct *p)
280280
{
281281
struct stackframe frame;
282282
unsigned long stack_page;
283283
int count = 0;
284-
if (!p || p == current || task_is_running(p))
285-
return 0;
286284

287285
frame.fp = thread_saved_fp(p);
288286
frame.sp = thread_saved_sp(p);

arch/arm64/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ struct task_struct;
257257
/* Free all resources held by a thread. */
258258
extern void release_thread(struct task_struct *);
259259

260-
unsigned long get_wchan(struct task_struct *p);
260+
unsigned long __get_wchan(struct task_struct *p);
261261

262262
void update_sctlr_el1(u64 sctlr);
263263

arch/arm64/kernel/process.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -528,13 +528,11 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
528528
return last;
529529
}
530530

531-
unsigned long get_wchan(struct task_struct *p)
531+
unsigned long __get_wchan(struct task_struct *p)
532532
{
533533
struct stackframe frame;
534534
unsigned long stack_page, ret = 0;
535535
int count = 0;
536-
if (!p || p == current || task_is_running(p))
537-
return 0;
538536

539537
stack_page = (unsigned long)try_get_task_stack(p);
540538
if (!stack_page)

arch/csky/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ static inline void release_thread(struct task_struct *dead_task)
8181

8282
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
8383

84-
unsigned long get_wchan(struct task_struct *p);
84+
unsigned long __get_wchan(struct task_struct *p);
8585

8686
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
8787
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->usp)

arch/csky/kernel/stacktrace.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,11 @@ static bool save_wchan(unsigned long pc, void *arg)
111111
return false;
112112
}
113113

114-
unsigned long get_wchan(struct task_struct *task)
114+
unsigned long __get_wchan(struct task_struct *task)
115115
{
116116
unsigned long pc = 0;
117117

118-
if (likely(task && task != current && !task_is_running(task)))
119-
walk_stackframe(task, NULL, save_wchan, &pc);
118+
walk_stackframe(task, NULL, save_wchan, &pc);
120119
return pc;
121120
}
122121

arch/h8300/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static inline void release_thread(struct task_struct *dead_task)
105105
{
106106
}
107107

108-
unsigned long get_wchan(struct task_struct *p);
108+
unsigned long __get_wchan(struct task_struct *p);
109109

110110
#define KSTK_EIP(tsk) \
111111
({ \

arch/h8300/kernel/process.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,12 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
128128
return 0;
129129
}
130130

131-
unsigned long get_wchan(struct task_struct *p)
131+
unsigned long __get_wchan(struct task_struct *p)
132132
{
133133
unsigned long fp, pc;
134134
unsigned long stack_page;
135135
int count = 0;
136136

137-
if (!p || p == current || task_is_running(p))
138-
return 0;
139-
140137
stack_page = (unsigned long)p;
141138
fp = ((struct pt_regs *)p->thread.ksp)->er6;
142139
do {

arch/hexagon/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct thread_struct {
6464
extern void release_thread(struct task_struct *dead_task);
6565

6666
/* Get wait channel for task P. */
67-
extern unsigned long get_wchan(struct task_struct *p);
67+
extern unsigned long __get_wchan(struct task_struct *p);
6868

6969
/* The following stuff is pretty HEXAGON specific. */
7070

arch/hexagon/kernel/process.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,11 @@ void flush_thread(void)
130130
* is an identification of the point at which the scheduler
131131
* was invoked by a blocked thread.
132132
*/
133-
unsigned long get_wchan(struct task_struct *p)
133+
unsigned long __get_wchan(struct task_struct *p)
134134
{
135135
unsigned long fp, pc;
136136
unsigned long stack_page;
137137
int count = 0;
138-
if (!p || p == current || task_is_running(p))
139-
return 0;
140138

141139
stack_page = (unsigned long)task_stack_page(p);
142140
fp = ((struct hexagon_switch_stack *)p->thread.switch_sp)->fp;

arch/ia64/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ struct task_struct;
330330
#define release_thread(dead_task)
331331

332332
/* Get wait channel for task P. */
333-
extern unsigned long get_wchan (struct task_struct *p);
333+
extern unsigned long __get_wchan (struct task_struct *p);
334334

335335
/* Return instruction pointer of blocked task TSK. */
336336
#define KSTK_EIP(tsk) \

arch/ia64/kernel/process.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -523,15 +523,12 @@ exit_thread (struct task_struct *tsk)
523523
}
524524

525525
unsigned long
526-
get_wchan (struct task_struct *p)
526+
__get_wchan (struct task_struct *p)
527527
{
528528
struct unw_frame_info info;
529529
unsigned long ip;
530530
int count = 0;
531531

532-
if (!p || p == current || task_is_running(p))
533-
return 0;
534-
535532
/*
536533
* Note: p may not be a blocked task (it could be current or
537534
* another process running on some other CPU. Rather than

arch/m68k/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ static inline void release_thread(struct task_struct *dead_task)
150150
{
151151
}
152152

153-
unsigned long get_wchan(struct task_struct *p);
153+
unsigned long __get_wchan(struct task_struct *p);
154154

155155
#define KSTK_EIP(tsk) \
156156
({ \

arch/m68k/kernel/process.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,13 +263,11 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
263263
}
264264
EXPORT_SYMBOL(dump_fpu);
265265

266-
unsigned long get_wchan(struct task_struct *p)
266+
unsigned long __get_wchan(struct task_struct *p)
267267
{
268268
unsigned long fp, pc;
269269
unsigned long stack_page;
270270
int count = 0;
271-
if (!p || p == current || task_is_running(p))
272-
return 0;
273271

274272
stack_page = (unsigned long)task_stack_page(p);
275273
fp = ((struct switch_stack *)p->thread.ksp)->a6;

arch/microblaze/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static inline void release_thread(struct task_struct *dead_task)
6868
{
6969
}
7070

71-
unsigned long get_wchan(struct task_struct *p);
71+
unsigned long __get_wchan(struct task_struct *p);
7272

7373
/* The size allocated for kernel stacks. This _must_ be a power of two! */
7474
# define KERNEL_STACK_SIZE 0x2000

arch/microblaze/kernel/process.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
112112
return 0;
113113
}
114114

115-
unsigned long get_wchan(struct task_struct *p)
115+
unsigned long __get_wchan(struct task_struct *p)
116116
{
117117
/* TBD (used by procfs) */
118118
return 0;

arch/mips/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ static inline void flush_thread(void)
369369
{
370370
}
371371

372-
unsigned long get_wchan(struct task_struct *p);
372+
unsigned long __get_wchan(struct task_struct *p);
373373

374374
#define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \
375375
THREAD_SIZE - 32 - sizeof(struct pt_regs))

arch/mips/kernel/process.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ static int __init frame_info_init(void)
511511

512512
/*
513513
* Without schedule() frame info, result given by
514-
* thread_saved_pc() and get_wchan() are not reliable.
514+
* thread_saved_pc() and __get_wchan() are not reliable.
515515
*/
516516
if (schedule_mfi.pc_offset < 0)
517517
printk("Can't analyze schedule() prologue at %p\n", schedule);
@@ -652,18 +652,16 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
652652
#endif
653653

654654
/*
655-
* get_wchan - a maintenance nightmare^W^Wpain in the ass ...
655+
* __get_wchan - a maintenance nightmare^W^Wpain in the ass ...
656656
*/
657-
unsigned long get_wchan(struct task_struct *task)
657+
unsigned long __get_wchan(struct task_struct *task)
658658
{
659659
unsigned long pc = 0;
660660
#ifdef CONFIG_KALLSYMS
661661
unsigned long sp;
662662
unsigned long ra = 0;
663663
#endif
664664

665-
if (!task || task == current || task_is_running(task))
666-
goto out;
667665
if (!task_stack_page(task))
668666
goto out;
669667

arch/nds32/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ extern struct task_struct *last_task_used_math;
8383
/* Prepare to copy thread state - unlazy all lazy status */
8484
#define prepare_to_copy(tsk) do { } while (0)
8585

86-
unsigned long get_wchan(struct task_struct *p);
86+
unsigned long __get_wchan(struct task_struct *p);
8787

8888
#define cpu_relax() barrier()
8989

arch/nds32/kernel/process.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,12 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpu)
233233

234234
EXPORT_SYMBOL(dump_fpu);
235235

236-
unsigned long get_wchan(struct task_struct *p)
236+
unsigned long __get_wchan(struct task_struct *p)
237237
{
238238
unsigned long fp, lr;
239239
unsigned long stack_start, stack_end;
240240
int count = 0;
241241

242-
if (!p || p == current || task_is_running(p))
243-
return 0;
244-
245242
if (IS_ENABLED(CONFIG_FRAME_POINTER)) {
246243
stack_start = (unsigned long)end_of_stack(p);
247244
stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE;
@@ -258,5 +255,3 @@ unsigned long get_wchan(struct task_struct *p)
258255
}
259256
return 0;
260257
}
261-
262-
EXPORT_SYMBOL(get_wchan);

arch/nios2/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static inline void release_thread(struct task_struct *dead_task)
6969
{
7070
}
7171

72-
extern unsigned long get_wchan(struct task_struct *p);
72+
extern unsigned long __get_wchan(struct task_struct *p);
7373

7474
#define task_pt_regs(p) \
7575
((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1)

arch/nios2/kernel/process.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,12 @@ void dump(struct pt_regs *fp)
217217
pr_emerg("\n\n");
218218
}
219219

220-
unsigned long get_wchan(struct task_struct *p)
220+
unsigned long __get_wchan(struct task_struct *p)
221221
{
222222
unsigned long fp, pc;
223223
unsigned long stack_page;
224224
int count = 0;
225225

226-
if (!p || p == current || task_is_running(p))
227-
return 0;
228-
229226
stack_page = (unsigned long)p;
230227
fp = ((struct switch_stack *)p->thread.ksp)->fp; /* ;dgt2 */
231228
do {

arch/openrisc/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ struct thread_struct {
7373

7474
void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp);
7575
void release_thread(struct task_struct *);
76-
unsigned long get_wchan(struct task_struct *p);
76+
unsigned long __get_wchan(struct task_struct *p);
7777

7878
#define cpu_relax() barrier()
7979

arch/openrisc/kernel/process.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ void dump_elf_thread(elf_greg_t *dest, struct pt_regs* regs)
263263
dest[35] = 0;
264264
}
265265

266-
unsigned long get_wchan(struct task_struct *p)
266+
unsigned long __get_wchan(struct task_struct *p)
267267
{
268268
/* TODO */
269269

arch/parisc/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ struct mm_struct;
273273
/* Free all resources held by a thread. */
274274
extern void release_thread(struct task_struct *);
275275

276-
extern unsigned long get_wchan(struct task_struct *p);
276+
extern unsigned long __get_wchan(struct task_struct *p);
277277

278278
#define KSTK_EIP(tsk) ((tsk)->thread.regs.iaoq[0])
279279
#define KSTK_ESP(tsk) ((tsk)->thread.regs.gr[30])

arch/parisc/kernel/process.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,15 +240,12 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
240240
}
241241

242242
unsigned long
243-
get_wchan(struct task_struct *p)
243+
__get_wchan(struct task_struct *p)
244244
{
245245
struct unwind_frame_info info;
246246
unsigned long ip;
247247
int count = 0;
248248

249-
if (!p || p == current || task_is_running(p))
250-
return 0;
251-
252249
/*
253250
* These bracket the sleeping functions..
254251
*/

arch/powerpc/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ struct thread_struct {
300300

301301
#define task_pt_regs(tsk) ((tsk)->thread.regs)
302302

303-
unsigned long get_wchan(struct task_struct *p);
303+
unsigned long __get_wchan(struct task_struct *p);
304304

305305
#define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
306306
#define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)

0 commit comments

Comments
 (0)