This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [libc/string] State of PAGE_COPY_FWD / PAGE_COPY_THRESHOLD
- From: Adhemerval Zanella <adhemerval dot zanella at linaro dot org>
- To: libc-alpha at sourceware dot org
- Date: Tue, 1 Nov 2016 11:59:37 -0200
- Subject: Re: [libc/string] State of PAGE_COPY_FWD / PAGE_COPY_THRESHOLD
- Authentication-results: sourceware.org; auth=none
- References: <E122D105-776D-4B9B-A15C-0A7C24BC0910@linaro.org>
On 01/11/2016 07:28, Maxim Kuvyrkov wrote:
> I wanted to check performance impact of using linux zero page sharing in calls to memset (PTR, 0, SIZE). I remembered seeing PAGE_COPY_FWD_MAYBE and PAGE_COPY_THRESHOLD in string/memcpy.c, and my plan was to copy this logic to an experimental memset() implementation.
>
> Closer inspection of the current code showed that only Mach port attempted to use full-page copying in memcpy.c, but now even the Mach port disables it. The net result is that code in string/memcpy.c, as well as parts of headers sysdeps/generic/pagecopy.h and sysdeps/generic/memcopy.h are dead code.
>
> From the above we have 2 questions:
> 1. Is it possible to use full-page copy (with COW) in the Linux glibc port for memcpy() and/or memset(0)?
It is still possible to use the algorithms string/mem{cpy,set}, you just need to
make some change on the architecture you are aiming for.
On x86_64, for instance, you will need to remove any possible assembly
implementation so sysdeps won't use it instead. While configuring
with --disable-multi-arch (to remove the ifunc usage and keep it
simpler), I removed:
deleted: sysdeps/x86_64/memcpy.S
deleted: sysdeps/x86_64/memcpy_chk.S
deleted: sysdeps/x86_64/memmove.S
deleted: sysdeps/x86_64/mempcpy.S
deleted: sysdeps/x86_64/wordcopy.c
The 'memcpy.S' is the default optimized implementation and 'memcpy_chk.S'
is an empty one (since it is implemented on memcpy.S for x86_64 and we
will need the symbols provided). Same logic applies for the other removed
one (memmove.S and mempcpy.S).
I also removed sysdeps/x86_64/wordcopy.c because the idea is to use the
default one on string/wordcopy.c.
Next it will require to define OP_T_THRES so I created the file
'sysdeps/x86_64/memcopy.h' with the contents:
$ cat sysdeps/x86_64/memcopy.h
#include <sysdeps/generic/memcopy.h>
#undef OP_T_THRES
#define OP_T_THRES 8
(I think we should just define it to WORDSIZE/8 somewhere).
This should enable the build and use of generic memcpy implementation.
To actually use the PAGE_COPY_* macro you will need to add a arch
specific pagecopy.h header. Using the x86_64 example:
$ cat sysdeps/x86/pagecopy.h
#define PAGE_SIZE 4096
#define PAGE_COPY_THRESHOLD PAGE_SIZE
#define PAGE_COPY_FWD(dstp, srcp, nbytes_left, nbytes) /* Implement it */
It should work on any other architecture as well. Now the question
is whether this actually does make sense for Linux. Hurd/mach provided
a syscall (?) to actually copy the pages (vm_copy) which seems to apply
some tricks to avoid full copy pages. By 'linux zero page sharing' are
you referring to KSM (Kernel Samepage Merging)?
If so, on a system without a provided kernel interface to work directed
with underlying memory mapping (such as for mach), mem{cpy,set} will
actually need to touch the pages and it will be up to kernel page fault
mechanism to actually handle it (by identifying common pages and adjusting
vma mapping accordingly). And AFAIK this are only enabled on KSM if you
actually madavise the page explicit. So I am not grasping the need to
actually implement page copying on Linux.
>
> 2. If not, then is there any reason to keep the dead code around or should we clean it up?
In fact I think hurd/mach intent is indeed to actually use it and
it is not using due a missing adjustment in commit
99f8dc922033821edcc13f9f8360e9fda40dfcff (Fix -Wundef warning on
PAGE_COPY_THRESHOLD). It should have changed 'sysdeps/mach/pagecopy.h"
PAGE_THRESHOLD definition to PAGE_COPY_THRESHOLD.
>
> --
> Maxim Kuvyrkov
> www.linaro.org
>
>
>