1 | // SPDX-License-Identifier: MIT |
---|---|
2 | /* |
3 | * Copyright © 2020 Intel Corporation |
4 | */ |
5 | #include <linux/dma-resv.h> |
6 | #include "i915_gem_ww.h" |
7 | #include "gem/i915_gem_object.h" |
8 | |
9 | void i915_gem_ww_ctx_init(struct i915_gem_ww_ctx *ww, bool intr) |
10 | { |
11 | ww_acquire_init(ctx: &ww->ctx, ww_class: &reservation_ww_class); |
12 | INIT_LIST_HEAD(list: &ww->obj_list); |
13 | ww->intr = intr; |
14 | ww->contended = NULL; |
15 | } |
16 | |
17 | static void i915_gem_ww_ctx_unlock_all(struct i915_gem_ww_ctx *ww) |
18 | { |
19 | struct drm_i915_gem_object *obj; |
20 | |
21 | while ((obj = list_first_entry_or_null(&ww->obj_list, struct drm_i915_gem_object, obj_link))) { |
22 | list_del(entry: &obj->obj_link); |
23 | i915_gem_object_unlock(obj); |
24 | i915_gem_object_put(obj); |
25 | } |
26 | } |
27 | |
28 | void i915_gem_ww_unlock_single(struct drm_i915_gem_object *obj) |
29 | { |
30 | list_del(entry: &obj->obj_link); |
31 | i915_gem_object_unlock(obj); |
32 | i915_gem_object_put(obj); |
33 | } |
34 | |
35 | void i915_gem_ww_ctx_fini(struct i915_gem_ww_ctx *ww) |
36 | { |
37 | i915_gem_ww_ctx_unlock_all(ww); |
38 | WARN_ON(ww->contended); |
39 | ww_acquire_fini(ctx: &ww->ctx); |
40 | } |
41 | |
42 | int __must_check i915_gem_ww_ctx_backoff(struct i915_gem_ww_ctx *ww) |
43 | { |
44 | int ret = 0; |
45 | |
46 | if (WARN_ON(!ww->contended)) |
47 | return -EINVAL; |
48 | |
49 | i915_gem_ww_ctx_unlock_all(ww); |
50 | if (ww->intr) |
51 | ret = dma_resv_lock_slow_interruptible(obj: ww->contended->base.resv, ctx: &ww->ctx); |
52 | else |
53 | dma_resv_lock_slow(obj: ww->contended->base.resv, ctx: &ww->ctx); |
54 | |
55 | if (!ret) |
56 | list_add_tail(new: &ww->contended->obj_link, head: &ww->obj_list); |
57 | else |
58 | i915_gem_object_put(obj: ww->contended); |
59 | |
60 | ww->contended = NULL; |
61 | |
62 | return ret; |
63 | } |
64 |