diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index cc05ddd..917f905 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -63,9 +63,9 @@ EXPORT_SYMBOL(fence_context_alloc);
  *
  * Unlike fence_signal, this function must be called with fence->lock held.
  */
-int fence_signal_locked(struct fence *fence)
+int fence_signal_locked(struct fence *fence, unsigned long flags)
 {
-	struct fence_cb *cur, *tmp;
+	struct fence_cb *cur;
 	int ret = 0;
 
 	lockdep_assert_held(fence->lock);
@@ -88,9 +88,12 @@ int fence_signal_locked(struct fence *fence)
 	} else
 		trace_fence_signaled(fence);
 
-	list_for_each_entry_safe(cur, tmp, &fence->cb_list, node) {
+	while (!list_empty(&fence->cb_list)) {
+		cur = list_first_entry(&fence->cb_list, struct fence_cb, node);
 		list_del_init(&cur->node);
+		spin_unlock_irqrestore(fence->lock, flags);
 		cur->func(fence, cur);
+		spin_lock_irqsave(fence->lock, flags);
 	}
 	return ret;
 }
@@ -124,12 +127,15 @@ int fence_signal(struct fence *fence)
 	trace_fence_signaled(fence);
 
 	if (test_bit(FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags)) {
-		struct fence_cb *cur, *tmp;
+		struct fence_cb *cur;
 
 		spin_lock_irqsave(fence->lock, flags);
-		list_for_each_entry_safe(cur, tmp, &fence->cb_list, node) {
+		while (!list_empty(&fence->cb_list)) {
+			cur = list_first_entry(&fence->cb_list, struct fence_cb, node);
 			list_del_init(&cur->node);
+			spin_unlock_irqrestore(fence->lock, flags);
 			cur->func(fence, cur);
+			spin_lock_irqsave(fence->lock, flags);
 		}
 		spin_unlock_irqrestore(fence->lock, flags);
 	}
@@ -211,7 +217,7 @@ void fence_enable_sw_signaling(struct fence *fence)
 		spin_lock_irqsave(fence->lock, flags);
 
 		if (!fence->ops->enable_signaling(fence))
-			fence_signal_locked(fence);
+			fence_signal_locked(fence, flags);
 
 		spin_unlock_irqrestore(fence->lock, flags);
 	}
@@ -266,7 +272,7 @@ int fence_add_callback(struct fence *fence, struct fence_cb *cb,
 		trace_fence_enable_signal(fence);
 
 		if (!fence->ops->enable_signaling(fence)) {
-			fence_signal_locked(fence);
+			fence_signal_locked(fence, flags);
 			ret = -ENOENT;
 		}
 	}
@@ -366,7 +372,7 @@ fence_default_wait(struct fence *fence, bool intr, signed long timeout)
 		trace_fence_enable_signal(fence);
 
 		if (!fence->ops->enable_signaling(fence)) {
-			fence_signal_locked(fence);
+			fence_signal_locked(fence, flags);
 			goto out;
 		}
 	}
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 62e8e6d..2271f7f 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -146,7 +146,7 @@ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
 
 	list_for_each_entry_safe(pt, next, &obj->active_list_head,
 				 active_list) {
-		if (fence_is_signaled_locked(&pt->base))
+		if (fence_is_signaled_locked(&pt->base, flags))
 			list_del_init(&pt->active_list);
 	}
 
diff --git a/drivers/dma-buf/sync_debug.c b/drivers/dma-buf/sync_debug.c
index 2dd4c3d..a7556d3 100644
--- a/drivers/dma-buf/sync_debug.c
+++ b/drivers/dma-buf/sync_debug.c
@@ -71,12 +71,13 @@ static const char *sync_status_str(int status)
 	return "error";
 }
 
-static void sync_print_fence(struct seq_file *s, struct fence *fence, bool show)
+static void sync_print_fence(struct seq_file *s, struct fence *fence,
+		bool show, unsigned long flags)
 {
 	int status = 1;
 	struct sync_timeline *parent = fence_parent(fence);
 
-	if (fence_is_signaled_locked(fence))
+	if (fence_is_signaled_locked(fence, flags))
 		status = fence->status;
 
 	seq_printf(s, "  %s%sfence %s",
@@ -124,13 +125,14 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
 	list_for_each(pos, &obj->child_list_head) {
 		struct sync_pt *pt =
 			container_of(pos, struct sync_pt, child_list);
-		sync_print_fence(s, &pt->base, false);
+		sync_print_fence(s, &pt->base, false, flags);
 	}
 	spin_unlock_irqrestore(&obj->child_list_lock, flags);
 }
 
 static void sync_print_sync_file(struct seq_file *s,
-				  struct sync_file *sync_file)
+				  struct sync_file *sync_file,
+				  unsigned long flags)
 {
 	int i;
 
@@ -141,9 +143,9 @@ static void sync_print_sync_file(struct seq_file *s,
 		struct fence_array *array = to_fence_array(sync_file->fence);
 
 		for (i = 0; i < array->num_fences; ++i)
-			sync_print_fence(s, array->fences[i], true);
+			sync_print_fence(s, array->fences[i], true, flags);
 	} else {
-		sync_print_fence(s, sync_file->fence, true);
+		sync_print_fence(s, sync_file->fence, true, flags);
 	}
 }
 
@@ -172,7 +174,7 @@ static int sync_debugfs_show(struct seq_file *s, void *unused)
 		struct sync_file *sync_file =
 			container_of(pos, struct sync_file, sync_file_list);
 
-		sync_print_sync_file(s, sync_file);
+		sync_print_sync_file(s, sync_file, flags);
 		seq_puts(s, "\n");
 	}
 	spin_unlock_irqrestore(&sync_file_list_lock, flags);
diff --git a/include/linux/fence.h b/include/linux/fence.h
index 0d76305..073f380 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -220,7 +220,7 @@ static inline void fence_put(struct fence *fence)
 }
 
 int fence_signal(struct fence *fence);
-int fence_signal_locked(struct fence *fence);
+int fence_signal_locked(struct fence *fence, unsigned long flags);
 signed long fence_default_wait(struct fence *fence, bool intr, signed long timeout);
 int fence_add_callback(struct fence *fence, struct fence_cb *cb,
 		       fence_func_t func);
@@ -239,13 +239,13 @@ void fence_enable_sw_signaling(struct fence *fence);
  * This function requires fence->lock to be held.
  */
 static inline bool
-fence_is_signaled_locked(struct fence *fence)
+fence_is_signaled_locked(struct fence *fence, unsigned long flags)
 {
 	if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags))
 		return true;
 
 	if (fence->ops->signaled && fence->ops->signaled(fence)) {
-		fence_signal_locked(fence);
+		fence_signal_locked(fence, flags);
 		return true;
 	}
 
