Commit 3e506793 authored by Christian König's avatar Christian König
Browse files

dma-buf: abstract fence locking v2



Add dma_fence_lock_irqsafe() and dma_fence_unlock_irqrestore() wrappers
and mechanically apply them everywhere.

Just a pre-requisite cleanup for a follow up patch.

v2: add some missing i915 bits, add abstraction for lockdep assertion as
    well
v3: one more suggestion by Tvrtko

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@igalia.com>
Link: https://lore.kernel.org/r/20260219160822.1529-4-christian.koenig@amd.com
parent 541c8f24
Loading
Loading
Loading
Loading
+22 −26
Original line number Diff line number Diff line
@@ -366,7 +366,7 @@ void dma_fence_signal_timestamp_locked(struct dma_fence *fence,
	struct dma_fence_cb *cur, *tmp;
	struct list_head cb_list;

	lockdep_assert_held(fence->lock);
	dma_fence_assert_held(fence);

	if (unlikely(test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
				      &fence->flags)))
@@ -414,9 +414,9 @@ void dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp)
	if (WARN_ON(!fence))
		return;

	spin_lock_irqsave(fence->lock, flags);
	dma_fence_lock_irqsave(fence, flags);
	dma_fence_signal_timestamp_locked(fence, timestamp);
	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);
}
EXPORT_SYMBOL(dma_fence_signal_timestamp);

@@ -475,9 +475,9 @@ bool dma_fence_check_and_signal(struct dma_fence *fence)
	unsigned long flags;
	bool ret;

	spin_lock_irqsave(fence->lock, flags);
	dma_fence_lock_irqsave(fence, flags);
	ret = dma_fence_check_and_signal_locked(fence);
	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);

	return ret;
}
@@ -503,9 +503,9 @@ void dma_fence_signal(struct dma_fence *fence)

	tmp = dma_fence_begin_signalling();

	spin_lock_irqsave(fence->lock, flags);
	dma_fence_lock_irqsave(fence, flags);
	dma_fence_signal_timestamp_locked(fence, ktime_get());
	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);

	dma_fence_end_signalling(tmp);
}
@@ -606,10 +606,10 @@ void dma_fence_release(struct kref *kref)
		 * don't leave chains dangling. We set the error flag first
		 * so that the callbacks know this signal is due to an error.
		 */
		spin_lock_irqsave(fence->lock, flags);
		dma_fence_lock_irqsave(fence, flags);
		fence->error = -EDEADLK;
		dma_fence_signal_locked(fence);
		spin_unlock_irqrestore(fence->lock, flags);
		dma_fence_unlock_irqrestore(fence, flags);
	}

	ops = rcu_dereference(fence->ops);
@@ -639,7 +639,7 @@ static bool __dma_fence_enable_signaling(struct dma_fence *fence)
	const struct dma_fence_ops *ops;
	bool was_set;

	lockdep_assert_held(fence->lock);
	dma_fence_assert_held(fence);

	was_set = test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
				   &fence->flags);
@@ -675,9 +675,9 @@ void dma_fence_enable_sw_signaling(struct dma_fence *fence)
{
	unsigned long flags;

	spin_lock_irqsave(fence->lock, flags);
	dma_fence_lock_irqsave(fence, flags);
	__dma_fence_enable_signaling(fence);
	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);
}
EXPORT_SYMBOL(dma_fence_enable_sw_signaling);

@@ -717,8 +717,7 @@ int dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb,
		return -ENOENT;
	}

	spin_lock_irqsave(fence->lock, flags);

	dma_fence_lock_irqsave(fence, flags);
	if (__dma_fence_enable_signaling(fence)) {
		cb->func = func;
		list_add_tail(&cb->node, &fence->cb_list);
@@ -726,8 +725,7 @@ int dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb,
		INIT_LIST_HEAD(&cb->node);
		ret = -ENOENT;
	}

	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);

	return ret;
}
@@ -750,9 +748,9 @@ int dma_fence_get_status(struct dma_fence *fence)
	unsigned long flags;
	int status;

	spin_lock_irqsave(fence->lock, flags);
	dma_fence_lock_irqsave(fence, flags);
	status = dma_fence_get_status_locked(fence);
	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);

	return status;
}
@@ -782,13 +780,11 @@ dma_fence_remove_callback(struct dma_fence *fence, struct dma_fence_cb *cb)
	unsigned long flags;
	bool ret;

	spin_lock_irqsave(fence->lock, flags);

	dma_fence_lock_irqsave(fence, flags);
	ret = !list_empty(&cb->node);
	if (ret)
		list_del_init(&cb->node);

	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);

	return ret;
}
@@ -827,7 +823,7 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
	unsigned long flags;
	signed long ret = timeout ? timeout : 1;

	spin_lock_irqsave(fence->lock, flags);
	dma_fence_lock_irqsave(fence, flags);

	if (dma_fence_test_signaled_flag(fence))
		goto out;
@@ -851,11 +847,11 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
			__set_current_state(TASK_INTERRUPTIBLE);
		else
			__set_current_state(TASK_UNINTERRUPTIBLE);
		spin_unlock_irqrestore(fence->lock, flags);
		dma_fence_unlock_irqrestore(fence, flags);

		ret = schedule_timeout(ret);

		spin_lock_irqsave(fence->lock, flags);
		dma_fence_lock_irqsave(fence, flags);
		if (ret > 0 && intr && signal_pending(current))
			ret = -ERESTARTSYS;
	}
@@ -865,7 +861,7 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
	__set_current_state(TASK_RUNNING);

out:
	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);
	return ret;
}
EXPORT_SYMBOL(dma_fence_default_wait);
+4 −2
Original line number Diff line number Diff line
@@ -410,8 +410,10 @@ struct race_thread {

static void __wait_for_callbacks(struct dma_fence *f)
{
	spin_lock_irq(f->lock);
	spin_unlock_irq(f->lock);
	unsigned long flags;

	dma_fence_lock_irqsave(f, flags);
	dma_fence_unlock_irqrestore(f, flags);
}

static int thread_signal_callback(void *arg)
+7 −7
Original line number Diff line number Diff line
@@ -156,12 +156,12 @@ static void timeline_fence_release(struct dma_fence *fence)
	struct sync_timeline *parent = dma_fence_parent(fence);
	unsigned long flags;

	spin_lock_irqsave(fence->lock, flags);
	dma_fence_lock_irqsave(fence, flags);
	if (!list_empty(&pt->link)) {
		list_del(&pt->link);
		rb_erase(&pt->node, &parent->pt_tree);
	}
	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);

	sync_timeline_put(parent);
	dma_fence_free(fence);
@@ -179,7 +179,7 @@ static void timeline_fence_set_deadline(struct dma_fence *fence, ktime_t deadlin
	struct sync_pt *pt = dma_fence_to_sync_pt(fence);
	unsigned long flags;

	spin_lock_irqsave(fence->lock, flags);
	dma_fence_lock_irqsave(fence, flags);
	if (test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) {
		if (ktime_before(deadline, pt->deadline))
			pt->deadline = deadline;
@@ -187,7 +187,7 @@ static void timeline_fence_set_deadline(struct dma_fence *fence, ktime_t deadlin
		pt->deadline = deadline;
		__set_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags);
	}
	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);
}

static const struct dma_fence_ops timeline_fence_ops = {
@@ -431,13 +431,13 @@ static int sw_sync_ioctl_get_deadline(struct sync_timeline *obj, unsigned long a
		goto put_fence;
	}

	spin_lock_irqsave(fence->lock, flags);
	dma_fence_lock_irqsave(fence, flags);
	if (!test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) {
		ret = -ENOENT;
		goto unlock;
	}
	data.deadline_ns = ktime_to_ns(pt->deadline);
	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);

	dma_fence_put(fence);

@@ -450,7 +450,7 @@ static int sw_sync_ioctl_get_deadline(struct sync_timeline *obj, unsigned long a
	return 0;

unlock:
	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);
put_fence:
	dma_fence_put(fence);

+2 −2
Original line number Diff line number Diff line
@@ -479,10 +479,10 @@ bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid,
	if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence)
		return false;

	spin_lock_irqsave(fence->lock, flags);
	dma_fence_lock_irqsave(fence, flags);
	if (!dma_fence_is_signaled_locked(fence))
		dma_fence_set_error(fence, -ENODATA);
	spin_unlock_irqrestore(fence->lock, flags);
	dma_fence_unlock_irqrestore(fence, flags);

	while (!dma_fence_is_signaled(fence) &&
	       ktime_to_ns(ktime_sub(deadline, ktime_get())) > 0)
+2 −2
Original line number Diff line number Diff line
@@ -2785,8 +2785,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
	dma_fence_put(vm->last_unlocked);
	dma_fence_wait(vm->last_tlb_flush, false);
	/* Make sure that all fence callbacks have completed */
	spin_lock_irqsave(vm->last_tlb_flush->lock, flags);
	spin_unlock_irqrestore(vm->last_tlb_flush->lock, flags);
	dma_fence_lock_irqsave(vm->last_tlb_flush, flags);
	dma_fence_unlock_irqrestore(vm->last_tlb_flush, flags);
	dma_fence_put(vm->last_tlb_flush);

	list_for_each_entry_safe(mapping, tmp, &vm->freed, list) {
Loading