[RFC PATCH 15/16] MIPS: prep stack walkers for THREAD_INFO_IN_TASK

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When CONFIG_THREAD_INFO_IN_TASK is selected, task stacks may be freed
before a task is destroyed. To account for this, the stacks are
refcounted, and when manipulating the stack of another task, it is
necessary to get/put the stack to ensure it isn't freed and/or re-used
while we do so.

This patch reworks the MIPS stack walking code to account for this.
When CONFIG_THREAD_INFO_IN_TASK is not selected these perform no
refcounting, and this should only be a structural change that does not
affect behaviour.

Signed-off-by: Matt Redfearn <matt.redfearn@xxxxxxxx>
---

 arch/mips/kernel/process.c    | 3 ++-
 arch/mips/kernel/stacktrace.c | 5 +++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 45d0b6b037ee..24b4e8c02508 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -627,7 +627,7 @@ unsigned long get_wchan(struct task_struct *task)
 
 	if (!task || task == current || task->state == TASK_RUNNING)
 		goto out;
-	if (!task_stack_page(task))
+	if (!try_get_task_stack(task))
 		goto out;
 
 	pc = thread_saved_pc(task);
@@ -639,6 +639,7 @@ unsigned long get_wchan(struct task_struct *task)
 		pc = unwind_stack(task, &sp, pc, &ra);
 #endif
 
+	put_task_stack(task);
 out:
 	return pc;
 }
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c
index 7c7c902249f2..babf2dd165a0 100644
--- a/arch/mips/kernel/stacktrace.c
+++ b/arch/mips/kernel/stacktrace.c
@@ -81,6 +81,9 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 
 	WARN_ON(trace->nr_entries || !trace->max_entries);
 
+	if (!try_get_task_stack(tsk))
+		return;
+
 	if (tsk != current) {
 		regs->regs[29] = tsk->thread.reg29;
 		regs->regs[31] = 0;
@@ -88,5 +91,7 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 	} else
 		prepare_frametrace(regs);
 	save_context_stack(trace, tsk, regs, tsk == current);
+
+	put_task_stack(tsk);
 }
 EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
-- 
2.7.4



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux