diff options
-rw-r--r-- | Documentation/markers.txt | 17 | ||||
-rw-r--r-- | include/linux/marker.h | 16 | ||||
-rw-r--r-- | kernel/marker.c | 12 |
3 files changed, 33 insertions, 12 deletions
diff --git a/Documentation/markers.txt b/Documentation/markers.txt index d2b3d0e91b2..951a2f342b9 100644 --- a/Documentation/markers.txt +++ b/Documentation/markers.txt @@ -15,10 +15,12 @@ provide at runtime. A marker can be "on" (a probe is connected to it) or "off" (no probe is attached). When a marker is "off" it has no effect, except for adding a tiny time penalty (checking a condition for a branch) and space penalty (adding a few bytes for the function call at the end of the -instrumented function and adds a data structure in a separate section). When a -marker is "on", the function you provide is called each time the marker is -executed, in the execution context of the caller. When the function provided -ends its execution, it returns to the caller (continuing from the marker site). +instrumented function and adds a data structure in a separate section). The +immediate values are used to minimize the impact on data cache, encoding the +condition in the instruction stream. When a marker is "on", the function you +provide is called each time the marker is executed, in the execution context of +the caller. When the function provided ends its execution, it returns to the +caller (continuing from the marker site). You can put markers at important locations in the code. Markers are lightweight hooks that can pass an arbitrary number of parameters, @@ -90,6 +92,13 @@ notrace void probe_tracepoint_name(unsigned int arg1, struct task_struct *tsk) /* write data to trace buffers ... */ } +* Optimization for a given architecture + +To force use of a non-optimized version of the markers, _trace_mark() should be +used. It takes the same parameters as the normal markers, but it does not use +the immediate values based on code patching. + + * Probe / marker example See the example provided in samples/markers/src diff --git a/include/linux/marker.h b/include/linux/marker.h index 1f4e2e5a920..1b2e37ecb6f 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h @@ -14,6 +14,7 @@ #include <stdarg.h> #include <linux/types.h> +#include <linux/immediate.h> struct module; struct marker; @@ -43,7 +44,7 @@ struct marker { const char *format; /* Marker format string, describing the * variable argument list. */ - char state; /* Marker state. */ + DEFINE_IMV(char, state);/* Immediate value state. */ char ptype; /* probe type : 0 : single, 1 : multi */ /* Probe wrapper */ void (*call)(const struct marker *mdata, void *call_private, ...); @@ -84,9 +85,16 @@ struct marker { do { \ DEFINE_MARKER(name, format); \ __mark_check_format(format, ## args); \ - if (unlikely(__mark_##name.state)) { \ - (*__mark_##name.call) \ - (&__mark_##name, call_private, ## args);\ + if (!generic) { \ + if (unlikely(imv_read(__mark_##name.state))) \ + (*__mark_##name.call) \ + (&__mark_##name, call_private, \ + ## args); \ + } else { \ + if (unlikely(_imv_read(__mark_##name.state))) \ + (*__mark_##name.call) \ + (&__mark_##name, call_private, \ + ## args); \ } \ } while (0) diff --git a/kernel/marker.c b/kernel/marker.c index 15ecb2aa907..cdf49fd2eae 100644 --- a/kernel/marker.c +++ b/kernel/marker.c @@ -24,6 +24,7 @@ #include <linux/marker.h> #include <linux/err.h> #include <linux/slab.h> +#include <linux/immediate.h> extern struct marker __start___markers[]; extern struct marker __stop___markers[]; @@ -532,7 +533,7 @@ static int set_marker(struct marker_entry *entry, struct marker *elem, smp_wmb(); elem->ptype = entry->ptype; - if (elem->tp_name && (active ^ elem->state)) { + if (elem->tp_name && (active ^ _imv_read(elem->state))) { WARN_ON(!elem->tp_cb); /* * It is ok to directly call the probe registration because type @@ -562,7 +563,7 @@ static int set_marker(struct marker_entry *entry, struct marker *elem, (unsigned long)elem->tp_cb)); } } - elem->state = active; + elem->state__imv = active; return ret; } @@ -578,7 +579,7 @@ static void disable_marker(struct marker *elem) int ret; /* leave "call" as is. It is known statically. */ - if (elem->tp_name && elem->state) { + if (elem->tp_name && _imv_read(elem->state)) { WARN_ON(!elem->tp_cb); /* * It is ok to directly call the probe registration because type @@ -593,7 +594,7 @@ static void disable_marker(struct marker *elem) */ module_put(__module_text_address((unsigned long)elem->tp_cb)); } - elem->state = 0; + elem->state__imv = 0; elem->single.func = __mark_empty_function; /* Update the function before setting the ptype */ smp_wmb(); @@ -657,6 +658,9 @@ static void marker_update_probes(void) /* Markers in modules. */ module_update_markers(); tracepoint_probe_update_all(); + /* Update immediate values */ + core_imv_update(); + module_imv_update(); } /** |