Skip to content

Commit cd29f22

Browse files
a-darwishPeter Zijlstra
authored andcommitted
dma-buf: Use sequence counter with associated wound/wait mutex
A sequence counter write side critical section must be protected by some form of locking to serialize writers. If the serialization primitive is not disabling preemption implicitly, preemption has to be explicitly disabled before entering the sequence counter write side critical section. The dma-buf reservation subsystem uses plain sequence counters to manage updates to reservations. Writer serialization is accomplished through a wound/wait mutex. Acquiring a wound/wait mutex does not disable preemption, so this needs to be done manually before and after the write side critical section. Use the newly-added seqcount_ww_mutex_t instead: - It associates the ww_mutex with the sequence count, which enables lockdep to validate that the write side critical section is properly serialized. - It removes the need to explicitly add preempt_disable/enable() around the write side critical section because the write_begin/end() functions for this new data type automatically do this. If lockdep is disabled this ww_mutex lock association is compiled out and has neither storage size nor runtime overhead. Signed-off-by: Ahmed S. Darwish <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Acked-by: Daniel Vetter <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 318ce71 commit cd29f22

File tree

3 files changed

+2
-10
lines changed

3 files changed

+2
-10
lines changed

drivers/dma-buf/dma-resv.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ subsys_initcall(dma_resv_lockdep);
129129
void dma_resv_init(struct dma_resv *obj)
130130
{
131131
ww_mutex_init(&obj->lock, &reservation_ww_class);
132-
seqcount_init(&obj->seq);
132+
seqcount_ww_mutex_init(&obj->seq, &obj->lock);
133133

134134
RCU_INIT_POINTER(obj->fence, NULL);
135135
RCU_INIT_POINTER(obj->fence_excl, NULL);
@@ -260,7 +260,6 @@ void dma_resv_add_shared_fence(struct dma_resv *obj, struct dma_fence *fence)
260260
fobj = dma_resv_get_list(obj);
261261
count = fobj->shared_count;
262262

263-
preempt_disable();
264263
write_seqcount_begin(&obj->seq);
265264

266265
for (i = 0; i < count; ++i) {
@@ -282,7 +281,6 @@ void dma_resv_add_shared_fence(struct dma_resv *obj, struct dma_fence *fence)
282281
smp_store_mb(fobj->shared_count, count);
283282

284283
write_seqcount_end(&obj->seq);
285-
preempt_enable();
286284
dma_fence_put(old);
287285
}
288286
EXPORT_SYMBOL(dma_resv_add_shared_fence);
@@ -309,14 +307,12 @@ void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence)
309307
if (fence)
310308
dma_fence_get(fence);
311309

312-
preempt_disable();
313310
write_seqcount_begin(&obj->seq);
314311
/* write_seqcount_begin provides the necessary memory barrier */
315312
RCU_INIT_POINTER(obj->fence_excl, fence);
316313
if (old)
317314
old->shared_count = 0;
318315
write_seqcount_end(&obj->seq);
319-
preempt_enable();
320316

321317
/* inplace update, no shared fences */
322318
while (i--)
@@ -394,13 +390,11 @@ int dma_resv_copy_fences(struct dma_resv *dst, struct dma_resv *src)
394390
src_list = dma_resv_get_list(dst);
395391
old = dma_resv_get_excl(dst);
396392

397-
preempt_disable();
398393
write_seqcount_begin(&dst->seq);
399394
/* write_seqcount_begin provides the necessary memory barrier */
400395
RCU_INIT_POINTER(dst->fence_excl, new);
401396
RCU_INIT_POINTER(dst->fence, dst_list);
402397
write_seqcount_end(&dst->seq);
403-
preempt_enable();
404398

405399
dma_resv_list_free(src_list);
406400
dma_fence_put(old);

drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,9 @@ static int amdgpu_amdkfd_remove_eviction_fence(struct amdgpu_bo *bo,
258258
new->shared_count = k;
259259

260260
/* Install the new fence list, seqcount provides the barriers */
261-
preempt_disable();
262261
write_seqcount_begin(&resv->seq);
263262
RCU_INIT_POINTER(resv->fence, new);
264263
write_seqcount_end(&resv->seq);
265-
preempt_enable();
266264

267265
/* Drop the references to the removed fences or move them to ef_list */
268266
for (i = j, k = 0; i < old->shared_count; ++i) {

include/linux/dma-resv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ struct dma_resv_list {
6969
*/
7070
struct dma_resv {
7171
struct ww_mutex lock;
72-
seqcount_t seq;
72+
seqcount_ww_mutex_t seq;
7373

7474
struct dma_fence __rcu *fence_excl;
7575
struct dma_resv_list __rcu *fence;

0 commit comments

Comments
 (0)