1 /* $NetBSD: i915_gem_fence.c,v 1.4 2021/12/19 12:36:15 riastradh Exp $ */ 2 3 /* 4 * SPDX-License-Identifier: MIT 5 * 6 * Copyright 2019 Intel Corporation 7 */ 8 9 #include <sys/cdefs.h> 10 __KERNEL_RCSID(0, "$NetBSD: i915_gem_fence.c,v 1.4 2021/12/19 12:36:15 riastradh Exp $"); 11 12 #include "i915_drv.h" 13 #include "i915_gem_object.h" 14 15 struct stub_fence { 16 struct dma_fence dma; 17 spinlock_t lock; 18 struct i915_sw_fence chain; 19 }; 20 21 static int __i915_sw_fence_call 22 stub_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) 23 { 24 struct stub_fence *stub = container_of(fence, typeof(*stub), chain); 25 26 switch (state) { 27 case FENCE_COMPLETE: 28 dma_fence_signal(&stub->dma); 29 break; 30 31 case FENCE_FREE: 32 dma_fence_put(&stub->dma); 33 break; 34 } 35 36 return NOTIFY_DONE; 37 } 38 39 static const char *stub_driver_name(struct dma_fence *fence) 40 { 41 return DRIVER_NAME; 42 } 43 44 static const char *stub_timeline_name(struct dma_fence *fence) 45 { 46 return "object"; 47 } 48 49 static void stub_release(struct dma_fence *fence) 50 { 51 struct stub_fence *stub = container_of(fence, typeof(*stub), dma); 52 53 i915_sw_fence_fini(&stub->chain); 54 55 BUILD_BUG_ON(offsetof(typeof(*stub), dma)); 56 spin_lock_destroy(&stub->lock); 57 dma_fence_free(&stub->dma); 58 } 59 60 static const struct dma_fence_ops stub_fence_ops = { 61 .get_driver_name = stub_driver_name, 62 .get_timeline_name = stub_timeline_name, 63 .release = stub_release, 64 }; 65 66 struct dma_fence * 67 i915_gem_object_lock_fence(struct drm_i915_gem_object *obj) 68 { 69 struct stub_fence *stub; 70 71 assert_object_held(obj); 72 73 stub = kmalloc(sizeof(*stub), GFP_KERNEL); 74 if (!stub) 75 return NULL; 76 77 i915_sw_fence_init(&stub->chain, stub_notify); 78 spin_lock_init(&stub->lock); 79 dma_fence_init(&stub->dma, &stub_fence_ops, &stub->lock, 80 0, 0); 81 82 if (i915_sw_fence_await_reservation(&stub->chain, 83 obj->base.resv, NULL, 84 true, I915_FENCE_TIMEOUT, 85 I915_FENCE_GFP) < 0) 86 goto err; 87 88 dma_resv_add_excl_fence(obj->base.resv, &stub->dma); 89 90 return &stub->dma; 91 92 err: 93 stub_release(&stub->dma); 94 return NULL; 95 } 96 97 void i915_gem_object_unlock_fence(struct drm_i915_gem_object *obj, 98 struct dma_fence *fence) 99 { 100 struct stub_fence *stub = container_of(fence, typeof(*stub), dma); 101 102 i915_sw_fence_commit(&stub->chain); 103 } 104