diff options
Diffstat (limited to 'drivers/gpu/drm')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 103 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_reset.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_timeline.c | 38 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_timeline.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/mock_gem_device.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/mock_timeline.c | 3 |
7 files changed, 109 insertions, 58 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0133d1da3d3c..8a181b455197 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -1975,7 +1975,10 @@ struct drm_i915_private { | |||
| 1975 | void (*resume)(struct drm_i915_private *); | 1975 | void (*resume)(struct drm_i915_private *); |
| 1976 | void (*cleanup_engine)(struct intel_engine_cs *engine); | 1976 | void (*cleanup_engine)(struct intel_engine_cs *engine); |
| 1977 | 1977 | ||
| 1978 | struct list_head timelines; | 1978 | struct i915_gt_timelines { |
| 1979 | struct mutex mutex; /* protects list, tainted by GPU */ | ||
| 1980 | struct list_head list; | ||
| 1981 | } timelines; | ||
| 1979 | 1982 | ||
| 1980 | struct list_head active_rings; | 1983 | struct list_head active_rings; |
| 1981 | struct list_head closed_vma; | 1984 | struct list_head closed_vma; |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 15acd052da46..761714448ff3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -3222,33 +3222,6 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | |||
| 3222 | return ret; | 3222 | return ret; |
| 3223 | } | 3223 | } |
| 3224 | 3224 | ||
| 3225 | static long wait_for_timeline(struct i915_timeline *tl, | ||
| 3226 | unsigned int flags, long timeout) | ||
| 3227 | { | ||
| 3228 | struct i915_request *rq; | ||
| 3229 | |||
| 3230 | rq = i915_gem_active_get_unlocked(&tl->last_request); | ||
| 3231 | if (!rq) | ||
| 3232 | return timeout; | ||
| 3233 | |||
| 3234 | /* | ||
| 3235 | * "Race-to-idle". | ||
| 3236 | * | ||
| 3237 | * Switching to the kernel context is often used a synchronous | ||
| 3238 | * step prior to idling, e.g. in suspend for flushing all | ||
| 3239 | * current operations to memory before sleeping. These we | ||
| 3240 | * want to complete as quickly as possible to avoid prolonged | ||
| 3241 | * stalls, so allow the gpu to boost to maximum clocks. | ||
| 3242 | */ | ||
| 3243 | if (flags & I915_WAIT_FOR_IDLE_BOOST) | ||
| 3244 | gen6_rps_boost(rq, NULL); | ||
| 3245 | |||
| 3246 | timeout = i915_request_wait(rq, flags, timeout); | ||
| 3247 | i915_request_put(rq); | ||
| 3248 | |||
| 3249 | return timeout; | ||
| 3250 | } | ||
| 3251 | |||
| 3252 | static int wait_for_engines(struct drm_i915_private *i915) | 3225 | static int wait_for_engines(struct drm_i915_private *i915) |
| 3253 | { | 3226 | { |
| 3254 | if (wait_for(intel_engines_are_idle(i915), I915_IDLE_ENGINES_TIMEOUT)) { | 3227 | if (wait_for(intel_engines_are_idle(i915), I915_IDLE_ENGINES_TIMEOUT)) { |
| @@ -3262,6 +3235,52 @@ static int wait_for_engines(struct drm_i915_private *i915) | |||
| 3262 | return 0; | 3235 | return 0; |
| 3263 | } | 3236 | } |
| 3264 | 3237 | ||
| 3238 | static long | ||
| 3239 | wait_for_timelines(struct drm_i915_private *i915, | ||
| 3240 | unsigned int flags, long timeout) | ||
| 3241 | { | ||
| 3242 | struct i915_gt_timelines *gt = &i915->gt.timelines; | ||
| 3243 | struct i915_timeline *tl; | ||
| 3244 | |||
| 3245 | if (!READ_ONCE(i915->gt.active_requests)) | ||
| 3246 | return timeout; | ||
| 3247 | |||
| 3248 | mutex_lock(>->mutex); | ||
| 3249 | list_for_each_entry(tl, >->list, link) { | ||
| 3250 | struct i915_request *rq; | ||
| 3251 | |||
| 3252 | rq = i915_gem_active_get_unlocked(&tl->last_request); | ||
| 3253 | if (!rq) | ||
| 3254 | continue; | ||
| 3255 | |||
| 3256 | mutex_unlock(>->mutex); | ||
| 3257 | |||
| 3258 | /* | ||
| 3259 | * "Race-to-idle". | ||
| 3260 | * | ||
| 3261 | * Switching to the kernel context is often used a synchronous | ||
| 3262 | * step prior to idling, e.g. in suspend for flushing all | ||
| 3263 | * current operations to memory before sleeping. These we | ||
| 3264 | * want to complete as quickly as possible to avoid prolonged | ||
| 3265 | * stalls, so allow the gpu to boost to maximum clocks. | ||
| 3266 | */ | ||
| 3267 | if (flags & I915_WAIT_FOR_IDLE_BOOST) | ||
| 3268 | gen6_rps_boost(rq, NULL); | ||
| 3269 | |||
| 3270 | timeout = i915_request_wait(rq, flags, timeout); | ||
| 3271 | i915_request_put(rq); | ||
| 3272 | if (timeout < 0) | ||
| 3273 | return timeout; | ||
| 3274 | |||
| 3275 | /* restart after reacquiring the lock */ | ||
| 3276 | mutex_lock(>->mutex); | ||
| 3277 | tl = list_entry(>->list, typeof(*tl), link); | ||
| 3278 | } | ||
| 3279 | mutex_unlock(>->mutex); | ||
| 3280 | |||
| 3281 | return timeout; | ||
| 3282 | } | ||
| 3283 | |||
| 3265 | int i915_gem_wait_for_idle(struct drm_i915_private *i915, | 3284 | int i915_gem_wait_for_idle(struct drm_i915_private *i915, |
| 3266 | unsigned int flags, long timeout) | 3285 | unsigned int flags, long timeout) |
| 3267 | { | 3286 | { |
| @@ -3273,17 +3292,15 @@ int i915_gem_wait_for_idle(struct drm_i915_private *i915, | |||
| 3273 | if (!READ_ONCE(i915->gt.awake)) | 3292 | if (!READ_ONCE(i915->gt.awake)) |
| 3274 | return 0; | 3293 | return 0; |
| 3275 | 3294 | ||
| 3295 | timeout = wait_for_timelines(i915, flags, timeout); | ||
| 3296 | if (timeout < 0) | ||
| 3297 | return timeout; | ||
| 3298 | |||
| 3276 | if (flags & I915_WAIT_LOCKED) { | 3299 | if (flags & I915_WAIT_LOCKED) { |
| 3277 | struct i915_timeline *tl; | ||
| 3278 | int err; | 3300 | int err; |
| 3279 | 3301 | ||
| 3280 | lockdep_assert_held(&i915->drm.struct_mutex); | 3302 | lockdep_assert_held(&i915->drm.struct_mutex); |
| 3281 | 3303 | ||
| 3282 | list_for_each_entry(tl, &i915->gt.timelines, link) { | ||
| 3283 | timeout = wait_for_timeline(tl, flags, timeout); | ||
| 3284 | if (timeout < 0) | ||
| 3285 | return timeout; | ||
| 3286 | } | ||
| 3287 | if (GEM_SHOW_DEBUG() && !timeout) { | 3304 | if (GEM_SHOW_DEBUG() && !timeout) { |
| 3288 | /* Presume that timeout was non-zero to begin with! */ | 3305 | /* Presume that timeout was non-zero to begin with! */ |
| 3289 | dev_warn(&i915->drm.pdev->dev, | 3306 | dev_warn(&i915->drm.pdev->dev, |
| @@ -3297,17 +3314,6 @@ int i915_gem_wait_for_idle(struct drm_i915_private *i915, | |||
| 3297 | 3314 | ||
| 3298 | i915_retire_requests(i915); | 3315 | i915_retire_requests(i915); |
| 3299 | GEM_BUG_ON(i915->gt.active_requests); | 3316 | GEM_BUG_ON(i915->gt.active_requests); |
| 3300 | } else { | ||
| 3301 | struct intel_engine_cs *engine; | ||
| 3302 | enum intel_engine_id id; | ||
| 3303 | |||
| 3304 | for_each_engine(engine, i915, id) { | ||
| 3305 | struct i915_timeline *tl = &engine->timeline; | ||
| 3306 | |||
| 3307 | timeout = wait_for_timeline(tl, flags, timeout); | ||
| 3308 | if (timeout < 0) | ||
| 3309 | return timeout; | ||
| 3310 | } | ||
| 3311 | } | 3317 | } |
| 3312 | 3318 | ||
| 3313 | return 0; | 3319 | return 0; |
| @@ -5008,6 +5014,8 @@ int i915_gem_init(struct drm_i915_private *dev_priv) | |||
| 5008 | dev_priv->gt.cleanup_engine = intel_engine_cleanup; | 5014 | dev_priv->gt.cleanup_engine = intel_engine_cleanup; |
| 5009 | } | 5015 | } |
| 5010 | 5016 | ||
| 5017 | i915_timelines_init(dev_priv); | ||
| 5018 | |||
| 5011 | ret = i915_gem_init_userptr(dev_priv); | 5019 | ret = i915_gem_init_userptr(dev_priv); |
| 5012 | if (ret) | 5020 | if (ret) |
| 5013 | return ret; | 5021 | return ret; |
| @@ -5130,8 +5138,10 @@ err_unlock: | |||
| 5130 | err_uc_misc: | 5138 | err_uc_misc: |
| 5131 | intel_uc_fini_misc(dev_priv); | 5139 | intel_uc_fini_misc(dev_priv); |
| 5132 | 5140 | ||
| 5133 | if (ret != -EIO) | 5141 | if (ret != -EIO) { |
| 5134 | i915_gem_cleanup_userptr(dev_priv); | 5142 | i915_gem_cleanup_userptr(dev_priv); |
| 5143 | i915_timelines_fini(dev_priv); | ||
| 5144 | } | ||
| 5135 | 5145 | ||
| 5136 | if (ret == -EIO) { | 5146 | if (ret == -EIO) { |
| 5137 | mutex_lock(&dev_priv->drm.struct_mutex); | 5147 | mutex_lock(&dev_priv->drm.struct_mutex); |
| @@ -5182,6 +5192,7 @@ void i915_gem_fini(struct drm_i915_private *dev_priv) | |||
| 5182 | 5192 | ||
| 5183 | intel_uc_fini_misc(dev_priv); | 5193 | intel_uc_fini_misc(dev_priv); |
| 5184 | i915_gem_cleanup_userptr(dev_priv); | 5194 | i915_gem_cleanup_userptr(dev_priv); |
| 5195 | i915_timelines_fini(dev_priv); | ||
| 5185 | 5196 | ||
| 5186 | i915_gem_drain_freed_objects(dev_priv); | 5197 | i915_gem_drain_freed_objects(dev_priv); |
| 5187 | 5198 | ||
| @@ -5284,7 +5295,6 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv) | |||
| 5284 | if (!dev_priv->priorities) | 5295 | if (!dev_priv->priorities) |
| 5285 | goto err_dependencies; | 5296 | goto err_dependencies; |
| 5286 | 5297 | ||
| 5287 | INIT_LIST_HEAD(&dev_priv->gt.timelines); | ||
| 5288 | INIT_LIST_HEAD(&dev_priv->gt.active_rings); | 5298 | INIT_LIST_HEAD(&dev_priv->gt.active_rings); |
| 5289 | INIT_LIST_HEAD(&dev_priv->gt.closed_vma); | 5299 | INIT_LIST_HEAD(&dev_priv->gt.closed_vma); |
| 5290 | 5300 | ||
| @@ -5328,7 +5338,6 @@ void i915_gem_cleanup_early(struct drm_i915_private *dev_priv) | |||
| 5328 | GEM_BUG_ON(!llist_empty(&dev_priv->mm.free_list)); | 5338 | GEM_BUG_ON(!llist_empty(&dev_priv->mm.free_list)); |
| 5329 | GEM_BUG_ON(atomic_read(&dev_priv->mm.free_count)); | 5339 | GEM_BUG_ON(atomic_read(&dev_priv->mm.free_count)); |
| 5330 | WARN_ON(dev_priv->mm.object_count); | 5340 | WARN_ON(dev_priv->mm.object_count); |
| 5331 | WARN_ON(!list_empty(&dev_priv->gt.timelines)); | ||
| 5332 | 5341 | ||
| 5333 | kmem_cache_destroy(dev_priv->priorities); | 5342 | kmem_cache_destroy(dev_priv->priorities); |
| 5334 | kmem_cache_destroy(dev_priv->dependencies); | 5343 | kmem_cache_destroy(dev_priv->dependencies); |
diff --git a/drivers/gpu/drm/i915/i915_reset.c b/drivers/gpu/drm/i915/i915_reset.c index 99bd3bc336b3..d2dca85a543d 100644 --- a/drivers/gpu/drm/i915/i915_reset.c +++ b/drivers/gpu/drm/i915/i915_reset.c | |||
| @@ -854,7 +854,8 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915) | |||
| 854 | * | 854 | * |
| 855 | * No more can be submitted until we reset the wedged bit. | 855 | * No more can be submitted until we reset the wedged bit. |
| 856 | */ | 856 | */ |
| 857 | list_for_each_entry(tl, &i915->gt.timelines, link) { | 857 | mutex_lock(&i915->gt.timelines.mutex); |
| 858 | list_for_each_entry(tl, &i915->gt.timelines.list, link) { | ||
| 858 | struct i915_request *rq; | 859 | struct i915_request *rq; |
| 859 | long timeout; | 860 | long timeout; |
| 860 | 861 | ||
| @@ -876,9 +877,12 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915) | |||
| 876 | timeout = dma_fence_default_wait(&rq->fence, true, | 877 | timeout = dma_fence_default_wait(&rq->fence, true, |
| 877 | MAX_SCHEDULE_TIMEOUT); | 878 | MAX_SCHEDULE_TIMEOUT); |
| 878 | i915_request_put(rq); | 879 | i915_request_put(rq); |
| 879 | if (timeout < 0) | 880 | if (timeout < 0) { |
| 881 | mutex_unlock(&i915->gt.timelines.mutex); | ||
| 880 | goto unlock; | 882 | goto unlock; |
| 883 | } | ||
| 881 | } | 884 | } |
| 885 | mutex_unlock(&i915->gt.timelines.mutex); | ||
| 882 | 886 | ||
| 883 | intel_engines_sanitize(i915, false); | 887 | intel_engines_sanitize(i915, false); |
| 884 | 888 | ||
diff --git a/drivers/gpu/drm/i915/i915_timeline.c b/drivers/gpu/drm/i915/i915_timeline.c index 4667cc08c416..84550f17d3df 100644 --- a/drivers/gpu/drm/i915/i915_timeline.c +++ b/drivers/gpu/drm/i915/i915_timeline.c | |||
| @@ -13,7 +13,7 @@ void i915_timeline_init(struct drm_i915_private *i915, | |||
| 13 | struct i915_timeline *timeline, | 13 | struct i915_timeline *timeline, |
| 14 | const char *name) | 14 | const char *name) |
| 15 | { | 15 | { |
| 16 | lockdep_assert_held(&i915->drm.struct_mutex); | 16 | struct i915_gt_timelines *gt = &i915->gt.timelines; |
| 17 | 17 | ||
| 18 | /* | 18 | /* |
| 19 | * Ideally we want a set of engines on a single leaf as we expect | 19 | * Ideally we want a set of engines on a single leaf as we expect |
| @@ -23,9 +23,12 @@ void i915_timeline_init(struct drm_i915_private *i915, | |||
| 23 | */ | 23 | */ |
| 24 | BUILD_BUG_ON(KSYNCMAP < I915_NUM_ENGINES); | 24 | BUILD_BUG_ON(KSYNCMAP < I915_NUM_ENGINES); |
| 25 | 25 | ||
| 26 | timeline->i915 = i915; | ||
| 26 | timeline->name = name; | 27 | timeline->name = name; |
| 27 | 28 | ||
| 28 | list_add(&timeline->link, &i915->gt.timelines); | 29 | mutex_lock(>->mutex); |
| 30 | list_add(&timeline->link, >->list); | ||
| 31 | mutex_unlock(>->mutex); | ||
| 29 | 32 | ||
| 30 | /* Called during early_init before we know how many engines there are */ | 33 | /* Called during early_init before we know how many engines there are */ |
| 31 | 34 | ||
| @@ -39,6 +42,17 @@ void i915_timeline_init(struct drm_i915_private *i915, | |||
| 39 | i915_syncmap_init(&timeline->sync); | 42 | i915_syncmap_init(&timeline->sync); |
| 40 | } | 43 | } |
| 41 | 44 | ||
| 45 | void i915_timelines_init(struct drm_i915_private *i915) | ||
| 46 | { | ||
| 47 | struct i915_gt_timelines *gt = &i915->gt.timelines; | ||
| 48 | |||
| 49 | mutex_init(>->mutex); | ||
| 50 | INIT_LIST_HEAD(>->list); | ||
| 51 | |||
| 52 | /* via i915_gem_wait_for_idle() */ | ||
| 53 | i915_gem_shrinker_taints_mutex(i915, >->mutex); | ||
| 54 | } | ||
| 55 | |||
| 42 | /** | 56 | /** |
| 43 | * i915_timelines_park - called when the driver idles | 57 | * i915_timelines_park - called when the driver idles |
| 44 | * @i915: the drm_i915_private device | 58 | * @i915: the drm_i915_private device |
| @@ -51,11 +65,11 @@ void i915_timeline_init(struct drm_i915_private *i915, | |||
| 51 | */ | 65 | */ |
| 52 | void i915_timelines_park(struct drm_i915_private *i915) | 66 | void i915_timelines_park(struct drm_i915_private *i915) |
| 53 | { | 67 | { |
| 68 | struct i915_gt_timelines *gt = &i915->gt.timelines; | ||
| 54 | struct i915_timeline *timeline; | 69 | struct i915_timeline *timeline; |
| 55 | 70 | ||
| 56 | lockdep_assert_held(&i915->drm.struct_mutex); | 71 | mutex_lock(>->mutex); |
| 57 | 72 | list_for_each_entry(timeline, >->list, link) { | |
| 58 | list_for_each_entry(timeline, &i915->gt.timelines, link) { | ||
| 59 | /* | 73 | /* |
| 60 | * All known fences are completed so we can scrap | 74 | * All known fences are completed so we can scrap |
| 61 | * the current sync point tracking and start afresh, | 75 | * the current sync point tracking and start afresh, |
| @@ -64,15 +78,20 @@ void i915_timelines_park(struct drm_i915_private *i915) | |||
| 64 | */ | 78 | */ |
| 65 | i915_syncmap_free(&timeline->sync); | 79 | i915_syncmap_free(&timeline->sync); |
| 66 | } | 80 | } |
| 81 | mutex_unlock(>->mutex); | ||
| 67 | } | 82 | } |
| 68 | 83 | ||
| 69 | void i915_timeline_fini(struct i915_timeline *timeline) | 84 | void i915_timeline_fini(struct i915_timeline *timeline) |
| 70 | { | 85 | { |
| 86 | struct i915_gt_timelines *gt = &timeline->i915->gt.timelines; | ||
| 87 | |||
| 71 | GEM_BUG_ON(!list_empty(&timeline->requests)); | 88 | GEM_BUG_ON(!list_empty(&timeline->requests)); |
| 72 | 89 | ||
| 73 | i915_syncmap_free(&timeline->sync); | 90 | i915_syncmap_free(&timeline->sync); |
| 74 | 91 | ||
| 92 | mutex_lock(>->mutex); | ||
| 75 | list_del(&timeline->link); | 93 | list_del(&timeline->link); |
| 94 | mutex_unlock(>->mutex); | ||
| 76 | } | 95 | } |
| 77 | 96 | ||
| 78 | struct i915_timeline * | 97 | struct i915_timeline * |
| @@ -99,6 +118,15 @@ void __i915_timeline_free(struct kref *kref) | |||
| 99 | kfree(timeline); | 118 | kfree(timeline); |
| 100 | } | 119 | } |
| 101 | 120 | ||
| 121 | void i915_timelines_fini(struct drm_i915_private *i915) | ||
| 122 | { | ||
| 123 | struct i915_gt_timelines *gt = &i915->gt.timelines; | ||
| 124 | |||
| 125 | GEM_BUG_ON(!list_empty(>->list)); | ||
| 126 | |||
| 127 | mutex_destroy(>->mutex); | ||
| 128 | } | ||
| 129 | |||
| 102 | #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) | 130 | #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) |
| 103 | #include "selftests/mock_timeline.c" | 131 | #include "selftests/mock_timeline.c" |
| 104 | #include "selftests/i915_timeline.c" | 132 | #include "selftests/i915_timeline.c" |
diff --git a/drivers/gpu/drm/i915/i915_timeline.h b/drivers/gpu/drm/i915/i915_timeline.h index 38c1e15e927a..87ad2dd31c20 100644 --- a/drivers/gpu/drm/i915/i915_timeline.h +++ b/drivers/gpu/drm/i915/i915_timeline.h | |||
| @@ -66,6 +66,7 @@ struct i915_timeline { | |||
| 66 | 66 | ||
| 67 | struct list_head link; | 67 | struct list_head link; |
| 68 | const char *name; | 68 | const char *name; |
| 69 | struct drm_i915_private *i915; | ||
| 69 | 70 | ||
| 70 | struct kref kref; | 71 | struct kref kref; |
| 71 | }; | 72 | }; |
| @@ -134,6 +135,8 @@ static inline bool i915_timeline_sync_is_later(struct i915_timeline *tl, | |||
| 134 | return __i915_timeline_sync_is_later(tl, fence->context, fence->seqno); | 135 | return __i915_timeline_sync_is_later(tl, fence->context, fence->seqno); |
| 135 | } | 136 | } |
| 136 | 137 | ||
| 138 | void i915_timelines_init(struct drm_i915_private *i915); | ||
| 137 | void i915_timelines_park(struct drm_i915_private *i915); | 139 | void i915_timelines_park(struct drm_i915_private *i915); |
| 140 | void i915_timelines_fini(struct drm_i915_private *i915); | ||
| 138 | 141 | ||
| 139 | #endif | 142 | #endif |
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 8ab5a2688a0c..14ae46fda49f 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c | |||
| @@ -68,13 +68,14 @@ static void mock_device_release(struct drm_device *dev) | |||
| 68 | i915_gem_contexts_fini(i915); | 68 | i915_gem_contexts_fini(i915); |
| 69 | mutex_unlock(&i915->drm.struct_mutex); | 69 | mutex_unlock(&i915->drm.struct_mutex); |
| 70 | 70 | ||
| 71 | i915_timelines_fini(i915); | ||
| 72 | |||
| 71 | drain_workqueue(i915->wq); | 73 | drain_workqueue(i915->wq); |
| 72 | i915_gem_drain_freed_objects(i915); | 74 | i915_gem_drain_freed_objects(i915); |
| 73 | 75 | ||
| 74 | mutex_lock(&i915->drm.struct_mutex); | 76 | mutex_lock(&i915->drm.struct_mutex); |
| 75 | mock_fini_ggtt(&i915->ggtt); | 77 | mock_fini_ggtt(&i915->ggtt); |
| 76 | mutex_unlock(&i915->drm.struct_mutex); | 78 | mutex_unlock(&i915->drm.struct_mutex); |
| 77 | WARN_ON(!list_empty(&i915->gt.timelines)); | ||
| 78 | 79 | ||
| 79 | destroy_workqueue(i915->wq); | 80 | destroy_workqueue(i915->wq); |
| 80 | 81 | ||
| @@ -226,7 +227,8 @@ struct drm_i915_private *mock_gem_device(void) | |||
| 226 | if (!i915->priorities) | 227 | if (!i915->priorities) |
| 227 | goto err_dependencies; | 228 | goto err_dependencies; |
| 228 | 229 | ||
| 229 | INIT_LIST_HEAD(&i915->gt.timelines); | 230 | i915_timelines_init(i915); |
| 231 | |||
| 230 | INIT_LIST_HEAD(&i915->gt.active_rings); | 232 | INIT_LIST_HEAD(&i915->gt.active_rings); |
| 231 | INIT_LIST_HEAD(&i915->gt.closed_vma); | 233 | INIT_LIST_HEAD(&i915->gt.closed_vma); |
| 232 | 234 | ||
| @@ -253,6 +255,7 @@ err_context: | |||
| 253 | i915_gem_contexts_fini(i915); | 255 | i915_gem_contexts_fini(i915); |
| 254 | err_unlock: | 256 | err_unlock: |
| 255 | mutex_unlock(&i915->drm.struct_mutex); | 257 | mutex_unlock(&i915->drm.struct_mutex); |
| 258 | i915_timelines_fini(i915); | ||
| 256 | kmem_cache_destroy(i915->priorities); | 259 | kmem_cache_destroy(i915->priorities); |
| 257 | err_dependencies: | 260 | err_dependencies: |
| 258 | kmem_cache_destroy(i915->dependencies); | 261 | kmem_cache_destroy(i915->dependencies); |
diff --git a/drivers/gpu/drm/i915/selftests/mock_timeline.c b/drivers/gpu/drm/i915/selftests/mock_timeline.c index dcf3b16f5a07..cf39ccd9fc05 100644 --- a/drivers/gpu/drm/i915/selftests/mock_timeline.c +++ b/drivers/gpu/drm/i915/selftests/mock_timeline.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | void mock_timeline_init(struct i915_timeline *timeline, u64 context) | 11 | void mock_timeline_init(struct i915_timeline *timeline, u64 context) |
| 12 | { | 12 | { |
| 13 | timeline->i915 = NULL; | ||
| 13 | timeline->fence_context = context; | 14 | timeline->fence_context = context; |
| 14 | 15 | ||
| 15 | spin_lock_init(&timeline->lock); | 16 | spin_lock_init(&timeline->lock); |
| @@ -24,5 +25,5 @@ void mock_timeline_init(struct i915_timeline *timeline, u64 context) | |||
| 24 | 25 | ||
| 25 | void mock_timeline_fini(struct i915_timeline *timeline) | 26 | void mock_timeline_fini(struct i915_timeline *timeline) |
| 26 | { | 27 | { |
| 27 | i915_timeline_fini(timeline); | 28 | i915_syncmap_free(&timeline->sync); |
| 28 | } | 29 | } |
