This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: x86: Add 32 bit vDSO time function support


Hi Stefani

The guidelines are described at https://sourceware.org/glibc/wiki/Contribution%20checklist .
I think the first thing you should do is arrange the FSF copyright Assignment (part 8).

Now, related to your patch, first thing is usually we only backport bugfixes. The release
manager and community can make exceptions although. You patch also lacks a proper ChangeLog,
check part 11 of the link. Finally GLIBC current policy is to accept kernel internal
that are *already* implemented in Linux kernel, so the vDSO support do x86 32 bit kernel
should be either published in a kernel release on pushed in a stable kernel tree (usually
vanilla one).


On 04-03-2014 04:49, Stefani Seibold wrote:
> Hi,
>
> in the near future the linux will support vDSO time functions for the
> x86 32 bit kernels. This will be also supported the ia32 emulation mode.
>
> The VDSO time functions __vdso_time(), __vdso_gettimeofday() and
> __vdso_clock_getttime() are fast and a reliable way to get the exact
> time without the overhead of a kernel system call.
>
> This result in a  performance increase between 4 and 13 for this
> functions, depending on the CPU and the function.
>
> I will attach the patch against glibc-2.19, which is not very intrusive,
> since it only make changes in the  sysdeps/unix/sysv/linux/i386 path.
>
> How is the procedure to get this patch into the glibc mainline?
>
> - Stefani
>
> diff -u -N -r -p glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/bits/libc-vdso.h glibc-2.18/sysdeps/unix/sysv/linux/i386/bits/libc-vdso.h
> --- glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/bits/libc-vdso.h	1970-01-01 01:00:00.000000000 +0100
> +++ glibc-2.18/sysdeps/unix/sysv/linux/i386/bits/libc-vdso.h	2014-03-03 11:29:26.799650036 +0100
> @@ -0,0 +1,31 @@
> +/* Resolve function pointers to VDSO functions.
> +   Copyright (C) 2005-2013 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef _LIBC_VDSO_H
> +#define _LIBC_VDSO_H
> +
> +#include <time.h>
> +#include <sys/time.h>
> +
> +#ifdef SHARED
> +
> +extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
> +
> +#endif
> +
> +#endif /* _LIBC_VDSO_H */
> diff -u -N -r -p glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/clock_gettime.c glibc-2.18/sysdeps/unix/sysv/linux/i386/clock_gettime.c
> --- glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/clock_gettime.c	1970-01-01 01:00:00.000000000 +0100
> +++ glibc-2.18/sysdeps/unix/sysv/linux/i386/clock_gettime.c	2014-03-03 11:44:54.873047522 +0100
> @@ -0,0 +1,20 @@
> +#include "bits/libc-vdso.h"
> +
> +#ifdef SHARED
> +# define SYSCALL_GETTIME(id, tp) \
> +  ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> +  long int v_ret;							  \
> +  PTR_DEMANGLE (f);							  \
> +  v_ret = f (id, tp);							  \
> +  if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) {				  \
> +    __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, ));			  \
> +    v_ret = -1;								  \
> +  }									  \
> +  v_ret; })
> +# define INTERNAL_GETTIME(id, tp) \
> +  ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> +  PTR_DEMANGLE (f);							  \
> +  f (id, tp); })
> +#endif
> +
> +#include "../clock_gettime.c"
> diff -u -N -r -p glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/gettimeofday.c glibc-2.18/sysdeps/unix/sysv/linux/i386/gettimeofday.c
> --- glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/gettimeofday.c	1970-01-01 01:00:00.000000000 +0100
> +++ glibc-2.18/sysdeps/unix/sysv/linux/i386/gettimeofday.c	2014-03-03 17:08:02.021699309 +0100
> @@ -0,0 +1,65 @@
> +/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <sys/time.h>
> +
> +#ifdef SHARED
> +
> +# include <dl-vdso.h>
> +# include <sysdep.h>
> +# include <errno.h>
> +
> +static int
> +fallback_gettimeofday (struct timeval *tv, struct timezone *tz)
> +{
> +  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> +}
> +
> +void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
> +
> +void *
> +gettimeofday_ifunc (void)
> +{
> +  PREPARE_VERSION (linux25, "LINUX_2.5", 61765109);
> +
> +  /* If the vDSO is not available we fall back on the old syscall.  */
> +  return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux25)
> +	  ?: (void *) fallback_gettimeofday);
> +}
> +asm (".type __gettimeofday, %gnu_indirect_function");
> +
> +/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
> +   let us do it in C because it doesn't know we're defining __gettimeofday
> +   here in this file.  */
> +asm (".globl __GI___gettimeofday\n"
> +     "__GI___gettimeofday = __gettimeofday");
> +
> +#else
> +
> +# include <sysdep.h>
> +# include <errno.h>
> +
> +int
> +__gettimeofday (struct timeval *tv, struct timezone *tz)
> +{
> +  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> +}
> +libc_hidden_def (__gettimeofday)
> +
> +#endif
> +weak_alias (__gettimeofday, gettimeofday)
> +libc_hidden_weak (gettimeofday)
> diff -u -N -r -p glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/init-first.c glibc-2.18/sysdeps/unix/sysv/linux/i386/init-first.c
> --- glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/init-first.c	1970-01-01 01:00:00.000000000 +0100
> +++ glibc-2.18/sysdeps/unix/sysv/linux/i386/init-first.c	2014-03-03 16:16:37.766257808 +0100
> @@ -0,0 +1,52 @@
> +/* Initialization code run first thing by the ELF startup code.  Linux/i386.
> +   Copyright (C) 2007-2013 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifdef SHARED
> +# include <time.h>
> +# include <sysdep.h>
> +# include <dl-vdso.h>
> +# include <bits/libc-vdso.h>
> +
> +long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
> +  __attribute__ ((nocommon));
> +strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
> +
> +
> +long int fallback_clock_gettime(clockid_t id, struct timespec *tp)
> +{
> +  INTERNAL_SYSCALL_DECL (err);
> +  return INTERNAL_SYSCALL (clock_gettime, err, 2, id, tp);
> +}
> +
> +
> +static inline void
> +_libc_vdso_platform_setup (void)
> +{
> +  PREPARE_VERSION (linux25, "LINUX_2.5", 61765109);
> +
> +  void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux25);
> +  if (p == NULL)
> +    p = fallback_clock_gettime;
> +  PTR_MANGLE (p);
> +  __GI___vdso_clock_gettime = p;
> +}
> +
> +# define VDSO_SETUP _libc_vdso_platform_setup
> +#endif
> +
> +#include <csu/init-first.c>
> diff -u -N -r -p glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/Makefile glibc-2.18/sysdeps/unix/sysv/linux/i386/Makefile
> --- glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/Makefile	2013-08-11 00:52:55.000000000 +0200
> +++ glibc-2.18/sysdeps/unix/sysv/linux/i386/Makefile	2014-03-03 11:34:21.922960487 +0100
> @@ -21,3 +21,7 @@ endif
>  ifeq ($(subdir),stdlib)
>  gen-as-const-headers += ucontext_i.sym
>  endif
> +
> +ifeq ($(subdir),elf)
> +sysdep_routines += dl-vdso
> +endif
> diff -u -N -r -p glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/time.c glibc-2.18/sysdeps/unix/sysv/linux/i386/time.c
> --- glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/time.c	1970-01-01 01:00:00.000000000 +0100
> +++ glibc-2.18/sysdeps/unix/sysv/linux/i386/time.c	2014-03-03 16:19:09.428361771 +0100
> @@ -0,0 +1,67 @@
> +/* Copyright (C) 2001-2013 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifdef SHARED
> +/* Redefine time so that the compiler won't complain about the type
> +   mismatch with the IFUNC selector in strong_alias, below.  */
> +#undef time
> +#define time __redirect_time
> +#include <time.h>
> +#include <sysdep.h>
> +
> +static time_t
> +fallback_time (time_t *t)
> +{
> +  INTERNAL_SYSCALL_DECL (err);
> +  return INTERNAL_SYSCALL (time, err, 1, t);
> +}
> +
> +
> +#include <dl-vdso.h>
> +
> +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
> +   ifunc symbol properly.  */
> +extern __typeof (__redirect_time) __libc_time;
> +void *time_ifunc (void) __asm__ ("__libc_time");
> +
> +void *
> +time_ifunc (void)
> +{
> +  PREPARE_VERSION (linux25, "LINUX_2.5", 61765109);
> +
> +  /* If the vDSO is not available we fall back on the old syscall.  */
> +  return _dl_vdso_vsym ("__vdso_time", &linux25) ?: (void *) fallback_time;
> +}
> +__asm (".type __libc_time, %gnu_indirect_function");
> +
> +#undef time
> +strong_alias (__libc_time, time)
> +libc_hidden_ver (__libc_time, time)
> +
> +#else
> +
> +# include <time.h>
> +# include <sysdep.h>
> +
> +time_t
> +time (time_t *t)
> +{
> +  INTERNAL_SYSCALL_DECL (err);
> +  return INTERNAL_SYSCALL (time, err, 1, t);
> +}
> +
> +#endif
> diff -u -N -r -p glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/timespec_get.c glibc-2.18/sysdeps/unix/sysv/linux/i386/timespec_get.c
> --- glibc-2.18.orig/sysdeps/unix/sysv/linux/i386/timespec_get.c	1970-01-01 01:00:00.000000000 +0100
> +++ glibc-2.18/sysdeps/unix/sysv/linux/i386/timespec_get.c	2014-03-03 11:22:34.829800368 +0100
> @@ -0,0 +1,10 @@
> +#include "bits/libc-vdso.h"
> +
> +#ifdef SHARED
> +# define INTERNAL_GETTIME(id, tp) \
> +  ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> +  PTR_DEMANGLE (f);							  \
> +  f (id, tp); })
> +#endif
> +
> +#include "../timespec_get.c"
>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]