diff options
author | Josh Stone <joshua.i.stone@intel.com> | 2008-05-23 20:35:55 -0700 |
---|---|---|
committer | Josh Stone <joshua.i.stone@intel.com> | 2008-05-27 16:19:03 -0700 |
commit | 2cda5f46cba978e19590efd7fee0b3075f8eb8df (patch) | |
tree | d613226eb1fe124643018b5e4c45f7019df635ea | |
parent | a2eab6ee228991f3ebfa5f628857ec6c703c85d1 (diff) | |
download | systemtap-steved-2cda5f46cba978e19590efd7fee0b3075f8eb8df.tar.gz systemtap-steved-2cda5f46cba978e19590efd7fee0b3075f8eb8df.tar.xz systemtap-steved-2cda5f46cba978e19590efd7fee0b3075f8eb8df.zip |
Add prototypes for using the 2.6.26 probe_kernel_* functions.
For now, the autoconf for the new code is disabled, because it shows
poorer performance than our existing dereferencing functions. This is
probably because ours get inlined and optimized. The code is being
committed so that we may re-evaluate its usefulness in the future.
This addresses bugzilla 6432.
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | buildrun.cxx | 6 | ||||
-rw-r--r-- | runtime/ChangeLog | 8 | ||||
-rw-r--r-- | runtime/autoconf-probe-kernel.c | 7 | ||||
-rw-r--r-- | runtime/loc2c-runtime.h | 125 |
5 files changed, 120 insertions, 38 deletions
@@ -1,3 +1,9 @@ +2008-05-27 Josh Stone <joshua.i.stone@intel.com> + + PR 6432 + * buildrun.cxx (compile_pass): Add the autoconf test for probe_kernel_* + functions, but leave it #if-0'ed for now. + 2008-05-23 Jim Keniston <jkenisto@us.ibm.com> PR 4311, cont. Address powerpc dwarfless test failures. @@ -6,9 +12,9 @@ that map to sys_ni_syscall. 2008-05-23 Srinivasa DS <srinivasa@in.ibm.com> - PR 6429: Inerim fix to avoid compilation error of systemtap module - * runtime/transport/symbols.c: added definitions of struct - module_sect_attr, struct module_sect_attrs for 2.6.25 above kernels. + PR 6429: Inerim fix to avoid compilation error of systemtap module + * runtime/transport/symbols.c: added definitions of struct + module_sect_attr, struct module_sect_attrs for 2.6.25 above kernels. 2008-05-22 Wenji Huang <wenji.huang@oracle.com> diff --git a/buildrun.cxx b/buildrun.cxx index 76efe7c0..a39f2b63 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -96,6 +96,12 @@ compile_pass (systemtap_session& s) o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-nameidata.c, -DSTAPCONF_NAMEIDATA_CLEANUP,)" << endl; o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-unregister-kprobes.c, -DSTAPCONF_UNREGISTER_KPROBES,)" << endl; o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-module-nsections.c, -DSTAPCONF_MODULE_NSECTIONS,)" << endl; +#if 0 + /* NB: For now, the performance hit of probe_kernel_read/write (vs. our + * homegrown safe-access functions) is deemed undesireable, so we'll skip + * this autoconf. */ + o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-probe-kernel.c, -DSTAPCONF_PROBE_KERNEL,)" << endl; +#endif for (unsigned i=0; i<s.macros.size(); i++) o << "EXTRA_CFLAGS += -D " << lex_cast_qstring(s.macros[i]) << endl; diff --git a/runtime/ChangeLog b/runtime/ChangeLog index bdf6e56d..3d506a18 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,11 @@ +2008-05-27 Josh Stone <joshua.i.stone@intel.com> + + PR 6432 + * loc2c-runtime.h (kread, kwrite, deref, store_deref): Add + architecture-neutral implementations, using probe_kernel_* + facilites (controlled by autoconf). + * autoconf-probe-kernel.c: test for above. + 2008-05-16 David Smith <dsmith@redhat.com> PR 6499. diff --git a/runtime/autoconf-probe-kernel.c b/runtime/autoconf-probe-kernel.c new file mode 100644 index 00000000..93fbaae6 --- /dev/null +++ b/runtime/autoconf-probe-kernel.c @@ -0,0 +1,7 @@ +#include <linux/uaccess.h> + +void probe_kernel(void *dst, void *src, size_t size) +{ + (void)probe_kernel_read(dst, src, size); + (void)probe_kernel_write(dst, src, size); +} diff --git a/runtime/loc2c-runtime.h b/runtime/loc2c-runtime.h index 66fd1e43..a7472691 100644 --- a/runtime/loc2c-runtime.h +++ b/runtime/loc2c-runtime.h @@ -9,6 +9,7 @@ * later version. */ +#include <linux/uaccess.h> #include <linux/types.h> #define intptr_t long #define uintptr_t unsigned long @@ -31,9 +32,6 @@ << (sizeof (base) * 8 - (higherbits) - (nbits)))) -/* These operations are target-specific. */ -#include <asm/uaccess.h> - /* Given a DWARF register number, fetch its intptr_t (long) value from the probe context, or store a new value into the probe context. @@ -173,6 +171,61 @@ #endif + +/* NB: this autoconf is always disabled, pending further performance eval. */ +#if defined STAPCONF_PROBE_KERNEL + +/* Kernel 2.6.26 adds probe_kernel_{read,write}, which lets us write + * architecture-neutral implementations of kread, kwrite, deref, and + * store_deref. + * + * NB: deref and store_deref shouldn't be used with 64-bit values on 32-bit + * platforms, because they will lose data in the conversion to intptr_t. We + * generally want to encourage using kread and kwrite instead. + */ + +#define kread(ptr) ({ \ + typeof(*(ptr)) _v; \ + if (probe_kernel_read((void *)&_v, (void *)(ptr), sizeof(*(ptr)))) \ + DEREF_FAULT(ptr); \ + _v; \ + }) + +#define kwrite(ptr, value) ({ \ + typeof(*(ptr)) _v; \ + _v = (typeof(*(ptr)))(value); \ + if (probe_kernel_write((void *)(ptr), (void *)&_v, sizeof(*(ptr)))) \ + STORE_DEREF_FAULT(ptr); \ + }) + +#define deref(size, addr) ({ \ + intptr_t _i; \ + switch (size) { \ + case 1: _i = kread((u8 *)(addr)); break; \ + case 2: _i = kread((u16 *)(addr)); break; \ + case 4: _i = kread((u32 *)(addr)); break; \ + case 8: _i = kread((u64 *)(addr)); break; \ + default: __deref_bad(); \ + /* uninitialized _i should also be caught by -Werror */ \ + } \ + _i; \ + }) + +#define store_deref(size, addr, value) ({ \ + switch (size) { \ + case 1: kwrite((u8 *)(addr), (value)); break; \ + case 2: kwrite((u16 *)(addr), (value)); break; \ + case 4: kwrite((u32 *)(addr), (value)); break; \ + case 8: kwrite((u64 *)(addr), (value)); break; \ + default: __store_deref_bad(); \ + } \ + }) + +extern void __deref_bad(void); +extern void __store_deref_bad(void); + +#else /* !STAPCONF_PROBE_KERNEL */ + #if defined __i386__ #define deref(size, addr) \ @@ -614,38 +667,6 @@ #endif /* (s390) || (s390x) */ -#define deref_string(dst, addr, maxbytes) \ - ({ \ - uintptr_t _addr; \ - size_t _len; \ - unsigned char _c; \ - char *_d = (dst); \ - for (_len = (maxbytes), _addr = (uintptr_t)(addr); \ - _len > 1 && (_c = deref (1, _addr)) != '\0'; \ - --_len, ++_addr) \ - if (_d) \ - *_d++ = _c; \ - if (_d) \ - *_d = '\0'; \ - (dst); \ - }) - -#define deref_buffer(dst, addr, numbytes) \ - ({ \ - uintptr_t _addr; \ - size_t _len; \ - unsigned char _c; \ - char *_d = (dst); \ - for (_len = (numbytes), _addr = (uintptr_t)(addr); \ - _len >= 1; \ - --_len, ++_addr) { \ - _c = deref (1, _addr); \ - if (_d) \ - *_d++ = _c; \ - } \ - (dst); \ - }) - #if defined __i386__ @@ -678,6 +699,40 @@ #endif +#endif /* STAPCONF_PROBE_KERNEL */ + +#define deref_string(dst, addr, maxbytes) \ + ({ \ + uintptr_t _addr; \ + size_t _len; \ + unsigned char _c; \ + char *_d = (dst); \ + for (_len = (maxbytes), _addr = (uintptr_t)(addr); \ + _len > 1 && (_c = deref (1, _addr)) != '\0'; \ + --_len, ++_addr) \ + if (_d) \ + *_d++ = _c; \ + if (_d) \ + *_d = '\0'; \ + (dst); \ + }) + +#define deref_buffer(dst, addr, numbytes) \ + ({ \ + uintptr_t _addr; \ + size_t _len; \ + unsigned char _c; \ + char *_d = (dst); \ + for (_len = (numbytes), _addr = (uintptr_t)(addr); \ + _len >= 1; \ + --_len, ++_addr) { \ + _c = deref (1, _addr); \ + if (_d) \ + *_d++ = _c; \ + } \ + (dst); \ + }) + #define CATCH_DEREF_FAULT() \ if (0) { \ deref_fault: ; \ |