struct lttng_cs_type {
const char *name;
const char *length_name;
- const char *save_func_name;
- void (*save_func)(struct stack_trace *trace);
};
static struct lttng_cs_type cs_types[] = {
{
.name = "callstack_kernel",
.length_name = "_callstack_kernel_length",
- .save_func_name = "save_stack_trace",
- .save_func = NULL,
},
{
.name = "callstack_user",
.length_name = "_callstack_user_length",
- .save_func_name = "save_stack_trace_user",
- .save_func = NULL,
},
};
return cs_types[mode].length_name;
}
-static
-int init_type(enum lttng_cs_ctx_modes mode)
-{
- unsigned long func;
-
- if (cs_types[mode].save_func)
- return 0;
- func = kallsyms_lookup_funcptr(cs_types[mode].save_func_name);
- if (!func) {
- printk(KERN_WARNING "LTTng: symbol lookup failed: %s\n",
- cs_types[mode].save_func_name);
- return -EINVAL;
- }
- cs_types[mode].save_func = (void *) func;
- return 0;
-}
-
static
void lttng_cs_set_init(struct lttng_cs __percpu *cs_set)
{
/* reset stack trace, no need to clear memory */
trace->nr_entries = 0;
- if (fdata->mode == CALLSTACK_USER)
+ if (fdata->mode == CALLSTACK_USER) {
++per_cpu(callstack_user_nesting, ctx->cpu);
-
- /* do the real work and reserve space */
- cs_types[fdata->mode].save_func(trace);
-
- if (fdata->mode == CALLSTACK_USER)
+ /* do the real work and reserve space */
+ save_stack_trace_user(trace);
per_cpu(callstack_user_nesting, ctx->cpu)--;
+ } else {
+ save_stack_trace(trace);
+ }
/*
* Remove final ULONG_MAX delimiter. If we cannot find it, add
enum lttng_cs_ctx_modes mode;
};
-static
-unsigned int (*save_func_kernel)(unsigned long *store, unsigned int size,
- unsigned int skipnr);
-static
-unsigned int (*save_func_user)(unsigned long *store, unsigned int size);
-
static
const char *lttng_cs_ctx_mode_name(enum lttng_cs_ctx_modes mode)
{
}
}
-static
-int init_type_callstack_kernel(void)
-{
- unsigned long func;
- const char *func_name = "stack_trace_save";
-
- if (save_func_kernel)
- return 0;
- func = kallsyms_lookup_funcptr(func_name);
- if (!func) {
- printk(KERN_WARNING "LTTng: symbol lookup failed: %s\n",
- func_name);
- return -EINVAL;
- }
- save_func_kernel = (void *) func;
- return 0;
-}
-
-static
-int init_type_callstack_user(void)
-{
- unsigned long func;
- const char *func_name = "stack_trace_save_user";
-
- if (save_func_user)
- return 0;
- func = kallsyms_lookup_funcptr(func_name);
- if (!func) {
- printk(KERN_WARNING "LTTng: symbol lookup failed: %s\n",
- func_name);
- return -EINVAL;
- }
- save_func_user = (void *) func;
- return 0;
-}
-
-static
-int init_type(enum lttng_cs_ctx_modes mode)
-{
- switch (mode) {
- case CALLSTACK_KERNEL:
- return init_type_callstack_kernel();
- case CALLSTACK_USER:
- return init_type_callstack_user();
- default:
- return -EINVAL;
- }
-}
-
static
void lttng_cs_set_init(struct lttng_cs __percpu *cs_set)
{
switch (fdata->mode) {
case CALLSTACK_KERNEL:
/* do the real work and reserve space */
- trace->nr_entries = save_func_kernel(trace->entries,
+ trace->nr_entries = stack_trace_save(trace->entries,
MAX_ENTRIES, 0);
break;
case CALLSTACK_USER:
++per_cpu(callstack_user_nesting, ctx->cpu);
/* do the real work and reserve space */
- trace->nr_entries = save_func_user(trace->entries,
+ trace->nr_entries = stack_trace_save_user(trace->entries,
MAX_ENTRIES);
per_cpu(callstack_user_nesting, ctx->cpu)--;
break;
#include "lttng-events.h"
#include "wrapper/ringbuffer/backend.h"
#include "wrapper/ringbuffer/frontend.h"
-#include "wrapper/kallsyms.h"
#include "lttng-tracer.h"
#include "lttng-endian.h"
struct field_data *fdata;
int ret;
- ret = init_type(mode);
- if (ret)
- return ret;
length_field = lttng_append_context(ctx);
if (!length_field)
return -ENOMEM;