Skip to content

Commit 6dbe277

Browse files
keith-packardairlied
authored andcommitted
i915: Don't run retire work handler while suspended
At leavevt and lastclose time, cancel any pending retire work handler invocation, and keep the retire work handler from requeuing itself if it is currently running. This patch restructures i915_gem_idle to perform all of these tasks instead of having both leavevt and lastclose call a sequence of functions. Signed-off-by: Keith Packard <[email protected]> Signed-off-by: Eric Anholt <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
1 parent ba1eb1d commit 6dbe277

File tree

1 file changed

+28
-22
lines changed

1 file changed

+28
-22
lines changed

drivers/gpu/drm/i915/i915_gem.c

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ static int i915_gem_object_get_page_list(struct drm_gem_object *obj);
5050
static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
5151
static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
5252

53+
static void
54+
i915_gem_cleanup_ringbuffer(struct drm_device *dev);
55+
5356
int
5457
i915_gem_init_ioctl(struct drm_device *dev, void *data,
5558
struct drm_file *file_priv)
@@ -582,7 +585,7 @@ i915_add_request(struct drm_device *dev, uint32_t flush_domains)
582585
was_empty = list_empty(&dev_priv->mm.request_list);
583586
list_add_tail(&request->list, &dev_priv->mm.request_list);
584587

585-
if (was_empty)
588+
if (was_empty && !dev_priv->mm.suspended)
586589
schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
587590
return seqno;
588591
}
@@ -731,7 +734,8 @@ i915_gem_retire_work_handler(struct work_struct *work)
731734

732735
mutex_lock(&dev->struct_mutex);
733736
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))
735739
schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
736740
mutex_unlock(&dev->struct_mutex);
737741
}
@@ -2227,14 +2231,24 @@ i915_gem_idle(struct drm_device *dev)
22272231
uint32_t seqno, cur_seqno, last_seqno;
22282232
int stuck, ret;
22292233

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);
22312238
return 0;
2239+
}
22322240

22332241
/* Hack! Don't let anybody do execbuf while we don't control the chip.
22342242
* We need to replace this with a semaphore, or something.
22352243
*/
22362244
dev_priv->mm.suspended = 1;
22372245

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+
22382252
i915_kernel_lost_context(dev);
22392253

22402254
/* Flush the GPU along with all non-CPU write domains
@@ -2284,13 +2298,19 @@ i915_gem_idle(struct drm_device *dev)
22842298

22852299
/* Move all buffers out of the GTT. */
22862300
ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list);
2287-
if (ret)
2301+
if (ret) {
2302+
mutex_unlock(&dev->struct_mutex);
22882303
return ret;
2304+
}
22892305

22902306
BUG_ON(!list_empty(&dev_priv->mm.active_list));
22912307
BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
22922308
BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
22932309
BUG_ON(!list_empty(&dev_priv->mm.request_list));
2310+
2311+
i915_gem_cleanup_ringbuffer(dev);
2312+
mutex_unlock(&dev->struct_mutex);
2313+
22942314
return 0;
22952315
}
22962316

@@ -2503,34 +2523,20 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
25032523
{
25042524
int ret;
25052525

2506-
mutex_lock(&dev->struct_mutex);
25072526
ret = i915_gem_idle(dev);
2508-
if (ret == 0)
2509-
i915_gem_cleanup_ringbuffer(dev);
2510-
mutex_unlock(&dev->struct_mutex);
2511-
25122527
drm_irq_uninstall(dev);
25132528

2514-
return 0;
2529+
return ret;
25152530
}
25162531

25172532
void
25182533
i915_gem_lastclose(struct drm_device *dev)
25192534
{
25202535
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-
}
25322536

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);
25342540
}
25352541

25362542
void

0 commit comments

Comments
 (0)