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