@@ -2809,6 +2809,26 @@ i915_gem_get_seqno(struct drm_i915_private *dev_priv, u32 *seqno)
2809
2809
return 0 ;
2810
2810
}
2811
2811
2812
+ static void i915_gem_mark_busy (const struct intel_engine_cs * engine )
2813
+ {
2814
+ struct drm_i915_private * dev_priv = engine -> i915 ;
2815
+
2816
+ dev_priv -> gt .active_engines |= intel_engine_flag (engine );
2817
+ if (dev_priv -> gt .awake )
2818
+ return ;
2819
+
2820
+ intel_runtime_pm_get_noresume (dev_priv );
2821
+ dev_priv -> gt .awake = true;
2822
+
2823
+ i915_update_gfx_val (dev_priv );
2824
+ if (INTEL_GEN (dev_priv ) >= 6 )
2825
+ gen6_rps_busy (dev_priv );
2826
+
2827
+ queue_delayed_work (dev_priv -> wq ,
2828
+ & dev_priv -> gt .retire_work ,
2829
+ round_jiffies_up_relative (HZ ));
2830
+ }
2831
+
2812
2832
/*
2813
2833
* NB: This function is not allowed to fail. Doing so would mean the the
2814
2834
* request is not being tracked for completion but the work itself is
@@ -2819,7 +2839,6 @@ void __i915_add_request(struct drm_i915_gem_request *request,
2819
2839
bool flush_caches )
2820
2840
{
2821
2841
struct intel_engine_cs * engine ;
2822
- struct drm_i915_private * dev_priv ;
2823
2842
struct intel_ringbuffer * ringbuf ;
2824
2843
u32 request_start ;
2825
2844
u32 reserved_tail ;
@@ -2829,7 +2848,6 @@ void __i915_add_request(struct drm_i915_gem_request *request,
2829
2848
return ;
2830
2849
2831
2850
engine = request -> engine ;
2832
- dev_priv = request -> i915 ;
2833
2851
ringbuf = request -> ringbuf ;
2834
2852
2835
2853
/*
@@ -2895,12 +2913,6 @@ void __i915_add_request(struct drm_i915_gem_request *request,
2895
2913
}
2896
2914
/* Not allowed to fail! */
2897
2915
WARN (ret , "emit|add_request failed: %d!\n" , ret );
2898
-
2899
- queue_delayed_work (dev_priv -> wq ,
2900
- & dev_priv -> mm .retire_work ,
2901
- round_jiffies_up_relative (HZ ));
2902
- intel_mark_busy (dev_priv );
2903
-
2904
2916
/* Sanity check that the reserved size was large enough. */
2905
2917
ret = intel_ring_get_tail (ringbuf ) - request_start ;
2906
2918
if (ret < 0 )
@@ -2909,6 +2921,8 @@ void __i915_add_request(struct drm_i915_gem_request *request,
2909
2921
"Not enough space reserved (%d bytes) "
2910
2922
"for adding the request (%d bytes)\n" ,
2911
2923
reserved_tail , ret );
2924
+
2925
+ i915_gem_mark_busy (engine );
2912
2926
}
2913
2927
2914
2928
static bool i915_context_is_banned (struct drm_i915_private * dev_priv ,
@@ -3223,72 +3237,105 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *engine)
3223
3237
WARN_ON (i915_verify_lists (engine -> dev ));
3224
3238
}
3225
3239
3226
- bool
3227
- i915_gem_retire_requests (struct drm_i915_private * dev_priv )
3240
+ void i915_gem_retire_requests (struct drm_i915_private * dev_priv )
3228
3241
{
3229
3242
struct intel_engine_cs * engine ;
3230
- bool idle = true;
3243
+
3244
+ lockdep_assert_held (& dev_priv -> dev -> struct_mutex );
3245
+
3246
+ if (dev_priv -> gt .active_engines == 0 )
3247
+ return ;
3248
+
3249
+ GEM_BUG_ON (!dev_priv -> gt .awake );
3231
3250
3232
3251
for_each_engine (engine , dev_priv ) {
3233
3252
i915_gem_retire_requests_ring (engine );
3234
- idle &= list_empty (& engine -> request_list );
3235
- if (i915 .enable_execlists ) {
3236
- spin_lock_bh (& engine -> execlist_lock );
3237
- idle &= list_empty (& engine -> execlist_queue );
3238
- spin_unlock_bh (& engine -> execlist_lock );
3239
- }
3253
+ if (list_empty (& engine -> request_list ))
3254
+ dev_priv -> gt .active_engines &= ~intel_engine_flag (engine );
3240
3255
}
3241
3256
3242
- if (idle )
3257
+ if (dev_priv -> gt . active_engines == 0 )
3243
3258
mod_delayed_work (dev_priv -> wq ,
3244
- & dev_priv -> mm .idle_work ,
3259
+ & dev_priv -> gt .idle_work ,
3245
3260
msecs_to_jiffies (100 ));
3246
-
3247
- return idle ;
3248
3261
}
3249
3262
3250
3263
static void
3251
3264
i915_gem_retire_work_handler (struct work_struct * work )
3252
3265
{
3253
3266
struct drm_i915_private * dev_priv =
3254
- container_of (work , typeof (* dev_priv ), mm .retire_work .work );
3267
+ container_of (work , typeof (* dev_priv ), gt .retire_work .work );
3255
3268
struct drm_device * dev = dev_priv -> dev ;
3256
- bool idle ;
3257
3269
3258
3270
/* Come back later if the device is busy... */
3259
- idle = false;
3260
3271
if (mutex_trylock (& dev -> struct_mutex )) {
3261
- idle = i915_gem_retire_requests (dev_priv );
3272
+ i915_gem_retire_requests (dev_priv );
3262
3273
mutex_unlock (& dev -> struct_mutex );
3263
3274
}
3264
- if (!idle )
3265
- queue_delayed_work (dev_priv -> wq , & dev_priv -> mm .retire_work ,
3275
+
3276
+ /* Keep the retire handler running until we are finally idle.
3277
+ * We do not need to do this test under locking as in the worst-case
3278
+ * we queue the retire worker once too often.
3279
+ */
3280
+ if (lockless_dereference (dev_priv -> gt .awake ))
3281
+ queue_delayed_work (dev_priv -> wq ,
3282
+ & dev_priv -> gt .retire_work ,
3266
3283
round_jiffies_up_relative (HZ ));
3267
3284
}
3268
3285
3269
3286
static void
3270
3287
i915_gem_idle_work_handler (struct work_struct * work )
3271
3288
{
3272
3289
struct drm_i915_private * dev_priv =
3273
- container_of (work , typeof (* dev_priv ), mm .idle_work .work );
3290
+ container_of (work , typeof (* dev_priv ), gt .idle_work .work );
3274
3291
struct drm_device * dev = dev_priv -> dev ;
3275
3292
struct intel_engine_cs * engine ;
3293
+ unsigned int stuck_engines ;
3294
+ bool rearm_hangcheck ;
3295
+
3296
+ if (!READ_ONCE (dev_priv -> gt .awake ))
3297
+ return ;
3298
+
3299
+ if (READ_ONCE (dev_priv -> gt .active_engines ))
3300
+ return ;
3301
+
3302
+ rearm_hangcheck =
3303
+ cancel_delayed_work_sync (& dev_priv -> gpu_error .hangcheck_work );
3304
+
3305
+ if (!mutex_trylock (& dev -> struct_mutex )) {
3306
+ /* Currently busy, come back later */
3307
+ mod_delayed_work (dev_priv -> wq ,
3308
+ & dev_priv -> gt .idle_work ,
3309
+ msecs_to_jiffies (50 ));
3310
+ goto out_rearm ;
3311
+ }
3312
+
3313
+ if (dev_priv -> gt .active_engines )
3314
+ goto out_unlock ;
3276
3315
3277
3316
for_each_engine (engine , dev_priv )
3278
- if (!list_empty (& engine -> request_list ))
3279
- return ;
3317
+ i915_gem_batch_pool_fini (& engine -> batch_pool );
3280
3318
3281
- /* we probably should sync with hangcheck here, using cancel_work_sync.
3282
- * Also locking seems to be fubar here, engine->request_list is protected
3283
- * by dev->struct_mutex. */
3319
+ GEM_BUG_ON (! dev_priv -> gt . awake );
3320
+ dev_priv -> gt . awake = false;
3321
+ rearm_hangcheck = false;
3284
3322
3285
- intel_mark_idle (dev_priv );
3323
+ stuck_engines = intel_kick_waiters (dev_priv );
3324
+ if (unlikely (stuck_engines )) {
3325
+ DRM_DEBUG_DRIVER ("kicked stuck waiters...missed irq\n" );
3326
+ dev_priv -> gpu_error .missed_irq_rings |= stuck_engines ;
3327
+ }
3286
3328
3287
- if (mutex_trylock (& dev -> struct_mutex )) {
3288
- for_each_engine (engine , dev_priv )
3289
- i915_gem_batch_pool_fini (& engine -> batch_pool );
3329
+ if (INTEL_GEN (dev_priv ) >= 6 )
3330
+ gen6_rps_idle (dev_priv );
3331
+ intel_runtime_pm_put (dev_priv );
3332
+ out_unlock :
3333
+ mutex_unlock (& dev -> struct_mutex );
3290
3334
3291
- mutex_unlock (& dev -> struct_mutex );
3335
+ out_rearm :
3336
+ if (rearm_hangcheck ) {
3337
+ GEM_BUG_ON (!dev_priv -> gt .awake );
3338
+ i915_queue_hangcheck (dev_priv );
3292
3339
}
3293
3340
}
3294
3341
@@ -4421,7 +4468,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
4421
4468
4422
4469
ret = __i915_wait_request (target , true, NULL , NULL );
4423
4470
if (ret == 0 )
4424
- queue_delayed_work (dev_priv -> wq , & dev_priv -> mm .retire_work , 0 );
4471
+ queue_delayed_work (dev_priv -> wq , & dev_priv -> gt .retire_work , 0 );
4425
4472
4426
4473
i915_gem_request_unreference (target );
4427
4474
@@ -4939,13 +4986,13 @@ i915_gem_suspend(struct drm_device *dev)
4939
4986
mutex_unlock (& dev -> struct_mutex );
4940
4987
4941
4988
cancel_delayed_work_sync (& dev_priv -> gpu_error .hangcheck_work );
4942
- cancel_delayed_work_sync (& dev_priv -> mm .retire_work );
4943
- flush_delayed_work (& dev_priv -> mm .idle_work );
4989
+ cancel_delayed_work_sync (& dev_priv -> gt .retire_work );
4990
+ flush_delayed_work (& dev_priv -> gt .idle_work );
4944
4991
4945
4992
/* Assert that we sucessfully flushed all the work and
4946
4993
* reset the GPU back to its idle, low power state.
4947
4994
*/
4948
- WARN_ON (dev_priv -> mm . busy );
4995
+ WARN_ON (dev_priv -> gt . awake );
4949
4996
4950
4997
return 0 ;
4951
4998
@@ -5247,9 +5294,9 @@ i915_gem_load_init(struct drm_device *dev)
5247
5294
init_engine_lists (& dev_priv -> engine [i ]);
5248
5295
for (i = 0 ; i < I915_MAX_NUM_FENCES ; i ++ )
5249
5296
INIT_LIST_HEAD (& dev_priv -> fence_regs [i ].lru_list );
5250
- INIT_DELAYED_WORK (& dev_priv -> mm .retire_work ,
5297
+ INIT_DELAYED_WORK (& dev_priv -> gt .retire_work ,
5251
5298
i915_gem_retire_work_handler );
5252
- INIT_DELAYED_WORK (& dev_priv -> mm .idle_work ,
5299
+ INIT_DELAYED_WORK (& dev_priv -> gt .idle_work ,
5253
5300
i915_gem_idle_work_handler );
5254
5301
init_waitqueue_head (& dev_priv -> gpu_error .wait_queue );
5255
5302
init_waitqueue_head (& dev_priv -> gpu_error .reset_queue );
0 commit comments