Skip to content

Commit

Permalink
Revert "sched: Add wrapper for get_wchan() to keep task blocked"
Browse files Browse the repository at this point in the history
This reverts commit e9ede14 which is
commit 42a20f8 upstream.

It has been reported to be causing problems, and is being reworked
upstream and has been dropped from the current 5.15.y stable queue until
it gets resolved.

Reported-by: Chris Rankin <rankincj@gmail.com>
Reported-by: Thorsten Leemhuis <linux@leemhuis.info>
Link: https://lore.kernel.org/r/ed000478-2a60-0066-c337-a04bffc112b1@leemhuis.info
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Greg Kroah-Hartman committed Nov 18, 2021
1 parent b51c1a5 commit 961913f
Show file tree
Hide file tree
Showing 50 changed files with 112 additions and 80 deletions.
2 changes: 1 addition & 1 deletion arch/alpha/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
struct task_struct;
extern void release_thread(struct task_struct *);

unsigned long __get_wchan(struct task_struct *p);
unsigned long get_wchan(struct task_struct *p);

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

Expand Down
5 changes: 3 additions & 2 deletions arch/alpha/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,11 +376,12 @@ thread_saved_pc(struct task_struct *t)
}

unsigned long
__get_wchan(struct task_struct *p)
get_wchan(struct task_struct *p)
{
unsigned long schedule_frame;
unsigned long pc;

if (!p || p == current || task_is_running(p))
return 0;
/*
* This one depends on the frame size of schedule(). Do a
* "disass schedule" in gdb to find the frame size. Also, the
Expand Down
2 changes: 1 addition & 1 deletion arch/arc/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ struct task_struct;
extern void start_thread(struct pt_regs * regs, unsigned long pc,
unsigned long usp);

extern unsigned int __get_wchan(struct task_struct *p);
extern unsigned int get_wchan(struct task_struct *p);

#endif /* !__ASSEMBLY__ */

Expand Down
4 changes: 2 additions & 2 deletions arch/arc/kernel/stacktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* = specifics of data structs where trace is saved(CONFIG_STACKTRACE etc)
*
* vineetg: March 2009
* -Implemented correct versions of thread_saved_pc() and __get_wchan()
* -Implemented correct versions of thread_saved_pc() and get_wchan()
*
* rajeshwarr: 2008
* -Initial implementation
Expand Down Expand Up @@ -248,7 +248,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
* Of course just returning schedule( ) would be pointless so unwind until
* the function is not in schedular code
*/
unsigned int __get_wchan(struct task_struct *tsk)
unsigned int get_wchan(struct task_struct *tsk)
{
return arc_unwind_core(tsk, NULL, __get_first_nonsched, NULL);
}
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ struct task_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);

unsigned long __get_wchan(struct task_struct *p);
unsigned long get_wchan(struct task_struct *p);

#define task_pt_regs(p) \
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
Expand Down
4 changes: 3 additions & 1 deletion arch/arm/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,13 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
return 0;
}

unsigned long __get_wchan(struct task_struct *p)
unsigned long get_wchan(struct task_struct *p)
{
struct stackframe frame;
unsigned long stack_page;
int count = 0;
if (!p || p == current || task_is_running(p))
return 0;

frame.fp = thread_saved_fp(p);
frame.sp = thread_saved_sp(p);
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ struct task_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);

unsigned long __get_wchan(struct task_struct *p);
unsigned long get_wchan(struct task_struct *p);

void set_task_sctlr_el1(u64 sctlr);

Expand Down
4 changes: 3 additions & 1 deletion arch/arm64/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,11 +544,13 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
return last;
}

unsigned long __get_wchan(struct task_struct *p)
unsigned long get_wchan(struct task_struct *p)
{
struct stackframe frame;
unsigned long stack_page, ret = 0;
int count = 0;
if (!p || p == current || task_is_running(p))
return 0;

stack_page = (unsigned long)try_get_task_stack(p);
if (!stack_page)
Expand Down
2 changes: 1 addition & 1 deletion arch/csky/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ static inline void release_thread(struct task_struct *dead_task)

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

unsigned long __get_wchan(struct task_struct *p);
unsigned long get_wchan(struct task_struct *p);

#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->usp)
Expand Down
5 changes: 3 additions & 2 deletions arch/csky/kernel/stacktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,12 @@ static bool save_wchan(unsigned long pc, void *arg)
return false;
}

unsigned long __get_wchan(struct task_struct *task)
unsigned long get_wchan(struct task_struct *task)
{
unsigned long pc = 0;

walk_stackframe(task, NULL, save_wchan, &pc);
if (likely(task && task != current && !task_is_running(task)))
walk_stackframe(task, NULL, save_wchan, &pc);
return pc;
}

Expand Down
2 changes: 1 addition & 1 deletion arch/h8300/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ static inline void release_thread(struct task_struct *dead_task)
{
}

unsigned long __get_wchan(struct task_struct *p);
unsigned long get_wchan(struct task_struct *p);

#define KSTK_EIP(tsk) \
({ \
Expand Down
5 changes: 4 additions & 1 deletion arch/h8300/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,15 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
return 0;
}

unsigned long __get_wchan(struct task_struct *p)
unsigned long get_wchan(struct task_struct *p)
{
unsigned long fp, pc;
unsigned long stack_page;
int count = 0;

if (!p || p == current || task_is_running(p))
return 0;

stack_page = (unsigned long)p;
fp = ((struct pt_regs *)p->thread.ksp)->er6;
do {
Expand Down
2 changes: 1 addition & 1 deletion arch/hexagon/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct thread_struct {
extern void release_thread(struct task_struct *dead_task);

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

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

Expand Down
4 changes: 3 additions & 1 deletion arch/hexagon/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,13 @@ void flush_thread(void)
* is an identification of the point at which the scheduler
* was invoked by a blocked thread.
*/
unsigned long __get_wchan(struct task_struct *p)
unsigned long get_wchan(struct task_struct *p)
{
unsigned long fp, pc;
unsigned long stack_page;
int count = 0;
if (!p || p == current || task_is_running(p))
return 0;

stack_page = (unsigned long)task_stack_page(p);
fp = ((struct hexagon_switch_stack *)p->thread.switch_sp)->fp;
Expand Down
2 changes: 1 addition & 1 deletion arch/ia64/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ struct task_struct;
#define release_thread(dead_task)

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

/* Return instruction pointer of blocked task TSK. */
#define KSTK_EIP(tsk) \
Expand Down
5 changes: 4 additions & 1 deletion arch/ia64/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,12 +523,15 @@ exit_thread (struct task_struct *tsk)
}

unsigned long
__get_wchan (struct task_struct *p)
get_wchan (struct task_struct *p)
{
struct unw_frame_info info;
unsigned long ip;
int count = 0;

if (!p || p == current || task_is_running(p))
return 0;

/*
* Note: p may not be a blocked task (it could be current or
* another process running on some other CPU. Rather than
Expand Down
2 changes: 1 addition & 1 deletion arch/m68k/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ static inline void release_thread(struct task_struct *dead_task)
{
}

unsigned long __get_wchan(struct task_struct *p);
unsigned long get_wchan(struct task_struct *p);

#define KSTK_EIP(tsk) \
({ \
Expand Down
4 changes: 3 additions & 1 deletion arch/m68k/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,11 +263,13 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
}
EXPORT_SYMBOL(dump_fpu);

unsigned long __get_wchan(struct task_struct *p)
unsigned long get_wchan(struct task_struct *p)
{
unsigned long fp, pc;
unsigned long stack_page;
int count = 0;
if (!p || p == current || task_is_running(p))
return 0;

stack_page = (unsigned long)task_stack_page(p);
fp = ((struct switch_stack *)p->thread.ksp)->a6;
Expand Down
2 changes: 1 addition & 1 deletion arch/microblaze/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static inline void release_thread(struct task_struct *dead_task)
{
}

unsigned long __get_wchan(struct task_struct *p);
unsigned long get_wchan(struct task_struct *p);

/* The size allocated for kernel stacks. This _must_ be a power of two! */
# define KERNEL_STACK_SIZE 0x2000
Expand Down
2 changes: 1 addition & 1 deletion arch/microblaze/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
return 0;
}

unsigned long __get_wchan(struct task_struct *p)
unsigned long get_wchan(struct task_struct *p)
{
/* TBD (used by procfs) */
return 0;
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ static inline void flush_thread(void)
{
}

unsigned long __get_wchan(struct task_struct *p);
unsigned long get_wchan(struct task_struct *p);

#define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \
THREAD_SIZE - 32 - sizeof(struct pt_regs))
Expand Down
8 changes: 5 additions & 3 deletions arch/mips/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ static int __init frame_info_init(void)

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

/*
* __get_wchan - a maintenance nightmare^W^Wpain in the ass ...
* get_wchan - a maintenance nightmare^W^Wpain in the ass ...
*/
unsigned long __get_wchan(struct task_struct *task)
unsigned long get_wchan(struct task_struct *task)
{
unsigned long pc = 0;
#ifdef CONFIG_KALLSYMS
unsigned long sp;
unsigned long ra = 0;
#endif

if (!task || task == current || task_is_running(task))
goto out;
if (!task_stack_page(task))
goto out;

Expand Down
2 changes: 1 addition & 1 deletion arch/nds32/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ extern struct task_struct *last_task_used_math;
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)

unsigned long __get_wchan(struct task_struct *p);
unsigned long get_wchan(struct task_struct *p);

#define cpu_relax() barrier()

Expand Down
7 changes: 6 additions & 1 deletion arch/nds32/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,12 +233,15 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpu)

EXPORT_SYMBOL(dump_fpu);

unsigned long __get_wchan(struct task_struct *p)
unsigned long get_wchan(struct task_struct *p)
{
unsigned long fp, lr;
unsigned long stack_start, stack_end;
int count = 0;

if (!p || p == current || task_is_running(p))
return 0;

if (IS_ENABLED(CONFIG_FRAME_POINTER)) {
stack_start = (unsigned long)end_of_stack(p);
stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE;
Expand All @@ -255,3 +258,5 @@ unsigned long __get_wchan(struct task_struct *p)
}
return 0;
}

EXPORT_SYMBOL(get_wchan);
2 changes: 1 addition & 1 deletion arch/nios2/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ static inline void release_thread(struct task_struct *dead_task)
{
}

extern unsigned long __get_wchan(struct task_struct *p);
extern unsigned long get_wchan(struct task_struct *p);

#define task_pt_regs(p) \
((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1)
Expand Down
5 changes: 4 additions & 1 deletion arch/nios2/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,15 @@ void dump(struct pt_regs *fp)
pr_emerg("\n\n");
}

unsigned long __get_wchan(struct task_struct *p)
unsigned long get_wchan(struct task_struct *p)
{
unsigned long fp, pc;
unsigned long stack_page;
int count = 0;

if (!p || p == current || task_is_running(p))
return 0;

stack_page = (unsigned long)p;
fp = ((struct switch_stack *)p->thread.ksp)->fp; /* ;dgt2 */
do {
Expand Down
2 changes: 1 addition & 1 deletion arch/openrisc/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ struct thread_struct {

void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp);
void release_thread(struct task_struct *);
unsigned long __get_wchan(struct task_struct *p);
unsigned long get_wchan(struct task_struct *p);

#define cpu_relax() barrier()

Expand Down
2 changes: 1 addition & 1 deletion arch/openrisc/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ void dump_elf_thread(elf_greg_t *dest, struct pt_regs* regs)
dest[35] = 0;
}

unsigned long __get_wchan(struct task_struct *p)
unsigned long get_wchan(struct task_struct *p)
{
/* TODO */

Expand Down
2 changes: 1 addition & 1 deletion arch/parisc/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ struct mm_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);

extern unsigned long __get_wchan(struct task_struct *p);
extern unsigned long get_wchan(struct task_struct *p);

#define KSTK_EIP(tsk) ((tsk)->thread.regs.iaoq[0])
#define KSTK_ESP(tsk) ((tsk)->thread.regs.gr[30])
Expand Down
5 changes: 4 additions & 1 deletion arch/parisc/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,15 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
}

unsigned long
__get_wchan(struct task_struct *p)
get_wchan(struct task_struct *p)
{
struct unwind_frame_info info;
unsigned long ip;
int count = 0;

if (!p || p == current || task_is_running(p))
return 0;

/*
* These bracket the sleeping functions..
*/
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ struct thread_struct {

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

unsigned long __get_wchan(struct task_struct *p);
unsigned long get_wchan(struct task_struct *p);

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

0 comments on commit 961913f

Please sign in to comment.