All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/3] ARM: thread_info to task_struct
@ 2018-03-15 17:08 Zubin Mithra
  2018-03-15 17:08 ` [RFC 1/3] arm: factor out current_stack_pointer Zubin Mithra
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Zubin Mithra @ 2018-03-15 17:08 UTC (permalink / raw)
  To: linux-arm-kernel

These are a set of preparatory patches for moving the thread_info into
the task_struct for ARM. The patches that perform the actual move are
not implemented yet. A patch to make a register(such as sp_usr) point to
thread_info will likely be required, eventually.

Zubin Mithra (3):
  arm: factor out current_stack_pointer
  arm: make cpu a percpu variable
  arm: add refcounting for task stacks

 arch/arm/include/asm/cputype.h       |  3 +++
 arch/arm/include/asm/percpu.h        |  2 ++
 arch/arm/include/asm/smp.h           |  3 ++-
 arch/arm/include/asm/stack_pointer.h |  9 +++++++++
 arch/arm/include/asm/thread_info.h   |  6 +-----
 arch/arm/kernel/process.c            | 21 +++++++++++++++------
 arch/arm/kernel/return_address.c     |  1 +
 arch/arm/kernel/setup.c              |  2 +-
 arch/arm/kernel/smp.c                |  5 +++--
 arch/arm/kernel/stacktrace.c         |  8 ++++++++
 arch/arm/kernel/topology.c           |  5 +++++
 arch/arm/kernel/traps.c              |  5 +++++
 arch/arm/kernel/unwind.c             |  1 +
 13 files changed, 56 insertions(+), 15 deletions(-)
 create mode 100644 arch/arm/include/asm/stack_pointer.h

-- 
2.16.2.804.g6dcf76e118-goog

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC 1/3] arm: factor out current_stack_pointer
  2018-03-15 17:08 [RFC 0/3] ARM: thread_info to task_struct Zubin Mithra
@ 2018-03-15 17:08 ` Zubin Mithra
  2018-03-15 17:58   ` Mark Rutland
  2018-03-15 17:08 ` [RFC 2/3] arm: make cpu a percpu variable Zubin Mithra
  2018-03-15 17:08 ` [RFC 3/3] arm: add refcounting for task stacks Zubin Mithra
  2 siblings, 1 reply; 6+ messages in thread
From: Zubin Mithra @ 2018-03-15 17:08 UTC (permalink / raw)
  To: linux-arm-kernel

Multiple header files that rely on current_stack_pointer do not have the
necessary include <asm/thread_info.h>, and are thus fragile to changes
in the header soup.

Subsequent patches will affect the header soup such that including
<asm/thread_info.h> will result in a circular header include. Factor
current_thread_info into its own header and have all the users include
this header explicitely.

Signed-off-by: Zubin Mithra <zsm@chromium.org>
---
 arch/arm/include/asm/percpu.h        | 2 ++
 arch/arm/include/asm/stack_pointer.h | 9 +++++++++
 arch/arm/include/asm/thread_info.h   | 6 +-----
 arch/arm/kernel/return_address.c     | 1 +
 arch/arm/kernel/stacktrace.c         | 1 +
 arch/arm/kernel/unwind.c             | 1 +
 6 files changed, 15 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/include/asm/stack_pointer.h

diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
index a89b4076cde4..6a19e634d0cf 100644
--- a/arch/arm/include/asm/percpu.h
+++ b/arch/arm/include/asm/percpu.h
@@ -16,6 +16,8 @@
 #ifndef _ASM_ARM_PERCPU_H_
 #define _ASM_ARM_PERCPU_H_
 
+#include <asm/stack_pointer.h>
+
 /*
  * Same as asm-generic/percpu.h, except that we store the per cpu offset
  * in the TPIDRPRW. TPIDRPRW only exists on V6K and V7
diff --git a/arch/arm/include/asm/stack_pointer.h b/arch/arm/include/asm/stack_pointer.h
new file mode 100644
index 000000000000..5a6a8c6d9208
--- /dev/null
+++ b/arch/arm/include/asm/stack_pointer.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_STACK_POINTER_H
+#define __ASM_STACK_POINTER_H
+
+/*
+ * how to get the current stack pointer in C
+ */
+register unsigned long current_stack_pointer asm ("sp");
+
+#endif
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index e71cc35de163..56317024d221 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -25,6 +25,7 @@
 struct task_struct;
 
 #include <asm/types.h>
+#include <asm/stack_pointer.h>
 
 typedef unsigned long mm_segment_t;
 
@@ -75,11 +76,6 @@ struct thread_info {
 	.addr_limit	= KERNEL_DS,					\
 }
 
-/*
- * how to get the current stack pointer in C
- */
-register unsigned long current_stack_pointer asm ("sp");
-
 /*
  * how to get the thread information struct from C
  */
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
index 36ed35073289..d76e64250816 100644
--- a/arch/arm/kernel/return_address.c
+++ b/arch/arm/kernel/return_address.c
@@ -14,6 +14,7 @@
 #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
 #include <linux/sched.h>
 
+#include <asm/stack_pointer.h>
 #include <asm/stacktrace.h>
 
 struct return_address_data {
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index a56e7c856ab5..d519b8e0797f 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -4,6 +4,7 @@
 #include <linux/stacktrace.h>
 
 #include <asm/sections.h>
+#include <asm/stack_pointer.h>
 #include <asm/stacktrace.h>
 #include <asm/traps.h>
 
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 0bee233fef9a..860f8ac187e0 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -45,6 +45,7 @@
 #include <linux/spinlock.h>
 #include <linux/list.h>
 
+#include <asm/stack_pointer.h>
 #include <asm/stacktrace.h>
 #include <asm/traps.h>
 #include <asm/unwind.h>
-- 
2.16.2.804.g6dcf76e118-goog

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC 2/3] arm: make cpu a percpu variable
  2018-03-15 17:08 [RFC 0/3] ARM: thread_info to task_struct Zubin Mithra
  2018-03-15 17:08 ` [RFC 1/3] arm: factor out current_stack_pointer Zubin Mithra
@ 2018-03-15 17:08 ` Zubin Mithra
  2018-03-15 18:06   ` Mark Rutland
  2018-03-15 17:08 ` [RFC 3/3] arm: add refcounting for task stacks Zubin Mithra
  2 siblings, 1 reply; 6+ messages in thread
From: Zubin Mithra @ 2018-03-15 17:08 UTC (permalink / raw)
  To: linux-arm-kernel

Without CONFIG_THREAD_INFO_IN_TASK, core code maintains thread_info::cpu
and arch specific code can use this to build raw_smp_processor_id().
With CONFIG_THREAD_INFO_IN_TASK, core code maintains task_struct::cpu,
and arch specific code cannot access this due to header file circular
dependency.

Instead, we can maintain a percpu variable containing the cpu number.

This also means that cpu numbers obtained using smp_processor_id cannot
be used to set_my_cpu_offset. Use task_cpu(current) instead to get the
cpu in those cases.

Earlier raw_smp_processor_id() was current_thread_info()->cpu :-
	mov	r3, sp
	bic     r3, r3, #8128
	bic     r3, r3, #63
	ldr     r0, [r3, #16]

Now it is *raw_cpu_ptr(&cpu_number) :-
	movw	r3, #57344
	movt	r3, #32917
	mrc	15, 0, r0, cr13, cr0, {4}
	ldr	r0, [r3, r0]

Signed-off-by: Zubin Mithra <zsm@chromium.org>
---
 arch/arm/include/asm/cputype.h | 3 +++
 arch/arm/include/asm/smp.h     | 3 ++-
 arch/arm/kernel/setup.c        | 2 +-
 arch/arm/kernel/smp.c          | 5 +++--
 arch/arm/kernel/topology.c     | 5 +++++
 5 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index cb546425da8a..10148c7af12f 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -2,6 +2,9 @@
 #ifndef __ASM_ARM_CPUTYPE_H
 #define __ASM_ARM_CPUTYPE_H
 
+#include <asm/percpu.h>
+DECLARE_PER_CPU(int, cpu_number);
+
 #include <linux/stringify.h>
 #include <linux/kernel.h>
 
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 709a55989cb0..7e7b198174d6 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -18,7 +18,8 @@
 # error "<asm/smp.h> included in non-SMP build"
 #endif
 
-#define raw_smp_processor_id() (current_thread_info()->cpu)
+#include <asm/cputype.h>
+#define raw_smp_processor_id() (*raw_cpu_ptr(&cpu_number))
 
 struct seq_file;
 
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index fc40a2b40595..6323b4d80306 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -521,7 +521,7 @@ static void __init elf_hwcap_fixup(void)
 void notrace cpu_init(void)
 {
 #ifndef CONFIG_CPU_V7M
-	unsigned int cpu = smp_processor_id();
+	unsigned int cpu = task_cpu(current);
 	struct stack *stk = &stacks[cpu];
 
 	if (cpu >= NR_CPUS) {
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 2da087926ebe..9584a52eb156 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -372,7 +372,8 @@ asmlinkage void secondary_start_kernel(void)
 	 * All kernel threads share the same mm context; grab a
 	 * reference and switch to it.
 	 */
-	cpu = smp_processor_id();
+	cpu = task_cpu(current);
+	set_my_cpu_offset(per_cpu_offset(cpu));
 	mmgrab(mm);
 	current->active_mm = mm;
 	cpumask_set_cpu(cpu, mm_cpumask(mm));
@@ -436,7 +437,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
 
 void __init smp_prepare_boot_cpu(void)
 {
-	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
+	set_my_cpu_offset(per_cpu_offset(task_cpu(current)));
 }
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index 24ac3cab411d..34b2136deab6 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -30,6 +30,9 @@
 #include <asm/cputype.h>
 #include <asm/topology.h>
 
+DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number);
+EXPORT_PER_CPU_SYMBOL(cpu_number);
+
 /*
  * cpu capacity scale management
  */
@@ -310,6 +313,8 @@ void __init init_cpu_topology(void)
 	for_each_possible_cpu(cpu) {
 		struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]);
 
+		per_cpu(cpu_number, cpu) = cpu;
+
 		cpu_topo->thread_id = -1;
 		cpu_topo->core_id =  -1;
 		cpu_topo->socket_id = -1;
-- 
2.16.2.804.g6dcf76e118-goog

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC 3/3] arm: add refcounting for task stacks
  2018-03-15 17:08 [RFC 0/3] ARM: thread_info to task_struct Zubin Mithra
  2018-03-15 17:08 ` [RFC 1/3] arm: factor out current_stack_pointer Zubin Mithra
  2018-03-15 17:08 ` [RFC 2/3] arm: make cpu a percpu variable Zubin Mithra
@ 2018-03-15 17:08 ` Zubin Mithra
  2 siblings, 0 replies; 6+ messages in thread
From: Zubin Mithra @ 2018-03-15 17:08 UTC (permalink / raw)
  To: linux-arm-kernel

When CONFIG_THREAD_INFO_IN_TASK is enabled, thread stacks may be freed
before a stack is destroyed. This patch adds in recounting to ensure
freed stacks are not used. If CONFIG_THREAD_INFO_IN_TASK is not used, no
refcounting is performed.

Signed-off-by: Zubin Mithra <zsm@chromium.org>
---
 arch/arm/kernel/process.c    | 21 +++++++++++++++------
 arch/arm/kernel/stacktrace.c |  7 +++++++
 arch/arm/kernel/traps.c      |  5 +++++
 3 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 1523cb18b109..d3f87d3049da 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -297,7 +297,7 @@ EXPORT_SYMBOL(dump_fpu);
 unsigned long get_wchan(struct task_struct *p)
 {
 	struct stackframe frame;
-	unsigned long stack_page;
+	unsigned long stack_page, ret = 0;
 	int count = 0;
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
@@ -306,16 +306,25 @@ unsigned long get_wchan(struct task_struct *p)
 	frame.sp = thread_saved_sp(p);
 	frame.lr = 0;			/* recovered from the stack */
 	frame.pc = thread_saved_pc(p);
-	stack_page = (unsigned long)task_stack_page(p);
+
+	stack_page = (unsigned long)try_get_task_stack(p);
+	if (!stack_page)
+		return 0;
+
 	do {
 		if (frame.sp < stack_page ||
 		    frame.sp >= stack_page + THREAD_SIZE ||
 		    unwind_frame(&frame) < 0)
-			return 0;
-		if (!in_sched_functions(frame.pc))
-			return frame.pc;
+			goto out;
+		if (!in_sched_functions(frame.pc)) {
+			ret = frame.pc;
+			goto out;
+		}
 	} while (count ++ < 16);
-	return 0;
+
+out:
+	put_task_stack(p);
+	return ret;
 }
 
 unsigned long arch_randomize_brk(struct mm_struct *mm)
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index d519b8e0797f..ff20d5941724 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -1,6 +1,7 @@
 #include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
+#include <linux/sched/task_stack.h>
 #include <linux/stacktrace.h>
 
 #include <asm/sections.h>
@@ -105,6 +106,9 @@ static noinline void __save_stack_trace(struct task_struct *tsk,
 	struct stack_trace_data data;
 	struct stackframe frame;
 
+	if (!try_get_task_stack(tsk))
+		return;
+
 	data.trace = trace;
 	data.skip = trace->skip;
 	data.no_sched_functions = nosched;
@@ -118,6 +122,7 @@ static noinline void __save_stack_trace(struct task_struct *tsk,
 		 */
 		if (trace->nr_entries < trace->max_entries)
 			trace->entries[trace->nr_entries++] = ULONG_MAX;
+		put_task_stack(tsk);
 		return;
 #else
 		frame.fp = thread_saved_fp(tsk);
@@ -137,6 +142,8 @@ static noinline void __save_stack_trace(struct task_struct *tsk,
 	walk_stackframe(&frame, save_trace, &data);
 	if (trace->nr_entries < trace->max_entries)
 		trace->entries[trace->nr_entries++] = ULONG_MAX;
+
+	put_task_stack(tsk);
 }
 
 void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 5e3633c24e63..3eb923033591 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -216,6 +216,9 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
 	if (!tsk)
 		tsk = current;
 
+	if (!try_get_task_stack(tsk))
+		return;
+
 	if (regs) {
 		fp = frame_pointer(regs);
 		mode = processor_mode(regs);
@@ -239,6 +242,8 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
 
 	if (ok)
 		c_backtrace(fp, mode);
+
+	put_task_stack(tsk);
 }
 #endif
 
-- 
2.16.2.804.g6dcf76e118-goog

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC 1/3] arm: factor out current_stack_pointer
  2018-03-15 17:08 ` [RFC 1/3] arm: factor out current_stack_pointer Zubin Mithra
@ 2018-03-15 17:58   ` Mark Rutland
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Rutland @ 2018-03-15 17:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 15, 2018 at 05:08:57PM +0000, Zubin Mithra wrote:
> Multiple header files that rely on current_stack_pointer do not have the
> necessary include <asm/thread_info.h>, and are thus fragile to changes
> in the header soup.
> 
> Subsequent patches will affect the header soup such that including
> <asm/thread_info.h> will result in a circular header include. Factor
> current_thread_info into its own header and have all the users include
> this header explicitely.

Nit: s/explicitely/explicitly/

> Signed-off-by: Zubin Mithra <zsm@chromium.org>

I can't remember precisely what the circular include dependency was that
necessitated this for arm64, but regardless this looks reasonable to me.
FWIW:

Acked-by: Mark Rutland <mark.rutland@arm.com>

... though we'll need the rest of the THREAD_INFO_IN_TASK patches for
this to be a worthwhile change.

Thanks,
Mark.

> ---
>  arch/arm/include/asm/percpu.h        | 2 ++
>  arch/arm/include/asm/stack_pointer.h | 9 +++++++++
>  arch/arm/include/asm/thread_info.h   | 6 +-----
>  arch/arm/kernel/return_address.c     | 1 +
>  arch/arm/kernel/stacktrace.c         | 1 +
>  arch/arm/kernel/unwind.c             | 1 +
>  6 files changed, 15 insertions(+), 5 deletions(-)
>  create mode 100644 arch/arm/include/asm/stack_pointer.h
> 
> diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
> index a89b4076cde4..6a19e634d0cf 100644
> --- a/arch/arm/include/asm/percpu.h
> +++ b/arch/arm/include/asm/percpu.h
> @@ -16,6 +16,8 @@
>  #ifndef _ASM_ARM_PERCPU_H_
>  #define _ASM_ARM_PERCPU_H_
>  
> +#include <asm/stack_pointer.h>
> +
>  /*
>   * Same as asm-generic/percpu.h, except that we store the per cpu offset
>   * in the TPIDRPRW. TPIDRPRW only exists on V6K and V7
> diff --git a/arch/arm/include/asm/stack_pointer.h b/arch/arm/include/asm/stack_pointer.h
> new file mode 100644
> index 000000000000..5a6a8c6d9208
> --- /dev/null
> +++ b/arch/arm/include/asm/stack_pointer.h
> @@ -0,0 +1,9 @@
> +#ifndef __ASM_STACK_POINTER_H
> +#define __ASM_STACK_POINTER_H
> +
> +/*
> + * how to get the current stack pointer in C
> + */
> +register unsigned long current_stack_pointer asm ("sp");
> +
> +#endif
> diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
> index e71cc35de163..56317024d221 100644
> --- a/arch/arm/include/asm/thread_info.h
> +++ b/arch/arm/include/asm/thread_info.h
> @@ -25,6 +25,7 @@
>  struct task_struct;
>  
>  #include <asm/types.h>
> +#include <asm/stack_pointer.h>
>  
>  typedef unsigned long mm_segment_t;
>  
> @@ -75,11 +76,6 @@ struct thread_info {
>  	.addr_limit	= KERNEL_DS,					\
>  }
>  
> -/*
> - * how to get the current stack pointer in C
> - */
> -register unsigned long current_stack_pointer asm ("sp");
> -
>  /*
>   * how to get the thread information struct from C
>   */
> diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
> index 36ed35073289..d76e64250816 100644
> --- a/arch/arm/kernel/return_address.c
> +++ b/arch/arm/kernel/return_address.c
> @@ -14,6 +14,7 @@
>  #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
>  #include <linux/sched.h>
>  
> +#include <asm/stack_pointer.h>
>  #include <asm/stacktrace.h>
>  
>  struct return_address_data {
> diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
> index a56e7c856ab5..d519b8e0797f 100644
> --- a/arch/arm/kernel/stacktrace.c
> +++ b/arch/arm/kernel/stacktrace.c
> @@ -4,6 +4,7 @@
>  #include <linux/stacktrace.h>
>  
>  #include <asm/sections.h>
> +#include <asm/stack_pointer.h>
>  #include <asm/stacktrace.h>
>  #include <asm/traps.h>
>  
> diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
> index 0bee233fef9a..860f8ac187e0 100644
> --- a/arch/arm/kernel/unwind.c
> +++ b/arch/arm/kernel/unwind.c
> @@ -45,6 +45,7 @@
>  #include <linux/spinlock.h>
>  #include <linux/list.h>
>  
> +#include <asm/stack_pointer.h>
>  #include <asm/stacktrace.h>
>  #include <asm/traps.h>
>  #include <asm/unwind.h>
> -- 
> 2.16.2.804.g6dcf76e118-goog
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC 2/3] arm: make cpu a percpu variable
  2018-03-15 17:08 ` [RFC 2/3] arm: make cpu a percpu variable Zubin Mithra
@ 2018-03-15 18:06   ` Mark Rutland
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Rutland @ 2018-03-15 18:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 15, 2018 at 05:08:58PM +0000, Zubin Mithra wrote:
> Without CONFIG_THREAD_INFO_IN_TASK, core code maintains thread_info::cpu
> and arch specific code can use this to build raw_smp_processor_id().
> With CONFIG_THREAD_INFO_IN_TASK, core code maintains task_struct::cpu,
> and arch specific code cannot access this due to header file circular
> dependency.
> 
> Instead, we can maintain a percpu variable containing the cpu number.
> 
> This also means that cpu numbers obtained using smp_processor_id cannot
> be used to set_my_cpu_offset. Use task_cpu(current) instead to get the
> cpu in those cases.
> 
> Earlier raw_smp_processor_id() was current_thread_info()->cpu :-
> 	mov	r3, sp
> 	bic     r3, r3, #8128
> 	bic     r3, r3, #63
> 	ldr     r0, [r3, #16]
> 
> Now it is *raw_cpu_ptr(&cpu_number) :-
> 	movw	r3, #57344
> 	movt	r3, #32917
> 	mrc	15, 0, r0, cr13, cr0, {4}
> 	ldr	r0, [r3, r0]

It's probably worth noting that with the thread_info moved off of the
stack, were we to use that to get at the cpu number, this would require
a similar sequence to the raw_cpu_ptr() code here.

This might make more sense after a patch using a register for the
thread_info (which would also allow for having separate IRQ stacks).

> 
> Signed-off-by: Zubin Mithra <zsm@chromium.org>
> ---
>  arch/arm/include/asm/cputype.h | 3 +++
>  arch/arm/include/asm/smp.h     | 3 ++-
>  arch/arm/kernel/setup.c        | 2 +-
>  arch/arm/kernel/smp.c          | 5 +++--
>  arch/arm/kernel/topology.c     | 5 +++++
>  5 files changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
> index cb546425da8a..10148c7af12f 100644
> --- a/arch/arm/include/asm/cputype.h
> +++ b/arch/arm/include/asm/cputype.h
> @@ -2,6 +2,9 @@
>  #ifndef __ASM_ARM_CPUTYPE_H
>  #define __ASM_ARM_CPUTYPE_H
>  
> +#include <asm/percpu.h>
> +DECLARE_PER_CPU(int, cpu_number);
> +

Why isn't this defined in <asm/smp.h>, as we do on arm64?

> --- a/arch/arm/include/asm/smp.h
> +++ b/arch/arm/include/asm/smp.h
> @@ -18,7 +18,8 @@
>  # error "<asm/smp.h> included in non-SMP build"
>  #endif
>  
> -#define raw_smp_processor_id() (current_thread_info()->cpu)
> +#include <asm/cputype.h>
> +#define raw_smp_processor_id() (*raw_cpu_ptr(&cpu_number))

It might be worth dragging the comment along from arm64, explaining why
we must use *raw_cpu_ptr(), and not this_cpu_read(), etc.

> --- a/arch/arm/kernel/topology.c
> +++ b/arch/arm/kernel/topology.c
> @@ -30,6 +30,9 @@
>  #include <asm/cputype.h>
>  #include <asm/topology.h>
>  
> +DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number);
> +EXPORT_PER_CPU_SYMBOL(cpu_number);

Why not in smp.c, as with arm64?

> +
>  /*
>   * cpu capacity scale management
>   */
> @@ -310,6 +313,8 @@ void __init init_cpu_topology(void)
>  	for_each_possible_cpu(cpu) {
>  		struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]);
>  
> +		per_cpu(cpu_number, cpu) = cpu;

Likewise, why isn't this in smp_prepare_cpus() in smp.c?

This isn't toplogy related, so it would be better placed there.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-03-15 18:06 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-15 17:08 [RFC 0/3] ARM: thread_info to task_struct Zubin Mithra
2018-03-15 17:08 ` [RFC 1/3] arm: factor out current_stack_pointer Zubin Mithra
2018-03-15 17:58   ` Mark Rutland
2018-03-15 17:08 ` [RFC 2/3] arm: make cpu a percpu variable Zubin Mithra
2018-03-15 18:06   ` Mark Rutland
2018-03-15 17:08 ` [RFC 3/3] arm: add refcounting for task stacks Zubin Mithra

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.