atomic_t refs;
 };
 
-static struct bp_patching_desc *bp_desc;
+static struct bp_patching_desc bp_desc;
 
 static __always_inline
-struct bp_patching_desc *try_get_desc(struct bp_patching_desc **descp)
+struct bp_patching_desc *try_get_desc(void)
 {
-       /* rcu_dereference */
-       struct bp_patching_desc *desc = __READ_ONCE(*descp);
+       struct bp_patching_desc *desc = &bp_desc;
 
-       if (!desc || !arch_atomic_inc_not_zero(&desc->refs))
+       if (!arch_atomic_inc_not_zero(&desc->refs))
                return NULL;
 
        return desc;
 }
 
-static __always_inline void put_desc(struct bp_patching_desc *desc)
+static __always_inline void put_desc(void)
 {
+       struct bp_patching_desc *desc = &bp_desc;
+
        smp_mb__before_atomic();
        arch_atomic_dec(&desc->refs);
 }
 
        /*
         * Having observed our INT3 instruction, we now must observe
-        * bp_desc:
+        * bp_desc with non-zero refcount:
         *
-        *      bp_desc = desc                  INT3
+        *      bp_desc.refs = 1                INT3
         *      WMB                             RMB
-        *      write INT3                      if (desc)
+        *      write INT3                      if (bp_desc.refs != 0)
         */
        smp_rmb();
 
-       desc = try_get_desc(&bp_desc);
+       desc = try_get_desc();
        if (!desc)
                return 0;
 
        ret = 1;
 
 out_put:
-       put_desc(desc);
+       put_desc();
        return ret;
 }
 
  */
 static void text_poke_bp_batch(struct text_poke_loc *tp, unsigned int nr_entries)
 {
-       struct bp_patching_desc desc = {
-               .vec = tp,
-               .nr_entries = nr_entries,
-               .refs = ATOMIC_INIT(1),
-       };
        unsigned char int3 = INT3_INSN_OPCODE;
        unsigned int i;
        int do_sync;
 
        lockdep_assert_held(&text_mutex);
 
-       smp_store_release(&bp_desc, &desc); /* rcu_assign_pointer */
+       bp_desc.vec = tp;
+       bp_desc.nr_entries = nr_entries;
+
+       /*
+        * Corresponds to the implicit memory barrier in try_get_desc() to
+        * ensure reading a non-zero refcount provides up to date bp_desc data.
+        */
+       atomic_set_release(&bp_desc.refs, 1);
 
        /*
         * Corresponding read barrier in int3 notifier for making sure the
                text_poke_sync();
 
        /*
-        * Remove and synchronize_rcu(), except we have a very primitive
-        * refcount based completion.
+        * Remove and wait for refs to be zero.
         */
-       WRITE_ONCE(bp_desc, NULL); /* RCU_INIT_POINTER */
-       if (!atomic_dec_and_test(&desc.refs))
-               atomic_cond_read_acquire(&desc.refs, !VAL);
+       if (!atomic_dec_and_test(&bp_desc.refs))
+               atomic_cond_read_acquire(&bp_desc.refs, !VAL);
 }
 
 static void text_poke_loc_init(struct text_poke_loc *tp, void *addr,