tracing: Adding new functions for kernel access to Ftrace instances
Adding 2 new functions - 1) struct trace_array *trace_array_get_by_name(const char *name); Return pointer to a trace array with given name. If it does not exist, create and return pointer to the new trace array. 2) int trace_array_set_clr_event(struct trace_array *tr, const char *system ,const char *event, bool enable); Enable/Disable events to this trace array. Additionally, - To handle reference counters, export trace_array_put() - Due to introduction of the above 2 new functions, we no longer need to export - ftrace_set_clr_event & trace_array_create APIs. Link: http://lkml.kernel.org/r/1574276919-11119-2-git-send-email-divya.indi@oracle.com Signed-off-by: Divya Indi <divya.indi@oracle.com> Reviewed-by: Aruna Ramakrishna <aruna.ramakrishna@oracle.com> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
committed by
Steven Rostedt (VMware)
parent
fc809bc5ce
commit
2887978714
@@ -29,7 +29,8 @@ struct trace_array;
|
|||||||
void trace_printk_init_buffers(void);
|
void trace_printk_init_buffers(void);
|
||||||
int trace_array_printk(struct trace_array *tr, unsigned long ip,
|
int trace_array_printk(struct trace_array *tr, unsigned long ip,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
struct trace_array *trace_array_create(const char *name);
|
void trace_array_put(struct trace_array *tr);
|
||||||
|
struct trace_array *trace_array_get_by_name(const char *name);
|
||||||
int trace_array_destroy(struct trace_array *tr);
|
int trace_array_destroy(struct trace_array *tr);
|
||||||
#endif /* CONFIG_TRACING */
|
#endif /* CONFIG_TRACING */
|
||||||
|
|
||||||
|
|||||||
@@ -555,7 +555,8 @@ extern int trace_event_get_offsets(struct trace_event_call *call);
|
|||||||
|
|
||||||
int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set);
|
int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set);
|
||||||
int trace_set_clr_event(const char *system, const char *event, int set);
|
int trace_set_clr_event(const char *system, const char *event, int set);
|
||||||
|
int trace_array_set_clr_event(struct trace_array *tr, const char *system,
|
||||||
|
const char *event, bool enable);
|
||||||
/*
|
/*
|
||||||
* The double __builtin_constant_p is because gcc will give us an error
|
* The double __builtin_constant_p is because gcc will give us an error
|
||||||
* if we try to allocate the static variable to fmt if it is not a
|
* if we try to allocate the static variable to fmt if it is not a
|
||||||
|
|||||||
@@ -301,12 +301,24 @@ static void __trace_array_put(struct trace_array *this_tr)
|
|||||||
this_tr->ref--;
|
this_tr->ref--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* trace_array_put - Decrement the reference counter for this trace array.
|
||||||
|
*
|
||||||
|
* NOTE: Use this when we no longer need the trace array returned by
|
||||||
|
* trace_array_get_by_name(). This ensures the trace array can be later
|
||||||
|
* destroyed.
|
||||||
|
*
|
||||||
|
*/
|
||||||
void trace_array_put(struct trace_array *this_tr)
|
void trace_array_put(struct trace_array *this_tr)
|
||||||
{
|
{
|
||||||
|
if (!this_tr)
|
||||||
|
return;
|
||||||
|
|
||||||
mutex_lock(&trace_types_lock);
|
mutex_lock(&trace_types_lock);
|
||||||
__trace_array_put(this_tr);
|
__trace_array_put(this_tr);
|
||||||
mutex_unlock(&trace_types_lock);
|
mutex_unlock(&trace_types_lock);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(trace_array_put);
|
||||||
|
|
||||||
int tracing_check_open_get_tr(struct trace_array *tr)
|
int tracing_check_open_get_tr(struct trace_array *tr)
|
||||||
{
|
{
|
||||||
@@ -8437,24 +8449,15 @@ static void update_tracer_options(struct trace_array *tr)
|
|||||||
mutex_unlock(&trace_types_lock);
|
mutex_unlock(&trace_types_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct trace_array *trace_array_create(const char *name)
|
static struct trace_array *trace_array_create(const char *name)
|
||||||
{
|
{
|
||||||
struct trace_array *tr;
|
struct trace_array *tr;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&event_mutex);
|
|
||||||
mutex_lock(&trace_types_lock);
|
|
||||||
|
|
||||||
ret = -EEXIST;
|
|
||||||
list_for_each_entry(tr, &ftrace_trace_arrays, list) {
|
|
||||||
if (tr->name && strcmp(tr->name, name) == 0)
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
tr = kzalloc(sizeof(*tr), GFP_KERNEL);
|
tr = kzalloc(sizeof(*tr), GFP_KERNEL);
|
||||||
if (!tr)
|
if (!tr)
|
||||||
goto out_unlock;
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
tr->name = kstrdup(name, GFP_KERNEL);
|
tr->name = kstrdup(name, GFP_KERNEL);
|
||||||
if (!tr->name)
|
if (!tr->name)
|
||||||
@@ -8499,8 +8502,8 @@ struct trace_array *trace_array_create(const char *name)
|
|||||||
|
|
||||||
list_add(&tr->list, &ftrace_trace_arrays);
|
list_add(&tr->list, &ftrace_trace_arrays);
|
||||||
|
|
||||||
mutex_unlock(&trace_types_lock);
|
tr->ref++;
|
||||||
mutex_unlock(&event_mutex);
|
|
||||||
|
|
||||||
return tr;
|
return tr;
|
||||||
|
|
||||||
@@ -8510,24 +8513,77 @@ struct trace_array *trace_array_create(const char *name)
|
|||||||
kfree(tr->name);
|
kfree(tr->name);
|
||||||
kfree(tr);
|
kfree(tr);
|
||||||
|
|
||||||
out_unlock:
|
|
||||||
mutex_unlock(&trace_types_lock);
|
|
||||||
mutex_unlock(&event_mutex);
|
|
||||||
|
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(trace_array_create);
|
|
||||||
|
|
||||||
static int instance_mkdir(const char *name)
|
static int instance_mkdir(const char *name)
|
||||||
{
|
{
|
||||||
return PTR_ERR_OR_ZERO(trace_array_create(name));
|
struct trace_array *tr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&event_mutex);
|
||||||
|
mutex_lock(&trace_types_lock);
|
||||||
|
|
||||||
|
ret = -EEXIST;
|
||||||
|
list_for_each_entry(tr, &ftrace_trace_arrays, list) {
|
||||||
|
if (tr->name && strcmp(tr->name, name) == 0)
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr = trace_array_create(name);
|
||||||
|
|
||||||
|
ret = PTR_ERR_OR_ZERO(tr);
|
||||||
|
|
||||||
|
out_unlock:
|
||||||
|
mutex_unlock(&trace_types_lock);
|
||||||
|
mutex_unlock(&event_mutex);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* trace_array_get_by_name - Create/Lookup a trace array, given its name.
|
||||||
|
* @name: The name of the trace array to be looked up/created.
|
||||||
|
*
|
||||||
|
* Returns pointer to trace array with given name.
|
||||||
|
* NULL, if it cannot be created.
|
||||||
|
*
|
||||||
|
* NOTE: This function increments the reference counter associated with the
|
||||||
|
* trace array returned. This makes sure it cannot be freed while in use.
|
||||||
|
* Use trace_array_put() once the trace array is no longer needed.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct trace_array *trace_array_get_by_name(const char *name)
|
||||||
|
{
|
||||||
|
struct trace_array *tr;
|
||||||
|
|
||||||
|
mutex_lock(&event_mutex);
|
||||||
|
mutex_lock(&trace_types_lock);
|
||||||
|
|
||||||
|
list_for_each_entry(tr, &ftrace_trace_arrays, list) {
|
||||||
|
if (tr->name && strcmp(tr->name, name) == 0)
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr = trace_array_create(name);
|
||||||
|
|
||||||
|
if (IS_ERR(tr))
|
||||||
|
tr = NULL;
|
||||||
|
out_unlock:
|
||||||
|
if (tr)
|
||||||
|
tr->ref++;
|
||||||
|
|
||||||
|
mutex_unlock(&trace_types_lock);
|
||||||
|
mutex_unlock(&event_mutex);
|
||||||
|
return tr;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(trace_array_get_by_name);
|
||||||
|
|
||||||
static int __remove_instance(struct trace_array *tr)
|
static int __remove_instance(struct trace_array *tr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (tr->ref || (tr->current_trace && tr->current_trace->ref))
|
/* Reference counter for a newly created trace array = 1. */
|
||||||
|
if (tr->ref > 1 || (tr->current_trace && tr->current_trace->ref))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
list_del(&tr->list);
|
list_del(&tr->list);
|
||||||
|
|||||||
@@ -345,7 +345,6 @@ extern struct list_head ftrace_trace_arrays;
|
|||||||
extern struct mutex trace_types_lock;
|
extern struct mutex trace_types_lock;
|
||||||
|
|
||||||
extern int trace_array_get(struct trace_array *tr);
|
extern int trace_array_get(struct trace_array *tr);
|
||||||
extern void trace_array_put(struct trace_array *tr);
|
|
||||||
extern int tracing_check_open_get_tr(struct trace_array *tr);
|
extern int tracing_check_open_get_tr(struct trace_array *tr);
|
||||||
|
|
||||||
extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs);
|
extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs);
|
||||||
|
|||||||
@@ -827,7 +827,6 @@ 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
|
||||||
@@ -852,6 +851,32 @@ int trace_set_clr_event(const char *system, const char *event, int set)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(trace_set_clr_event);
|
EXPORT_SYMBOL_GPL(trace_set_clr_event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* trace_array_set_clr_event - enable or disable an event for a trace array.
|
||||||
|
* @tr: concerned trace array.
|
||||||
|
* @system: system name to match (NULL for any system)
|
||||||
|
* @event: event name to match (NULL for all events, within system)
|
||||||
|
* @enable: true to enable, false to disable
|
||||||
|
*
|
||||||
|
* This is a way for other parts of the kernel to enable or disable
|
||||||
|
* event recording.
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -EINVAL if the parameters do not match any
|
||||||
|
* registered events.
|
||||||
|
*/
|
||||||
|
int trace_array_set_clr_event(struct trace_array *tr, const char *system,
|
||||||
|
const char *event, bool enable)
|
||||||
|
{
|
||||||
|
int set;
|
||||||
|
|
||||||
|
if (!tr)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
set = (enable == true) ? 1 : 0;
|
||||||
|
return __ftrace_set_clr_event(tr, NULL, system, event, set);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(trace_array_set_clr_event);
|
||||||
|
|
||||||
/* 128 should be much more than enough */
|
/* 128 should be much more than enough */
|
||||||
#define EVENT_BUF_SIZE 127
|
#define EVENT_BUF_SIZE 127
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user