|
@@ -74,11 +74,6 @@ static struct tracer_opt dummy_tracer_opt[] = {
|
|
|
{ }
|
|
|
};
|
|
|
|
|
|
-static struct tracer_flags dummy_tracer_flags = {
|
|
|
- .val = 0,
|
|
|
- .opts = dummy_tracer_opt
|
|
|
-};
|
|
|
-
|
|
|
static int
|
|
|
dummy_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set)
|
|
|
{
|
|
@@ -1258,12 +1253,20 @@ int __init register_tracer(struct tracer *type)
|
|
|
|
|
|
if (!type->set_flag)
|
|
|
type->set_flag = &dummy_set_flag;
|
|
|
- if (!type->flags)
|
|
|
- type->flags = &dummy_tracer_flags;
|
|
|
- else
|
|
|
+ if (!type->flags) {
|
|
|
+ /*allocate a dummy tracer_flags*/
|
|
|
+ type->flags = kmalloc(sizeof(*type->flags), GFP_KERNEL);
|
|
|
+ if (!type->flags)
|
|
|
+ return -ENOMEM;
|
|
|
+ type->flags->val = 0;
|
|
|
+ type->flags->opts = dummy_tracer_opt;
|
|
|
+ } else
|
|
|
if (!type->flags->opts)
|
|
|
type->flags->opts = dummy_tracer_opt;
|
|
|
|
|
|
+ /* store the tracer for __set_tracer_option */
|
|
|
+ type->flags->trace = type;
|
|
|
+
|
|
|
ret = run_tracer_selftest(type);
|
|
|
if (ret < 0)
|
|
|
goto out;
|
|
@@ -3505,7 +3508,7 @@ static int __set_tracer_option(struct trace_array *tr,
|
|
|
struct tracer_flags *tracer_flags,
|
|
|
struct tracer_opt *opts, int neg)
|
|
|
{
|
|
|
- struct tracer *trace = tr->current_trace;
|
|
|
+ struct tracer *trace = tracer_flags->trace;
|
|
|
int ret;
|
|
|
|
|
|
ret = trace->set_flag(tr, tracer_flags->val, opts->bit, !neg);
|
|
@@ -6391,11 +6394,8 @@ create_trace_option_files(struct trace_array *tr, struct tracer *tracer)
|
|
|
return;
|
|
|
|
|
|
for (i = 0; i < tr->nr_topts; i++) {
|
|
|
- /*
|
|
|
- * Check if these flags have already been added.
|
|
|
- * Some tracers share flags.
|
|
|
- */
|
|
|
- if (tr->topts[i].tracer->flags == tracer->flags)
|
|
|
+ /* Make sure there's no duplicate flags. */
|
|
|
+ if (WARN_ON_ONCE(tr->topts[i].tracer->flags == tracer->flags))
|
|
|
return;
|
|
|
}
|
|
|
|