Skip to content

Commit

Permalink
lkpi: dont use callout while holding non-sleepable lock
Browse files Browse the repository at this point in the history
  • Loading branch information
johalun committed Mar 8, 2018
1 parent 3c836a2 commit c34ed6f
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions linuxkpi/gplv2/include/linux/dma-fence.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,22 +157,41 @@ dma_fence_signal(struct dma_fence *fence)

if (!ktime_to_ns(fence->timestamp)) {
fence->timestamp = ktime_get();
#ifdef __FreeBSD__
mb();
#else
smp_mb__before_atomic();
#endif
}

if (test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
return (-EINVAL);


if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags)) {
struct dma_fence_cb *cur, *tmp;

#ifdef __linux__
struct dma_fence_cb *cur, *tmp;
spin_lock_irqsave(fence->lock, flags);
list_for_each_entry_safe(cur, tmp, &fence->cb_list, node) {
list_del_init(&cur->node);
cur->func(fence, cur);
}
spin_unlock_irqrestore(fence->lock, flags);
#else
// On FreeBSD spinlock is a sleep lock
// Fix calling callout function with non-sleepable lock help
struct dma_fence_cb *cur;
spin_lock_irqsave(fence->lock, flags);
while (!list_empty(&fence->cb_list)) {
cur = list_first_entry(&fence->cb_list, struct dma_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);
#endif
}
return (0);
}
Expand Down Expand Up @@ -367,7 +386,7 @@ dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count)

static inline signed long
dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
bool intr, signed long timeout, uint32_t *idx)
bool intr, signed long timeout, uint32_t *idx)
{
struct default_wait_cb *cb;
signed long ret;
Expand Down

0 comments on commit c34ed6f

Please sign in to comment.