Immediates Values (real variables)
Subsystems (15)
cover Immediates Values (real variables)
Hi Andrew,
Here is the new version of the immediate values. It should be _must_ more useful like this: it now provides full variables encoded as load immediates in the instruction stream. It has been thoroughly tested too.
It applies to 2.6.22-rc6-mm1 (just like the text edit lock) It depends on the text edit lock patches.
Mathieu
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/8 Immediate values - Global modules list and module mutex
Remove "static" from module_mutex and the modules list so it can be used by other builtin objects in the kernel. Otherwise, every code depending on the module list would have to be put in kernel/module.c. Since the immediate values depends on the module list but can be considered as logically different, it makes sense to implement them in their own file.
--- include/linux/module.h | 4 ++++ kernel/module.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-)
kernel/module.c +2 -2
@@ -65,8 +65,8 @@static DEFINE_SPINLOCK (modlist_lock);/* List of modules, protected by module_mutex AND modlist_lock */ -static DEFINE_MUTEX (module_mutex); -static LIST_HEAD (modules); +DEFINE_MUTEX (module_mutex); +LIST_HEAD (modules);static DECLARE_MUTEX (notify_mutex);static BLOCKING_NOTIFIER_HEAD (module_notify_list);
include/linux/module.h +4 -0
@@ -60,6 +60,10 @@struct kobject *drivers_dir; }; +/* Protects the list of modules. */ +extern struct mutex module_mutex; +extern struct list_head modules; +/* These are either module local, or the kernel's dummy ones. */ extern int init_module (void );extern void cleanup_module (void );
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 2/8 Immediate Value - Architecture Independent Code
In reply to Mathieu DesnoyersImmediate values are used as read mostly variables that are rarely updated. They use code patching to modify the values inscribed in the instruction stream. It provides a way to save precious cache lines that would otherwise have to be used by these variables.
There is a generic _immediate_read() version, which uses standard global variables, and optimized per architecture immediate_read() implementations, which use a load immediate to remove a data cache hit. When the immediate values functionnality is disabled in the kernel, it falls back to global variables.
It adds a new rodata section "__immediate" to place the pointers to the enable value. Immediate values activation functions sits in kernel/immediate.c.
Immediate values refer to the memory address of a previously declared integer. This integer holds the information about the state of the immediate values associated, and must be accessed through the API found in linux/immediate.h.
At module load time, each immediate value is checked to see if it must be enabled. It would be the case if the variable they refer to is exported from another module and already enabled.
In the early stages of start_kernel(), the immediate values are updated to reflect the state of the variable they refer to.
* Why should this be merged *
It improves performances on heavy memory I/O workloads.
An interesting result shows the potential this infrastructure has by showing the slowdown a simple system call such as getppid() suffers when it is used under heavy user-space cache trashing:
Random walk L1 and L2 trashing surrounding a getppid() call:
(note: in this test, do_syscal_trace was taken at each system call, see Documentation/immediate.txt in these patches for details)
- No memory pressure : getppid() takes 1573 cycles
- With memory pressure : getppid() takes 15589 cycles
We therefore have a slowdown of 10 times just to get the kernel variables from memory. Another test on the same architecture (Intel P4) measured the memory latency to be 559 cycles. Therefore, each cache line removed from the hot path would improve the syscall time of 3.5% in these conditions.
--- include/asm-generic/vmlinux.lds.h | 7 ++ include/linux/immediate.h | 53 ++++++++++++++++ include/linux/module.h | 6 + init/main.c | 2 kernel/Makefile | 1 kernel/immediate.c | 119 ++++++++++++++++++++++++++++++++++++++ kernel/module.c | 16 +++++ 7 files changed, 204 insertions(+)
include/linux/immediate.h new file +53 -0
@@ -0,0 +1,53 @@ +#ifndef _LINUX_IMMEDIATE_H +#define _LINUX_IMMEDIATE_H + +/* +* Immediate values, can be updated at runtime and save cache lines. +* +* (C) Copyright 2007 Mathieu Desnoyers <[email protected]> +* +* This file is released under the GPLv2. +* See the file COPYING for more details. +*/ + +#ifdef __KERNEL__ + +#ifdef CONFIG_IMMEDIATE +#include <asm/immediate.h> +#else +#include <asm-generic/immediate.h> +#endif + +/* +* Always access this type with the provided functions. +*/ +#define DEFINE_IMMEDIATE_TYPE (type, name) \ + typedef struct { type value; } name + +/* +* Standard pre-defined immediate types. +*/ +DEFINE_IMMEDIATE_TYPE (char, immediate_char_t); +DEFINE_IMMEDIATE_TYPE (short, immediate_short_t); +DEFINE_IMMEDIATE_TYPE (int, immediate_int_t); +DEFINE_IMMEDIATE_TYPE (long, immediate_long_t); +DEFINE_IMMEDIATE_TYPE(void*, immediate_void_ptr_t); + +/* +* Use this macro to initialize an immediate value to an initial static value. +*/ +#define IMMEDIATE_INIT (i) { (i) } + +/* +* Force a data read of the immediate value instead of the immediate value +* based mechanism. Useful for __init and __exit section data read. +*/ +#define _immediate_read (var) (var)->value + +/* +* Force the use of a normal if () statement depending on an immediate value. +*/ +#define _immediate_if (var) if (_immediate_read(var)) + +#endif /* __KERNEL__ */ +#endif
include/asm-generic/vmlinux.lds.h +7 -0
@@ -122,6 +122,13 @@ VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \ } \ \ +/* Immediate values: pointers */ \ + __immediate : AT(ADDR(__immediate) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___immediate) = .; \ + *(__immediate ) \ + VMLINUX_SYMBOL(__stop___immediate) = .; \ + } \ + \/* Kernel symbol table: strings */ \ __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ *(__ksymtab_strings) \
include/linux/module.h +6 -0
@@ -15,6 +15,7 @@#include <linux/stringify.h> #include <linux/kobject.h> #include <linux/moduleparam.h> +#include <linux/immediate.h> #include <asm/local.h> #include <asm/module.h>
@@ -374,6 +375,11 @@/* The command line arguments (may be mangled). People like keeping pointers to this stuff */ char *args; + +#ifdef CONFIG_IMMEDIATE +const struct __immediate *immediate; +unsigned int num_immediate; +#endif };#ifndef MODULE_ARCH_INIT #define MODULE_ARCH_INIT {}
kernel/module.c +16 -0
@@ -32,6 +32,7 @@#include <linux/cpu.h> #include <linux/moduleparam.h> #include <linux/errno.h> +#include <linux/immediate.h> #include <linux/err.h> #include <linux/vermagic.h> #include <linux/notifier.h>
@@ -1623,6 +1624,7 @@unsigned int unusedcrcindex;unsigned int unusedgplindex;unsigned int unusedgplcrcindex; +unsigned int immediateindex =0 ;struct module *mod;long err =0 ;void *percpu =NULL , *ptr =NULL ;/* Stops spurious gcc warning */
@@ -1719,6 +1721,9 @@#ifdef ARCH_UNWIND_SECTION_NAME unwindex =find_sec (hdr, sechdrs, secstrings,ARCH_UNWIND_SECTION_NAME );#endif +#ifdef CONFIG_IMMEDIATE + immediateindex =find_sec (hdr, sechdrs, secstrings,"__immediate" ); +#endif /* Don't keep modinfo section */ sechdrs[infoindex].sh_flags &= ~(unsigned long )SHF_ALLOC ;
@@ -1729,6 +1734,8 @@#endif if (unwindex) sechdrs[unwindex].sh_flags |=SHF_ALLOC ; +if (immediateindex) + sechdrs[immediateindex].sh_flags |=SHF_ALLOC ;/* Check module struct version now, before we try to use module. */ if (!check_modstruct_version (sechdrs, versindex, mod)) {
@@ -1869,6 +1876,13 @@ mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;if (gplfuturecrcindex) mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr; +#ifdef CONFIG_IMMEDIATE +if (immediateindex) { + mod->immediate = (void *)sechdrs[immediateindex].sh_addr; + mod->num_immediate = + sechdrs[immediateindex].sh_size /sizeof (*mod->immediate); + } +#endif mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr;if (unusedcrcindex)
@@ -1934,6 +1948,8 @@ }#endif +module_immediate_setup (mod); + err =module_finalize (hdr, sechdrs, mod);if (err <0 ) goto cleanup;
kernel/Makefile +1 -0
@@ -58,6 +58,7 @@ obj-$(CONFIG_SYSCTL) += utsname_sysctl.o obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o +obj-$(CONFIG_IMMEDIATE) += immediate.o ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) # According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
kernel/immediate.c new file +119 -0
119 lines not on this page · raw message
init/main.c +2 -0
@@ -56,6 +56,7 @@#include <linux/pid_namespace.h> #include <linux/device.h> #include <linux/kthread.h> +#include <linux/immediate.h> #include <asm/io.h> #include <asm/bugs.h>
@@ -521,6 +522,7 @@unwind_init ();lockdep_init ();container_init_early (); +immediate_update_early ();local_irq_disable ();early_boot_irqs_off ();
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 2/8] Immediate Value - Architecture Independent Code
Quoted 1 line · Mathieu Desnoyers
+#ifdef
__KERNEL__
no need for this. unless you add the header to header-y in the Kbuild file it's not exported to userspace at all.
include/linux/immediate.h line 19
Quoted 5 lines
include/linux/immediate.h new file +5
-0+#ifdef CONFIG_IMMEDIATE +#include <asm/immediate.h> +#else +#include <asm-generic/immediate.h> +#endif
Nack on this one. linux/*.h should never include asm-generic headers.
Either put the !CONFIG_IMMEDIATE code directly into this file or let every arch have a one-liner immediate.h that includes the asm-generic one. The first method is probably a lot nicer.
kernel/immediate.c line 30
Quoted 5 lines
kernel/immediate.c new file +5
-0+/* +* modules_mutex nests inside immediate_mutex. immediate_mutex protects builtin +* immediates and module immediates. +*/ +DEFINE_MUTEX (immediate_mutex);
Why is this non-static?
kernel/immediate.c line 36
Quoted 6 lines
kernel/immediate.c new file +6
-0+ +/* +* Sets a range of immediates to a enabled state : set the enable bit. +*/ +static void _immediate_update_range ( +const struct __immediate *begin,const struct __immediate *end)
static void _immediate_update_range(const struct __immediate *begin,
const struct __immediate *end)
same for a few more functions here.
Quoted 1 line
+#ifdef
CONFIG_MODULES
...
kernel/immediate.c line 70
Quoted 3 lines
kernel/immediate.c new file +3
-0+#endif + +#ifdef CONFIG_MODULES
please put all this code into a single ifdef block.
note that the exported functions probably want some kerneldoc documentation.
PATCH 1/1 Immediate Values - Architecture Independent Code - Fixes following HCH comments
In reply to Mathieu DesnoyersImmediate Values - Architecture Independent Code - Fixes following HCH comments
Various coding style fixes following Christoph's comments Put asm-generic/immediate.h content into linux/immediate.h. Remove ifdef __KERNEL__ in .h never exported to user space. Make immediate_mutex static.
It applies after "Immediate Values - Architecture Independent Code".
--- include/linux/immediate.h | 18 ++++++++++++++---- kernel/immediate.c | 15 +++++++-------- 2 files changed, 21 insertions(+), 12 deletions(-)
include/linux/immediate.h +14 -4
@@ -10,12 +10,23 @@* See the file COPYING for more details. */ -#ifdef __KERNEL__ -#ifdef CONFIG_IMMEDIATE #include <asm/immediate.h> #else -#include <asm-generic/immediate.h> +/* +* Generic immediate values: a simple, standard, memory load. +*/ + +struct module ; + +#define immediate_read (var) _immediate_read(var) +#define immediate_set (var, i) ((var)->value = (i)) +#define _immediate_set (var, i) immediate_set(var, i) +#define immediate_set_early (var, i) immediate_set(var, i) +#define immediate_if (var) if (immediate_read(var)) + +static inline void module_immediate_setup (struct module *mod) { } +static inline void immediate_update_early (void ) { }#endif /*
@@ -49,5 +60,4 @@ DEFINE_IMMEDIATE_TYPE(void*, immediate_v*/ #define _immediate_if (var) if (_immediate_read(var)) -#endif /* __KERNEL__ */ #endif
kernel/immediate.c +7 -8
@@ -27,13 +27,13 @@ extern const struct __immediate __stop__* modules_mutex nests inside immediate_mutex. immediate_mutex protects builtin * immediates and module immediates. */ -DEFINE_MUTEX (immediate_mutex); +static DEFINE_MUTEX (immediate_mutex);/* * Sets a range of immediates to a enabled state : set the enable bit. */ -static void _immediate_update_range ( -const struct __immediate *begin,const struct __immediate *end) +static inline void _immediate_update_range (const struct __immediate *begin, +const struct __immediate *end) {const struct __immediate *iter;int ret;
@@ -63,11 +63,10 @@ static void _immediate_update_range(*/ void module_immediate_setup (struct module *mod) { -_immediate_update_range (mod->immediate, mod->immediate+mod->num_immediate); +_immediate_update_range (mod->immediate, + mod->immediate+mod->num_immediate); } -#endif -#ifdef CONFIG_MODULES /* * immediate mutex nests inside the modules mutex. */
@@ -103,8 +102,8 @@ EXPORT_SYMBOL_GPL(immediate_update);* Update the immediate values to the state of the variables they refer to. It * is done before SMP is active, at the very beginning of start_kernel(). */ -void __init immediate_update_early_range ( -const struct __immediate *begin,const struct __immediate *end) +void __init immediate_update_early_range (const struct __immediate *begin, +const struct __immediate *end) {const struct __immediate *iter;
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/1 Immediate Values - Architecture Independent Code - kerneldoc
Immediate Values - Architecture Independent Code - kerneldoc
Add kerneldoc to Immediate Values API.
--- include/linux/immediate.h | 66 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-)
include/linux/immediate.h +61 -5
@@ -19,18 +19,64 @@struct module ; +/** +* immediate_read - read immediate variable +* @var: pointer of type immediate_*_t +* +* Reads the value of @var. +*/ #define immediate_read (var) _immediate_read(var) + +/** +* immediate_set - set immediate variable (with locking) +* @var: pointer of type immediate_*_t +* @i: required value +* +* Sets the value of @var, taking the module_mutex if required by +* the architecture. +*/ #define immediate_set (var, i) ((var)->value = (i)) + +/** +* _immediate_set - set immediate variable (without locking) +* @var: pointer of type immediate_*_t +* @i: required value +* +* Sets the value of @var. Must be called with module_mutex held. +*/ #define _immediate_set (var, i) immediate_set(var, i) + +/** +* immediate_set_early - set immediate variable at early boot +* @var: pointer of type immediate_*_t +* @i: required value +* +* Sets the value of @var. Should be used for early boot updates. +*/ #define immediate_set_early (var, i) immediate_set(var, i) + +/** +* immediate_if - if () statement depending on an immediate value +* @var: pointer of type immediate_*_t +* +* Use as an if () statement depending on an immediate value. +*/ #define immediate_if (var) if (immediate_read(var)) +/* +* Internal update functions. +*/ static inline void module_immediate_setup (struct module *mod) { }static inline void immediate_update_early (void ) { }#endif -/* -* Always access this type with the provided functions. +/** +* DEFINE_IMMEDIATE_TYPE - Define an immediate type +* @type: type that the immediate should hold +* @name: name of the immediate type +* +* Define new immediate types. Naming scheme is immediate_*_t. +* Always access these types with the provided functions. */ #define DEFINE_IMMEDIATE_TYPE (type, name) \ typedef struct { type value; } name
@@ -44,18 +90,28 @@ DEFINE_IMMEDIATE_TYPE(int, immediate_intDEFINE_IMMEDIATE_TYPE (long, immediate_long_t); DEFINE_IMMEDIATE_TYPE(void*, immediate_void_ptr_t); -/* -* Use this macro to initialize an immediate value to an initial static value. +/** +* IMMEDIATE_INIT - Static initialization of an immediate variable +* @i: required value +* +* Use this macro to initialize an immediate value to an initial static +* value. */ #define IMMEDIATE_INIT (i) { (i) } -/* +/** +* _immediate_read - Read immediate value with standard memory load. +* @var: pointer of type immediate_*_t +* * Force a data read of the immediate value instead of the immediate value * based mechanism. Useful for __init and __exit section data read. */ #define _immediate_read (var) (var)->value/* +* _immediate_if - if () statement depending on immediate value (memory load) +* @var: pointer of type immediate_*_t +* * Force the use of a normal if () statement depending on an immediate value. */ #define _immediate_if (var) if (_immediate_read(var))
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/1 Immediate Values - Architecture Independent Code - kerneldoc for implementation
Immediate Values - Architecture Independent Code - kerneldoc for implementation
Add kerneldoc to Immediate Values API.
It applies after
"Immediate Values - Architecture Independent Code - kerneldoc"
--- kernel/immediate.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-)
kernel/immediate.c +17 -7
@@ -54,7 +54,10 @@ static inline void _immediate_update_ran }#ifdef CONFIG_MODULES -/* +/** +* module_immediate_setup - Update immediate values in a module +* @mod: pointer to the struct module +* * Setup the immediate according to the variable upon which it depends. Called * by load_module with module_mutex held. This mutex protects against concurrent * modifications to modules'immediates. Therefore, since
@@ -89,6 +92,12 @@ static inline void immediate_update_modustatic inline void immediate_update_modules (int lock) { }#endif +/** +* immediate_update - update all immediate values in the kernel +* @lock: should a module_mutex be taken ? +* +* Iterate on the kernel core and modules to update the immediate values. +*/ void immediate_update (int lock) {/* Core kernel immediates */
@@ -98,11 +107,7 @@ void immediate_update(int lock) }EXPORT_SYMBOL_GPL (immediate_update); -/* -* Update the immediate values to the state of the variables they refer to. It -* is done before SMP is active, at the very beginning of start_kernel(). -*/ -void __init immediate_update_early_range (const struct __immediate *begin, +static void __init immediate_update_early_range (const struct __immediate *begin,const struct __immediate *end) {const struct __immediate *iter;
@@ -111,7 +116,12 @@ void __init immediate_update_early_rangearch_immediate_update_early (iter); } - +/** +* immediate_update_early - Update immediate values at boot time +* +* Update the immediate values to the state of the variables they refer to. It +* is done before SMP is active, at the very beginning of start_kernel(). +*/ void __init immediate_update_early (void ) {immediate_update_early_range (__start___immediate, __stop___immediate);
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/1 Immediate Value - Architecture Independent Code Deferred Sync
In reply to Mathieu DesnoyersLinux Kernel Markers - Architecture Independent Code Deferred Sync
Upon marker probe_unregister, we delay call to synchronize_sched() to accelerate mass unregistration (only when there is no more reference to a give module do we call synchronize_sched()). However, we need to make sure every critical region have ended before we re-arm a marker that has been unregistered and then registered back with a different probe data.
--- kernel/marker.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
kernel/marker.c +20 -2
@@ -30,11 +30,21 @@ extern struct __mark_marker __stop___mar/* * module_mutex nests inside markers_mutex. Markers mutex protects the builtin -* and module markers, and the hash table. +* and module markers, the hash table and deferred_sync. */ DEFINE_MUTEX (markers_mutex);/* +* Marker deferred synchronization. +* Upon marker probe_unregister, we delay call to synchronize_sched() to +* accelerate mass unregistration (only when there is no more reference to a +* give module do we call synchronize_sched()). However, we need to make sure +* every critical region have ended before we re-arm a marker that has been +* unregistered and then registered back with a different probe data. +*/ +static int deferred_sync; + +/* * Marker hash table, containing the active markers. * Protected by module_mutex. */
@@ -303,8 +313,10 @@ static inline void __marker_update_probe __stop___markers, probe_module, &refcount);/* Markers in modules. */ __marker_update_probes_modules (probe_module, &refcount); -if (probe_module && refcount ==0 ) +if (probe_module && refcount ==0 ) {synchronize_sched (); + deferred_sync =0 ; + } }#ifdef CONFIG_MODULES
@@ -353,6 +365,10 @@ int marker_probe_register(const char *na ret = -EBUSY ; goto end; } +if (deferred_sync) { +synchronize_sched (); + deferred_sync =0 ; + } ret =_add_marker (name, format, probe, pdata);if (ret) goto end;
@@ -384,6 +400,7 @@ void *marker_probe_unregister(const char/* In what module is the probe handler ? */ probe_module =__module_text_address ((unsigned long )entry->probe); pdata =_remove_marker (name); + deferred_sync =1 ;_marker_update_probes (probe_module); end:mutex_unlock (&markers_mutex);
@@ -425,6 +442,7 @@ iter_end:/* In what module is the probe handler ? */ probe_module =__module_text_address ((unsigned long )entry->probe); pdata =_remove_marker (entry->name); + deferred_sync =1 ;_marker_update_probes (probe_module); end:mutex_unlock (&markers_mutex);
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [PATCH] Immediate Value - Architecture Independent Code Deferred Sync
Please drop, wrong thread. Will repost in the right one.
Quoted 90 lines · * Mathieu Desnoyers ([email protected]) wrote:
Linux Kernel Markers - Architecture Independent Code Deferred Sync
Upon marker
probe_unregister, we delay call tosynchronize_sched()to accelerate mass unregistration (only when there is no more reference to a give module do we callsynchronize_sched()). However, we need to make sure every critical region have ended before we re-arm a marker that has been unregistered and then registered back with a different probe data.Signed-off-by Mathieu Desnoyers <[email protected]>CC Christoph Hellwig <[email protected]>--- kernel/marker.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)Index:
linux-2.6-lttng/kernel/marker.c
===================================================================kernel/marker.c +20
-2@@ -30,11 +30,21 @@ extern struct __mark_marker __stop___mar/* * module_mutex nests inside markers_mutex. Markers mutex protects the builtin -* and module markers, and the hash table. +* and module markers, the hash table and deferred_sync. */ DEFINE_MUTEX (markers_mutex);/* +* Marker deferred synchronization. +* Upon marker probe_unregister, we delay call to synchronize_sched() to +* accelerate mass unregistration (only when there is no more reference to a +* give module do we call synchronize_sched()). However, we need to make sure +* every critical region have ended before we re-arm a marker that has been +* unregistered and then registered back with a different probe data. +*/ +static int deferred_sync; + +/* * Marker hash table, containing the active markers. * Protected by module_mutex. */ @@ -303,8 +313,10 @@ static inline void __marker_update_probe __stop___markers, probe_module, &refcount);/* Markers in modules. */ __marker_update_probes_modules (probe_module, &refcount); -if (probe_module && refcount ==0 ) +if (probe_module && refcount ==0 ) {synchronize_sched (); + deferred_sync =0 ; + } }#ifdef CONFIG_MODULES @@ -353,6 +365,10 @@ int marker_probe_register(const char *na ret = -EBUSY ; goto end; } +if (deferred_sync) { +synchronize_sched (); + deferred_sync =0 ; + } ret =_add_marker (name, format, probe, pdata);if (ret) goto end;@@ -384,6 +400,7 @@ void *marker_probe_unregister(const char/* In what module is the probe handler ? */ probe_module =__module_text_address ((unsigned long )entry->probe); pdata =_remove_marker (name); + deferred_sync =1 ;_marker_update_probes (probe_module); end:mutex_unlock (&markers_mutex);@@ -425,6 +442,7 @@ iter_end:/* In what module is the probe handler ? */ probe_module =__module_text_address ((unsigned long )entry->probe); pdata =_remove_marker (entry->name); + deferred_sync =1 ;_marker_update_probes (probe_module); end:mutex_unlock (&markers_mutex);Signature · 8 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 3/8 Immediate Values - Non Optimized Architectures
In reply to Mathieu DesnoyersArchitecture agnostic, generic, version of the immediate values. It uses a global variable to mimic the immediate values.
--- include/asm-alpha/immediate.h | 1 + include/asm-arm/immediate.h | 1 + include/asm-arm26/immediate.h | 1 + include/asm-blackfin/immediate.h | 1 + include/asm-cris/immediate.h | 1 + include/asm-frv/immediate.h | 1 + include/asm-generic/immediate.h | 19 +++++++++++++++++++ include/asm-h8300/immediate.h | 1 + include/asm-i386/immediate.h | 1 + include/asm-ia64/immediate.h | 1 + include/asm-m32r/immediate.h | 1 + include/asm-m68k/immediate.h | 1 + include/asm-m68knommu/immediate.h | 1 + include/asm-mips/immediate.h | 1 + include/asm-parisc/immediate.h | 1 + include/asm-powerpc/immediate.h | 1 + include/asm-ppc/immediate.h | 1 + include/asm-s390/immediate.h | 1 + include/asm-sh/immediate.h | 1 + include/asm-sh64/immediate.h | 1 + include/asm-sparc/immediate.h | 1 + include/asm-sparc64/immediate.h | 1 + include/asm-um/immediate.h | 1 + include/asm-v850/immediate.h | 1 + include/asm-x86_64/immediate.h | 1 + include/asm-xtensa/immediate.h | 1 + 26 files changed, 44 insertions(+)
include/asm-generic/immediate.h new file +19 -0
@@ -0,0 +1,19 @@ +#ifndef _ASM_GENERIC_IMMEDIATE_H +#define _ASM_GENERIC_IMMEDIATE_H + +/* +* Generic immediate values: a simple, standard, memory load. +*/ + +struct module ; + +#define immediate_read (var) _immediate_read(var) +#define immediate_set (var, i) ((var)->value = (i)) +#define _immediate_set (var, i) immediate_set(var, i) +#define immediate_set_early (var, i) immediate_set(var, i) +#define immediate_if (var) if (immediate_read(var)) + +static inline void module_immediate_setup (struct module *mod) { } +static inline void immediate_update_early (void ) { } + +#endif /* _ASM_GENERIC_IMMEDIATE_H */
include/asm-alpha/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-arm/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-arm26/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-cris/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-frv/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-h8300/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-ia64/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-m32r/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-m68k/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-m68knommu/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-mips/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-parisc/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-ppc/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-s390/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-sh/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-sh64/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-sparc/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-sparc64/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-um/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-v850/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-x86_64/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-xtensa/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-i386/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-powerpc/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
include/asm-blackfin/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 3/8] Immediate Values - Non Optimized Architectures
Should be dropped, following Christoph's advice.
Quoted 218 lines · * Mathieu Desnoyers ([email protected]) wrote:
Architecture agnostic, generic, version of the immediate values. It uses a global variable to mimic the immediate values.
Signed-off-by Mathieu Desnoyers <[email protected]>--- include/asm-alpha/immediate.h | 1 + include/asm-arm/immediate.h | 1 + include/asm-arm26/immediate.h | 1 + include/asm-blackfin/immediate.h | 1 + include/asm-cris/immediate.h | 1 + include/asm-frv/immediate.h | 1 + include/asm-generic/immediate.h | 19 +++++++++++++++++++ include/asm-h8300/immediate.h | 1 + include/asm-i386/immediate.h | 1 + include/asm-ia64/immediate.h | 1 + include/asm-m32r/immediate.h | 1 + include/asm-m68k/immediate.h | 1 + include/asm-m68knommu/immediate.h | 1 + include/asm-mips/immediate.h | 1 + include/asm-parisc/immediate.h | 1 + include/asm-powerpc/immediate.h | 1 + include/asm-ppc/immediate.h | 1 + include/asm-s390/immediate.h | 1 + include/asm-sh/immediate.h | 1 + include/asm-sh64/immediate.h | 1 + include/asm-sparc/immediate.h | 1 + include/asm-sparc64/immediate.h | 1 + include/asm-um/immediate.h | 1 + include/asm-v850/immediate.h | 1 + include/asm-x86_64/immediate.h | 1 + include/asm-xtensa/immediate.h | 1 + 26 files changed, 44 insertions(+)Index:
linux-2.6-lttng/include/asm-generic/immediate.h
===================================================================include/asm-generic/immediate.h new file +19
-0@@ -0,0 +1,19 @@ +#ifndef _ASM_GENERIC_IMMEDIATE_H +#define _ASM_GENERIC_IMMEDIATE_H + +/* +* Generic immediate values: a simple, standard, memory load. +*/ + +struct module ; + +#define immediate_read (var) _immediate_read(var) +#define immediate_set (var, i) ((var)->value = (i)) +#define _immediate_set (var, i) immediate_set(var, i) +#define immediate_set_early (var, i) immediate_set(var, i) +#define immediate_if (var) if (immediate_read(var)) + +static inline void module_immediate_setup (struct module *mod) { } +static inline void immediate_update_early (void ) { } + +#endif /* _ASM_GENERIC_IMMEDIATE_H */ Index:
linux-2.6-lttng/include/asm-alpha/immediate.h
===================================================================include/asm-alpha/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-arm/immediate.h
===================================================================include/asm-arm/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-arm26/immediate.h
===================================================================include/asm-arm26/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-cris/immediate.h
===================================================================include/asm-cris/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-frv/immediate.h
===================================================================include/asm-frv/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-h8300/immediate.h
===================================================================include/asm-h8300/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-ia64/immediate.h
===================================================================include/asm-ia64/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-m32r/immediate.h
===================================================================include/asm-m32r/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-m68k/immediate.h
===================================================================include/asm-m68k/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-m68knommu/immediate.h
===================================================================include/asm-m68knommu/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-mips/immediate.h
===================================================================include/asm-mips/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-parisc/immediate.h
===================================================================include/asm-parisc/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-ppc/immediate.h
===================================================================include/asm-ppc/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-s390/immediate.h
===================================================================include/asm-s390/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-sh/immediate.h
===================================================================include/asm-sh/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-sh64/immediate.h
===================================================================include/asm-sh64/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-sparc/immediate.h
===================================================================include/asm-sparc/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-sparc64/immediate.h
===================================================================include/asm-sparc64/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-um/immediate.h
===================================================================include/asm-um/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-v850/immediate.h
===================================================================include/asm-v850/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-x86_64/immediate.h
===================================================================include/asm-x86_64/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-xtensa/immediate.h
===================================================================include/asm-xtensa/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-i386/immediate.h
===================================================================include/asm-i386/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-powerpc/immediate.h
===================================================================include/asm-powerpc/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Index:
linux-2.6-lttng/include/asm-blackfin/immediate.h
===================================================================include/asm-blackfin/immediate.h new file +1
-0@@ -0,0 +1 @@ +#include <asm-generic/immediate.h> Signature · 9 lines
-- Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 4/8 Immediate Value - Add kconfig menus
In reply to Mathieu DesnoyersImmediate values provide a way to use dynamic code patching to update variables sitting within the instruction stream. It saves caches lines normally used by static read mostly variables.
---
arch/alpha/Kconfig | 6 ++++++ arch/arm/Kconfig | 6 ++++++ arch/arm26/Kconfig | 6 ++++++ arch/avr32/Kconfig.debug | 7 +++++++ arch/cris/Kconfig | 6 ++++++ arch/frv/Kconfig | 6 ++++++ arch/h8300/Kconfig | 6 ++++++ arch/i386/Kconfig | 2 ++ arch/ia64/Kconfig | 3 +++ arch/m32r/Kconfig | 6 ++++++ arch/m68k/Kconfig | 6 ++++++ arch/m68knommu/Kconfig | 6 ++++++ arch/mips/Kconfig | 6 ++++++ arch/parisc/Kconfig | 6 ++++++ arch/powerpc/Kconfig | 3 +++ arch/ppc/Kconfig | 6 ++++++ arch/s390/Kconfig | 2 ++ arch/sh/Kconfig | 6 ++++++ arch/sh64/Kconfig | 6 ++++++ arch/sparc/Kconfig | 2 ++ arch/sparc64/Kconfig | 3 +++ arch/um/Kconfig | 6 ++++++ arch/v850/Kconfig | 6 ++++++ arch/x86_64/Kconfig | 3 +++ arch/xtensa/Kconfig | 6 ++++++ kernel/Kconfig.immediate | 11 +++++++++++ 26 files changed, 138 insertions(+)
arch/alpha/Kconfig +6 -0
@@ -653,6 +653,12 @@ source "arch/alpha/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/alpha/Kconfig.debug" # DUMMY_CONSOLE may be defined in drivers/video/console/Kconfig
arch/arm/Kconfig +6 -0
@@ -1046,6 +1046,12 @@ source "arch/arm/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/arm/Kconfig.debug" source "security/Kconfig"
arch/arm26/Kconfig +6 -0
@@ -244,6 +244,12 @@ source "drivers/usb/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/arm26/Kconfig.debug" source "security/Kconfig"
arch/cris/Kconfig +6 -0
@@ -198,6 +198,12 @@ source "drivers/usb/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/cris/Kconfig.debug" source "security/Kconfig"
arch/frv/Kconfig +6 -0
@@ -375,6 +375,12 @@ source "fs/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/frv/Kconfig.debug" source "security/Kconfig"
arch/h8300/Kconfig +6 -0
@@ -223,6 +223,12 @@ source "fs/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/h8300/Kconfig.debug" source "security/Kconfig"
arch/i386/Kconfig +2 -0
@@ -1249,6 +1249,8 @@ for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +source "kernel/Kconfig.immediate" + endif # INSTRUMENTATION source "arch/i386/Kconfig.debug"
arch/ia64/Kconfig +3 -0
@@ -593,6 +593,9 @@ a probepoint and specifies the callback. Kprobes is useful for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". + +source "kernel/Kconfig.immediate" + endmenu source "arch/ia64/Kconfig.debug"
arch/m32r/Kconfig +6 -0
@@ -408,6 +408,12 @@ source "arch/m32r/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/m32r/Kconfig.debug" source "security/Kconfig"
arch/m68k/Kconfig +6 -0
@@ -676,6 +676,12 @@ source "fs/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/m68k/Kconfig.debug" source "security/Kconfig"
arch/m68knommu/Kconfig +6 -0
@@ -668,6 +668,12 @@ source "fs/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/m68knommu/Kconfig.debug" source "security/Kconfig"
arch/mips/Kconfig +6 -0
@@ -1946,6 +1946,12 @@ source "arch/mips/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/mips/Kconfig.debug" source "security/Kconfig"
arch/parisc/Kconfig +6 -0
@@ -269,6 +269,12 @@ source "arch/parisc/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/parisc/Kconfig.debug" source "security/Kconfig"
arch/powerpc/Kconfig +3 -0
@@ -655,6 +655,9 @@ a probepoint and specifies the callback. Kprobes is useful for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". + +source "kernel/Kconfig.immediate" + endmenu source "arch/powerpc/Kconfig.debug"
arch/ppc/Kconfig +6 -0
@@ -1451,8 +1451,14 @@ source "lib/Kconfig" +menu "Instrumentation Support" + source "arch/powerpc/oprofile/Kconfig" +source "kernel/Kconfig.immediate" + +endmenu + source "arch/ppc/Kconfig.debug" source "security/Kconfig"
arch/s390/Kconfig +2 -0
@@ -547,6 +547,8 @@ for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +source "kernel/Kconfig.immediate" + endmenu source "arch/s390/Kconfig.debug"
arch/sh/Kconfig +6 -0
@@ -721,6 +721,12 @@ source "arch/sh/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/sh/Kconfig.debug" source "security/Kconfig"
arch/sh64/Kconfig +6 -0
@@ -284,6 +284,12 @@ source "arch/sh64/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/sh64/Kconfig.debug" source "security/Kconfig"
arch/sparc/Kconfig +2 -0
@@ -313,6 +313,8 @@ source "arch/sparc/oprofile/Kconfig" +source "kernel/Kconfig.immediate" + endmenu source "arch/sparc/Kconfig.debug"
arch/sparc64/Kconfig +3 -0
@@ -451,6 +451,9 @@ a probepoint and specifies the callback. Kprobes is useful for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". + +source "kernel/Kconfig.immediate" + endmenu source "arch/sparc64/Kconfig.debug"
arch/um/Kconfig +6 -0
@@ -335,4 +335,10 @@ bool default n +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/um/Kconfig.debug"
arch/v850/Kconfig +6 -0
@@ -331,6 +331,12 @@ source "drivers/usb/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/v850/Kconfig.debug" source "security/Kconfig"
arch/x86_64/Kconfig +3 -0
@@ -842,6 +842,9 @@ a probepoint and specifies the callback. Kprobes is useful for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". + +source "kernel/Kconfig.immediate" + endmenu source "arch/x86_64/Kconfig.debug"
arch/xtensa/Kconfig +6 -0
@@ -251,6 +251,12 @@ provide one yourself. endmenu +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/xtensa/Kconfig.debug" source "security/Kconfig"
kernel/Kconfig.immediate new file +11 -0
@@ -0,0 +1,11 @@ +# Immediate values configuration + +config IMMEDIATE + bool "Enable immediate values" + depends on X86_32 || PPC + default y if !EMBEDDED + help + Immediate values are used as read mostly variables that are rarely + updated. They use code patching to modify the values inscribed in the + instruction stream. It provides a way to save precious cache lines + that would otherwise have to be used by these variables.
arch/avr32/Kconfig.debug +7 -0
@@ -6,6 +6,9 @@ source "lib/Kconfig.debug" +menu "Instrumentation Support" + depends on EXPERIMENTAL + config KPROBES bool "Kprobes" depends on DEBUG_KERNEL
@@ -16,4 +19,8 @@ for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +source "kernel/Kconfig.immediate" + +endmenu + endmenu
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Alexey Dobriyan
NAKRe: [patch 4/8] Immediate Value - Add kconfig menus
Quoted 5 lines · Mathieu Desnoyers
Immediate values provide a way to use dynamic code patching to update variables sitting within the instruction stream. It saves caches lines normally used by static read mostly variables.
kernel/Kconfig.immediate | 11 +++++++++++
NAK, if this immediate stuff is so super-cool¹ it should be default on.
¹ it isn't
Re: [patch 4/8] Immediate Value - Add kconfig menus
Quoted 11 lines · * Alexey Dobriyan ([email protected]) wrote:
Quoted 5 lines · Mathieu Desnoyers
Immediate values provide a way to use dynamic code patching to update variables sitting within the instruction stream. It saves caches lines normally used by static read mostly variables.
kernel/Kconfig.immediate | 11 +++++++++++NAK, if this immediate stuff is so super-cool¹ it should be default on.
¹ it isn't
Hi Alexey,
On embedded systems, the tradeoff is not the same. The immediate values trade a little bit of system memory (to keep the pointers to the variable and instruction as well as the size of the variable, only used when the variable is updated) in order to remove cache line hot paths.
Also, embedded systems with physically read-only memory clearly does not want to enable this.
Mathieu
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 4/8] Immediate Value - Add kconfig menus
Quoted 4 lines
On embedded systems, the tradeoff is not the same. The immediate values trade a little bit of system memory (to keep the pointers to the variable and instruction as well as the size of the variable, only used when the variable is updated) in order to remove cache line hot paths.
Please remove the Kconfig. I don't think it makes sense. Such optimizations should be always enabled. We don't have CONFIG_GO_FASTER configs normally. Don't introduce them now.
Quoted 3 lines
Also, embedded systems with physically read-only memory clearly does not want to enable this.
We always patch the x86 kernel, so they have to deal with it anyways. The x86 port doesn't support XIP.
-Andi
Re: [patch 4/8] Immediate Value - Add kconfig menus
Quoted 10 lines · * Andi Kleen ([email protected]) wrote:
Quoted 4 lines
On embedded systems, the tradeoff is not the same. The immediate values trade a little bit of system memory (to keep the pointers to the variable and instruction as well as the size of the variable, only used when the variable is updated) in order to remove cache line hot paths.
Please remove the
Kconfig. I don't think it makes sense. Such optimizations should be always enabled. We don't haveCONFIG_GO_FASTERconfigs normally. Don't introduce them now.Quoted 1 line
Quoted 7 lines
Quoted 2 lines
Also, embedded systems with physically read-only memory clearly does not want to enable this.
We always patch the x86 kernel, so they have to deal with it anyways. The x86 port doesn't support XIP.
-Andi
Hehe, good timing, please see the immediate-values-kconfig-embedded.patch I just sent. ;) Well, the idea is to give the option to every architecture in the embedded menu, which is not limited to X86.
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 4/8] Immediate Value - Add kconfig menus
In reply to Mathieu DesnoyersShould be dropped,
replaced by :
immediate-values-kconfig-embedded.patch
Quoted 471 lines · * Mathieu Desnoyers ([email protected]) wrote:
Immediate values provide a way to use dynamic code patching to update variables sitting within the instruction stream. It saves caches lines normally used by static read mostly variables.
Signed-off-by Mathieu Desnoyers <[email protected]>CC Adrian Bunk <[email protected]>CC Andi Kleen <[email protected]>---
arch/alpha/Kconfig | 6 ++++++ arch/arm/Kconfig | 6 ++++++ arch/arm26/Kconfig | 6 ++++++ arch/avr32/Kconfig.debug | 7 +++++++ arch/cris/Kconfig | 6 ++++++ arch/frv/Kconfig | 6 ++++++ arch/h8300/Kconfig | 6 ++++++ arch/i386/Kconfig | 2 ++ arch/ia64/Kconfig | 3 +++ arch/m32r/Kconfig | 6 ++++++ arch/m68k/Kconfig | 6 ++++++ arch/m68knommu/Kconfig | 6 ++++++ arch/mips/Kconfig | 6 ++++++ arch/parisc/Kconfig | 6 ++++++ arch/powerpc/Kconfig | 3 +++ arch/ppc/Kconfig | 6 ++++++ arch/s390/Kconfig | 2 ++ arch/sh/Kconfig | 6 ++++++ arch/sh64/Kconfig | 6 ++++++ arch/sparc/Kconfig | 2 ++ arch/sparc64/Kconfig | 3 +++ arch/um/Kconfig | 6 ++++++ arch/v850/Kconfig | 6 ++++++ arch/x86_64/Kconfig | 3 +++ arch/xtensa/Kconfig | 6 ++++++ kernel/Kconfig.immediate | 11 +++++++++++ 26 files changed, 138 insertions(+)Index: linux-2.6-lttng/arch/alpha/Kconfig
===================================================================arch/alpha/Kconfig +6
-0@@ -653,6 +653,12 @@ source "arch/alpha/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/alpha/Kconfig.debug" # DUMMY_CONSOLE may be defined in drivers/video/console/KconfigIndex: linux-2.6-lttng/arch/arm/Kconfig
===================================================================arch/arm/Kconfig +6
-0@@ -1046,6 +1046,12 @@ source "arch/arm/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/arm/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/arm26/Kconfig
===================================================================arch/arm26/Kconfig +6
-0@@ -244,6 +244,12 @@ source "drivers/usb/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/arm26/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/cris/Kconfig
===================================================================arch/cris/Kconfig +6
-0@@ -198,6 +198,12 @@ source "drivers/usb/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/cris/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/frv/Kconfig
===================================================================arch/frv/Kconfig +6
-0@@ -375,6 +375,12 @@ source "fs/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/frv/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/h8300/Kconfig
===================================================================arch/h8300/Kconfig +6
-0@@ -223,6 +223,12 @@ source "fs/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/h8300/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/i386/Kconfig
===================================================================arch/i386/Kconfig +2
-0@@ -1249,6 +1249,8 @@ for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +source "kernel/Kconfig.immediate" + endif # INSTRUMENTATION source "arch/i386/Kconfig.debug"Index: linux-2.6-lttng/arch/ia64/Kconfig
===================================================================arch/ia64/Kconfig +3
-0@@ -593,6 +593,9 @@ a probepoint and specifies the callback. Kprobes is useful for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". + +source "kernel/Kconfig.immediate" + endmenu source "arch/ia64/Kconfig.debug"Index: linux-2.6-lttng/arch/m32r/Kconfig
===================================================================arch/m32r/Kconfig +6
-0@@ -408,6 +408,12 @@ source "arch/m32r/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/m32r/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/m68k/Kconfig
===================================================================arch/m68k/Kconfig +6
-0@@ -676,6 +676,12 @@ source "fs/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/m68k/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/m68knommu/Kconfig
===================================================================arch/m68knommu/Kconfig +6
-0@@ -668,6 +668,12 @@ source "fs/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/m68knommu/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/mips/Kconfig
===================================================================arch/mips/Kconfig +6
-0@@ -1946,6 +1946,12 @@ source "arch/mips/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/mips/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/parisc/Kconfig
===================================================================arch/parisc/Kconfig +6
-0@@ -269,6 +269,12 @@ source "arch/parisc/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/parisc/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/powerpc/Kconfig
===================================================================arch/powerpc/Kconfig +3
-0@@ -655,6 +655,9 @@ a probepoint and specifies the callback. Kprobes is useful for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". + +source "kernel/Kconfig.immediate" + endmenu source "arch/powerpc/Kconfig.debug"Index: linux-2.6-lttng/arch/ppc/Kconfig
===================================================================arch/ppc/Kconfig +6
-0@@ -1451,8 +1451,14 @@ source "lib/Kconfig" +menu "Instrumentation Support" + source "arch/powerpc/oprofile/Kconfig" +source "kernel/Kconfig.immediate" + +endmenu + source "arch/ppc/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/s390/Kconfig
===================================================================arch/s390/Kconfig +2
-0@@ -547,6 +547,8 @@ for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +source "kernel/Kconfig.immediate" + endmenu source "arch/s390/Kconfig.debug"Index: linux-2.6-lttng/arch/sh/Kconfig
===================================================================arch/sh/Kconfig +6
-0@@ -721,6 +721,12 @@ source "arch/sh/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/sh/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/sh64/Kconfig
===================================================================arch/sh64/Kconfig +6
-0@@ -284,6 +284,12 @@ source "arch/sh64/oprofile/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/sh64/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/sparc/Kconfig
===================================================================arch/sparc/Kconfig +2
-0@@ -313,6 +313,8 @@ source "arch/sparc/oprofile/Kconfig" +source "kernel/Kconfig.immediate" + endmenu source "arch/sparc/Kconfig.debug"Index: linux-2.6-lttng/arch/sparc64/Kconfig
===================================================================arch/sparc64/Kconfig +3
-0@@ -451,6 +451,9 @@ a probepoint and specifies the callback. Kprobes is useful for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". + +source "kernel/Kconfig.immediate" + endmenu source "arch/sparc64/Kconfig.debug"Index: linux-2.6-lttng/arch/um/Kconfig
===================================================================arch/um/Kconfig +6
-0@@ -335,4 +335,10 @@ bool default n +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/um/Kconfig.debug"Index: linux-2.6-lttng/arch/v850/Kconfig
===================================================================arch/v850/Kconfig +6
-0@@ -331,6 +331,12 @@ source "drivers/usb/Kconfig" +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/v850/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/arch/x86_64/Kconfig
===================================================================arch/x86_64/Kconfig +3
-0@@ -842,6 +842,9 @@ a probepoint and specifies the callback. Kprobes is useful for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". + +source "kernel/Kconfig.immediate" + endmenu source "arch/x86_64/Kconfig.debug"Index: linux-2.6-lttng/arch/xtensa/Kconfig
===================================================================arch/xtensa/Kconfig +6
-0@@ -251,6 +251,12 @@ provide one yourself. endmenu +menu "Instrumentation Support" + +source "kernel/Kconfig.immediate" + +endmenu + source "arch/xtensa/Kconfig.debug" source "security/Kconfig"Index: linux-2.6-lttng/kernel/Kconfig.immediate
===================================================================kernel/Kconfig.immediate new file +11
-0@@ -0,0 +1,11 @@ +# Immediate values configuration + +config IMMEDIATE + bool "Enable immediate values" + depends on X86_32 || PPC + default y if !EMBEDDED + help + Immediate values are used as read mostly variables that are rarely + updated. They use code patching to modify the values inscribed in the + instruction stream. It provides a way to save precious cache lines + that would otherwise have to be used by these variables.Index: linux-2.6-lttng/arch/avr32/Kconfig.debug
===================================================================arch/avr32/Kconfig.debug +7
-0@@ -6,6 +6,9 @@ source "lib/Kconfig.debug" +menu "Instrumentation Support" + depends on EXPERIMENTAL + config KPROBES bool "Kprobes" depends on DEBUG_KERNEL@@ -16,4 +19,8 @@ for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +source "kernel/Kconfig.immediate" + +endmenu + endmenuSignature · 9 lines
-- Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/1 Immediate Value - Kconfig menu in EMBEDDED
In reply to Mathieu DesnoyersImmediate Values - Kconfig menu in EMBEDDED
Immediate values provide a way to use dynamic code patching to update variables sitting within the instruction stream. It saves caches lines normally used by static read mostly variables. Enable it by default, but let users disable it through the EMBEDDED menu with the "Disable immediate values" submenu entry.
--- init/Kconfig | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
init/Kconfig +21 -0
@@ -410,6 +410,17 @@ config CC_OPTIMIZE_FOR_SIZE config SYSCTL bool +config IMMEDIATE + default y if !DISABLE_IMMEDIATE + depends on X86_32 || PPC + bool + help + Immediate values are used as read mostly variables that are rarely + updated. They use code patching to modify the values inscribed in the + instruction stream. It provides a way to save precious cache lines + that would otherwise have to be used by these variables. Can be + disabled through the EMBEDDED menu. + menuconfig EMBEDDED bool "Configure standard kernel features (for small systems)" help
@@ -672,6 +683,16 @@ config PROC_KPAGEMAP information on page-level memory usage. Disabling this interface will reduce the size of the kernel for small machines. +config DISABLE_IMMEDIATE + default y if EMBEDDED + bool "Disable immediate values" if EMBEDDED + depends on X86_32 || PPC + help + Disable code patching based immediate values for embedded systems. It + consumes slightly more memory and requires to modify the instruction + stream each time a variable is updated. Should really be disabled for + embedded systems with read-only text. + endmenu # General setup config RT_MUTEXES
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 5/8 Immediate Values - kprobe header fix
In reply to Mathieu DesnoyersSince the immediate values depend on the same int3 handler as kprobes implements for i386, we have to get architecture specific defines available for the kprobes trap handler (especially restore_interrupts()) wven when CONFIG_KPROBES is not selected.
That kind of ifdef around a whole header does not make sense in the first place anyway.
--- include/linux/kprobes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/kprobes.h +1 -1
@@ -36,9 +36,9 @@#include <linux/spinlock.h> #include <linux/rcupdate.h> -#ifdef CONFIG_KPROBES #include <asm/kprobes.h> +#ifdef CONFIG_KPROBES /* kprobe_status settings */ #define KPROBE_HIT_ACTIVE 0x00000001#define KPROBE_HIT_SS 0x00000002
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 5/8] Immediate Values - kprobe header fix
Quoted 22 lines · Mathieu Desnoyers
Since the immediate values depend on the same int3 handler as kprobes implements for i386, we have to get architecture specific defines available for the kprobes trap handler (especially
restore_interrupts()) wven whenCONFIG_KPROBESis not selected.That kind of ifdef around a whole header does not make sense in the first place anyway.
Signed-off-by Mathieu Desnoyers <[email protected]>--- include/linux/kprobes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)Index:
linux-2.6-lttng/include/linux/kprobes.h
===================================================================
include/linux/kprobes.h line 39
Quoted 5 lines
include/linux/kprobes.h +0
-1@@ -36,9 +36,9 @@#include <linux/spinlock.h> #include <linux/rcupdate.h> -#ifdef CONFIG_KPROBES #include <asm/kprobes.h>
but this one isn't available on architectures that don't have kprobes, so you can't include linux/kprobes.h in generic code without ifdef protection anymore.
I'd say move the code to asm/kdebug.h if it's need by more than just kprobes.
Re: [patch 5/8] Immediate Values - kprobe header fix
In reply to Mathieu DesnoyersShould be dropped, following Christoph's advice.
Quoted 43 lines · * Mathieu Desnoyers ([email protected]) wrote:
Since the immediate values depend on the same int3 handler as kprobes implements for i386, we have to get architecture specific defines available for the kprobes trap handler (especially
restore_interrupts()) wven whenCONFIG_KPROBESis not selected.That kind of ifdef around a whole header does not make sense in the first place anyway.
Signed-off-by Mathieu Desnoyers <[email protected]>--- include/linux/kprobes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)Index:
linux-2.6-lttng/include/linux/kprobes.h
===================================================================include/linux/kprobes.h +1
-1@@ -36,9 +36,9 @@#include <linux/spinlock.h> #include <linux/rcupdate.h> -#ifdef CONFIG_KPROBES #include <asm/kprobes.h> +#ifdef CONFIG_KPROBES /* kprobe_status settings */ #define KPROBE_HIT_ACTIVE 0x00000001#define KPROBE_HIT_SS 0x00000002Signature · 9 lines
-- Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/1 Immediate Values - Move Kprobes i386 restore_interrupt to kdebug.h
In reply to Mathieu DesnoyersImmediate Values - Move Kprobes i386 restore_interrupt to kdebug.h
Since the breakpoint handler is useful both to kprobes and immediate values, it makes sense to make the required restore_interrupt() available through asm-i386/kdebug.h.
This patch replaces "immediate-values-kprobes-headers.patch".
--- include/asm-i386/kdebug.h | 10 ++++++++++ include/asm-i386/kprobes.h | 9 --------- 2 files changed, 10 insertions(+), 9 deletions(-)
include/asm-i386/kdebug.h +10 -0
@@ -6,6 +6,7 @@* from x86_64 architecture. */ #include <linux/notifier.h> +#include <asm/ptrace.h> struct pt_regs ;
@@ -31,4 +32,13 @@ enum die_val { DIE_PAGE_FAULT_NO_CONTEXT, }; +/* trap3/1 are intr gates for kprobes. So, restore the status of IF, +* if necessary, before executing the original int3/1 (trap) handler. +*/ +static inline void restore_interrupts (struct pt_regs *regs) +{ +if (regs->eflags &IF_MASK ) +local_irq_enable (); +} +#endif
include/asm-i386/kprobes.h +0 -9
@@ -80,15 +80,6 @@ struct kprobe_ctlblk {struct prev_kprobe prev_kprobe; }; -/* trap3/1 are intr gates for kprobes. So, restore the status of IF, -* if necessary, before executing the original int3/1 (trap) handler. -*/ -static inline void restore_interrupts (struct pt_regs *regs) -{ -if (regs->eflags &IF_MASK ) -local_irq_enable (); -} -extern int kprobe_exceptions_notify (struct notifier_block *self,unsigned long val,void *data);extern int kernel_text_is_ro;
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 6/8 Immediate Value - i386 Optimization
In reply to Mathieu Desnoyersi386 optimization of the immediate values which uses a movl with code patching to set/unset the value used to populate the register used as variable source.
--- arch/i386/kernel/Makefile | 1 arch/i386/kernel/immediate.c | 295 +++++++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/traps.c | 8 - include/asm-i386/immediate.h | 118 +++++++++++++++++ 4 files changed, 417 insertions(+), 5 deletions(-)
include/asm-i386/immediate.h +117 -1
@@ -1 +1,117 @@ -#include <asm-generic/immediate.h> +#ifndef _ASM_I386_IMMEDIATE_H +#define _ASM_I386_IMMEDIATE_H + +/* +* Immediate values. i386 architecture optimizations. +* +* (C) Copyright 2006 Mathieu Desnoyers <[email protected]> +* +* This file is released under the GPLv2. +* See the file COPYING for more details. +*/ + +struct module ; + +struct __immediate { +long var;/* Pointer to the identifier variable of the +* immediate value +*/ +long immediate;/* +* Pointer to the memory location of the +* immediate value within the instruction. +*/ +long size;/* Type size. */ +}; + +/* +* Optimized version of the immediate. +* Make sure the 2 and 4 bytes update will be atomic by aligning the immediate +* value. +* 2 bytes (short) uses a 66H prefix. +* If size is bigger than 4 bytes, fall back on a memory read. +* Do not use in __init and __exit functions. Use _immediate_read() instead. +*/ +#define immediate_read (var) \ + ({ \ + __typeof__((var)->value) value; \ + switch (sizeof(value)) { \ + case 1: \ + asm ( ".section __immediate, \"a\", @progbits;\n\t" \ + ".long %1, (0f)+1, 1;\n\t" \ + ".previous;\n\t" \ + "0:\n\t" \ + "mov %2,%0;\n\t" \ + : "=r" (value) \ + : "m" ((var)->value), \ + "i" (0)); \ + break; \ + case 2: \ + asm ( ".section __immediate, \"a\", @progbits;\n\t" \ + ".long %1, (0f)+2, 2;\n\t" \ + ".previous;\n\t" \ + "1:\n\t" \ + ".align 2;\n\t" \ + "0:\n\t" \ + "mov %2,%0;\n\t" \ + : "=r" (value) \ + : "m" ((var)->value), \ + "i" (0)); \ + break; \ + case 4: \ + asm ( ".section __immediate, \"a\", @progbits;\n\t" \ + ".long %1, (0f)+1, 4;\n\t" \ + ".previous;\n\t" \ + "1:\n\t" \ + ".org (1b)+(3-((1b)%%4)), 0x90;\n\t" \ + "0:\n\t" \ + "mov %2,%0;\n\t" \ + : "=r" (value) \ + : "m" ((var)->value), \ + "i" (0)); \ + break; \ + default:value = (var)->value; \ + break; \ + }; \ + value; \ + }) + +/* +* Update immediate value, can take module mutex. +*/ +#define immediate_set (var, i) \ + (var)->value = (i); \ + immediate_update(1); + +/* +* Update immediate value. Module mutex must already be taken. +*/ +#define _immediate_set (var, i) \ + (var)->value = (i); \ + immediate_update(0); + +/* +* Update immediate value at early boot. +*/ +#define immediate_set_early (var, i) \ + (var)->value = (i); \ + immediate_update_early(); + +/* +* Branch depending on an immediate value. Could eventually be optimized further +* by improving gcc to give the ability to patch a jump instruction instead of +* the value it depends on. +* Do not use in __init and __exit functions. Use _immediate_if() instead. +*/ +#define immediate_if (var) if (unlikely(immediate_read(var))) + +/* +* Used internally. +*/ + +extern void immediate_update (int lock); +extern void module_immediate_setup (struct module *mod); +extern void immediate_update_early (void ); +extern int arch_immediate_update (const struct __immediate *immediate); +extern void arch_immediate_update_early (const struct __immediate *immediate); + +#endif /* _ASM_I386_IMMEDIATE_H */
arch/i386/kernel/Makefile +1 -0
@@ -35,6 +35,7 @@ obj-y += sysenter.o vsyscall.o obj-$(CONFIG_ACPI_SRAT) += srat.o obj-$(CONFIG_EFI) += efi.o efi_stub.o +obj-$(CONFIG_IMMEDIATE) += immediate.o obj-$(CONFIG_DOUBLEFAULT) += doublefault.o obj-$(CONFIG_SERIAL_8250) += legacy_serial.o obj-$(CONFIG_VM86) += vm86.o
arch/i386/kernel/immediate.c new file +295 -0
295 lines not on this page · raw message
arch/i386/kernel/traps.c +4 -4
@@ -629,7 +629,7 @@ } DO_VM86_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->eip) -#ifndef CONFIG_KPROBES +#if !defined(CONFIG_KPROBES ) && !defined(CONFIG_IMMEDIATE ) DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)#endif DO_VM86_ERROR (4 ,SIGSEGV ,"overflow" , overflow)
@@ -856,14 +856,14 @@nmi_exit (); } -#ifdef CONFIG_KPROBES +#if defined(CONFIG_KPROBES ) || defined(CONFIG_IMMEDIATE ) fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) {if (notify_die (DIE_INT3 ,"int3" , regs, error_code,3 ,SIGTRAP ) ==NOTIFY_STOP )return ; -/* This is an interrupt gate, because kprobes wants interrupts -disabled. Normal trap handlers don't. */ +/* This is an interrupt gate, because kprobes and immediate values wants +* interrupts disabled. Normal trap handlers don't. */ restore_interrupts (regs);do_trap (3 ,SIGTRAP ,"int3" ,1 , regs, error_code,NULL ); }
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/1 Immediate Values - Pre Fix i386 Optimization
Immediate Values - Pre Fix i386 Optimization
Since I removed the immediate-values-non-optimized-architectures.patch, we need to redo it to apply immediate-values-i386-optimization.patch correctly.
It should be applied _before_ the immediate-values-i386-optimization.patch and folded with it.
--- include/asm-i386/immediate.h | 1 + 1 file changed, 1 insertion(+)
include/asm-i386/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/1 Immediate Values - i386 Optimization - kerneldoc
In reply to Mathieu DesnoyersImmediate Values - i386 Optimization - kerneldoc
Add kerneldoc to Immediate Values (i386 Optimization) API.
--- include/asm-i386/immediate.h | 50 ++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 15 deletions(-)
include/asm-i386/immediate.h +35 -15
@@ -23,13 +23,16 @@ struct __immediate {long size;/* Type size. */ }; -/* +/** +* immediate_read - read immediate variable +* @var: pointer of type immediate_*_t +* +* Reads the value of @var. * Optimized version of the immediate. -* Make sure the 2 and 4 bytes update will be atomic by aligning the immediate -* value. -* 2 bytes (short) uses a 66H prefix. -* If size is bigger than 4 bytes, fall back on a memory read. * Do not use in __init and __exit functions. Use _immediate_read() instead. +* Makes sure the 2 and 4 bytes update will be atomic by aligning the immediate +* value. 2 bytes (short) uses a 66H prefix. If size is bigger than 4 bytes, +* fall back on a memory read. */ #define immediate_read (var) \ ({ \
@@ -75,39 +78,56 @@ struct __immediate { value; \ }) -/* -* Update immediate value, can take module mutex. + +/** +* immediate_set - set immediate variable (with locking) +* @var: pointer of type immediate_*_t +* @i: required value +* +* Sets the value of @var, taking the module_mutex if required by +* the architecture. */ #define immediate_set (var, i) \ (var)->value = (i); \ immediate_update(1); -/* -* Update immediate value. Module mutex must already be taken. +/** +* _immediate_set - set immediate variable (without locking) +* @var: pointer of type immediate_*_t +* @i: required value +* +* Sets the value of @var. Must be called with module_mutex held. */ #define _immediate_set (var, i) \ (var)->value = (i); \ immediate_update(0); -/* -* Update immediate value at early boot. +/** +* immediate_set_early - set immediate variable at early boot +* @var: pointer of type immediate_*_t +* @i: required value +* +* Sets the value of @var. Should be used for early boot updates. */ #define immediate_set_early (var, i) \ (var)->value = (i); \ immediate_update_early(); -/* +/** +* immediate_if - if () statement depending on an immediate value +* @var: pointer of type immediate_*_t +* +* Use as an if () statement depending on an immediate value. +* Do not use in __init and __exit functions. Use _immediate_if() instead. * Branch depending on an immediate value. Could eventually be optimized further * by improving gcc to give the ability to patch a jump instruction instead of * the value it depends on. -* Do not use in __init and __exit functions. Use _immediate_if() instead. */ #define immediate_if (var) if (unlikely(immediate_read(var)))/* -* Used internally. +* Internal update functions. */ -extern void immediate_update (int lock);extern void module_immediate_setup (struct module *mod);extern void immediate_update_early (void );
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/1 Immediate Values - i386 Optimization - kerneldoc for implementation
Immediate Values - i386 Optimization - kerneldoc for implementation
Add kerneldoc to Immediate Values (i386 Optimization) API. It applies after
"Immediate Values - i386 Optimization - kerneldoc"
--- arch/i386/kernel/immediate.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
arch/i386/kernel/immediate.c +11 -4
@@ -170,8 +170,12 @@ static struct notifier_block immediate_n .priority = 0x7fffffff, /* we need to be notified first */ }; -/* -* Must be called with immediate_mutex held. + +/** +* arch_immediate_update - update one immediate value +* @immediate: pointer of type const struct __immediate to update +* +* Update one immediate value. Must be called with immediate_mutex held. */ __kprobes int arch_immediate_update (const struct __immediate *immediate) {
@@ -266,8 +270,11 @@ __kprobes int arch_immediate_update(consreturn 0 ; } -/* -* Very early initialization of the in-core immediate values. +/** +* arch_immediate_update_early - update one immediate value at boot time +* @immediate: pointer of type const struct __immediate to update +* +* Update one immediate value at boot time. */ void __init arch_immediate_update_early (const struct __immediate *immediate) {
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 7/8 Immediate Value - PowerPC Optimization
In reply to Mathieu DesnoyersPowerPC optimization of the immediate values which uses a li instruction, patched with an immediate value.
--- arch/powerpc/kernel/Makefile | 1 arch/powerpc/kernel/immediate.c | 98 ++++++++++++++++++++++++++++++++++++ include/asm-powerpc/immediate.h | 107 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 205 insertions(+), 1 deletion(-)
include/asm-powerpc/immediate.h +106 -1
@@ -1 +1,106 @@ -#include <asm-generic/immediate.h> +#ifndef _ASM_POWERPC_IMMEDIATE_H +#define _ASM_POWERPC_IMMEDIATE_H + +/* +* Immediate values. PowerPC architecture optimizations. +* +* (C) Copyright 2006 Mathieu Desnoyers <[email protected]> +* +* This file is released under the GPLv2. +* See the file COPYING for more details. +*/ + +#include <asm/asm-compat.h> + +struct module ; + +struct __immediate { +long var;/* Identifier variable of the immediate value */ +long immediate;/* +* Pointer to the memory location that holds +* the immediate value within the load immediate +* instruction. +*/ +long size;/* Type size. */ +}; + +/* +* Optimized version of the immediate. +* Make sure the 2 bytes update will be atomic by aligning the immediate +* value. +* Use a normal memory read for the 4 bytes immediate because there is no way to +* atomically update it without using a seqlock read side, which would cost more +* in term of total i-cache and d-cache space than a simple memory read. +* Do not use in __init and __exit functions. Use _immediate_read() instead. +*/ +#define immediate_read (var) \ + ({ \ + __typeof__((var)->value) value; \ + switch (sizeof(value)) { \ + case 1: \ + asm ( ".section __immediate, \"a\", @progbits;\n\t" \ + PPC_LONG "%1, ((0f)+3), 1;\n\t" \ + ".previous;\n\t" \ + "0:\n\t" \ + "li %0,%2;\n\t" \ + : "=r" (value) \ + : "i" (&(var)->value), \ + "i" (0)); \ + break; \ + case 2: \ + asm ( ".section __immediate, \"a\", @progbits;\n\t" \ + PPC_LONG "%1, ((0f)+2), 2;\n\t" \ + ".previous;\n\t" \ + ".align 2\n\t" \ + "0:\n\t" \ + "li %0,%2;\n\t" \ + : "=r" (value) \ + : "i" (&(var)->value), \ + "i" (0)); \ + break; \ + default: \ + value = (var)->value; \ + break; \ + }; \ + value; \ + }) + +/* +* Update immediate value, can take module mutex. +*/ +#define immediate_set (var, i) \ + (var)->value = (i); \ + immediate_update(1); + +/* +* Update immediate value. Module mutex must already be taken. +*/ +#define _immediate_set (var, i) \ + (var)->value = (i); \ + immediate_update(0); + +/* +* Update immediate value at early boot. +*/ +#define immediate_set_early (var, i) \ + (var)->value = (i); \ + immediate_update_early(); + +/* +* Branch depending on an immediate value. Could eventually be optimized further +* by improving gcc to give the ability to patch a jump instruction instead of +* the value it depends on. +* Do not use in __init and __exit functions. Use _immediate_if() instead. +*/ +#define immediate_if (var) if (unlikely(immediate_read(var))) + +/* +* Used internally. +*/ +extern void immediate_update (int lock); +extern void module_immediate_setup (struct module *mod); +extern void immediate_update_early (void ); +extern int arch_immediate_update (const struct __immediate *immediate); +extern void arch_immediate_update_early (const struct __immediate *immediate); + +#endif /* _ASM_POWERPC_IMMEDIATE_H */
arch/powerpc/kernel/Makefile +1 -0
@@ -103,3 +103,4 @@ extra-$(CONFIG_PPC_FPU) += fpu.o extra-$(CONFIG_PPC64) += entry_64.o +obj-$(CONFIG_IMMEDIATE) += immediate.o
arch/powerpc/kernel/immediate.c new file +98 -0
98 lines not on this page · raw message
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/1 Immediate Values - Pre fix powerpc Optimization
Immediate Values - Pre fix powerpc Optimization
Since I removed the immediate-values-non-optimized-architectures.patch, we need to redo it to apply immediate-values-powerpc-optimization.patch correctly.
It applies _before_ immediate-values-powerpc-optimization.patch and can be folded with it.
--- include/asm-powerpc/immediate.h | 1 + 1 file changed, 1 insertion(+)
include/asm-powerpc/immediate.h new file +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/immediate.h>
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/1 Immediate Values - PowerPC Optimization - kerneldoc
In reply to Mathieu DesnoyersImmediate Values - PowerPC Optimization - kerneldoc
Add kerneldoc to Immediate Values (PowerPC Optimization) API.
--- include/asm-powerpc/immediate.h | 51 ++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 15 deletions(-)
include/asm-powerpc/immediate.h +36 -15
@@ -24,14 +24,18 @@ struct __immediate {long size;/* Type size. */ }; -/* +/** +* immediate_read - read immediate variable +* @var: pointer of type immediate_*_t +* +* Reads the value of @var. * Optimized version of the immediate. -* Make sure the 2 bytes update will be atomic by aligning the immediate -* value. -* Use a normal memory read for the 4 bytes immediate because there is no way to -* atomically update it without using a seqlock read side, which would cost more -* in term of total i-cache and d-cache space than a simple memory read. * Do not use in __init and __exit functions. Use _immediate_read() instead. +* Makes sure the 2 bytes update will be atomic by aligning the immediate +* value. Use a normal memory read for the 4 bytes immediate because there is no +* way to atomically update it without using a seqlock read side, which would +* cost more in term of total i-cache and d-cache space than a simple memory +* read. */ #define immediate_read (var) \ ({ \
@@ -65,37 +69,54 @@ struct __immediate { value; \ }) -/* -* Update immediate value, can take module mutex. +/** +* immediate_set - set immediate variable (with locking) +* @var: pointer of type immediate_*_t +* @i: required value +* +* Sets the value of @var, taking the module_mutex if required by +* the architecture. */ #define immediate_set (var, i) \ (var)->value = (i); \ immediate_update(1); -/* -* Update immediate value. Module mutex must already be taken. +/** +* _immediate_set - set immediate variable (without locking) +* @var: pointer of type immediate_*_t +* @i: required value +* +* Sets the value of @var. Must be called with module_mutex held. */ #define _immediate_set (var, i) \ (var)->value = (i); \ immediate_update(0); -/* -* Update immediate value at early boot. +/** +* immediate_set_early - set immediate variable at early boot +* @var: pointer of type immediate_*_t +* @i: required value +* +* Sets the value of @var. Should be used for early boot updates. */ #define immediate_set_early (var, i) \ (var)->value = (i); \ immediate_update_early(); -/* +/** +* immediate_if - if () statement depending on an immediate value +* @var: pointer of type immediate_*_t +* +* Use as an if () statement depending on an immediate value. +* Do not use in __init and __exit functions. Use _immediate_if() instead. * Branch depending on an immediate value. Could eventually be optimized further * by improving gcc to give the ability to patch a jump instruction instead of * the value it depends on. -* Do not use in __init and __exit functions. Use _immediate_if() instead. */ #define immediate_if (var) if (unlikely(immediate_read(var)))/* -* Used internally. +* Internal update functions. */ extern void immediate_update (int lock);extern void module_immediate_setup (struct module *mod);
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/1 Immediate Values - PowerPC Optimization - kerneldoc for implementation
Immediate Values - PowerPC Optimization - kerneldoc for implementation
Add kerneldoc to Immediate Values (PowerPC Optimization) API. It applies after
"Immediate Values - PowerPC Optimization - kerneldoc"
--- arch/powerpc/kernel/immediate.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
arch/powerpc/kernel/immediate.c +10 -5
@@ -13,8 +13,11 @@#define LI_OPCODE_LEN 2 -/* -* The immediate value are aligned. +/** +* arch_immediate_update - update one immediate value +* @immediate: pointer of type const struct __immediate to update +* +* Update one immediate value. Must be called with immediate_mutex held. */ int arch_immediate_update (const struct __immediate *immediate) {
@@ -68,8 +71,11 @@ int arch_immediate_update(const struct _return 0 ; } -/* -* Very early initialization of the in-core immediate values. +/** +* arch_immediate_update_early - update one immediate value at boot time +* @immediate: pointer of type const struct __immediate to update +* +* Update one immediate value at boot time. * We can use flush_icache_range, since the cpu identification has been done in * the early_init stage. */
@@ -95,4 +101,3 @@ void __init arch_immediate_update_early(flush_icache_range ((unsigned long )immediate->immediate, immediate->size); } -
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 8/8 Immediate Value - Documentation
In reply to Mathieu Desnoyers--- Documentation/immediate.txt | 180 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+)
Documentation/immediate.txt new file +180 -0
@@ -0,0 +1,180 @@ + Using the Immediate Values + + Mathieu Desnoyers + + +This document introduces Immediate Values and their use. + +* Purpose of immediate values + +An immediate value is used to compile into the kernel variables that sits within +the instruction stream. They are meant to be rarely updated but read often. +Using immediate values for these variables will save cache lines. + +This infrastructure is specialized in supporting dynamic patching of the values +in the instruction stream when multiple CPUs are running without disturbing the +normal system behavior. + +Compiling code meant to be rarely enabled at runtime can be done using +immediate_if() as condition surrounding the code. + +* Usage + +In order to use the macro immediate, you should include linux/immediate.h. + +#include <linux/immediate.h> + +immediate_char_t this_immediate; +EXPORT_SYMBOL(this_immediate); + + +Add, in your code : + +Use immediate_set(&this_immediate) to set the immediate value. + +Use immediate_read(&this_immediate) to read the immediate value. + +The immediate mechanism supports inserting multiple instances of the same +immediate. Immediate values can be put in inline functions, inlined static +functions, and unrolled loops. + +If you have to read the immediate values from a function declared as __init or +__exit, you should explicitly use _immediate_read(), which will fall back on a +global variable read. Failing to do so will leave a reference to the __init +section after it is freed (it would generate a modpost warning). + +The prefered idiom to dynamically enable compiled-in code is to use +immediate_if (&this_immediate), which may eventually use gcc improvements to +provide a jump instruction patching based condition instead of a immediate value +feeding a conditional jump. You should use _immediate_if () instead of +immediate_if () in functions marked __init or __exit. + +immediate_set_early() should be used only at early kernel boot time, before SMP +is activated. + +If you need to declare your own immediate types (for instance, a pointer to +struct task_struct), use: + +DEFINE_IMMEDIATE_TYPE(struct task_struct*, immediate_task_struct_ptr_t); + +and declare your variable with: +immediate_task_struct_ptr_t myptr; + +You can choose to set an initial static value to the immediate by using, for +instance: + +immediate_task_struct_ptr_t myptr = IMMEDIATE_INIT(10); + + +* Optimization for a given architecture + +One can implement optimized immediate values for a given architecture by +replacing asm-$ARCH/immediate.h. + +* Performance improvement + +* Memory hit for a data-based branch + +Here are the results on a 3GHz Pentium 4: + +number of tests : 100 +number of branches per test : 100000 +memory hit cycles per iteration (mean) : 636.611 +L1 cache hit cycles per iteration (mean) : 89.6413 +instruction stream based test, cycles per iteration (mean) : 85.3438 +Just getting the pointer from a modulo on a pseudo-random value, doing + noting with it, cycles per iteration (mean) : 77.5044 + +So: +Base case: 77.50 cycles +instruction stream based test: +7.8394 cycles +L1 cache hit based test: +12.1369 cycles +Memory load based test: +559.1066 cycles + +So let's say we have a ping flood coming at +(14014 packets transmitted, 14014 received, 0% packet loss, time 1826ms) +7674 packets per second. If we put 2 markers for irq entry/exit, it +brings us to 15348 markers sites executed per second. + +(15348 exec/s) * (559 cycles/exec) / (3G cycles/s) = 0.0029 +We therefore have a 0.29% slowdown just on this case. + +Compared to this, the instruction stream based test will cause a +slowdown of: + +(15348 exec/s) * (7.84 cycles/exec) / (3G cycles/s) = 0.00004 +For a 0.004% slowdown. + +If we plan to use this for memory allocation, spinlock, and all sort of +very high event rate tracing, we can assume it will execute 10 to 100 +times more sites per second, which brings us to 0.4% slowdown with the +instruction stream based test compared to 29% slowdown with the memory +load based test on a system with high memory pressure. + + + +* Markers impact under heavy memory load + +Running a kernel with my LTTng instrumentation set, in a test that +generates memory pressure (from userspace) by trashing L1 and L2 caches +between calls to getppid() (note: syscall_trace is active and calls +a marker upon syscall entry and syscall exit; markers are disarmed). +This test is done in user-space, so there are some delays due to IRQs +coming and to the scheduler. (UP 2.6.22-rc6-mm1 kernel, task with -20 +nice level) + +My first set of results : Linear cache trashing, turned out not to be +very interesting, because it seems like the linearity of the memset on a +full array is somehow detected and it does not "really" trash the +caches. + +Now the most interesting result : Random walk L1 and L2 trashing +surrounding a getppid() call. + +- Markers compiled out (but syscall_trace execution forced) +number of tests : 10000 +No memory pressure +Reading timestamps takes 108.033 cycles +getppid : 1681.4 cycles +With memory pressure +Reading timestamps takes 102.938 cycles +getppid : 15691.6 cycles + + +- With the immediate values based markers: +number of tests : 10000 +No memory pressure +Reading timestamps takes 108.006 cycles +getppid : 1681.84 cycles +With memory pressure +Reading timestamps takes 100.291 cycles +getppid : 11793 cycles + + +- With global variables based markers: +number of tests : 10000 +No memory pressure +Reading timestamps takes 107.999 cycles +getppid : 1669.06 cycles +With memory pressure +Reading timestamps takes 102.839 cycles +getppid : 12535 cycles + + +The result is quite interesting in that the kernel is slower without +markers than with markers. I explain it by the fact that the data +accessed is not layed out in the same manner in the cache lines when the +markers are compiled in or out. It seems that it aligns the function's +data better to compile-in the markers in this case. + +But since the interesting comparison is between the immediate values and +global variables based markers, and because they share the same memory +layout, except for the movl being replaced by a movz, we see that the +global variable based markers (2 markers) adds 742 cycles to each system +call (syscall entry and exit are traced and memory locations for both +global variables lie on the same cache line). + +Therefore, not only is it interesting to use the immediate values to +dynamically activate dormant code such as the markers, but I think it +should also be considered as a replacement for many of the "read mostly" +static variables.
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68