diff mbox

[RFC,2/6] posix: add linux-only memfd fallback

Message ID 1437615403-13554-3-git-send-email-marcandre.lureau@redhat.com
State New
Headers show

Commit Message

Marc-André Lureau July 23, 2015, 1:36 a.m. UTC
Implement memfd_create() fallback if not available in system libc.
memfd_create() is still not included in glibc today, atlhough it's been
available since Linux 3.17 in Oct 2014.

memfd has numerous advantages over traditional shm/mmap for ipc memory
sharing with fd handler, which we are going to make use of for
vhost-user logging memory in following patches.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qemu/osdep.h | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

Comments

Michael S. Tsirkin July 23, 2015, 3:25 p.m. UTC | #1
On Thu, Jul 23, 2015 at 03:36:39AM +0200, Marc-André Lureau wrote:
> Implement memfd_create() fallback if not available in system libc.
> memfd_create() is still not included in glibc today, atlhough it's been
> available since Linux 3.17 in Oct 2014.
> 
> memfd has numerous advantages over traditional shm/mmap for ipc memory
> sharing with fd handler, which we are going to make use of for
> vhost-user logging memory in following patches.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  include/qemu/osdep.h | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
> 
> diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> index 3247364..adc138b 100644
> --- a/include/qemu/osdep.h
> +++ b/include/qemu/osdep.h
> @@ -6,6 +6,7 @@
>  #include <stddef.h>
>  #include <stdbool.h>
>  #include <stdint.h>
> +#include <unistd.h>
>  #include <sys/types.h>
>  #ifdef __OpenBSD__
>  #include <sys/signal.h>
> @@ -20,6 +21,64 @@
>  
>  #include <sys/time.h>
>  
> +#ifdef CONFIG_LINUX
> +
> +#ifndef F_LINUX_SPECIFIC_BASE
> +#define F_LINUX_SPECIFIC_BASE 1024
> +#endif
> +
> +#ifndef F_ADD_SEALS
> +#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
> +#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
> +
> +#define F_SEAL_SEAL     0x0001  /* prevent further seals from being set */
> +#define F_SEAL_SHRINK   0x0002  /* prevent file from shrinking */
> +#define F_SEAL_GROW     0x0004  /* prevent file from growing */
> +#define F_SEAL_WRITE    0x0008  /* prevent writes */
> +#endif

These are from include/uapi/linux/fcntl.h,
they should be imported into linux-headers I think.

> +
> +#ifndef MFD_ALLOW_SEALING
> +#define MFD_ALLOW_SEALING 0x0002U
> +#endif
> +
> +#ifndef MFD_CLOEXEC
> +#define MFD_CLOEXEC 0x0001U
> +#endif
> +
> +#ifndef __NR_memfd_create
> +#  if defined __x86_64__
> +#    define __NR_memfd_create 319
> +#  elif defined __arm__
> +#    define __NR_memfd_create 385
> +#  elif defined __aarch64__
> +#    define __NR_memfd_create 279
> +#  elif defined _MIPS_SIM
> +#    if _MIPS_SIM == _MIPS_SIM_ABI32
> +#      define __NR_memfd_create 4354
> +#    endif
> +#    if _MIPS_SIM == _MIPS_SIM_NABI32
> +#      define __NR_memfd_create 6318
> +#    endif
> +#    if _MIPS_SIM == _MIPS_SIM_ABI64
> +#      define __NR_memfd_create 5314
> +#    endif

What's defining all these macros?

> +#  elif defined __i386__
> +#    define __NR_memfd_create 356
> +#  else
> +#    warning "__NR_memfd_create unknown for your architecture"
> +#    define __NR_memfd_create 0xffffffff
> +#  endif
> +#endif
> +
> +#ifndef CONFIG_MEMFD
> +static inline int memfd_create(const char *name, unsigned int flags)
> +{
> +        return syscall(__NR_memfd_create, name, flags);
> +}
> +#endif

How about making these non-inline?

I think we need stubs for non-posix systems, right?

> +
> +#endif /* LINUX */
> +
>  #if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10
>  /* [u]int_fast*_t not in <sys/int_types.h> */
>  typedef unsigned char           uint_fast8_t;
> -- 
> 2.4.3
Paolo Bonzini July 28, 2015, 8:11 a.m. UTC | #2
On 23/07/2015 17:25, Michael S. Tsirkin wrote:
> > +#ifdef CONFIG_LINUX
> > +
> > +#ifndef F_LINUX_SPECIFIC_BASE
> > +#define F_LINUX_SPECIFIC_BASE 1024
> > +#endif
> > +
> > +#ifndef F_ADD_SEALS
> > +#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
> > +#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
> > +
> > +#define F_SEAL_SEAL     0x0001  /* prevent further seals from being set */
> > +#define F_SEAL_SHRINK   0x0002  /* prevent file from shrinking */
> > +#define F_SEAL_GROW     0x0004  /* prevent file from growing */
> > +#define F_SEAL_WRITE    0x0008  /* prevent writes */
> > +#endif
>
> These are from include/uapi/linux/fcntl.h,
> they should be imported into linux-headers I think.

linux-headers is usually used for virt-related features that we want in
QEMU a few weeks before they are distributed upstream.

Here, I think just including linux/fcntl.h is enough.

>> +#ifndef __NR_memfd_create
>> +#  if defined __x86_64__
>> +#    define __NR_memfd_create 319
>> +#  elif defined __arm__
>> +#    define __NR_memfd_create 385
>> +#  elif defined __aarch64__
>> +#    define __NR_memfd_create 279
>> +#  elif defined _MIPS_SIM
>> +#    if _MIPS_SIM == _MIPS_SIM_ABI32
>> +#      define __NR_memfd_create 4354
>> +#    endif
>> +#    if _MIPS_SIM == _MIPS_SIM_NABI32
>> +#      define __NR_memfd_create 6318
>> +#    endif
>> +#    if _MIPS_SIM == _MIPS_SIM_ABI64
>> +#      define __NR_memfd_create 5314
>> +#    endif
> 
> What's defining all these macros?

They're in asm/unistd.h.

I think that, instead of making qemu/osdep.h the new qemu-common.h, the
wrappers added by patch 3 should be declared in a new header
qemu/memfd.h.  The implementation in util/memfd.c can include both
linux/fcntl.h and asm/unistd.h.

Paolo
Marc-André Lureau July 28, 2015, 10:58 a.m. UTC | #3
Hi

On Tue, Jul 28, 2015 at 10:11 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>
>> What's defining all these macros?
>
> They're in asm/unistd.h.
>
> I think that, instead of making qemu/osdep.h the new qemu-common.h, the
> wrappers added by patch 3 should be declared in a new header
> qemu/memfd.h.  The implementation in util/memfd.c can include both
> linux/fcntl.h and asm/unistd.h.
>

Ok, shouldn't it keep the inline function? this avoids future clash
when upgrading glibc.
Paolo Bonzini July 28, 2015, 11:50 a.m. UTC | #4
On 28/07/2015 12:58, Marc-André Lureau wrote:
> Hi
> 
> On Tue, Jul 28, 2015 at 10:11 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>>
>>> What's defining all these macros?
>>
>> They're in asm/unistd.h.
>>
>> I think that, instead of making qemu/osdep.h the new qemu-common.h, the
>> wrappers added by patch 3 should be declared in a new header
>> qemu/memfd.h.  The implementation in util/memfd.c can include both
>> linux/fcntl.h and asm/unistd.h.
>>
> 
> Ok, shouldn't it keep the inline function? this avoids future clash
> when upgrading glibc.

Can the inline function stay in util/memfd.c?

Paolo
Marc-André Lureau July 28, 2015, 2:25 p.m. UTC | #5
Hi

On Tue, Jul 28, 2015 at 1:50 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:
> Can the inline function stay in util/memfd.c?

I see little benefits in that, only the qemu_memfd_alloc helpers would
then be exported. Then the inline is probably unnecessary if moved in
the memfd.c.
Paolo Bonzini July 28, 2015, 4:37 p.m. UTC | #6
On 28/07/2015 16:25, Marc-André Lureau wrote:
> > Can the inline function stay in util/memfd.c?
> I see little benefits in that, only the qemu_memfd_alloc helpers would
> then be exported. Then the inline is probably unnecessary if moved in
> the memfd.c.

That's just a matter of taste, I agree.

Paolo
diff mbox

Patch

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 3247364..adc138b 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -6,6 +6,7 @@ 
 #include <stddef.h>
 #include <stdbool.h>
 #include <stdint.h>
+#include <unistd.h>
 #include <sys/types.h>
 #ifdef __OpenBSD__
 #include <sys/signal.h>
@@ -20,6 +21,64 @@ 
 
 #include <sys/time.h>
 
+#ifdef CONFIG_LINUX
+
+#ifndef F_LINUX_SPECIFIC_BASE
+#define F_LINUX_SPECIFIC_BASE 1024
+#endif
+
+#ifndef F_ADD_SEALS
+#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
+#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
+
+#define F_SEAL_SEAL     0x0001  /* prevent further seals from being set */
+#define F_SEAL_SHRINK   0x0002  /* prevent file from shrinking */
+#define F_SEAL_GROW     0x0004  /* prevent file from growing */
+#define F_SEAL_WRITE    0x0008  /* prevent writes */
+#endif
+
+#ifndef MFD_ALLOW_SEALING
+#define MFD_ALLOW_SEALING 0x0002U
+#endif
+
+#ifndef MFD_CLOEXEC
+#define MFD_CLOEXEC 0x0001U
+#endif
+
+#ifndef __NR_memfd_create
+#  if defined __x86_64__
+#    define __NR_memfd_create 319
+#  elif defined __arm__
+#    define __NR_memfd_create 385
+#  elif defined __aarch64__
+#    define __NR_memfd_create 279
+#  elif defined _MIPS_SIM
+#    if _MIPS_SIM == _MIPS_SIM_ABI32
+#      define __NR_memfd_create 4354
+#    endif
+#    if _MIPS_SIM == _MIPS_SIM_NABI32
+#      define __NR_memfd_create 6318
+#    endif
+#    if _MIPS_SIM == _MIPS_SIM_ABI64
+#      define __NR_memfd_create 5314
+#    endif
+#  elif defined __i386__
+#    define __NR_memfd_create 356
+#  else
+#    warning "__NR_memfd_create unknown for your architecture"
+#    define __NR_memfd_create 0xffffffff
+#  endif
+#endif
+
+#ifndef CONFIG_MEMFD
+static inline int memfd_create(const char *name, unsigned int flags)
+{
+        return syscall(__NR_memfd_create, name, flags);
+}
+#endif
+
+#endif /* LINUX */
+
 #if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10
 /* [u]int_fast*_t not in <sys/int_types.h> */
 typedef unsigned char           uint_fast8_t;