diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_timeline.c | 124 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_timeline.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_random.c | 33 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_random.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_timeline.c | 143 |
6 files changed, 280 insertions, 28 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8a181b455197..6a051381f535 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -1978,6 +1978,10 @@ struct drm_i915_private { | |||
| 1978 | struct i915_gt_timelines { | 1978 | struct i915_gt_timelines { |
| 1979 | struct mutex mutex; /* protects list, tainted by GPU */ | 1979 | struct mutex mutex; /* protects list, tainted by GPU */ |
| 1980 | struct list_head list; | 1980 | struct list_head list; |
| 1981 | |||
| 1982 | /* Pack multiple timelines' seqnos into the same page */ | ||
| 1983 | spinlock_t hwsp_lock; | ||
| 1984 | struct list_head hwsp_free_list; | ||
| 1981 | } timelines; | 1985 | } timelines; |
| 1982 | 1986 | ||
| 1983 | struct list_head active_rings; | 1987 | struct list_head active_rings; |
diff --git a/drivers/gpu/drm/i915/i915_timeline.c b/drivers/gpu/drm/i915/i915_timeline.c index 8d5792311a8f..add8fc33cf6e 100644 --- a/drivers/gpu/drm/i915/i915_timeline.c +++ b/drivers/gpu/drm/i915/i915_timeline.c | |||
| @@ -9,6 +9,18 @@ | |||
| 9 | #include "i915_timeline.h" | 9 | #include "i915_timeline.h" |
| 10 | #include "i915_syncmap.h" | 10 | #include "i915_syncmap.h" |
| 11 | 11 | ||
| 12 | struct i915_timeline_hwsp { | ||
| 13 | struct i915_vma *vma; | ||
| 14 | struct list_head free_link; | ||
| 15 | u64 free_bitmap; | ||
| 16 | }; | ||
| 17 | |||
| 18 | static inline struct i915_timeline_hwsp * | ||
| 19 | i915_timeline_hwsp(const struct i915_timeline *tl) | ||
| 20 | { | ||
| 21 | return tl->hwsp_ggtt->private; | ||
| 22 | } | ||
| 23 | |||
| 12 | static struct i915_vma *__hwsp_alloc(struct drm_i915_private *i915) | 24 | static struct i915_vma *__hwsp_alloc(struct drm_i915_private *i915) |
| 13 | { | 25 | { |
| 14 | struct drm_i915_gem_object *obj; | 26 | struct drm_i915_gem_object *obj; |
| @@ -27,28 +39,89 @@ static struct i915_vma *__hwsp_alloc(struct drm_i915_private *i915) | |||
| 27 | return vma; | 39 | return vma; |
| 28 | } | 40 | } |
| 29 | 41 | ||
| 30 | static int hwsp_alloc(struct i915_timeline *timeline) | 42 | static struct i915_vma * |
| 43 | hwsp_alloc(struct i915_timeline *timeline, unsigned int *cacheline) | ||
| 31 | { | 44 | { |
| 32 | struct i915_vma *vma; | 45 | struct drm_i915_private *i915 = timeline->i915; |
| 46 | struct i915_gt_timelines *gt = &i915->gt.timelines; | ||
| 47 | struct i915_timeline_hwsp *hwsp; | ||
| 33 | 48 | ||
| 34 | vma = __hwsp_alloc(timeline->i915); | 49 | BUILD_BUG_ON(BITS_PER_TYPE(u64) * CACHELINE_BYTES > PAGE_SIZE); |
| 35 | if (IS_ERR(vma)) | ||
| 36 | return PTR_ERR(vma); | ||
| 37 | 50 | ||
| 38 | timeline->hwsp_ggtt = vma; | 51 | spin_lock(>->hwsp_lock); |
| 39 | timeline->hwsp_offset = 0; | ||
| 40 | 52 | ||
| 41 | return 0; | 53 | /* hwsp_free_list only contains HWSP that have available cachelines */ |
| 54 | hwsp = list_first_entry_or_null(>->hwsp_free_list, | ||
| 55 | typeof(*hwsp), free_link); | ||
| 56 | if (!hwsp) { | ||
| 57 | struct i915_vma *vma; | ||
| 58 | |||
| 59 | spin_unlock(>->hwsp_lock); | ||
| 60 | |||
| 61 | hwsp = kmalloc(sizeof(*hwsp), GFP_KERNEL); | ||
| 62 | if (!hwsp) | ||
| 63 | return ERR_PTR(-ENOMEM); | ||
| 64 | |||
| 65 | vma = __hwsp_alloc(i915); | ||
| 66 | if (IS_ERR(vma)) { | ||
| 67 | kfree(hwsp); | ||
| 68 | return vma; | ||
| 69 | } | ||
| 70 | |||
| 71 | vma->private = hwsp; | ||
| 72 | hwsp->vma = vma; | ||
| 73 | hwsp->free_bitmap = ~0ull; | ||
| 74 | |||
| 75 | spin_lock(>->hwsp_lock); | ||
| 76 | list_add(&hwsp->free_link, >->hwsp_free_list); | ||
| 77 | } | ||
| 78 | |||
| 79 | GEM_BUG_ON(!hwsp->free_bitmap); | ||
| 80 | *cacheline = __ffs64(hwsp->free_bitmap); | ||
| 81 | hwsp->free_bitmap &= ~BIT_ULL(*cacheline); | ||
| 82 | if (!hwsp->free_bitmap) | ||
| 83 | list_del(&hwsp->free_link); | ||
| 84 | |||
| 85 | spin_unlock(>->hwsp_lock); | ||
| 86 | |||
| 87 | GEM_BUG_ON(hwsp->vma->private != hwsp); | ||
| 88 | return hwsp->vma; | ||
| 89 | } | ||
| 90 | |||
| 91 | static void hwsp_free(struct i915_timeline *timeline) | ||
| 92 | { | ||
| 93 | struct i915_gt_timelines *gt = &timeline->i915->gt.timelines; | ||
| 94 | struct i915_timeline_hwsp *hwsp; | ||
| 95 | |||
| 96 | hwsp = i915_timeline_hwsp(timeline); | ||
| 97 | if (!hwsp) /* leave global HWSP alone! */ | ||
| 98 | return; | ||
| 99 | |||
| 100 | spin_lock(>->hwsp_lock); | ||
| 101 | |||
| 102 | /* As a cacheline becomes available, publish the HWSP on the freelist */ | ||
| 103 | if (!hwsp->free_bitmap) | ||
| 104 | list_add_tail(&hwsp->free_link, >->hwsp_free_list); | ||
| 105 | |||
| 106 | hwsp->free_bitmap |= BIT_ULL(timeline->hwsp_offset / CACHELINE_BYTES); | ||
| 107 | |||
| 108 | /* And if no one is left using it, give the page back to the system */ | ||
| 109 | if (hwsp->free_bitmap == ~0ull) { | ||
| 110 | i915_vma_put(hwsp->vma); | ||
| 111 | list_del(&hwsp->free_link); | ||
| 112 | kfree(hwsp); | ||
| 113 | } | ||
| 114 | |||
| 115 | spin_unlock(>->hwsp_lock); | ||
| 42 | } | 116 | } |
| 43 | 117 | ||
| 44 | int i915_timeline_init(struct drm_i915_private *i915, | 118 | int i915_timeline_init(struct drm_i915_private *i915, |
| 45 | struct i915_timeline *timeline, | 119 | struct i915_timeline *timeline, |
| 46 | const char *name, | 120 | const char *name, |
| 47 | struct i915_vma *global_hwsp) | 121 | struct i915_vma *hwsp) |
| 48 | { | 122 | { |
| 49 | struct i915_gt_timelines *gt = &i915->gt.timelines; | 123 | struct i915_gt_timelines *gt = &i915->gt.timelines; |
| 50 | void *vaddr; | 124 | void *vaddr; |
| 51 | int err; | ||
| 52 | 125 | ||
| 53 | /* | 126 | /* |
| 54 | * Ideally we want a set of engines on a single leaf as we expect | 127 | * Ideally we want a set of engines on a single leaf as we expect |
| @@ -64,18 +137,22 @@ int i915_timeline_init(struct drm_i915_private *i915, | |||
| 64 | timeline->name = name; | 137 | timeline->name = name; |
| 65 | timeline->pin_count = 0; | 138 | timeline->pin_count = 0; |
| 66 | 139 | ||
| 67 | if (global_hwsp) { | 140 | timeline->hwsp_offset = I915_GEM_HWS_SEQNO_ADDR; |
| 68 | timeline->hwsp_ggtt = i915_vma_get(global_hwsp); | 141 | if (!hwsp) { |
| 69 | timeline->hwsp_offset = I915_GEM_HWS_SEQNO_ADDR; | 142 | unsigned int cacheline; |
| 70 | } else { | 143 | |
| 71 | err = hwsp_alloc(timeline); | 144 | hwsp = hwsp_alloc(timeline, &cacheline); |
| 72 | if (err) | 145 | if (IS_ERR(hwsp)) |
| 73 | return err; | 146 | return PTR_ERR(hwsp); |
| 147 | |||
| 148 | timeline->hwsp_offset = cacheline * CACHELINE_BYTES; | ||
| 74 | } | 149 | } |
| 150 | timeline->hwsp_ggtt = i915_vma_get(hwsp); | ||
| 75 | 151 | ||
| 76 | vaddr = i915_gem_object_pin_map(timeline->hwsp_ggtt->obj, I915_MAP_WB); | 152 | vaddr = i915_gem_object_pin_map(hwsp->obj, I915_MAP_WB); |
| 77 | if (IS_ERR(vaddr)) { | 153 | if (IS_ERR(vaddr)) { |
| 78 | i915_vma_put(timeline->hwsp_ggtt); | 154 | hwsp_free(timeline); |
| 155 | i915_vma_put(hwsp); | ||
| 79 | return PTR_ERR(vaddr); | 156 | return PTR_ERR(vaddr); |
| 80 | } | 157 | } |
| 81 | 158 | ||
| @@ -105,6 +182,9 @@ void i915_timelines_init(struct drm_i915_private *i915) | |||
| 105 | mutex_init(>->mutex); | 182 | mutex_init(>->mutex); |
| 106 | INIT_LIST_HEAD(>->list); | 183 | INIT_LIST_HEAD(>->list); |
| 107 | 184 | ||
| 185 | spin_lock_init(>->hwsp_lock); | ||
| 186 | INIT_LIST_HEAD(>->hwsp_free_list); | ||
| 187 | |||
| 108 | /* via i915_gem_wait_for_idle() */ | 188 | /* via i915_gem_wait_for_idle() */ |
| 109 | i915_gem_shrinker_taints_mutex(i915, >->mutex); | 189 | i915_gem_shrinker_taints_mutex(i915, >->mutex); |
| 110 | } | 190 | } |
| @@ -144,12 +224,13 @@ void i915_timeline_fini(struct i915_timeline *timeline) | |||
| 144 | GEM_BUG_ON(timeline->pin_count); | 224 | GEM_BUG_ON(timeline->pin_count); |
| 145 | GEM_BUG_ON(!list_empty(&timeline->requests)); | 225 | GEM_BUG_ON(!list_empty(&timeline->requests)); |
| 146 | 226 | ||
| 147 | i915_syncmap_free(&timeline->sync); | ||
| 148 | |||
| 149 | mutex_lock(>->mutex); | 227 | mutex_lock(>->mutex); |
| 150 | list_del(&timeline->link); | 228 | list_del(&timeline->link); |
| 151 | mutex_unlock(>->mutex); | 229 | mutex_unlock(>->mutex); |
| 152 | 230 | ||
| 231 | i915_syncmap_free(&timeline->sync); | ||
| 232 | hwsp_free(timeline); | ||
| 233 | |||
| 153 | i915_gem_object_unpin_map(timeline->hwsp_ggtt->obj); | 234 | i915_gem_object_unpin_map(timeline->hwsp_ggtt->obj); |
| 154 | i915_vma_put(timeline->hwsp_ggtt); | 235 | i915_vma_put(timeline->hwsp_ggtt); |
| 155 | } | 236 | } |
| @@ -226,6 +307,7 @@ void i915_timelines_fini(struct drm_i915_private *i915) | |||
| 226 | struct i915_gt_timelines *gt = &i915->gt.timelines; | 307 | struct i915_gt_timelines *gt = &i915->gt.timelines; |
| 227 | 308 | ||
| 228 | GEM_BUG_ON(!list_empty(>->list)); | 309 | GEM_BUG_ON(!list_empty(>->list)); |
| 310 | GEM_BUG_ON(!list_empty(>->hwsp_free_list)); | ||
| 229 | 311 | ||
| 230 | mutex_destroy(>->mutex); | 312 | mutex_destroy(>->mutex); |
| 231 | } | 313 | } |
diff --git a/drivers/gpu/drm/i915/i915_timeline.h b/drivers/gpu/drm/i915/i915_timeline.h index 0c3739d53d79..ab736e2e5707 100644 --- a/drivers/gpu/drm/i915/i915_timeline.h +++ b/drivers/gpu/drm/i915/i915_timeline.h | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include "i915_utils.h" | 33 | #include "i915_utils.h" |
| 34 | 34 | ||
| 35 | struct i915_vma; | 35 | struct i915_vma; |
| 36 | struct i915_timeline_hwsp; | ||
| 36 | 37 | ||
| 37 | struct i915_timeline { | 38 | struct i915_timeline { |
| 38 | u64 fence_context; | 39 | u64 fence_context; |
diff --git a/drivers/gpu/drm/i915/selftests/i915_random.c b/drivers/gpu/drm/i915/selftests/i915_random.c index 1f415ce47018..716a3f19f030 100644 --- a/drivers/gpu/drm/i915/selftests/i915_random.c +++ b/drivers/gpu/drm/i915/selftests/i915_random.c | |||
| @@ -41,18 +41,37 @@ u64 i915_prandom_u64_state(struct rnd_state *rnd) | |||
| 41 | return x; | 41 | return x; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | void i915_random_reorder(unsigned int *order, unsigned int count, | 44 | void i915_prandom_shuffle(void *arr, size_t elsz, size_t count, |
| 45 | struct rnd_state *state) | 45 | struct rnd_state *state) |
| 46 | { | 46 | { |
| 47 | unsigned int i, j; | 47 | char stack[128]; |
| 48 | |||
| 49 | if (WARN_ON(elsz > sizeof(stack) || count > U32_MAX)) | ||
| 50 | return; | ||
| 51 | |||
| 52 | if (!elsz || !count) | ||
| 53 | return; | ||
| 54 | |||
| 55 | /* Fisher-Yates shuffle courtesy of Knuth */ | ||
| 56 | while (--count) { | ||
| 57 | size_t swp; | ||
| 58 | |||
| 59 | swp = i915_prandom_u32_max_state(count + 1, state); | ||
| 60 | if (swp == count) | ||
| 61 | continue; | ||
| 48 | 62 | ||
| 49 | for (i = 0; i < count; i++) { | 63 | memcpy(stack, arr + count * elsz, elsz); |
| 50 | BUILD_BUG_ON(sizeof(unsigned int) > sizeof(u32)); | 64 | memcpy(arr + count * elsz, arr + swp * elsz, elsz); |
| 51 | j = i915_prandom_u32_max_state(count, state); | 65 | memcpy(arr + swp * elsz, stack, elsz); |
| 52 | swap(order[i], order[j]); | ||
| 53 | } | 66 | } |
| 54 | } | 67 | } |
| 55 | 68 | ||
| 69 | void i915_random_reorder(unsigned int *order, unsigned int count, | ||
| 70 | struct rnd_state *state) | ||
| 71 | { | ||
| 72 | i915_prandom_shuffle(order, sizeof(*order), count, state); | ||
| 73 | } | ||
| 74 | |||
| 56 | unsigned int *i915_random_order(unsigned int count, struct rnd_state *state) | 75 | unsigned int *i915_random_order(unsigned int count, struct rnd_state *state) |
| 57 | { | 76 | { |
| 58 | unsigned int *order, i; | 77 | unsigned int *order, i; |
diff --git a/drivers/gpu/drm/i915/selftests/i915_random.h b/drivers/gpu/drm/i915/selftests/i915_random.h index 7dffedc501ca..8e1ff9c105b6 100644 --- a/drivers/gpu/drm/i915/selftests/i915_random.h +++ b/drivers/gpu/drm/i915/selftests/i915_random.h | |||
| @@ -54,4 +54,7 @@ void i915_random_reorder(unsigned int *order, | |||
| 54 | unsigned int count, | 54 | unsigned int count, |
| 55 | struct rnd_state *state); | 55 | struct rnd_state *state); |
| 56 | 56 | ||
| 57 | void i915_prandom_shuffle(void *arr, size_t elsz, size_t count, | ||
| 58 | struct rnd_state *state); | ||
| 59 | |||
| 57 | #endif /* !__I915_SELFTESTS_RANDOM_H__ */ | 60 | #endif /* !__I915_SELFTESTS_RANDOM_H__ */ |
diff --git a/drivers/gpu/drm/i915/selftests/i915_timeline.c b/drivers/gpu/drm/i915/selftests/i915_timeline.c index 1585b614510d..c34340f074cf 100644 --- a/drivers/gpu/drm/i915/selftests/i915_timeline.c +++ b/drivers/gpu/drm/i915/selftests/i915_timeline.c | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | * Copyright © 2017-2018 Intel Corporation | 4 | * Copyright © 2017-2018 Intel Corporation |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <linux/prime_numbers.h> | ||
| 8 | |||
| 7 | #include "../i915_selftest.h" | 9 | #include "../i915_selftest.h" |
| 8 | #include "i915_random.h" | 10 | #include "i915_random.h" |
| 9 | 11 | ||
| @@ -11,6 +13,146 @@ | |||
| 11 | #include "mock_gem_device.h" | 13 | #include "mock_gem_device.h" |
| 12 | #include "mock_timeline.h" | 14 | #include "mock_timeline.h" |
| 13 | 15 | ||
| 16 | static struct page *hwsp_page(struct i915_timeline *tl) | ||
| 17 | { | ||
| 18 | struct drm_i915_gem_object *obj = tl->hwsp_ggtt->obj; | ||
| 19 | |||
| 20 | GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); | ||
| 21 | return sg_page(obj->mm.pages->sgl); | ||
| 22 | } | ||
| 23 | |||
| 24 | static unsigned long hwsp_cacheline(struct i915_timeline *tl) | ||
| 25 | { | ||
| 26 | unsigned long address = (unsigned long)page_address(hwsp_page(tl)); | ||
| 27 | |||
| 28 | return (address + tl->hwsp_offset) / CACHELINE_BYTES; | ||
| 29 | } | ||
| 30 | |||
| 31 | #define CACHELINES_PER_PAGE (PAGE_SIZE / CACHELINE_BYTES) | ||
| 32 | |||
| 33 | struct mock_hwsp_freelist { | ||
| 34 | struct drm_i915_private *i915; | ||
| 35 | struct radix_tree_root cachelines; | ||
| 36 | struct i915_timeline **history; | ||
| 37 | unsigned long count, max; | ||
| 38 | struct rnd_state prng; | ||
| 39 | }; | ||
| 40 | |||
| 41 | enum { | ||
| 42 | SHUFFLE = BIT(0), | ||
| 43 | }; | ||
| 44 | |||
| 45 | static void __mock_hwsp_record(struct mock_hwsp_freelist *state, | ||
| 46 | unsigned int idx, | ||
| 47 | struct i915_timeline *tl) | ||
| 48 | { | ||
| 49 | tl = xchg(&state->history[idx], tl); | ||
| 50 | if (tl) { | ||
| 51 | radix_tree_delete(&state->cachelines, hwsp_cacheline(tl)); | ||
| 52 | i915_timeline_put(tl); | ||
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 | static int __mock_hwsp_timeline(struct mock_hwsp_freelist *state, | ||
| 57 | unsigned int count, | ||
| 58 | unsigned int flags) | ||
| 59 | { | ||
| 60 | struct i915_timeline *tl; | ||
| 61 | unsigned int idx; | ||
| 62 | |||
| 63 | while (count--) { | ||
| 64 | unsigned long cacheline; | ||
| 65 | int err; | ||
| 66 | |||
| 67 | tl = i915_timeline_create(state->i915, "mock", NULL); | ||
| 68 | if (IS_ERR(tl)) | ||
| 69 | return PTR_ERR(tl); | ||
| 70 | |||
| 71 | cacheline = hwsp_cacheline(tl); | ||
| 72 | err = radix_tree_insert(&state->cachelines, cacheline, tl); | ||
| 73 | if (err) { | ||
| 74 | if (err == -EEXIST) { | ||
| 75 | pr_err("HWSP cacheline %lu already used; duplicate allocation!\n", | ||
| 76 | cacheline); | ||
| 77 | } | ||
| 78 | i915_timeline_put(tl); | ||
| 79 | return err; | ||
| 80 | } | ||
| 81 | |||
| 82 | idx = state->count++ % state->max; | ||
| 83 | __mock_hwsp_record(state, idx, tl); | ||
| 84 | } | ||
| 85 | |||
| 86 | if (flags & SHUFFLE) | ||
| 87 | i915_prandom_shuffle(state->history, | ||
| 88 | sizeof(*state->history), | ||
| 89 | min(state->count, state->max), | ||
| 90 | &state->prng); | ||
| 91 | |||
| 92 | count = i915_prandom_u32_max_state(min(state->count, state->max), | ||
| 93 | &state->prng); | ||
| 94 | while (count--) { | ||
| 95 | idx = --state->count % state->max; | ||
| 96 | __mock_hwsp_record(state, idx, NULL); | ||
| 97 | } | ||
| 98 | |||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | |||
| 102 | static int mock_hwsp_freelist(void *arg) | ||
| 103 | { | ||
| 104 | struct mock_hwsp_freelist state; | ||
| 105 | const struct { | ||
| 106 | const char *name; | ||
| 107 | unsigned int flags; | ||
| 108 | } phases[] = { | ||
| 109 | { "linear", 0 }, | ||
| 110 | { "shuffled", SHUFFLE }, | ||
| 111 | { }, | ||
| 112 | }, *p; | ||
| 113 | unsigned int na; | ||
| 114 | int err = 0; | ||
| 115 | |||
| 116 | INIT_RADIX_TREE(&state.cachelines, GFP_KERNEL); | ||
| 117 | state.prng = I915_RND_STATE_INITIALIZER(i915_selftest.random_seed); | ||
| 118 | |||
| 119 | state.i915 = mock_gem_device(); | ||
| 120 | if (!state.i915) | ||
| 121 | return -ENOMEM; | ||
| 122 | |||
| 123 | /* | ||
| 124 | * Create a bunch of timelines and check that their HWSP do not overlap. | ||
| 125 | * Free some, and try again. | ||
| 126 | */ | ||
| 127 | |||
| 128 | state.max = PAGE_SIZE / sizeof(*state.history); | ||
| 129 | state.count = 0; | ||
| 130 | state.history = kcalloc(state.max, sizeof(*state.history), GFP_KERNEL); | ||
| 131 | if (!state.history) { | ||
| 132 | err = -ENOMEM; | ||
| 133 | goto err_put; | ||
| 134 | } | ||
| 135 | |||
| 136 | mutex_lock(&state.i915->drm.struct_mutex); | ||
| 137 | for (p = phases; p->name; p++) { | ||
| 138 | pr_debug("%s(%s)\n", __func__, p->name); | ||
| 139 | for_each_prime_number_from(na, 1, 2 * CACHELINES_PER_PAGE) { | ||
| 140 | err = __mock_hwsp_timeline(&state, na, p->flags); | ||
| 141 | if (err) | ||
| 142 | goto out; | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | out: | ||
| 147 | for (na = 0; na < state.max; na++) | ||
| 148 | __mock_hwsp_record(&state, na, NULL); | ||
| 149 | mutex_unlock(&state.i915->drm.struct_mutex); | ||
| 150 | kfree(state.history); | ||
| 151 | err_put: | ||
| 152 | drm_dev_put(&state.i915->drm); | ||
| 153 | return err; | ||
| 154 | } | ||
| 155 | |||
| 14 | struct __igt_sync { | 156 | struct __igt_sync { |
| 15 | const char *name; | 157 | const char *name; |
| 16 | u32 seqno; | 158 | u32 seqno; |
| @@ -260,6 +402,7 @@ static int bench_sync(void *arg) | |||
| 260 | int i915_timeline_mock_selftests(void) | 402 | int i915_timeline_mock_selftests(void) |
| 261 | { | 403 | { |
| 262 | static const struct i915_subtest tests[] = { | 404 | static const struct i915_subtest tests[] = { |
| 405 | SUBTEST(mock_hwsp_freelist), | ||
| 263 | SUBTEST(igt_sync), | 406 | SUBTEST(igt_sync), |
| 264 | SUBTEST(bench_sync), | 407 | SUBTEST(bench_sync), |
| 265 | }; | 408 | }; |
