diff --git a/drivers/base/reservation.c b/drivers/base/reservation.c
index b82a5b6..c4bcf10 100644
--- a/drivers/base/reservation.c
+++ b/drivers/base/reservation.c
@@ -82,6 +82,8 @@ reservation_object_add_shared_inplace(struct reservation_object *obj,
 {
 	u32 i;
 
+	preempt_disable();
+	write_seqcount_begin(&obj->seq);
 	for (i = 0; i < fobj->shared_count; ++i) {
 		if (fobj->shared[i]->context == fence->context) {
 			struct fence *old_fence = fobj->shared[i];
@@ -90,6 +92,8 @@ reservation_object_add_shared_inplace(struct reservation_object *obj,
 
 			fobj->shared[i] = fence;
 
+			write_seqcount_end(&obj->seq);
+			preempt_enable();
 			fence_put(old_fence);
 			return;
 		}
@@ -101,8 +105,9 @@ reservation_object_add_shared_inplace(struct reservation_object *obj,
 	 * make the new fence visible before incrementing
 	 * fobj->shared_count
 	 */
-	smp_wmb();
 	fobj->shared_count++;
+	write_seqcount_end(&obj->seq);
+	preempt_enable();
 }
 
 static void
@@ -141,7 +146,11 @@ reservation_object_add_shared_replace(struct reservation_object *obj,
 		fobj->shared[fobj->shared_count++] = fence;
 
 done:
+	preempt_disable();
+	write_seqcount_begin(&obj->seq);
 	obj->fence = fobj;
+	write_seqcount_end(&obj->seq);
+	preempt_enable();
 	kfree(old);
 }
 
@@ -173,6 +182,8 @@ void reservation_object_add_excl_fence(struct reservation_object *obj,
 	u32 i = 0;
 
 	old = reservation_object_get_list(obj);
+	preempt_disable();
+	write_seqcount_begin(&obj->seq);
 	if (old) {
 		i = old->shared_count;
 		old->shared_count = 0;
@@ -182,7 +193,8 @@ void reservation_object_add_excl_fence(struct reservation_object *obj,
 		fence_get(fence);
 
 	obj->fence_excl = fence;
-
+	write_seqcount_end(&obj->seq);
+	preempt_enable();
 	/* inplace update, no shared fences */
 	while (i--)
 		fence_put(old->shared[i]);
@@ -191,3 +203,76 @@ void reservation_object_add_excl_fence(struct reservation_object *obj,
 		fence_put(old_fence);
 }
 EXPORT_SYMBOL(reservation_object_add_excl_fence);
+
+struct unsignaled {
+	unsigned shared_max;
+	unsigned shared_count;
+	struct fence **shared;
+	struct fence *exclusive;
+};
+
+static int reservation_object_unsignaled_rcu(struct reservation_object *obj,
+					     struct unsignaled *us)
+{
+	unsigned seq;
+	struct reservation_object_list *fobj, list;
+	struct fence *fence;
+
+retry:
+	seq = read_seqcount_begin(&obj->seq);
+	rcu_read_lock();
+
+	fobj = obj->fence;
+	fence = obj->exclusive;
+
+	/* Check pointers for validity */
+	if (read_seqcount_retry(&obj->seq, seq)) {
+		rcu_read_unlock();
+		goto retry;
+	}
+
+	list = *fobj;
+
+	/* Check list for validity */
+	if (read_seqcount_retry(&obj->seq, seq)) {
+		rcu_read_unlock();
+		goto retry;
+	}
+
+	if (list.shared_count == 0) {
+		if (fence &&
+		    !test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags) &&
+		    fence_get_rcu(fence))
+			us->exclusive = exclusive;
+		rcu_read_unlock();
+		return 0;
+	}
+	
+
+	/* Needs reallocation? Either in this function or outside */
+	if (us->shared_max < list.shared_count) {
+		rcu_read_unlock();
+		return -ENOMEM;
+	}
+
+	memcpy(us->shared, list.shared,
+	       list.shared_count * sizeof(*list.shared));
+
+	/* Check the fence pointer array for validity */
+	if (read_seqcount_retry(&obj->seq, seq)) {
+		rcu_read_unlock();
+		goto retry;
+	}
+
+	for (i = 0; i < list.shared_count; ++i) {
+		struct fence *fence = us->shared[i];
+	       
+		if (fence && !test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags)
+		    && fence_get_rcu(fence));			
+		us->shared[us->shared_count++] = fence;
+	}
+
+	rcu_read_unlock();
+	
+	return 0;
+}
diff --git a/include/linux/reservation.h b/include/linux/reservation.h
index b602365..4bf791a 100644
--- a/include/linux/reservation.h
+++ b/include/linux/reservation.h
@@ -52,6 +52,7 @@ struct reservation_object_list {
 
 struct reservation_object {
 	struct ww_mutex lock;
+	struct seqcount seq;
 
 	struct fence *fence_excl;
 	struct reservation_object_list *fence;
@@ -69,6 +70,7 @@ reservation_object_init(struct reservation_object *obj)
 	obj->fence_excl = NULL;
 	obj->fence = NULL;
 	obj->staged = NULL;
+	seqcount_init(&obj->seq);
 }
 
 static inline void
