Skip to content

Commit 2887978

Browse files
Divya Indirostedt
authored andcommitted
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/[email protected] Signed-off-by: Divya Indi <[email protected]> Reviewed-by: Aruna Ramakrishna <[email protected]> Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent fc809bc commit 2887978

File tree

5 files changed

+106
-24
lines changed

5 files changed

+106
-24
lines changed

include/linux/trace.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ struct trace_array;
2929
void trace_printk_init_buffers(void);
3030
int trace_array_printk(struct trace_array *tr, unsigned long ip,
3131
const char *fmt, ...);
32-
struct trace_array *trace_array_create(const char *name);
32+
void trace_array_put(struct trace_array *tr);
33+
struct trace_array *trace_array_get_by_name(const char *name);
3334
int trace_array_destroy(struct trace_array *tr);
3435
#endif /* CONFIG_TRACING */
3536

include/linux/trace_events.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,8 @@ extern int trace_event_get_offsets(struct trace_event_call *call);
555555

556556
int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set);
557557
int trace_set_clr_event(const char *system, const char *event, int set);
558-
558+
int trace_array_set_clr_event(struct trace_array *tr, const char *system,
559+
const char *event, bool enable);
559560
/*
560561
* The double __builtin_constant_p is because gcc will give us an error
561562
* if we try to allocate the static variable to fmt if it is not a

kernel/trace/trace.c

Lines changed: 76 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -301,12 +301,24 @@ static void __trace_array_put(struct trace_array *this_tr)
301301
this_tr->ref--;
302302
}
303303

304+
/**
305+
* trace_array_put - Decrement the reference counter for this trace array.
306+
*
307+
* NOTE: Use this when we no longer need the trace array returned by
308+
* trace_array_get_by_name(). This ensures the trace array can be later
309+
* destroyed.
310+
*
311+
*/
304312
void trace_array_put(struct trace_array *this_tr)
305313
{
314+
if (!this_tr)
315+
return;
316+
306317
mutex_lock(&trace_types_lock);
307318
__trace_array_put(this_tr);
308319
mutex_unlock(&trace_types_lock);
309320
}
321+
EXPORT_SYMBOL_GPL(trace_array_put);
310322

311323
int tracing_check_open_get_tr(struct trace_array *tr)
312324
{
@@ -8437,24 +8449,15 @@ static void update_tracer_options(struct trace_array *tr)
84378449
mutex_unlock(&trace_types_lock);
84388450
}
84398451

8440-
struct trace_array *trace_array_create(const char *name)
8452+
static struct trace_array *trace_array_create(const char *name)
84418453
{
84428454
struct trace_array *tr;
84438455
int ret;
84448456

8445-
mutex_lock(&event_mutex);
8446-
mutex_lock(&trace_types_lock);
8447-
8448-
ret = -EEXIST;
8449-
list_for_each_entry(tr, &ftrace_trace_arrays, list) {
8450-
if (tr->name && strcmp(tr->name, name) == 0)
8451-
goto out_unlock;
8452-
}
8453-
84548457
ret = -ENOMEM;
84558458
tr = kzalloc(sizeof(*tr), GFP_KERNEL);
84568459
if (!tr)
8457-
goto out_unlock;
8460+
return ERR_PTR(ret);
84588461

84598462
tr->name = kstrdup(name, GFP_KERNEL);
84608463
if (!tr->name)
@@ -8499,8 +8502,8 @@ struct trace_array *trace_array_create(const char *name)
84998502

85008503
list_add(&tr->list, &ftrace_trace_arrays);
85018504

8502-
mutex_unlock(&trace_types_lock);
8503-
mutex_unlock(&event_mutex);
8505+
tr->ref++;
8506+
85048507

85058508
return tr;
85068509

@@ -8510,24 +8513,77 @@ struct trace_array *trace_array_create(const char *name)
85108513
kfree(tr->name);
85118514
kfree(tr);
85128515

8513-
out_unlock:
8514-
mutex_unlock(&trace_types_lock);
8515-
mutex_unlock(&event_mutex);
8516-
85178516
return ERR_PTR(ret);
85188517
}
8519-
EXPORT_SYMBOL_GPL(trace_array_create);
85208518

85218519
static int instance_mkdir(const char *name)
85228520
{
8523-
return PTR_ERR_OR_ZERO(trace_array_create(name));
8521+
struct trace_array *tr;
8522+
int ret;
8523+
8524+
mutex_lock(&event_mutex);
8525+
mutex_lock(&trace_types_lock);
8526+
8527+
ret = -EEXIST;
8528+
list_for_each_entry(tr, &ftrace_trace_arrays, list) {
8529+
if (tr->name && strcmp(tr->name, name) == 0)
8530+
goto out_unlock;
8531+
}
8532+
8533+
tr = trace_array_create(name);
8534+
8535+
ret = PTR_ERR_OR_ZERO(tr);
8536+
8537+
out_unlock:
8538+
mutex_unlock(&trace_types_lock);
8539+
mutex_unlock(&event_mutex);
8540+
return ret;
8541+
}
8542+
8543+
/**
8544+
* trace_array_get_by_name - Create/Lookup a trace array, given its name.
8545+
* @name: The name of the trace array to be looked up/created.
8546+
*
8547+
* Returns pointer to trace array with given name.
8548+
* NULL, if it cannot be created.
8549+
*
8550+
* NOTE: This function increments the reference counter associated with the
8551+
* trace array returned. This makes sure it cannot be freed while in use.
8552+
* Use trace_array_put() once the trace array is no longer needed.
8553+
*
8554+
*/
8555+
struct trace_array *trace_array_get_by_name(const char *name)
8556+
{
8557+
struct trace_array *tr;
8558+
8559+
mutex_lock(&event_mutex);
8560+
mutex_lock(&trace_types_lock);
8561+
8562+
list_for_each_entry(tr, &ftrace_trace_arrays, list) {
8563+
if (tr->name && strcmp(tr->name, name) == 0)
8564+
goto out_unlock;
8565+
}
8566+
8567+
tr = trace_array_create(name);
8568+
8569+
if (IS_ERR(tr))
8570+
tr = NULL;
8571+
out_unlock:
8572+
if (tr)
8573+
tr->ref++;
8574+
8575+
mutex_unlock(&trace_types_lock);
8576+
mutex_unlock(&event_mutex);
8577+
return tr;
85248578
}
8579+
EXPORT_SYMBOL_GPL(trace_array_get_by_name);
85258580

85268581
static int __remove_instance(struct trace_array *tr)
85278582
{
85288583
int i;
85298584

8530-
if (tr->ref || (tr->current_trace && tr->current_trace->ref))
8585+
/* Reference counter for a newly created trace array = 1. */
8586+
if (tr->ref > 1 || (tr->current_trace && tr->current_trace->ref))
85318587
return -EBUSY;
85328588

85338589
list_del(&tr->list);

kernel/trace/trace.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,6 @@ extern struct list_head ftrace_trace_arrays;
345345
extern struct mutex trace_types_lock;
346346

347347
extern int trace_array_get(struct trace_array *tr);
348-
extern void trace_array_put(struct trace_array *tr);
349348
extern int tracing_check_open_get_tr(struct trace_array *tr);
350349

351350
extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs);

kernel/trace/trace_events.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,6 @@ int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set)
827827

828828
return ret;
829829
}
830-
EXPORT_SYMBOL_GPL(ftrace_set_clr_event);
831830

832831
/**
833832
* 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)
852851
}
853852
EXPORT_SYMBOL_GPL(trace_set_clr_event);
854853

854+
/**
855+
* trace_array_set_clr_event - enable or disable an event for a trace array.
856+
* @tr: concerned trace array.
857+
* @system: system name to match (NULL for any system)
858+
* @event: event name to match (NULL for all events, within system)
859+
* @enable: true to enable, false to disable
860+
*
861+
* This is a way for other parts of the kernel to enable or disable
862+
* event recording.
863+
*
864+
* Returns 0 on success, -EINVAL if the parameters do not match any
865+
* registered events.
866+
*/
867+
int trace_array_set_clr_event(struct trace_array *tr, const char *system,
868+
const char *event, bool enable)
869+
{
870+
int set;
871+
872+
if (!tr)
873+
return -ENOENT;
874+
875+
set = (enable == true) ? 1 : 0;
876+
return __ftrace_set_clr_event(tr, NULL, system, event, set);
877+
}
878+
EXPORT_SYMBOL_GPL(trace_array_set_clr_event);
879+
855880
/* 128 should be much more than enough */
856881
#define EVENT_BUF_SIZE 127
857882

0 commit comments

Comments
 (0)