Subject: Re: [PATCH v5 5/5] powerpc/perf: split callchain.c by bitness

From: Michal Suchánek <[email-masked]>
Date: Fri, 30 Aug 2019 08:42:25 +0200

On Fri, 30 Aug 2019 06:35:11 +0000 (UTC)
Christophe Leroy <[email-masked]> wrote:

> On 08/29/2019 10:28 PM, Michal Suchanek wrote:
> > Building callchain.c with !COMPAT proved quite ugly with all the
> > defines. Splitting out the 32bit and 64bit parts looks better.
> > 
> > Also rewrite current_is_64bit as common function. No other code change
> > intended.  
> 
> Nice result.
> 
> Could look even better by merging both read_user_stack_32(), see below.
> 
> Also a possible cosmetic change to Makefile.
> 
> ---
>  arch/powerpc/perf/Makefile       |  7 ++---
>  arch/powerpc/perf/callchain_32.c | 65 ++++++++++++++++------------------------
>  2 files changed, 29 insertions(+), 43 deletions(-)
> 
> diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
> index e9f3202251d0..53d614e98537 100644
> --- a/arch/powerpc/perf/Makefile
> +++ b/arch/powerpc/perf/Makefile
> @@ -1,9 +1,8 @@
>  # SPDX-License-Identifier: GPL-2.0
>  
> -obj-$(CONFIG_PERF_EVENTS)	+= callchain.o perf_regs.o
> -ifdef CONFIG_PERF_EVENTS
> -obj-y				+= callchain_$(BITS).o
> -obj-$(CONFIG_COMPAT)		+= callchain_32.o
> +obj-$(CONFIG_PERF_EVENTS)	+= callchain.o callchain_$(BITS).o perf_regs.o
> +ifdef CONFIG_COMPAT
> +obj-$(CONFIG_PERF_EVENTS)	+= callchain_32.o
>  endif
>  
That looks good.
>  obj-$(CONFIG_PPC_PERF_CTRS)	+= core-book3s.o bhrb.o
> diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c
> index 0bd4484eddaa..17c43ae03084 100644
> --- a/arch/powerpc/perf/callchain_32.c
> +++ b/arch/powerpc/perf/callchain_32.c
> @@ -15,50 +15,13 @@
>  #include <asm/sigcontext.h>
>  #include <asm/ucontext.h>
>  #include <asm/vdso.h>
> -#ifdef CONFIG_PPC64
> -#include "../kernel/ppc32.h"
> -#endif
>  #include <asm/pte-walk.h>
>  
>  #include "callchain.h"
>  
>  #ifdef CONFIG_PPC64
> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> -{
> -	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> -	    ((unsigned long)ptr & 3))
> -		return -EFAULT;
> -
> -	pagefault_disable();
> -	if (!__get_user_inatomic(*ret, ptr)) {
> -		pagefault_enable();
> -		return 0;
> -	}
> -	pagefault_enable();
> -
> -	return read_user_stack_slow(ptr, ret, 4);
> -}
> -#else /* CONFIG_PPC64 */
> -/*
> - * On 32-bit we just access the address and let hash_page create a
> - * HPTE if necessary, so there is no need to fall back to reading
> - * the page tables.  Since this is called at interrupt level,
> - * do_page_fault() won't treat a DSI as a page fault.
> - */
> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> -{
> -	int rc;
> -
> -	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> -	    ((unsigned long)ptr & 3))
> -		return -EFAULT;
> -
> -	pagefault_disable();
> -	rc = __get_user_inatomic(*ret, ptr);
> -	pagefault_enable();
> -
> -	return rc;
> -}
> +#include "../kernel/ppc32.h"
> +#else
>  
>  #define __SIGNAL_FRAMESIZE32	__SIGNAL_FRAMESIZE
>  #define sigcontext32		sigcontext
> @@ -95,6 +58,30 @@ struct rt_signal_frame_32 {
>  	int			abigap[56];
>  };
>  
> +/*
> + * On 32-bit we just access the address and let hash_page create a
> + * HPTE if necessary, so there is no need to fall back to reading
> + * the page tables.  Since this is called at interrupt level,
> + * do_page_fault() won't treat a DSI as a page fault.
> + */
> +static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> +{
> +	int rc;
> +
> +	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> +	    ((unsigned long)ptr & 3))
> +		return -EFAULT;
> +
> +	pagefault_disable();
> +	rc = __get_user_inatomic(*ret, ptr);
> +	pagefault_enable();
> +
> +	if (IS_ENABLED(CONFIG_PPC32) || !rc)
> +		return rc;
> +
> +	return read_user_stack_slow(ptr, ret, 4);
> +}
> +
>  static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
>  {
>  	if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))

I will leave consolidating this function to somebody who knows what the
desired semantic is. With a short ifdef section at the top of the file
it is a low-hanging fruit.

Thanks

Michal