Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: Christian König <christian.koenig@amd.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Link: https://lore.kernel.org/r/20260219160822.1529-4-christian.koenig@amd.com

+96 -56
+22 -26
drivers/dma-buf/dma-fence.c
··· 366 366 struct dma_fence_cb *cur, *tmp; 367 367 struct list_head cb_list; 368 368 369 - lockdep_assert_held(fence->lock); 369 + dma_fence_assert_held(fence); 370 370 371 371 if (unlikely(test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, 372 372 &fence->flags))) ··· 414 414 if (WARN_ON(!fence)) 415 415 return; 416 416 417 - spin_lock_irqsave(fence->lock, flags); 417 + dma_fence_lock_irqsave(fence, flags); 418 418 dma_fence_signal_timestamp_locked(fence, timestamp); 419 - spin_unlock_irqrestore(fence->lock, flags); 419 + dma_fence_unlock_irqrestore(fence, flags); 420 420 } 421 421 EXPORT_SYMBOL(dma_fence_signal_timestamp); 422 422 ··· 475 475 unsigned long flags; 476 476 bool ret; 477 477 478 - spin_lock_irqsave(fence->lock, flags); 478 + dma_fence_lock_irqsave(fence, flags); 479 479 ret = dma_fence_check_and_signal_locked(fence); 480 - spin_unlock_irqrestore(fence->lock, flags); 480 + dma_fence_unlock_irqrestore(fence, flags); 481 481 482 482 return ret; 483 483 } ··· 503 503 504 504 tmp = dma_fence_begin_signalling(); 505 505 506 - spin_lock_irqsave(fence->lock, flags); 506 + dma_fence_lock_irqsave(fence, flags); 507 507 dma_fence_signal_timestamp_locked(fence, ktime_get()); 508 - spin_unlock_irqrestore(fence->lock, flags); 508 + dma_fence_unlock_irqrestore(fence, flags); 509 509 510 510 dma_fence_end_signalling(tmp); 511 511 } ··· 606 606 * don't leave chains dangling. We set the error flag first 607 607 * so that the callbacks know this signal is due to an error. 608 608 */ 609 - spin_lock_irqsave(fence->lock, flags); 609 + dma_fence_lock_irqsave(fence, flags); 610 610 fence->error = -EDEADLK; 611 611 dma_fence_signal_locked(fence); 612 - spin_unlock_irqrestore(fence->lock, flags); 612 + dma_fence_unlock_irqrestore(fence, flags); 613 613 } 614 614 615 615 ops = rcu_dereference(fence->ops); ··· 639 639 const struct dma_fence_ops *ops; 640 640 bool was_set; 641 641 642 - lockdep_assert_held(fence->lock); 642 + dma_fence_assert_held(fence); 643 643 644 644 was_set = test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, 645 645 &fence->flags); ··· 675 675 { 676 676 unsigned long flags; 677 677 678 - spin_lock_irqsave(fence->lock, flags); 678 + dma_fence_lock_irqsave(fence, flags); 679 679 __dma_fence_enable_signaling(fence); 680 - spin_unlock_irqrestore(fence->lock, flags); 680 + dma_fence_unlock_irqrestore(fence, flags); 681 681 } 682 682 EXPORT_SYMBOL(dma_fence_enable_sw_signaling); 683 683 ··· 717 717 return -ENOENT; 718 718 } 719 719 720 - spin_lock_irqsave(fence->lock, flags); 721 - 720 + dma_fence_lock_irqsave(fence, flags); 722 721 if (__dma_fence_enable_signaling(fence)) { 723 722 cb->func = func; 724 723 list_add_tail(&cb->node, &fence->cb_list); ··· 725 726 INIT_LIST_HEAD(&cb->node); 726 727 ret = -ENOENT; 727 728 } 728 - 729 - spin_unlock_irqrestore(fence->lock, flags); 729 + dma_fence_unlock_irqrestore(fence, flags); 730 730 731 731 return ret; 732 732 } ··· 748 750 unsigned long flags; 749 751 int status; 750 752 751 - spin_lock_irqsave(fence->lock, flags); 753 + dma_fence_lock_irqsave(fence, flags); 752 754 status = dma_fence_get_status_locked(fence); 753 - spin_unlock_irqrestore(fence->lock, flags); 755 + dma_fence_unlock_irqrestore(fence, flags); 754 756 755 757 return status; 756 758 } ··· 780 782 unsigned long flags; 781 783 bool ret; 782 784 783 - spin_lock_irqsave(fence->lock, flags); 784 - 785 + dma_fence_lock_irqsave(fence, flags); 785 786 ret = !list_empty(&cb->node); 786 787 if (ret) 787 788 list_del_init(&cb->node); 788 - 789 - spin_unlock_irqrestore(fence->lock, flags); 789 + dma_fence_unlock_irqrestore(fence, flags); 790 790 791 791 return ret; 792 792 } ··· 823 827 unsigned long flags; 824 828 signed long ret = timeout ? timeout : 1; 825 829 826 - spin_lock_irqsave(fence->lock, flags); 830 + dma_fence_lock_irqsave(fence, flags); 827 831 828 832 if (dma_fence_test_signaled_flag(fence)) 829 833 goto out; ··· 847 851 __set_current_state(TASK_INTERRUPTIBLE); 848 852 else 849 853 __set_current_state(TASK_UNINTERRUPTIBLE); 850 - spin_unlock_irqrestore(fence->lock, flags); 854 + dma_fence_unlock_irqrestore(fence, flags); 851 855 852 856 ret = schedule_timeout(ret); 853 857 854 - spin_lock_irqsave(fence->lock, flags); 858 + dma_fence_lock_irqsave(fence, flags); 855 859 if (ret > 0 && intr && signal_pending(current)) 856 860 ret = -ERESTARTSYS; 857 861 } ··· 861 865 __set_current_state(TASK_RUNNING); 862 866 863 867 out: 864 - spin_unlock_irqrestore(fence->lock, flags); 868 + dma_fence_unlock_irqrestore(fence, flags); 865 869 return ret; 866 870 } 867 871 EXPORT_SYMBOL(dma_fence_default_wait);
+4 -2
drivers/dma-buf/st-dma-fence.c
··· 410 410 411 411 static void __wait_for_callbacks(struct dma_fence *f) 412 412 { 413 - spin_lock_irq(f->lock); 414 - spin_unlock_irq(f->lock); 413 + unsigned long flags; 414 + 415 + dma_fence_lock_irqsave(f, flags); 416 + dma_fence_unlock_irqrestore(f, flags); 415 417 } 416 418 417 419 static int thread_signal_callback(void *arg)
+7 -7
drivers/dma-buf/sw_sync.c
··· 156 156 struct sync_timeline *parent = dma_fence_parent(fence); 157 157 unsigned long flags; 158 158 159 - spin_lock_irqsave(fence->lock, flags); 159 + dma_fence_lock_irqsave(fence, flags); 160 160 if (!list_empty(&pt->link)) { 161 161 list_del(&pt->link); 162 162 rb_erase(&pt->node, &parent->pt_tree); 163 163 } 164 - spin_unlock_irqrestore(fence->lock, flags); 164 + dma_fence_unlock_irqrestore(fence, flags); 165 165 166 166 sync_timeline_put(parent); 167 167 dma_fence_free(fence); ··· 179 179 struct sync_pt *pt = dma_fence_to_sync_pt(fence); 180 180 unsigned long flags; 181 181 182 - spin_lock_irqsave(fence->lock, flags); 182 + dma_fence_lock_irqsave(fence, flags); 183 183 if (test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) { 184 184 if (ktime_before(deadline, pt->deadline)) 185 185 pt->deadline = deadline; ··· 187 187 pt->deadline = deadline; 188 188 __set_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags); 189 189 } 190 - spin_unlock_irqrestore(fence->lock, flags); 190 + dma_fence_unlock_irqrestore(fence, flags); 191 191 } 192 192 193 193 static const struct dma_fence_ops timeline_fence_ops = { ··· 431 431 goto put_fence; 432 432 } 433 433 434 - spin_lock_irqsave(fence->lock, flags); 434 + dma_fence_lock_irqsave(fence, flags); 435 435 if (!test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) { 436 436 ret = -ENOENT; 437 437 goto unlock; 438 438 } 439 439 data.deadline_ns = ktime_to_ns(pt->deadline); 440 - spin_unlock_irqrestore(fence->lock, flags); 440 + dma_fence_unlock_irqrestore(fence, flags); 441 441 442 442 dma_fence_put(fence); 443 443 ··· 450 450 return 0; 451 451 452 452 unlock: 453 - spin_unlock_irqrestore(fence->lock, flags); 453 + dma_fence_unlock_irqrestore(fence, flags); 454 454 put_fence: 455 455 dma_fence_put(fence); 456 456
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
··· 479 479 if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence) 480 480 return false; 481 481 482 - spin_lock_irqsave(fence->lock, flags); 482 + dma_fence_lock_irqsave(fence, flags); 483 483 if (!dma_fence_is_signaled_locked(fence)) 484 484 dma_fence_set_error(fence, -ENODATA); 485 - spin_unlock_irqrestore(fence->lock, flags); 485 + dma_fence_unlock_irqrestore(fence, flags); 486 486 487 487 while (!dma_fence_is_signaled(fence) && 488 488 ktime_to_ns(ktime_sub(deadline, ktime_get())) > 0)
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 2785 2785 dma_fence_put(vm->last_unlocked); 2786 2786 dma_fence_wait(vm->last_tlb_flush, false); 2787 2787 /* Make sure that all fence callbacks have completed */ 2788 - spin_lock_irqsave(vm->last_tlb_flush->lock, flags); 2789 - spin_unlock_irqrestore(vm->last_tlb_flush->lock, flags); 2788 + dma_fence_lock_irqsave(vm->last_tlb_flush, flags); 2789 + dma_fence_unlock_irqrestore(vm->last_tlb_flush, flags); 2790 2790 dma_fence_put(vm->last_tlb_flush); 2791 2791 2792 2792 list_for_each_entry_safe(mapping, tmp, &vm->freed, list) {
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
··· 639 639 * sure that the dma_fence structure isn't freed up. 640 640 */ 641 641 rcu_read_lock(); 642 - lock = vm->last_tlb_flush->lock; 642 + lock = dma_fence_spinlock(vm->last_tlb_flush); 643 643 rcu_read_unlock(); 644 644 645 645 spin_lock_irqsave(lock, flags);
+1 -1
drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
··· 148 148 { 149 149 struct dma_fence_cb *cur, *tmp; 150 150 151 - lockdep_assert_held(fence->lock); 151 + dma_fence_assert_held(fence); 152 152 153 153 list_for_each_entry_safe(cur, tmp, list, node) { 154 154 INIT_LIST_HEAD(&cur->node);
+11 -8
drivers/gpu/drm/i915/i915_active.c
··· 1045 1045 * nesting rules for the fence->lock; the inner lock is always the 1046 1046 * older lock. 1047 1047 */ 1048 - spin_lock_irqsave(fence->lock, flags); 1048 + dma_fence_lock_irqsave(fence, flags); 1049 1049 if (prev) 1050 - spin_lock_nested(prev->lock, SINGLE_DEPTH_NESTING); 1050 + spin_lock_nested(dma_fence_spinlock(prev), 1051 + SINGLE_DEPTH_NESTING); 1051 1052 1052 1053 /* 1053 1054 * A does the cmpxchg first, and so it sees C or NULL, as before, or ··· 1062 1061 */ 1063 1062 while (cmpxchg(__active_fence_slot(active), prev, fence) != prev) { 1064 1063 if (prev) { 1065 - spin_unlock(prev->lock); 1064 + spin_unlock(dma_fence_spinlock(prev)); 1066 1065 dma_fence_put(prev); 1067 1066 } 1068 - spin_unlock_irqrestore(fence->lock, flags); 1067 + dma_fence_unlock_irqrestore(fence, flags); 1069 1068 1070 1069 prev = i915_active_fence_get(active); 1071 1070 GEM_BUG_ON(prev == fence); 1072 1071 1073 - spin_lock_irqsave(fence->lock, flags); 1072 + dma_fence_lock_irqsave(fence, flags); 1074 1073 if (prev) 1075 - spin_lock_nested(prev->lock, SINGLE_DEPTH_NESTING); 1074 + spin_lock_nested(dma_fence_spinlock(prev), 1075 + SINGLE_DEPTH_NESTING); 1076 1076 } 1077 1077 1078 1078 /* ··· 1090 1088 */ 1091 1089 if (prev) { 1092 1090 __list_del_entry(&active->cb.node); 1093 - spin_unlock(prev->lock); /* serialise with prev->cb_list */ 1091 + /* serialise with prev->cb_list */ 1092 + spin_unlock(dma_fence_spinlock(prev)); 1094 1093 } 1095 1094 list_add_tail(&active->cb.node, &fence->cb_list); 1096 - spin_unlock_irqrestore(fence->lock, flags); 1095 + dma_fence_unlock_irqrestore(fence, flags); 1097 1096 1098 1097 return prev; 1099 1098 }
+3 -2
drivers/gpu/drm/nouveau/nouveau_drm.c
··· 156 156 static inline bool 157 157 nouveau_cli_work_ready(struct dma_fence *fence) 158 158 { 159 + unsigned long flags; 159 160 bool ret = true; 160 161 161 - spin_lock_irq(fence->lock); 162 + dma_fence_lock_irqsave(fence, flags); 162 163 if (!dma_fence_is_signaled_locked(fence)) 163 164 ret = false; 164 - spin_unlock_irq(fence->lock); 165 + dma_fence_unlock_irqrestore(fence, flags); 165 166 166 167 if (ret == true) 167 168 dma_fence_put(fence);
+3 -3
drivers/gpu/drm/scheduler/sched_fence.c
··· 156 156 struct dma_fence *parent; 157 157 unsigned long flags; 158 158 159 - spin_lock_irqsave(&fence->lock, flags); 159 + dma_fence_lock_irqsave(f, flags); 160 160 161 161 /* If we already have an earlier deadline, keep it: */ 162 162 if (test_bit(DRM_SCHED_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags) && 163 163 ktime_before(fence->deadline, deadline)) { 164 - spin_unlock_irqrestore(&fence->lock, flags); 164 + dma_fence_unlock_irqrestore(f, flags); 165 165 return; 166 166 } 167 167 168 168 fence->deadline = deadline; 169 169 set_bit(DRM_SCHED_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags); 170 170 171 - spin_unlock_irqrestore(&fence->lock, flags); 171 + dma_fence_unlock_irqrestore(f, flags); 172 172 173 173 /* 174 174 * smp_load_aquire() to ensure that if we are racing another
+2 -2
drivers/gpu/drm/xe/xe_sched_job.c
··· 190 190 unsigned long irq_flags; 191 191 bool signaled; 192 192 193 - spin_lock_irqsave(fence->lock, irq_flags); 193 + dma_fence_lock_irqsave(fence, irq_flags); 194 194 signaled = test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags); 195 195 if (!signaled) 196 196 dma_fence_set_error(fence, error); 197 - spin_unlock_irqrestore(fence->lock, irq_flags); 197 + dma_fence_unlock_irqrestore(fence, irq_flags); 198 198 199 199 return signaled; 200 200 }
+38
include/linux/dma-fence.h
··· 377 377 } while (1); 378 378 } 379 379 380 + /** 381 + * dma_fence_spinlock - return pointer to the spinlock protecting the fence 382 + * @fence: the fence to get the lock from 383 + * 384 + * Return the pointer to the extern lock. 385 + */ 386 + static inline spinlock_t *dma_fence_spinlock(struct dma_fence *fence) 387 + { 388 + return fence->lock; 389 + } 390 + 391 + /** 392 + * dma_fence_lock_irqsave - irqsave lock the fence 393 + * @fence: the fence to lock 394 + * @flags: where to store the CPU flags. 395 + * 396 + * Lock the fence, preventing it from changing to the signaled state. 397 + */ 398 + #define dma_fence_lock_irqsave(fence, flags) \ 399 + spin_lock_irqsave(fence->lock, flags) 400 + 401 + /** 402 + * dma_fence_unlock_irqrestore - unlock the fence and irqrestore 403 + * @fence: the fence to unlock 404 + * @flags the CPU flags to restore 405 + * 406 + * Unlock the fence, allowing it to change it's state to signaled again. 407 + */ 408 + #define dma_fence_unlock_irqrestore(fence, flags) \ 409 + spin_unlock_irqrestore(fence->lock, flags) 410 + 411 + /** 412 + * dma_fence_assert_held - lockdep assertion that fence is locked 413 + * @fence: the fence which should be locked 414 + */ 415 + #define dma_fence_assert_held(fence) \ 416 + lockdep_assert_held(dma_fence_spinlock(fence)); 417 + 380 418 #ifdef CONFIG_LOCKDEP 381 419 bool dma_fence_begin_signalling(void); 382 420 void dma_fence_end_signalling(bool cookie);