History

dma-buf/sw_sync: Synchronize signal vs syncpt free

During release of the syncpt, we remove it from the list of syncpt and the tree, but only if it is not already been removed. However, during signaling, we first remove the syncpt from the list. So, if we concurrently free and signal the syncpt, the free may decide that it is not part of the tree and immediately free itself -- meanwhile the signaler goes on to use the now freed datastructure. In particular, we get struck by commit 0e2f733addbf ("dma-buf: make dma_fence structure a bit smaller v2") as the cb_list is immediately clobbered by the kfree_rcu. v2: Avoid calling into timeline_fence_release() from under the spinlock

Chris Wilson committed 7 years ago

Commit d3c6dd11 parent 1c2b9391 file · +7 −9Browse files

Unified · Split

drivers/dma-buf/sw_sync.c+7−9
@@ -132,17 +132,14 @@ static void timeline_fence_release(struct dma_fence *fence) · 131 unmodified lines
132{132{
133 struct sync_pt *pt = dma_fence_to_sync_pt(fence);133 struct sync_pt *pt = dma_fence_to_sync_pt(fence);
134 struct sync_timeline *parent = dma_fence_parent(fence);134 struct sync_timeline *parent = dma_fence_parent(fence);
135 unsigned long flags;
135 136
137 spin_lock_irqsave(fence->lock, flags);
136 if (!list_empty(&pt->link)) {138 if (!list_empty(&pt->link)) {
137 unsigned long flags;139 list_del(&pt->link);
138 140 rb_erase(&pt->node, &parent->pt_tree);
139 spin_lock_irqsave(fence->lock, flags);
140 if (!list_empty(&pt->link)) {
141 list_del(&pt->link);
142 rb_erase(&pt->node, &parent->pt_tree);
143 }
144 spin_unlock_irqrestore(fence->lock, flags);
145 }141 }
142 spin_unlock_irqrestore(fence->lock, flags);
146 143
147 sync_timeline_put(parent);144 sync_timeline_put(parent);
148 dma_fence_free(fence);145 dma_fence_free(fence);
@@ -265,7 +262,8 @@ static struct sync_pt *sync_pt_create(struct sync_timeline *obj, · 116 unmodified lines
265 p = &parent->rb_left;262 p = &parent->rb_left;
266 } else {263 } else {
267 if (dma_fence_get_rcu(&other->base)) {264 if (dma_fence_get_rcu(&other->base)) {
268 dma_fence_put(&pt->base);265 sync_timeline_put(obj);
266 kfree(pt);
269 pt = other;267 pt = other;
270 goto unlock;268 goto unlock;
271 }269 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t