@@ -50,6 +50,9 @@ static int i915_gem_object_get_page_list(struct drm_gem_object *obj);
50
50
static void i915_gem_object_free_page_list (struct drm_gem_object * obj );
51
51
static int i915_gem_object_wait_rendering (struct drm_gem_object * obj );
52
52
53
+ static void
54
+ i915_gem_cleanup_ringbuffer (struct drm_device * dev );
55
+
53
56
int
54
57
i915_gem_init_ioctl (struct drm_device * dev , void * data ,
55
58
struct drm_file * file_priv )
@@ -582,7 +585,7 @@ i915_add_request(struct drm_device *dev, uint32_t flush_domains)
582
585
was_empty = list_empty (& dev_priv -> mm .request_list );
583
586
list_add_tail (& request -> list , & dev_priv -> mm .request_list );
584
587
585
- if (was_empty )
588
+ if (was_empty && ! dev_priv -> mm . suspended )
586
589
schedule_delayed_work (& dev_priv -> mm .retire_work , HZ );
587
590
return seqno ;
588
591
}
@@ -731,7 +734,8 @@ i915_gem_retire_work_handler(struct work_struct *work)
731
734
732
735
mutex_lock (& dev -> struct_mutex );
733
736
i915_gem_retire_requests (dev );
734
- if (!list_empty (& dev_priv -> mm .request_list ))
737
+ if (!dev_priv -> mm .suspended &&
738
+ !list_empty (& dev_priv -> mm .request_list ))
735
739
schedule_delayed_work (& dev_priv -> mm .retire_work , HZ );
736
740
mutex_unlock (& dev -> struct_mutex );
737
741
}
@@ -2227,14 +2231,24 @@ i915_gem_idle(struct drm_device *dev)
2227
2231
uint32_t seqno , cur_seqno , last_seqno ;
2228
2232
int stuck , ret ;
2229
2233
2230
- if (dev_priv -> mm .suspended )
2234
+ mutex_lock (& dev -> struct_mutex );
2235
+
2236
+ if (dev_priv -> mm .suspended || dev_priv -> ring .ring_obj == NULL ) {
2237
+ mutex_unlock (& dev -> struct_mutex );
2231
2238
return 0 ;
2239
+ }
2232
2240
2233
2241
/* Hack! Don't let anybody do execbuf while we don't control the chip.
2234
2242
* We need to replace this with a semaphore, or something.
2235
2243
*/
2236
2244
dev_priv -> mm .suspended = 1 ;
2237
2245
2246
+ /* Cancel the retire work handler, wait for it to finish if running
2247
+ */
2248
+ mutex_unlock (& dev -> struct_mutex );
2249
+ cancel_delayed_work_sync (& dev_priv -> mm .retire_work );
2250
+ mutex_lock (& dev -> struct_mutex );
2251
+
2238
2252
i915_kernel_lost_context (dev );
2239
2253
2240
2254
/* Flush the GPU along with all non-CPU write domains
@@ -2284,13 +2298,19 @@ i915_gem_idle(struct drm_device *dev)
2284
2298
2285
2299
/* Move all buffers out of the GTT. */
2286
2300
ret = i915_gem_evict_from_list (dev , & dev_priv -> mm .inactive_list );
2287
- if (ret )
2301
+ if (ret ) {
2302
+ mutex_unlock (& dev -> struct_mutex );
2288
2303
return ret ;
2304
+ }
2289
2305
2290
2306
BUG_ON (!list_empty (& dev_priv -> mm .active_list ));
2291
2307
BUG_ON (!list_empty (& dev_priv -> mm .flushing_list ));
2292
2308
BUG_ON (!list_empty (& dev_priv -> mm .inactive_list ));
2293
2309
BUG_ON (!list_empty (& dev_priv -> mm .request_list ));
2310
+
2311
+ i915_gem_cleanup_ringbuffer (dev );
2312
+ mutex_unlock (& dev -> struct_mutex );
2313
+
2294
2314
return 0 ;
2295
2315
}
2296
2316
@@ -2503,34 +2523,20 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
2503
2523
{
2504
2524
int ret ;
2505
2525
2506
- mutex_lock (& dev -> struct_mutex );
2507
2526
ret = i915_gem_idle (dev );
2508
- if (ret == 0 )
2509
- i915_gem_cleanup_ringbuffer (dev );
2510
- mutex_unlock (& dev -> struct_mutex );
2511
-
2512
2527
drm_irq_uninstall (dev );
2513
2528
2514
- return 0 ;
2529
+ return ret ;
2515
2530
}
2516
2531
2517
2532
void
2518
2533
i915_gem_lastclose (struct drm_device * dev )
2519
2534
{
2520
2535
int ret ;
2521
- drm_i915_private_t * dev_priv = dev -> dev_private ;
2522
-
2523
- mutex_lock (& dev -> struct_mutex );
2524
-
2525
- if (dev_priv -> ring .ring_obj != NULL ) {
2526
- ret = i915_gem_idle (dev );
2527
- if (ret )
2528
- DRM_ERROR ("failed to idle hardware: %d\n" , ret );
2529
-
2530
- i915_gem_cleanup_ringbuffer (dev );
2531
- }
2532
2536
2533
- mutex_unlock (& dev -> struct_mutex );
2537
+ ret = i915_gem_idle (dev );
2538
+ if (ret )
2539
+ DRM_ERROR ("failed to idle hardware: %d\n" , ret );
2534
2540
}
2535
2541
2536
2542
void
0 commit comments