This should be more efficient, disableable or done inside the probe. For GDB static tracepoints.
char *format;
char *name;
/* Probe wrapper */
- void (*call)(const struct marker *mdata, void *call_private, ...);
+ void (*call)(const struct marker *mdata, void *call_private, struct registers *regs, ...);
struct marker_probe_closure single;
struct marker_probe_closure *multi;
int refcount; /* Number of times armed. 0 if disarmed. */
* operations that modifies the execution flow of preemptible code.
*/
notrace void __mark_empty_function(const struct marker *mdata,
- void *probe_private, void *call_private, const char *fmt, va_list *args)
+ void *probe_private, struct registers *regs, void *call_private, const char *fmt, va_list *args)
{
}
//ust// EXPORT_SYMBOL_GPL(__mark_empty_function);
* rcu_dereference() for the pointer read.
*/
notrace void marker_probe_cb(const struct marker *mdata,
- void *call_private, ...)
+ void *call_private, struct registers *regs, ...)
{
va_list args;
char ptype;
/* Must read the ptr before private data. They are not data
* dependant, so we put an explicit smp_rmb() here. */
smp_rmb();
- va_start(args, call_private);
- func(mdata, mdata->single.probe_private, call_private,
+ va_start(args, regs);
+ func(mdata, mdata->single.probe_private, regs, call_private,
mdata->format, &args);
va_end(args);
} else {
*/
smp_read_barrier_depends();
for (i = 0; multi[i].func; i++) {
- va_start(args, call_private);
+ va_start(args, regs);
multi[i].func(mdata, multi[i].probe_private,
- call_private, mdata->format, &args);
+ regs, call_private, mdata->format, &args);
va_end(args);
}
}
* Should be connected to markers "MARK_NOARGS".
*/
static notrace void marker_probe_cb_noarg(const struct marker *mdata,
- void *call_private, ...)
+ void *call_private, struct registers *regs, ...)
{
va_list args; /* not initialized */
char ptype;
/* Must read the ptr before private data. They are not data
* dependant, so we put an explicit smp_rmb() here. */
smp_rmb();
- func(mdata, mdata->single.probe_private, call_private,
+ func(mdata, mdata->single.probe_private, regs, call_private,
mdata->format, &args);
} else {
struct marker_probe_closure *multi;
*/
smp_read_barrier_depends();
for (i = 0; multi[i].func; i++)
- multi[i].func(mdata, multi[i].probe_private,
+ multi[i].func(mdata, multi[i].probe_private, regs,
call_private, mdata->format, &args);
}
//ust// rcu_read_unlock_sched_notrace();
* format string to recover the variable argument list.
*/
typedef void marker_probe_func(const struct marker *mdata,
- void *probe_private, void *call_private,
+ void *probe_private, struct registers *regs, void *call_private,
const char *fmt, va_list *args);
struct marker_probe_closure {
/* Probe wrapper */
u16 channel_id; /* Numeric channel identifier, dynamic */
u16 event_id; /* Numeric event identifier, dynamic */
- void (*call)(const struct marker *mdata, void *call_private, ...);
+ void (*call)(const struct marker *mdata, void *call_private, struct registers *regs, ...);
struct marker_probe_closure single;
struct marker_probe_closure *multi;
const char *tp_name; /* Optional tracepoint name */
static const char __mstrtab_##channel##_##name[] \
__attribute__((section("__markers_strings"))) \
= #channel "\0" #name "\0" format; \
+ struct registers regs; \
static struct marker __mark_##channel##_##name \
__attribute__((section("__markers"), aligned(8))) = \
{ __mstrtab_##channel##_##name, \
__mark_##channel##_##name.state))) \
(*__mark_##channel##_##name.call) \
(&__mark_##channel##_##name, \
- call_private, ## args); \
+ call_private, ®s, ## args); \
} else { \
if (unlikely(_imv_read( \
__mark_##channel##_##name.state))) \
(*__mark_##channel##_##name.call) \
(&__mark_##channel##_##name, \
- call_private, ## args); \
+ call_private, ®s, ## args); \
} \
} while (0)
DEFINE_MARKER_TP(channel, name, tp_name, tp_cb, format);\
__mark_check_format(format, ## args); \
(*__mark_##channel##_##name.call)(&__mark_##channel##_##name, \
- call_private, ## args); \
+ call_private, ®s, ## args); \
} while (0)
extern void marker_update_probe_range(struct marker *begin,
extern marker_probe_func __mark_empty_function;
extern void marker_probe_cb(const struct marker *mdata,
- void *call_private, ...);
+ void *call_private, struct registers *regs, ...);
/*
* Connect a probe to a marker.
notrace void ltt_vtrace(const struct marker *mdata, void *probe_data,
- void *call_data, const char *fmt, va_list *args)
+ struct registers *regs, void *call_data,
+ const char *fmt, va_list *args)
{
int largest_align, ret;
struct ltt_active_marker *pdata;
}
notrace void ltt_trace(const struct marker *mdata, void *probe_data,
- void *call_data, const char *fmt, ...)
+ struct registers *regs, void *call_data,
+ const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
- ltt_vtrace(mdata, probe_data, call_data, fmt, &args);
+ ltt_vtrace(mdata, probe_data, regs, call_data, fmt, &args);
va_end(args);
}
struct marker; //ust//
extern void ltt_vtrace(const struct marker *mdata, void *probe_data,
- void *call_data, const char *fmt, va_list *args);
+ struct registers *regs, void *call_data, const char *fmt, va_list *args);
extern void ltt_trace(const struct marker *mdata, void *probe_data,
- void *call_data, const char *fmt, ...);
+ struct registers *regs, void *call_data, const char *fmt, ...);
/*
* Unique ID assigned to each registered probe.