unsigned *pshared_count,
                                      struct fence ***pshared)
 {
-       unsigned shared_count = 0;
-       unsigned retry = 1;
-       struct fence **shared = NULL, *fence_excl = NULL;
-       int ret = 0;
+       struct fence **shared = NULL;
+       struct fence *fence_excl;
+       unsigned int shared_count;
+       int ret = 1;
 
-       while (retry) {
+       do {
                struct reservation_object_list *fobj;
                unsigned seq;
+               unsigned int i;
 
-               seq = read_seqcount_begin(&obj->seq);
+               shared_count = i = 0;
 
                rcu_read_lock();
+               seq = read_seqcount_begin(&obj->seq);
+
+               fence_excl = rcu_dereference(obj->fence_excl);
+               if (fence_excl && !fence_get_rcu(fence_excl))
+                       goto unlock;
 
                fobj = rcu_dereference(obj->fence);
                if (fobj) {
                                }
 
                                ret = -ENOMEM;
-                               shared_count = 0;
                                break;
                        }
                        shared = nshared;
-                       memcpy(shared, fobj->shared, sz);
                        shared_count = fobj->shared_count;
-               } else
-                       shared_count = 0;
-               fence_excl = rcu_dereference(obj->fence_excl);
-
-               retry = read_seqcount_retry(&obj->seq, seq);
-               if (retry)
-                       goto unlock;
-
-               if (!fence_excl || fence_get_rcu(fence_excl)) {
-                       unsigned i;
 
                        for (i = 0; i < shared_count; ++i) {
-                               if (fence_get_rcu(shared[i]))
-                                       continue;
-
-                               /* uh oh, refcount failed, abort and retry */
-                               while (i--)
-                                       fence_put(shared[i]);
-
-                               if (fence_excl) {
-                                       fence_put(fence_excl);
-                                       fence_excl = NULL;
-                               }
-
-                               retry = 1;
-                               break;
+                               shared[i] = rcu_dereference(fobj->shared[i]);
+                               if (!fence_get_rcu(shared[i]))
+                                       break;
                        }
-               } else
-                       retry = 1;
+               }
+
+               if (i != shared_count || read_seqcount_retry(&obj->seq, seq)) {
+                       while (i--)
+                               fence_put(shared[i]);
+                       fence_put(fence_excl);
+                       goto unlock;
+               }
 
+               ret = 0;
 unlock:
                rcu_read_unlock();
-       }
-       *pshared_count = shared_count;
-       if (shared_count)
-               *pshared = shared;
-       else {
-               *pshared = NULL;
+       } while (ret);
+
+       if (!shared_count) {
                kfree(shared);
+               shared = NULL;
        }
+
+       *pshared_count = shared_count;
+       *pshared = shared;
        *pfence_excl = fence_excl;
 
        return ret;