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