mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v23 00/13] x86: Add x86 32 bit VDSO time function support
@ 2014-03-17 22:22 Stefani Seibold
  2014-03-17 22:22 ` [PATCH v23 01/13] x86, vdso: Make vsyscall_gtod_data handling x86 generic Stefani Seibold
                   ` (12 more replies)
  0 siblings, 13 replies; 32+ messages in thread
From: Stefani Seibold @ 2014-03-17 22:22 UTC (permalink / raw)
  To: gregkh, linux-kernel, x86, tglx, mingo, hpa, ak, aarcange,
	john.stultz, luto, xemul, gorcunov, andriy.shevchenko
  Cc: Martin.Runge, Andreas.Brief, Stefani Seibold

This patch add the functions vdso_gettimeofday(), vdso_clock_gettime()
and vdso_time() to the x86 32 bit VDSO.

The reason to do this was to get a fast reliable time stamp. Many developers
uses TSC to get a fast time stamp, without knowing the pitfalls. VDSO
time functions a fast and a reliable way, because the kernel knows the
best time source and the P- and C-state of the CPU.

The helper library to use the VDSO functions can be download at
http://http://seibold.net/vdso.c
The libary is very small, only 228 lines of code. Compile it with
gcc -Wall -O3 -fpic vdso.c -lrt -shared -o libvdso.so
and use it with LD_PRELOAD=<path>/libvdso.so

There is also a patch http://seibold.net/glibc.patch for glibc 2.19 which also
works for glibc 2.18.  This patch must be integrated into glibc.

Some linux 32 bit kernel benchmark results (all measurements are in nano
seconds):

Intel(R) Celeron(TM) CPU 400MHz

Average time kernel call:
 gettimeofday(): 1039
 clock_gettime(): 1578
 time(): 526
Average time VDSO call:
 gettimeofday(): 378
 clock_gettime(): 303
 time(): 60

Celeron(R) Dual-Core CPU T3100 1.90GHz

Average time kernel call:
 gettimeofday(): 209
 clock_gettime(): 406
 time(): 135
Average time VDSO call:
 gettimeofday(): 51
 clock_gettime(): 43
 time(): 10

So you can see a performance increase between 4 and 13, depending on the
CPU and the function.

The IA32 Emulation uses the whole 4 GB address space, so there is no
fixed address available.

The VDSO for a 32 bit application has now three pages:

^ Higher Address
|
+----------------------------------------+
+ VDSO page (includes code) ro+x         +
+----------------------------------------+
+ VVAR page (export kernel variables) ro +
+----------------------------------------+
+ HPET page (mapped registers) ro 
+----------------------------------------+
|
^ Lower Address

The VDSO page for a 32 bit resided still on 0xffffe000, the the VVAR and
HPET page are mapped before.

In the non compat mode the VMA of the VDSO is now 3 pages for a 32 bit kernel.
So this decrease the available logical address room by 2 pages.

The patch is against tip x86/vdso (1f2cbcf648962cdcf511d234cb39745baa9f5d07)

Changelog:
25.11.2012 - first release and proof of concept for linux 3.4
11.12.2012 - Port to linux 3.7 and code cleanup
12.12.2012 - fixes suggested by Andy Lutomirski
           - fixes suggested by John Stultz
           - use call VDSO32_vsyscall instead of int 80
           - code cleanup
17.12.2012 - support for IA32_EMULATION, this includes
             - code cleanup
             - include cleanup to fix compile warnings and errors
             - move out seqcount from seqlock, enable use in VDSO
             - map FIXMAP and HPET into the 32 bit address space
18.12.2012 - split into separate patches
30.01.2014 - revamp the code
             - code clean up
             - VDSO layout changed
             - no fixed addresses
             - port to 3.14
01.02.2014 - code cleanup
02.02.2014 - code cleanup
             - split into more patches
             - use HPET_COUNTER instead of hard coded value
             - fix changelog to the right year ;-)
02.02.2014 - reverse the mapping, this make the new VDSO 32 bit support
             full compatible.
03.02.2014 - code cleanup
             - fix comment
             - fix ABI break in vdso32.lds.S
04.02.2014 - revamp IA32 emulation support
             - introduce VVAR macro
             - rearranged vsyscall_gtod_data struture for IA32 emulation support
             - code cleanup
05.02.2014 - revamp IA32 emulation support
             - replace seqcount_t by an unsigned, to make the vsyscall_gtod_data
               structure independed of kernel config and functions.
08.02.2014 - revamp IA32 emulation support
             - replace all internal structures by fix size elements
10.02.2014 - code cleanup
             - add commets
             - revamp inline assembly
12.02.2014 - add conditional fixmap of vvar and hpet pages for 32 bit kernel
14.02.2014 - fix CONFIG_PARAVIRT_CLOCK, which is not supported in 32 bit VDSO
15.02.2014 - fix tsc
             code cleanup
             tested make ARCH=i386 allyesconfig and make allyesconfig
16.02.2014 - code cleanup
             - fix all C=1 warnings, also some one not introduced by this patch
             - hack to fix C=1 32 bit VDSO spinlock for a 64 bit kernel
             - fix VDSO Makefile for newer gcc
             tested for gcc 4.3.4 and 4.8.1
             tested ARCH=i386 allyesconfig, defconfig and allmodconfig
             tested X86_64 allyesconfig, defconfig and allmodconfig
17.02.2014 - In case of a 32 bit VDSO for a 64 bit kernel fake a 32 bit kernel
             configuration.
19.02.2014 - Add missing #undef and #define to fake proper 32 bit kernel config
             Add a missing #ifdef CONFIG_HPET_TIMER
             tested again ARCH=i386 allyesconfig, defconfig and allmodconfig
             tested again ARCH=X86_64 allyesconfig, defconfig and allmodconfig
02.03.2014 - Add fixes suggested by Andy Lutomirski
             - Patch alternatives in the 32 bit VDSO
	     - Use the default ABI for the 32 bit VDSO
	     - Inline the CLOCK MONOTONIC VDSO code
	     - Zero pad the VVAR page
	     - fix "patch alternatives" compile for 32 bit kernel
03.03.2014 - Add glibc.patch http://seibold.net/glibc.patch
             Add reviewed-by tags
17.03.2014 - Rebase on tip x86/vdso 1f2cbcf648962cdcf511d234cb39745baa9f5d07
             remove fixmap and compat mode dependencies

^ permalink raw reply	[flat|nested] 32+ messages in thread
* [Patch v22 02/12] x86: Add new func _install_special_mapping() to mmap.c
@ 2014-03-03 21:12 Stefani Seibold
  2014-03-05 22:30 ` [tip:x86/vdso] mm: " tip-bot for Stefani Seibold
  0 siblings, 1 reply; 32+ messages in thread
From: Stefani Seibold @ 2014-03-03 21:12 UTC (permalink / raw)
  To: gregkh, linux-kernel, x86, tglx, mingo, hpa, ak, aarcange,
	john.stultz, luto, xemul, gorcunov, andriy.shevchenko
  Cc: Martin.Runge, Andreas.Brief, Stefani Seibold

The _install_special_mapping() is the new base function for
install_special_mapping(). This function will return a pointer of the
created VMA or a error code in an ERR_PTR()

This new function will be needed by the for the vdso 32 bit support to map the
additonal vvar and hpet pages into the 32 bit address space. This will be done
with io_remap_pfn_range() and remap_pfn_range, which requieres a vm_area_struct.

Reviewed-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Stefani Seibold <stefani@seibold.net>
---
 include/linux/mm.h |  3 +++
 mm/mmap.c          | 20 ++++++++++++++++----
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index f28f46e..55342aa 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1740,6 +1740,9 @@ extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
 extern struct file *get_mm_exe_file(struct mm_struct *mm);
 
 extern int may_expand_vm(struct mm_struct *mm, unsigned long npages);
+extern struct vm_area_struct *_install_special_mapping(struct mm_struct *mm,
+				   unsigned long addr, unsigned long len,
+				   unsigned long flags, struct page **pages);
 extern int install_special_mapping(struct mm_struct *mm,
 				   unsigned long addr, unsigned long len,
 				   unsigned long flags, struct page **pages);
diff --git a/mm/mmap.c b/mm/mmap.c
index 20ff0c3..81ba54f 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2918,7 +2918,7 @@ static const struct vm_operations_struct special_mapping_vmops = {
  * The array pointer and the pages it points to are assumed to stay alive
  * for as long as this mapping might exist.
  */
-int install_special_mapping(struct mm_struct *mm,
+struct vm_area_struct *_install_special_mapping(struct mm_struct *mm,
 			    unsigned long addr, unsigned long len,
 			    unsigned long vm_flags, struct page **pages)
 {
@@ -2927,7 +2927,7 @@ int install_special_mapping(struct mm_struct *mm,
 
 	vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
 	if (unlikely(vma == NULL))
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
 	INIT_LIST_HEAD(&vma->anon_vma_chain);
 	vma->vm_mm = mm;
@@ -2948,11 +2948,23 @@ int install_special_mapping(struct mm_struct *mm,
 
 	perf_event_mmap(vma);
 
-	return 0;
+	return vma;
 
 out:
 	kmem_cache_free(vm_area_cachep, vma);
-	return ret;
+	return ERR_PTR(ret);
+}
+
+int install_special_mapping(struct mm_struct *mm,
+			    unsigned long addr, unsigned long len,
+			    unsigned long vm_flags, struct page **pages)
+{
+	struct vm_area_struct *vma = _install_special_mapping(mm,
+			    addr, len, vm_flags, pages);
+
+	if (IS_ERR(vma))
+		return PTR_ERR(vma);
+	return 0;
 }
 
 static DEFINE_MUTEX(mm_all_locks_mutex);
-- 
1.9.0


^ permalink raw reply	[flat|nested] 32+ messages in thread
* [PATCH v18 02/10] Add new func _install_special_mapping() to mmap.c
@ 2014-02-16 21:52 Stefani Seibold
  2014-02-17  0:52 ` [tip:x86/vdso] mm: " tip-bot for Stefani Seibold
  0 siblings, 1 reply; 32+ messages in thread
From: Stefani Seibold @ 2014-02-16 21:52 UTC (permalink / raw)
  To: gregkh, linux-kernel, x86, tglx, mingo, hpa, ak, aarcange,
	john.stultz, luto, xemul, gorcunov, andriy.shevchenko
  Cc: Martin.Runge, Andreas.Brief, Stefani Seibold

The _install_special_mapping() is the new base function for
install_special_mapping(). This function will return a pointer of the
created VMA or a error code in an ERR_PTR()

This new function will be needed by the for the vdso 32 bit support to map the
additonal vvar and hpet pages into the 32 bit address space. This will be done
with io_remap_pfn_range() and remap_pfn_range, which requieres a vm_area_struct.

Signed-off-by: Stefani Seibold <stefani@seibold.net>
---
 include/linux/mm.h |  3 +++
 mm/mmap.c          | 20 ++++++++++++++++----
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index f28f46e..55342aa 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1740,6 +1740,9 @@ extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
 extern struct file *get_mm_exe_file(struct mm_struct *mm);
 
 extern int may_expand_vm(struct mm_struct *mm, unsigned long npages);
+extern struct vm_area_struct *_install_special_mapping(struct mm_struct *mm,
+				   unsigned long addr, unsigned long len,
+				   unsigned long flags, struct page **pages);
 extern int install_special_mapping(struct mm_struct *mm,
 				   unsigned long addr, unsigned long len,
 				   unsigned long flags, struct page **pages);
diff --git a/mm/mmap.c b/mm/mmap.c
index 20ff0c3..81ba54f 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2918,7 +2918,7 @@ static const struct vm_operations_struct special_mapping_vmops = {
  * The array pointer and the pages it points to are assumed to stay alive
  * for as long as this mapping might exist.
  */
-int install_special_mapping(struct mm_struct *mm,
+struct vm_area_struct *_install_special_mapping(struct mm_struct *mm,
 			    unsigned long addr, unsigned long len,
 			    unsigned long vm_flags, struct page **pages)
 {
@@ -2927,7 +2927,7 @@ int install_special_mapping(struct mm_struct *mm,
 
 	vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
 	if (unlikely(vma == NULL))
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
 	INIT_LIST_HEAD(&vma->anon_vma_chain);
 	vma->vm_mm = mm;
@@ -2948,11 +2948,23 @@ int install_special_mapping(struct mm_struct *mm,
 
 	perf_event_mmap(vma);
 
-	return 0;
+	return vma;
 
 out:
 	kmem_cache_free(vm_area_cachep, vma);
-	return ret;
+	return ERR_PTR(ret);
+}
+
+int install_special_mapping(struct mm_struct *mm,
+			    unsigned long addr, unsigned long len,
+			    unsigned long vm_flags, struct page **pages)
+{
+	struct vm_area_struct *vma = _install_special_mapping(mm,
+			    addr, len, vm_flags, pages);
+
+	if (IS_ERR(vma))
+		return PTR_ERR(vma);
+	return 0;
 }
 
 static DEFINE_MUTEX(mm_all_locks_mutex);
-- 
1.8.5.5


^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2014-03-27 22:37 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-17 22:22 [PATCH v23 00/13] x86: Add x86 32 bit VDSO time function support Stefani Seibold
2014-03-17 22:22 ` [PATCH v23 01/13] x86, vdso: Make vsyscall_gtod_data handling x86 generic Stefani Seibold
2014-03-18 21:27   ` [tip:x86/vdso] " tip-bot for Stefani Seibold
2014-03-17 22:22 ` [PATCH v23 02/13] mm: Add new func _install_special_mapping() to mmap.c Stefani Seibold
2014-03-18 21:28   ` [tip:x86/vdso] " tip-bot for Stefani Seibold
2014-03-17 22:22 ` [PATCH v23 03/13] x86, vdso: Revamp vclock_gettime.c Stefani Seibold
2014-03-18 21:28   ` [tip:x86/vdso] " tip-bot for Stefani Seibold
2014-03-17 22:22 ` [PATCH v23 04/13] x86, vdso: __vdso_clock_gettime() cleanup Stefani Seibold
2014-03-18 21:28   ` [tip:x86/vdso] " tip-bot for Stefani Seibold
2014-03-17 22:22 ` [PATCH v23 05/13] x86, vdso: Replace VVAR(vsyscall_gtod_data) by gtod macro Stefani Seibold
2014-03-18 21:28   ` [tip:x86/vdso] " tip-bot for Stefani Seibold
2014-03-17 22:22 ` [PATCH v23 06/13] x86, vdso: Cleanup __vdso_gettimeofday() Stefani Seibold
2014-03-18 21:28   ` [tip:x86/vdso] " tip-bot for Stefani Seibold
2014-03-17 22:22 ` [PATCH v23 07/13] x86, vdso: Introduce VVAR marco for vdso32 Stefani Seibold
2014-03-18 21:29   ` [tip:x86/vdso] " tip-bot for Stefani Seibold
2014-03-17 22:22 ` [PATCH v23 08/13] x86, vdso: Patch alternatives in the 32-bit VDSO Stefani Seibold
2014-03-18 21:29   ` [tip:x86/vdso] " tip-bot for Andy Lutomirski
2014-03-17 22:22 ` [PATCH v23 09/13] x86, vdso: Add 32 bit VDSO time support for 32 bit kernel Stefani Seibold
2014-03-18 21:29   ` [tip:x86/vdso] " tip-bot for Stefani Seibold
2014-03-17 22:22 ` [PATCH v23 10/13] x86, vdso: Add 32 bit VDSO time support for 64 " Stefani Seibold
2014-03-18 21:29   ` [tip:x86/vdso] " tip-bot for Stefani Seibold
2014-03-27 20:44   ` [PATCH v23 10/13] " John Stultz
2014-03-27 21:12     ` Andy Lutomirski
2014-03-27 22:35     ` H. Peter Anvin
2014-03-17 22:22 ` [PATCH v23 11/13] x86, vdso: Zero-pad the VVAR page Stefani Seibold
2014-03-18 21:29   ` [tip:x86/vdso] " tip-bot for Andy Lutomirski
2014-03-17 22:22 ` [PATCH v23 12/13] x86, vdso32: Disable stack protector, adjust optimizations Stefani Seibold
2014-03-18 21:29   ` [tip:x86/vdso] " tip-bot for H. Peter Anvin
2014-03-17 22:22 ` [PATCH v23 13/13] x86, vdso32: handle 32 bit vDSO larger one page Stefani Seibold
2014-03-18 21:30   ` [tip:x86/vdso] " tip-bot for Stefani Seibold
  -- strict thread matches above, loose matches on Subject: below --
2014-03-03 21:12 [Patch v22 02/12] x86: Add new func _install_special_mapping() to mmap.c Stefani Seibold
2014-03-05 22:30 ` [tip:x86/vdso] mm: " tip-bot for Stefani Seibold
2014-02-16 21:52 [PATCH v18 02/10] " Stefani Seibold
2014-02-17  0:52 ` [tip:x86/vdso] mm: " tip-bot for Stefani Seibold

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome