Commit | Line | Data |
---|---|---|
5c43ec5d TH |
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(&ww->ctx, &reservation_ww_class); | |
12 | INIT_LIST_HEAD(&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(&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(&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(&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(ww->contended->base.resv, &ww->ctx); | |
52 | else | |
53 | dma_resv_lock_slow(ww->contended->base.resv, &ww->ctx); | |
54 | ||
55 | if (!ret) | |
56 | list_add_tail(&ww->contended->obj_link, &ww->obj_list); | |
57 | else | |
58 | i915_gem_object_put(ww->contended); | |
59 | ||
60 | ww->contended = NULL; | |
61 | ||
62 | return ret; | |
63 | } |