summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <joshua.i.stone@intel.com>2008-05-23 20:35:55 -0700
committerJosh Stone <joshua.i.stone@intel.com>2008-05-27 16:19:03 -0700
commit2cda5f46cba978e19590efd7fee0b3075f8eb8df (patch)
treed613226eb1fe124643018b5e4c45f7019df635ea
parenta2eab6ee228991f3ebfa5f628857ec6c703c85d1 (diff)
downloadsystemtap-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--ChangeLog12
-rw-r--r--buildrun.cxx6
-rw-r--r--runtime/ChangeLog8
-rw-r--r--runtime/autoconf-probe-kernel.c7
-rw-r--r--runtime/loc2c-runtime.h125
5 files changed, 120 insertions, 38 deletions
diff --git a/ChangeLog b/ChangeLog
index 0db1ca55..cb786d0e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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: ; \