}
 
+static int instance_delete(const char *name)
+{
+       struct trace_array *tr;
+       int found = 0;
+       int ret;
+
+       mutex_lock(&trace_types_lock);
+
+       ret = -ENODEV;
+       list_for_each_entry(tr, &ftrace_trace_arrays, list) {
+               if (tr->name && strcmp(tr->name, name) == 0) {
+                       found = 1;
+                       break;
+               }
+       }
+       if (!found)
+               goto out_unlock;
+
+       list_del(&tr->list);
+
+       event_trace_del_tracer(tr);
+       debugfs_remove_recursive(tr->dir);
+       free_percpu(tr->data);
+       ring_buffer_free(tr->buffer);
+
+       kfree(tr->name);
+       kfree(tr);
+
+       ret = 0;
+
+ out_unlock:
+       mutex_unlock(&trace_types_lock);
+
+       return ret;
+}
+
 static int instance_mkdir (struct inode *inode, struct dentry *dentry, umode_t mode)
 {
        struct dentry *parent;
        return ret;
 }
 
+static int instance_rmdir(struct inode *inode, struct dentry *dentry)
+{
+       struct dentry *parent;
+       int ret;
+
+       /* Paranoid: Make sure the parent is the "instances" directory */
+       parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias);
+       if (WARN_ON_ONCE(parent != trace_instance_dir))
+               return -ENOENT;
+
+       /* The caller did a dget() on dentry */
+       mutex_unlock(&dentry->d_inode->i_mutex);
+
+       /*
+        * The inode mutex is locked, but debugfs_create_dir() will also
+        * take the mutex. As the instances directory can not be destroyed
+        * or changed in any other way, it is safe to unlock it, and
+        * let the dentry try. If two users try to make the same dir at
+        * the same time, then the instance_delete() will determine the
+        * winner.
+        */
+       mutex_unlock(&inode->i_mutex);
+
+       ret = instance_delete(dentry->d_iname);
+
+       mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
+       mutex_lock(&dentry->d_inode->i_mutex);
+
+       return ret;
+}
+
 static const struct inode_operations instance_dir_inode_operations = {
        .lookup         = simple_lookup,
        .mkdir          = instance_mkdir,
+       .rmdir          = instance_rmdir,
 };
 
 static __init void create_trace_instances(struct dentry *d_tracer)
 
        }
 }
 
+/* Remove the event directory structure for a trace directory. */
+static void
+__trace_remove_event_dirs(struct trace_array *tr)
+{
+       struct ftrace_event_file *file, *next;
+
+       list_for_each_entry_safe(file, next, &tr->events, list) {
+               list_del(&file->list);
+               debugfs_remove_recursive(file->dir);
+               remove_subsystem(file->system);
+               kfree(file);
+       }
+}
+
 static void
 __add_event_to_tracers(struct ftrace_event_call *call,
                       struct ftrace_module_file_ops *file_ops)
        return 0;
 }
 
+int event_trace_del_tracer(struct trace_array *tr)
+{
+       /* Disable any running events */
+       __ftrace_set_clr_event(tr, NULL, NULL, NULL, 0);
+
+       mutex_lock(&event_mutex);
+
+       down_write(&trace_event_mutex);
+       __trace_remove_event_dirs(tr);
+       debugfs_remove_recursive(tr->event_dir);
+       up_write(&trace_event_mutex);
+
+       tr->event_dir = NULL;
+
+       mutex_unlock(&event_mutex);
+
+       return 0;
+}
+
 static __init int event_trace_enable(void)
 {
        struct trace_array *tr = top_trace_array();