#include <linux/uio.h>
 #include <linux/ioctl.h>
 #include <linux/jhash.h>
+#include <linux/refcount.h>
 #include <linux/trace_events.h>
 #include <linux/tracefs.h>
 #include <linux/types.h>
  * within a file a user_event might be created if it does not
  * already exist. These are globally used and their lifetime
  * is tied to the refcnt member. These cannot go away until the
- * refcnt reaches zero.
+ * refcnt reaches one.
  */
 struct user_event {
        struct tracepoint tracepoint;
        struct hlist_node node;
        struct list_head fields;
        struct list_head validators;
-       atomic_t refcnt;
+       refcount_t refcnt;
        int index;
        int flags;
        int min_size;
        return jhash(name, strlen(name), 0);
 }
 
+static __always_inline __must_check
+bool user_event_last_ref(struct user_event *user)
+{
+       return refcount_read(&user->refcnt) == 1;
+}
+
 static __always_inline __must_check
 size_t copy_nofault(void *addr, size_t bytes, struct iov_iter *i)
 {
 
        hash_for_each_possible(register_table, user, node, key)
                if (!strcmp(EVENT_NAME(user), name)) {
-                       atomic_inc(&user->refcnt);
+                       refcount_inc(&user->refcnt);
                        return user;
                }
 
 
        return ret;
 inc:
-       atomic_inc(&user->refcnt);
+       refcount_inc(&user->refcnt);
        update_reg_page_for(user);
        return 0;
 dec:
        update_reg_page_for(user);
-       atomic_dec(&user->refcnt);
+       refcount_dec(&user->refcnt);
        return 0;
 }
 
        ret = user_event_parse_cmd(name, &user);
 
        if (!ret)
-               atomic_dec(&user->refcnt);
+               refcount_dec(&user->refcnt);
 
        mutex_unlock(®_mutex);
 
 {
        struct user_event *user = container_of(ev, struct user_event, devent);
 
-       return atomic_read(&user->refcnt) != 0;
+       return !user_event_last_ref(user);
 }
 
 static int user_event_free(struct dyn_event *ev)
 {
        struct user_event *user = container_of(ev, struct user_event, devent);
 
-       if (atomic_read(&user->refcnt) != 0)
+       if (!user_event_last_ref(user))
                return -EBUSY;
 
        return destroy_user_event(user);
 
        user->index = index;
 
-       /* Ensure we track ref */
-       atomic_inc(&user->refcnt);
+       /* Ensure we track self ref and caller ref (2) */
+       refcount_set(&user->refcnt, 2);
 
        dyn_event_init(&user->devent, &user_event_dops);
        dyn_event_add(&user->devent, &user->call);
 static int delete_user_event(char *name)
 {
        u32 key;
-       int ret;
        struct user_event *user = find_user_event(name, &key);
 
        if (!user)
                return -ENOENT;
 
-       /* Ensure we are the last ref */
-       if (atomic_read(&user->refcnt) != 1) {
-               ret = -EBUSY;
-               goto put_ref;
-       }
-
-       ret = destroy_user_event(user);
+       refcount_dec(&user->refcnt);
 
-       if (ret)
-               goto put_ref;
-
-       return ret;
-put_ref:
-       /* No longer have this ref */
-       atomic_dec(&user->refcnt);
+       if (!user_event_last_ref(user))
+               return -EBUSY;
 
-       return ret;
+       return destroy_user_event(user);
 }
 
 /*
 
        new_refs->events[i] = user;
 
-       atomic_inc(&user->refcnt);
+       refcount_inc(&user->refcnt);
 
        rcu_assign_pointer(file->private_data, new_refs);
 
        ret = user_events_ref_add(file, user);
 
        /* No longer need parse ref, ref_add either worked or not */
-       atomic_dec(&user->refcnt);
+       refcount_dec(&user->refcnt);
 
        /* Positive number is index and valid */
        if (ret < 0)
                user = refs->events[i];
 
                if (user)
-                       atomic_dec(&user->refcnt);
+                       refcount_dec(&user->refcnt);
        }
 out:
        file->private_data = NULL;