Re: git: 6260bfb08742 - main - powerpc: Optimize copyinstr() to avoid repeatedly mapping user strings

Brandon Bergren bdragon at FreeBSD.org
Wed Dec 30 22:58:47 UTC 2020


Approved-By: bdragon (in IRC)

On Wed, Dec 30, 2020, at 4:45 PM, Piotr Kubaj wrote:
> The branch main has been updated by pkubaj (ports committer):
> 
> URL: 
> https://cgit.FreeBSD.org/src/commit/?id=6260bfb0874280d3fb58ac52699e2aee6ecca8a8
> 
> commit 6260bfb0874280d3fb58ac52699e2aee6ecca8a8
> Author:     Justin Hibbits <chmeeedalf at gmail.com>
> AuthorDate: 2020-06-04 18:15:15 +0000
> Commit:     Piotr Kubaj <pkubaj at FreeBSD.org>
> CommitDate: 2020-12-30 22:45:35 +0000
> 
>     powerpc: Optimize copyinstr() to avoid repeatedly mapping user strings
>     
>     Currently copyinstr() uses fubyte() to read each byte from userspace.
>     However, this means that for each byte, it calls pmap_map_user_ptr() to
>     map the string into memory.  This is needlessly wasteful, since the
>     string will rarely ever cross a segment boundary.  Instead, map a
>     segment at a time, and copy as much from that segment as possible at a
>     time.
>     
>     Measured with the HPT pmap on powerpc64, this saves roughly 8% time on
>     buildkernel, and 5% on buildworld, in wallclock time.
> ---
>  sys/powerpc/powerpc/copyinout.c | 46 +++++++++++++++++++++++++++++------------
>  1 file changed, 33 insertions(+), 13 deletions(-)
> 
> diff --git a/sys/powerpc/powerpc/copyinout.c b/sys/powerpc/powerpc/copyinout.c
> index 76965ad996b8..1528accc0e0e 100644
> --- a/sys/powerpc/powerpc/copyinout.c
> +++ b/sys/powerpc/powerpc/copyinout.c
> @@ -236,31 +236,51 @@ REMAP(copyin)(const void *udaddr, void *kaddr, size_t len)
>  int
>  REMAP(copyinstr)(const void *udaddr, void *kaddr, size_t len, size_t *done)
>  {
> +	struct		thread *td;
> +	pmap_t		pm;
> +	jmp_buf		env;
>  	const char	*up;
> -	char		*kp;
> -	size_t		l;
> -	int		rv, c;
> +	char		*kp, *p;
> +	size_t		i, l, t;
> +	int		rv;
>  
> -	kp = kaddr;
> -	up = udaddr;
> +	td = curthread;
> +	pm = &td->td_proc->p_vmspace->vm_pmap;
>  
> +	t = 0;
>  	rv = ENAMETOOLONG;
>  
> -	for (l = 0; len-- > 0; l++) {
> -		if ((c = fubyte(up++)) < 0) {
> +	td->td_pcb->pcb_onfault = &env;
> +	if (setjmp(env)) {
> +		rv = EFAULT;
> +		goto done;
> +	}
> +
> +	kp = kaddr;
> +	up = udaddr;
> +
> +	while (len > 0) {
> +		if (pmap_map_user_ptr(pm, up, (void **)&p, len, &l)) {
>  			rv = EFAULT;
> -			break;
> +			goto done;
>  		}
>  
> -		if (!(*kp++ = c)) {
> -			l++;
> -			rv = 0;
> -			break;
> +		for (i = 0; len > 0 && i < l; i++, t++, len--) {
> +			if ((*kp++ = *p++) == 0) {
> +				i++, t++;
> +				rv = 0;
> +				goto done;
> +			}
>  		}
> +
> +		up += l;
>  	}
>  
> +done:
> +	td->td_pcb->pcb_onfault = NULL;
> +
>  	if (done != NULL) {
> -		*done = l;
> +		*done = t;
>  	}
>  
>  	return (rv);
>

-- 
  Brandon Bergren
  bdragon at FreeBSD.org


More information about the dev-commits-src-all mailing list