All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86: use register variable to get stack pointer value
@ 2017-09-29 14:15 Andrey Ryabinin
  2017-09-29 15:38 ` Josh Poimboeuf
  2017-09-29 20:15 ` [tip:x86/urgent] x86/asm: Use " tip-bot for Andrey Ryabinin
  0 siblings, 2 replies; 5+ messages in thread
From: Andrey Ryabinin @ 2017-09-29 14:15 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86
  Cc: Josh Poimboeuf, Peter Zijlstra, Andy Lutomirski, Linus Torvalds,
	linux-kernel, Andrey Ryabinin

Currently we use current_stack_pointer() function to get the value
of the stack pointer register. Since commit f5caf621ee35
("x86/asm: Fix inline asm call constraints for Clang") we have stack
register variable declared. It can be used instead of current_stack_pointer()
function which allows to optimize away some excessive "mov %rsp, %<dst>"
instructions:

-mov    %rsp,%rdx
-sub    %rdx,%rax
-cmp    $0x3fff,%rax
-ja     ffffffff810722fd <ist_begin_non_atomic+0x2d>

+sub    %rsp,%rax
+cmp    $0x3fff,%rax
+ja     ffffffff810722fa <ist_begin_non_atomic+0x2a>

Remove current_stack_pointer(), rename __asm_call_sp to current_stack_pointer
and use it instead of removed function.

Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 arch/x86/include/asm/asm.h         |  4 ++--
 arch/x86/include/asm/thread_info.h | 11 -----------
 arch/x86/kernel/irq_32.c           |  6 +++---
 arch/x86/kernel/traps.c            |  2 +-
 arch/x86/mm/tlb.c                  |  2 +-
 5 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index 30c3c9ac784a..b0dc91f4bedc 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -141,8 +141,8 @@
  * gets set up by the containing function.  If you forget to do this, objtool
  * may print a "call without frame pointer save/setup" warning.
  */
-register unsigned long __asm_call_sp asm(_ASM_SP);
-#define ASM_CALL_CONSTRAINT "+r" (__asm_call_sp)
+register unsigned long current_stack_pointer asm(_ASM_SP);
+#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)
 #endif
 
 #endif /* _ASM_X86_ASM_H */
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 5161da1a0fa0..89e7eeb5cec1 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -158,17 +158,6 @@ struct thread_info {
  */
 #ifndef __ASSEMBLY__
 
-static inline unsigned long current_stack_pointer(void)
-{
-	unsigned long sp;
-#ifdef CONFIG_X86_64
-	asm("mov %%rsp,%0" : "=g" (sp));
-#else
-	asm("mov %%esp,%0" : "=g" (sp));
-#endif
-	return sp;
-}
-
 /*
  * Walks up the stack frames to make sure that the specified object is
  * entirely contained by a single stack frame.
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 1f38d9a4d9de..d4eb450144fd 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -64,7 +64,7 @@ static void call_on_stack(void *func, void *stack)
 
 static inline void *current_stack(void)
 {
-	return (void *)(current_stack_pointer() & ~(THREAD_SIZE - 1));
+	return (void *)(current_stack_pointer & ~(THREAD_SIZE - 1));
 }
 
 static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc)
@@ -88,7 +88,7 @@ static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc)
 
 	/* Save the next esp at the bottom of the stack */
 	prev_esp = (u32 *)irqstk;
-	*prev_esp = current_stack_pointer();
+	*prev_esp = current_stack_pointer;
 
 	if (unlikely(overflow))
 		call_on_stack(print_stack_overflow, isp);
@@ -139,7 +139,7 @@ void do_softirq_own_stack(void)
 
 	/* Push the previous esp onto the stack */
 	prev_esp = (u32 *)irqstk;
-	*prev_esp = current_stack_pointer();
+	*prev_esp = current_stack_pointer;
 
 	call_on_stack(__do_softirq, isp);
 }
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 34ea3651362e..67db4f43309e 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -142,7 +142,7 @@ void ist_begin_non_atomic(struct pt_regs *regs)
 	 * from double_fault.
 	 */
 	BUG_ON((unsigned long)(current_top_of_stack() -
-			       current_stack_pointer()) >= THREAD_SIZE);
+			       current_stack_pointer) >= THREAD_SIZE);
 
 	preempt_enable_no_resched();
 }
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 93fe97cce581..49d9778376d7 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -191,7 +191,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 			 * mapped in the new pgd, we'll double-fault.  Forcibly
 			 * map it.
 			 */
-			unsigned int index = pgd_index(current_stack_pointer());
+			unsigned int index = pgd_index(current_stack_pointer);
 			pgd_t *pgd = next->pgd + index;
 
 			if (unlikely(pgd_none(*pgd)))
-- 
2.13.6

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

* Re: [PATCH] x86: use register variable to get stack pointer value
  2017-09-29 14:15 [PATCH] x86: use register variable to get stack pointer value Andrey Ryabinin
@ 2017-09-29 15:38 ` Josh Poimboeuf
  2017-09-29 18:37   ` Andy Lutomirski
  2017-09-29 20:15 ` [tip:x86/urgent] x86/asm: Use " tip-bot for Andrey Ryabinin
  1 sibling, 1 reply; 5+ messages in thread
From: Josh Poimboeuf @ 2017-09-29 15:38 UTC (permalink / raw)
  To: Andrey Ryabinin
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86,
	Peter Zijlstra, Andy Lutomirski, Linus Torvalds, linux-kernel

On Fri, Sep 29, 2017 at 05:15:36PM +0300, Andrey Ryabinin wrote:
> Currently we use current_stack_pointer() function to get the value
> of the stack pointer register. Since commit f5caf621ee35
> ("x86/asm: Fix inline asm call constraints for Clang") we have stack
> register variable declared. It can be used instead of current_stack_pointer()
> function which allows to optimize away some excessive "mov %rsp, %<dst>"
> instructions:
> 
> -mov    %rsp,%rdx
> -sub    %rdx,%rax
> -cmp    $0x3fff,%rax
> -ja     ffffffff810722fd <ist_begin_non_atomic+0x2d>
> 
> +sub    %rsp,%rax
> +cmp    $0x3fff,%rax
> +ja     ffffffff810722fa <ist_begin_non_atomic+0x2a>
> 
> Remove current_stack_pointer(), rename __asm_call_sp to current_stack_pointer
> and use it instead of removed function.
> 
> Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>

Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>

-- 
Josh

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

* Re: [PATCH] x86: use register variable to get stack pointer value
  2017-09-29 15:38 ` Josh Poimboeuf
@ 2017-09-29 18:37   ` Andy Lutomirski
  2017-09-29 19:16     ` Josh Poimboeuf
  0 siblings, 1 reply; 5+ messages in thread
From: Andy Lutomirski @ 2017-09-29 18:37 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: Andrey Ryabinin, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	X86 ML, Peter Zijlstra, Andy Lutomirski, Linus Torvalds,
	linux-kernel

On Fri, Sep 29, 2017 at 8:38 AM, Josh Poimboeuf <jpoimboe@redhat.com> wrote:
> On Fri, Sep 29, 2017 at 05:15:36PM +0300, Andrey Ryabinin wrote:
>> Currently we use current_stack_pointer() function to get the value
>> of the stack pointer register. Since commit f5caf621ee35
>> ("x86/asm: Fix inline asm call constraints for Clang") we have stack
>> register variable declared. It can be used instead of current_stack_pointer()
>> function which allows to optimize away some excessive "mov %rsp, %<dst>"
>> instructions:
>>
>> -mov    %rsp,%rdx
>> -sub    %rdx,%rax
>> -cmp    $0x3fff,%rax
>> -ja     ffffffff810722fd <ist_begin_non_atomic+0x2d>
>>
>> +sub    %rsp,%rax
>> +cmp    $0x3fff,%rax
>> +ja     ffffffff810722fa <ist_begin_non_atomic+0x2a>
>>
>> Remove current_stack_pointer(), rename __asm_call_sp to current_stack_pointer
>> and use it instead of removed function.
>>
>> Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
>
> Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>


Ok with me.  As an alternative, you could leave it as
current_stack_pointer(), but either way is fine.

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

* Re: [PATCH] x86: use register variable to get stack pointer value
  2017-09-29 18:37   ` Andy Lutomirski
@ 2017-09-29 19:16     ` Josh Poimboeuf
  0 siblings, 0 replies; 5+ messages in thread
From: Josh Poimboeuf @ 2017-09-29 19:16 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Andrey Ryabinin, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	X86 ML, Peter Zijlstra, Linus Torvalds, linux-kernel

On Fri, Sep 29, 2017 at 11:37:52AM -0700, Andy Lutomirski wrote:
> On Fri, Sep 29, 2017 at 8:38 AM, Josh Poimboeuf <jpoimboe@redhat.com> wrote:
> > On Fri, Sep 29, 2017 at 05:15:36PM +0300, Andrey Ryabinin wrote:
> >> Currently we use current_stack_pointer() function to get the value
> >> of the stack pointer register. Since commit f5caf621ee35
> >> ("x86/asm: Fix inline asm call constraints for Clang") we have stack
> >> register variable declared. It can be used instead of current_stack_pointer()
> >> function which allows to optimize away some excessive "mov %rsp, %<dst>"
> >> instructions:
> >>
> >> -mov    %rsp,%rdx
> >> -sub    %rdx,%rax
> >> -cmp    $0x3fff,%rax
> >> -ja     ffffffff810722fd <ist_begin_non_atomic+0x2d>
> >>
> >> +sub    %rsp,%rax
> >> +cmp    $0x3fff,%rax
> >> +ja     ffffffff810722fa <ist_begin_non_atomic+0x2a>
> >>
> >> Remove current_stack_pointer(), rename __asm_call_sp to current_stack_pointer
> >> and use it instead of removed function.
> >>
> >> Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
> >
> > Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>
> 
> 
> Ok with me.  As an alternative, you could leave it as
> current_stack_pointer(), but either way is fine.

Good point, I think changing current_stack_pointer() to return the
global variable would be cleaner.

-- 
Josh

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

* [tip:x86/urgent] x86/asm: Use register variable to get stack pointer value
  2017-09-29 14:15 [PATCH] x86: use register variable to get stack pointer value Andrey Ryabinin
  2017-09-29 15:38 ` Josh Poimboeuf
@ 2017-09-29 20:15 ` tip-bot for Andrey Ryabinin
  1 sibling, 0 replies; 5+ messages in thread
From: tip-bot for Andrey Ryabinin @ 2017-09-29 20:15 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: torvalds, linux-kernel, luto, aryabinin, tglx, hpa, mingo,
	jpoimboe, peterz

Commit-ID:  196bd485ee4f03ce4c690bfcf38138abfcd0a4bc
Gitweb:     https://git.kernel.org/tip/196bd485ee4f03ce4c690bfcf38138abfcd0a4bc
Author:     Andrey Ryabinin <aryabinin@virtuozzo.com>
AuthorDate: Fri, 29 Sep 2017 17:15:36 +0300
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 29 Sep 2017 19:39:44 +0200

x86/asm: Use register variable to get stack pointer value

Currently we use current_stack_pointer() function to get the value
of the stack pointer register. Since commit:

  f5caf621ee35 ("x86/asm: Fix inline asm call constraints for Clang")

... we have a stack register variable declared. It can be used instead of
current_stack_pointer() function which allows to optimize away some
excessive "mov %rsp, %<dst>" instructions:

 -mov    %rsp,%rdx
 -sub    %rdx,%rax
 -cmp    $0x3fff,%rax
 -ja     ffffffff810722fd <ist_begin_non_atomic+0x2d>

 +sub    %rsp,%rax
 +cmp    $0x3fff,%rax
 +ja     ffffffff810722fa <ist_begin_non_atomic+0x2a>

Remove current_stack_pointer(), rename __asm_call_sp to current_stack_pointer
and use it instead of the removed function.

Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20170929141537.29167-1-aryabinin@virtuozzo.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/asm.h         |  4 ++--
 arch/x86/include/asm/thread_info.h | 11 -----------
 arch/x86/kernel/irq_32.c           |  6 +++---
 arch/x86/kernel/traps.c            |  2 +-
 arch/x86/mm/tlb.c                  |  2 +-
 5 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index 30c3c9a..b0dc91f 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -141,8 +141,8 @@
  * gets set up by the containing function.  If you forget to do this, objtool
  * may print a "call without frame pointer save/setup" warning.
  */
-register unsigned long __asm_call_sp asm(_ASM_SP);
-#define ASM_CALL_CONSTRAINT "+r" (__asm_call_sp)
+register unsigned long current_stack_pointer asm(_ASM_SP);
+#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)
 #endif
 
 #endif /* _ASM_X86_ASM_H */
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 5161da1a..89e7eeb 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -158,17 +158,6 @@ struct thread_info {
  */
 #ifndef __ASSEMBLY__
 
-static inline unsigned long current_stack_pointer(void)
-{
-	unsigned long sp;
-#ifdef CONFIG_X86_64
-	asm("mov %%rsp,%0" : "=g" (sp));
-#else
-	asm("mov %%esp,%0" : "=g" (sp));
-#endif
-	return sp;
-}
-
 /*
  * Walks up the stack frames to make sure that the specified object is
  * entirely contained by a single stack frame.
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 1f38d9a..d4eb450 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -64,7 +64,7 @@ static void call_on_stack(void *func, void *stack)
 
 static inline void *current_stack(void)
 {
-	return (void *)(current_stack_pointer() & ~(THREAD_SIZE - 1));
+	return (void *)(current_stack_pointer & ~(THREAD_SIZE - 1));
 }
 
 static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc)
@@ -88,7 +88,7 @@ static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc)
 
 	/* Save the next esp at the bottom of the stack */
 	prev_esp = (u32 *)irqstk;
-	*prev_esp = current_stack_pointer();
+	*prev_esp = current_stack_pointer;
 
 	if (unlikely(overflow))
 		call_on_stack(print_stack_overflow, isp);
@@ -139,7 +139,7 @@ void do_softirq_own_stack(void)
 
 	/* Push the previous esp onto the stack */
 	prev_esp = (u32 *)irqstk;
-	*prev_esp = current_stack_pointer();
+	*prev_esp = current_stack_pointer;
 
 	call_on_stack(__do_softirq, isp);
 }
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 34ea365..67db4f4 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -142,7 +142,7 @@ void ist_begin_non_atomic(struct pt_regs *regs)
 	 * from double_fault.
 	 */
 	BUG_ON((unsigned long)(current_top_of_stack() -
-			       current_stack_pointer()) >= THREAD_SIZE);
+			       current_stack_pointer) >= THREAD_SIZE);
 
 	preempt_enable_no_resched();
 }
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 93fe97c..49d9778 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -191,7 +191,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 			 * mapped in the new pgd, we'll double-fault.  Forcibly
 			 * map it.
 			 */
-			unsigned int index = pgd_index(current_stack_pointer());
+			unsigned int index = pgd_index(current_stack_pointer);
 			pgd_t *pgd = next->pgd + index;
 
 			if (unlikely(pgd_none(*pgd)))

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

end of thread, other threads:[~2017-09-29 20:19 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-29 14:15 [PATCH] x86: use register variable to get stack pointer value Andrey Ryabinin
2017-09-29 15:38 ` Josh Poimboeuf
2017-09-29 18:37   ` Andy Lutomirski
2017-09-29 19:16     ` Josh Poimboeuf
2017-09-29 20:15 ` [tip:x86/urgent] x86/asm: Use " tip-bot for Andrey Ryabinin

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.