Commit 28879787 authored by Divya Indi's avatar Divya Indi Committed by Steven Rostedt (VMware)
Browse files

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: default avatarDivya Indi <divya.indi@oracle.com>
Reviewed-by: default avatarAruna Ramakrishna <aruna.ramakrishna@oracle.com>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent fc809bc5
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -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 */


+2 −1
Original line number Original line Diff line number Diff line
@@ -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
+76 −20
Original line number Original line Diff line number Diff line
@@ -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);


	return ERR_PTR(ret);
}

static int instance_mkdir(const char *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:
out_unlock:
	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)
/**
 * 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)
{
{
	return PTR_ERR_OR_ZERO(trace_array_create(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);
+0 −1
Original line number Original line Diff line number Diff line
@@ -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);
+26 −1
Original line number Original line Diff line number Diff line
@@ -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