aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-10-15 00:41:13 -0400
committerDave Airlie <airlied@linux.ie>2008-10-17 17:10:53 -0400
commit6dbe2772d6af067845bab57be490c302f4490ac7 (patch)
tree5d84600a5ff20a5c5390c02df2400b626ac9b140 /drivers/gpu
parentba1eb1d825fdef40f69871caf8e5842d00efbbc5 (diff)
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 <keithp@keithp.com> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 99a86249bb1b..9ac73dd1b422 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -50,6 +50,9 @@ static int i915_gem_object_get_page_list(struct drm_gem_object *obj);
50static void i915_gem_object_free_page_list(struct drm_gem_object *obj); 50static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
51static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); 51static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
52 52
53static void
54i915_gem_cleanup_ringbuffer(struct drm_device *dev);
55
53int 56int
54i915_gem_init_ioctl(struct drm_device *dev, void *data, 57i915_gem_init_ioctl(struct drm_device *dev, void *data,
55 struct drm_file *file_priv) 58 struct drm_file *file_priv)
@@ -582,7 +585,7 @@ i915_add_request(struct drm_device *dev, uint32_t flush_domains)
582 was_empty = list_empty(&dev_priv->mm.request_list); 585 was_empty = list_empty(&dev_priv->mm.request_list);
583 list_add_tail(&request->list, &dev_priv->mm.request_list); 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 schedule_delayed_work(&dev_priv->mm.retire_work, HZ); 589 schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
587 return seqno; 590 return seqno;
588} 591}
@@ -731,7 +734,8 @@ i915_gem_retire_work_handler(struct work_struct *work)
731 734
732 mutex_lock(&dev->struct_mutex); 735 mutex_lock(&dev->struct_mutex);
733 i915_gem_retire_requests(dev); 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 schedule_delayed_work(&dev_priv->mm.retire_work, HZ); 739 schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
736 mutex_unlock(&dev->struct_mutex); 740 mutex_unlock(&dev->struct_mutex);
737} 741}
@@ -2227,14 +2231,24 @@ i915_gem_idle(struct drm_device *dev)
2227 uint32_t seqno, cur_seqno, last_seqno; 2231 uint32_t seqno, cur_seqno, last_seqno;
2228 int stuck, ret; 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 return 0; 2238 return 0;
2239 }
2232 2240
2233 /* Hack! Don't let anybody do execbuf while we don't control the chip. 2241 /* Hack! Don't let anybody do execbuf while we don't control the chip.
2234 * We need to replace this with a semaphore, or something. 2242 * We need to replace this with a semaphore, or something.
2235 */ 2243 */
2236 dev_priv->mm.suspended = 1; 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 i915_kernel_lost_context(dev); 2252 i915_kernel_lost_context(dev);
2239 2253
2240 /* Flush the GPU along with all non-CPU write domains 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 /* Move all buffers out of the GTT. */ 2299 /* Move all buffers out of the GTT. */
2286 ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list); 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 return ret; 2303 return ret;
2304 }
2289 2305
2290 BUG_ON(!list_empty(&dev_priv->mm.active_list)); 2306 BUG_ON(!list_empty(&dev_priv->mm.active_list));
2291 BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); 2307 BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
2292 BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); 2308 BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
2293 BUG_ON(!list_empty(&dev_priv->mm.request_list)); 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 return 0; 2314 return 0;
2295} 2315}
2296 2316
@@ -2503,34 +2523,20 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
2503{ 2523{
2504 int ret; 2524 int ret;
2505 2525
2506 mutex_lock(&dev->struct_mutex);
2507 ret = i915_gem_idle(dev); 2526 ret = i915_gem_idle(dev);
2508 if (ret == 0)
2509 i915_gem_cleanup_ringbuffer(dev);
2510 mutex_unlock(&dev->struct_mutex);
2511
2512 drm_irq_uninstall(dev); 2527 drm_irq_uninstall(dev);
2513 2528
2514 return 0; 2529 return ret;
2515} 2530}
2516 2531
2517void 2532void
2518i915_gem_lastclose(struct drm_device *dev) 2533i915_gem_lastclose(struct drm_device *dev)
2519{ 2534{
2520 int ret; 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
2536void 2542void