}
 #endif /* CONFIG_FTRACE_STARTUP_TEST */
 
+static void add_tracer_options(struct trace_array *tr, struct tracer *t);
+
 /**
  * register_tracer - register a tracer with the ftrace system.
  * @type - the plugin for the tracer
 
        type->next = trace_types;
        trace_types = type;
+       add_tracer_options(&global_trace, type);
 
  out:
        tracing_selftest_running = false;
 static struct trace_option_dentry *
 create_trace_option_files(struct trace_array *tr, struct tracer *tracer);
 
-static void
-destroy_trace_option_files(struct trace_option_dentry *topts);
-
 /*
  * Used to clear out the tracer before deletion of an instance.
  * Must have trace_types_lock held.
        tr->current_trace = &nop_trace;
 }
 
-static void update_tracer_options(struct trace_array *tr, struct tracer *t)
+static void add_tracer_options(struct trace_array *tr, struct tracer *t)
 {
-       static struct trace_option_dentry *topts;
-
        /* Only enable if the directory has been created already. */
        if (!tr->dir)
                return;
        if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL))
                return;
 
-       destroy_trace_option_files(topts);
-       topts = create_trace_option_files(tr, t);
+       /* Ignore if they were already created */
+       if (t->topts)
+               return;
+
+       t->topts = create_trace_option_files(tr, t);
 }
 
 static int tracing_set_tracer(struct trace_array *tr, const char *buf)
                free_snapshot(tr);
        }
 #endif
-       update_tracer_options(tr, t);
 
 #ifdef CONFIG_TRACER_MAX_TRACE
        if (t->use_max_tr && !had_max_tr) {
 #include "trace_selftest.c"
 #endif
 
-struct trace_option_dentry {
-       struct tracer_opt               *opt;
-       struct tracer_flags             *flags;
-       struct trace_array              *tr;
-       struct dentry                   *entry;
-};
-
 static ssize_t
 trace_options_read(struct file *filp, char __user *ubuf, size_t cnt,
                        loff_t *ppos)
        if (!topts)
                return NULL;
 
-       for (cnt = 0; opts[cnt].name; cnt++)
+       for (cnt = 0; opts[cnt].name; cnt++) {
                create_trace_option_file(tr, &topts[cnt], flags,
                                         &opts[cnt]);
+               WARN_ONCE(topts[cnt].entry == NULL,
+                         "Failed to create trace option: %s",
+                         opts[cnt].name);
+       }
 
        return topts;
 }
 
-static void
-destroy_trace_option_files(struct trace_option_dentry *topts)
-{
-       int cnt;
-
-       if (!topts)
-               return;
-
-       for (cnt = 0; topts[cnt].opt; cnt++)
-               tracefs_remove(topts[cnt].entry);
-
-       kfree(topts);
-}
-
 static struct dentry *
 create_trace_option_core_file(struct trace_array *tr,
                              const char *option, long index)
 static __init int tracer_init_tracefs(void)
 {
        struct dentry *d_tracer;
+       struct tracer *t;
 
        trace_access_lock_init();
 
 
        create_trace_options_dir(&global_trace);
 
-       /* If the tracer was started via cmdline, create options for it here */
-       if (global_trace.current_trace != &nop_trace)
-               update_tracer_options(&global_trace, global_trace.current_trace);
+       mutex_lock(&trace_types_lock);
+       for (t = trace_types; t; t = t->next)
+               add_tracer_options(&global_trace, t);
+       mutex_unlock(&trace_types_lock);
 
        return 0;
 }