mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-27 14:43:58 +08:00
tracing: Kernel access to Ftrace instances
Ftrace provides the feature “instances” that provides the capability to create multiple Ftrace ring buffers. However, currently these buffers are created/accessed via userspace only. The kernel APIs providing these features are not exported, hence cannot be used by other kernel components. This patch aims to extend this infrastructure to provide the flexibility to create/log/remove/ enable-disable existing trace events to these buffers from within the kernel. Link: http://lkml.kernel.org/r/1553106531-3281-2-git-send-email-divya.indi@oracle.com Signed-off-by: Divya Indi <divya.indi@oracle.com> Reviewed-by: Joe Jin <joe.jin@oracle.com> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
parent
40ed29b373
commit
f45d1225ad
@ -3053,6 +3053,7 @@ void trace_printk_init_buffers(void)
|
|||||||
if (global_trace.trace_buffer.buffer)
|
if (global_trace.trace_buffer.buffer)
|
||||||
tracing_start_cmdline_record();
|
tracing_start_cmdline_record();
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(trace_printk_init_buffers);
|
||||||
|
|
||||||
void trace_printk_start_comm(void)
|
void trace_printk_start_comm(void)
|
||||||
{
|
{
|
||||||
@ -3213,6 +3214,7 @@ int trace_array_printk(struct trace_array *tr,
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(trace_array_printk);
|
||||||
|
|
||||||
__printf(3, 4)
|
__printf(3, 4)
|
||||||
int trace_array_printk_buf(struct ring_buffer *buffer,
|
int trace_array_printk_buf(struct ring_buffer *buffer,
|
||||||
@ -8037,7 +8039,7 @@ static void update_tracer_options(struct trace_array *tr)
|
|||||||
mutex_unlock(&trace_types_lock);
|
mutex_unlock(&trace_types_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int instance_mkdir(const char *name)
|
struct trace_array *trace_array_create(const char *name)
|
||||||
{
|
{
|
||||||
struct trace_array *tr;
|
struct trace_array *tr;
|
||||||
int ret;
|
int ret;
|
||||||
@ -8101,7 +8103,7 @@ static int instance_mkdir(const char *name)
|
|||||||
mutex_unlock(&trace_types_lock);
|
mutex_unlock(&trace_types_lock);
|
||||||
mutex_unlock(&event_mutex);
|
mutex_unlock(&event_mutex);
|
||||||
|
|
||||||
return 0;
|
return tr;
|
||||||
|
|
||||||
out_free_tr:
|
out_free_tr:
|
||||||
free_trace_buffers(tr);
|
free_trace_buffers(tr);
|
||||||
@ -8113,33 +8115,21 @@ static int instance_mkdir(const char *name)
|
|||||||
mutex_unlock(&trace_types_lock);
|
mutex_unlock(&trace_types_lock);
|
||||||
mutex_unlock(&event_mutex);
|
mutex_unlock(&event_mutex);
|
||||||
|
|
||||||
return ret;
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(trace_array_create);
|
||||||
|
|
||||||
|
static int instance_mkdir(const char *name)
|
||||||
|
{
|
||||||
|
return PTR_ERR_OR_ZERO(trace_array_create(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int instance_rmdir(const char *name)
|
static int __remove_instance(struct trace_array *tr)
|
||||||
{
|
{
|
||||||
struct trace_array *tr;
|
|
||||||
int found = 0;
|
|
||||||
int ret;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
mutex_lock(&event_mutex);
|
|
||||||
mutex_lock(&trace_types_lock);
|
|
||||||
|
|
||||||
ret = -ENODEV;
|
|
||||||
list_for_each_entry(tr, &ftrace_trace_arrays, list) {
|
|
||||||
if (tr->name && strcmp(tr->name, name) == 0) {
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
goto out_unlock;
|
|
||||||
|
|
||||||
ret = -EBUSY;
|
|
||||||
if (tr->ref || (tr->current_trace && tr->current_trace->ref))
|
if (tr->ref || (tr->current_trace && tr->current_trace->ref))
|
||||||
goto out_unlock;
|
return -EBUSY;
|
||||||
|
|
||||||
list_del(&tr->list);
|
list_del(&tr->list);
|
||||||
|
|
||||||
@ -8165,10 +8155,46 @@ static int instance_rmdir(const char *name)
|
|||||||
free_cpumask_var(tr->tracing_cpumask);
|
free_cpumask_var(tr->tracing_cpumask);
|
||||||
kfree(tr->name);
|
kfree(tr->name);
|
||||||
kfree(tr);
|
kfree(tr);
|
||||||
|
tr = NULL;
|
||||||
|
|
||||||
ret = 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int trace_array_destroy(struct trace_array *tr)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!tr)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mutex_lock(&event_mutex);
|
||||||
|
mutex_lock(&trace_types_lock);
|
||||||
|
|
||||||
|
ret = __remove_instance(tr);
|
||||||
|
|
||||||
|
mutex_unlock(&trace_types_lock);
|
||||||
|
mutex_unlock(&event_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(trace_array_destroy);
|
||||||
|
|
||||||
|
static int instance_rmdir(const char *name)
|
||||||
|
{
|
||||||
|
struct trace_array *tr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&event_mutex);
|
||||||
|
mutex_lock(&trace_types_lock);
|
||||||
|
|
||||||
|
ret = -ENODEV;
|
||||||
|
list_for_each_entry(tr, &ftrace_trace_arrays, list) {
|
||||||
|
if (tr->name && strcmp(tr->name, name) == 0) {
|
||||||
|
ret = __remove_instance(tr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out_unlock:
|
|
||||||
mutex_unlock(&trace_types_lock);
|
mutex_unlock(&trace_types_lock);
|
||||||
mutex_unlock(&event_mutex);
|
mutex_unlock(&event_mutex);
|
||||||
|
|
||||||
|
@ -832,6 +832,7 @@ static int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(ftrace_set_clr_event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* trace_set_clr_event - enable or disable an event
|
* trace_set_clr_event - enable or disable an event
|
||||||
|
Loading…
Reference in New Issue
Block a user