aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-09-21 09:51:07 -0400
committerJani Nikula <jani.nikula@intel.com>2016-10-10 09:06:36 -0400
commitec7ce653d9f6eb22404dee468bf63d8fcaff9c42 (patch)
tree1d601fe3cc590961ca93e5fbe2a5d5914418e6da /drivers/gpu
parentac75694125f12f3ce92c30584b49533ed710da8e (diff)
drm/i915: Only shrink the unbound objects during freeze
At the point of creating the hibernation image, the runtime power manage core is disabled - and using the rpm functions triggers a warn. i915_gem_shrink_all() tries to unbind objects, which requires device access and so tries to how an rpm reference triggering a warning: [ 44.235420] ------------[ cut here ]------------ [ 44.235424] WARNING: CPU: 2 PID: 2199 at drivers/gpu/drm/i915/intel_runtime_pm.c:2688 intel_runtime_pm_get_if_in_use+0xe6/0xf0 [ 44.235426] WARN_ON_ONCE(ret < 0) [ 44.235445] Modules linked in: ctr ccm arc4 rt2800usb rt2x00usb rt2800lib rt2x00lib crc_ccitt mac80211 cmac cfg80211 btusb rfcomm bnep btrtl btbcm btintel bluetooth dcdbas x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_codec_realtek crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_codec_generic aesni_intel snd_hda_codec_hdmi aes_x86_64 lrw gf128mul snd_hda_intel glue_helper ablk_helper cryptd snd_hda_codec hid_multitouch joydev snd_hda_core binfmt_misc i2c_hid serio_raw snd_pcm acpi_pad snd_timer snd i2c_designware_platform 8250_dw nls_iso8859_1 i2c_designware_core lpc_ich mfd_core soundcore usbhid hid psmouse ahci libahci [ 44.235447] CPU: 2 PID: 2199 Comm: kworker/u8:8 Not tainted 4.8.0-rc5+ #130 [ 44.235447] Hardware name: Dell Inc. XPS 13 9343/0310JH, BIOS A07 11/11/2015 [ 44.235450] Workqueue: events_unbound async_run_entry_fn [ 44.235453] 0000000000000000 ffff8801b2f7fb98 ffffffff81306c2f ffff8801b2f7fbe8 [ 44.235454] 0000000000000000 ffff8801b2f7fbd8 ffffffff81056c01 00000a801f50ecc0 [ 44.235456] ffff88020ce50000 ffff88020ce59b60 ffffffff81a60b5c ffffffff81414840 [ 44.235456] Call Trace: [ 44.235459] [<ffffffff81306c2f>] dump_stack+0x4d/0x6e [ 44.235461] [<ffffffff81056c01>] __warn+0xd1/0xf0 [ 44.235464] [<ffffffff81414840>] ? i915_pm_suspend_late+0x30/0x30 [ 44.235465] [<ffffffff81056c6f>] warn_slowpath_fmt+0x4f/0x60 [ 44.235468] [<ffffffff814e73ce>] ? pm_runtime_get_if_in_use+0x6e/0xa0 [ 44.235469] [<ffffffff81433526>] intel_runtime_pm_get_if_in_use+0xe6/0xf0 [ 44.235471] [<ffffffff81458a26>] i915_gem_shrink+0x306/0x360 [ 44.235473] [<ffffffff81343fd4>] ? pci_platform_power_transition+0x24/0x90 [ 44.235475] [<ffffffff81414840>] ? i915_pm_suspend_late+0x30/0x30 [ 44.235476] [<ffffffff81458dfb>] i915_gem_shrink_all+0x1b/0x30 [ 44.235478] [<ffffffff814560b3>] i915_gem_freeze_late+0x33/0x90 [ 44.235479] [<ffffffff81414877>] i915_pm_freeze_late+0x37/0x40 [ 44.235481] [<ffffffff814e9b8e>] dpm_run_callback+0x4e/0x130 [ 44.235483] [<ffffffff814ea5db>] __device_suspend_late+0xdb/0x1f0 [ 44.235484] [<ffffffff814ea70f>] async_suspend_late+0x1f/0xa0 [ 44.235486] [<ffffffff81077557>] async_run_entry_fn+0x37/0x150 [ 44.235488] [<ffffffff8106f518>] process_one_work+0x148/0x3f0 [ 44.235490] [<ffffffff8106f8eb>] worker_thread+0x12b/0x490 [ 44.235491] [<ffffffff8106f7c0>] ? process_one_work+0x3f0/0x3f0 [ 44.235492] [<ffffffff81074d09>] kthread+0xc9/0xe0 [ 44.235495] [<ffffffff816e257f>] ret_from_fork+0x1f/0x40 [ 44.235496] [<ffffffff81074c40>] ? kthread_park+0x60/0x60 [ 44.235497] ---[ end trace e438706b97c7f132 ]--- Alternatively, to actually shrink everything we have to do so slightly earlier in the hibernation process. To keep lockdep silent, we need to take struct_mutex for the shrinker even though we know that we are the only user during the freeze. Fixes: 7aab2d534e35 ("drm/i915: Shrink objects prior to hibernation") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20160921135108.29574-2-chris@chris-wilson.co.uk (cherry picked from commit 6a800eabba34945c2986d70114b41d564bad52a8) Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c12
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c17
3 files changed, 28 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 8ae5853ea3c6..bfb2efd8d4d4 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1863,7 +1863,17 @@ static int i915_pm_resume(struct device *kdev)
1863/* freeze: before creating the hibernation_image */ 1863/* freeze: before creating the hibernation_image */
1864static int i915_pm_freeze(struct device *kdev) 1864static int i915_pm_freeze(struct device *kdev)
1865{ 1865{
1866 return i915_pm_suspend(kdev); 1866 int ret;
1867
1868 ret = i915_pm_suspend(kdev);
1869 if (ret)
1870 return ret;
1871
1872 ret = i915_gem_freeze(kdev_to_i915(kdev));
1873 if (ret)
1874 return ret;
1875
1876 return 0;
1867} 1877}
1868 1878
1869static int i915_pm_freeze_late(struct device *kdev) 1879static int i915_pm_freeze_late(struct device *kdev)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4dd307ed4336..e08001abf1f0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3076,6 +3076,7 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
3076void i915_gem_load_init(struct drm_device *dev); 3076void i915_gem_load_init(struct drm_device *dev);
3077void i915_gem_load_cleanup(struct drm_device *dev); 3077void i915_gem_load_cleanup(struct drm_device *dev);
3078void i915_gem_load_init_fences(struct drm_i915_private *dev_priv); 3078void i915_gem_load_init_fences(struct drm_i915_private *dev_priv);
3079int i915_gem_freeze(struct drm_i915_private *dev_priv);
3079int i915_gem_freeze_late(struct drm_i915_private *dev_priv); 3080int i915_gem_freeze_late(struct drm_i915_private *dev_priv);
3080 3081
3081void *i915_gem_object_alloc(struct drm_device *dev); 3082void *i915_gem_object_alloc(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index eb1ca8886bb9..981a106901ae 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4596,6 +4596,19 @@ void i915_gem_load_cleanup(struct drm_device *dev)
4596 rcu_barrier(); 4596 rcu_barrier();
4597} 4597}
4598 4598
4599int i915_gem_freeze(struct drm_i915_private *dev_priv)
4600{
4601 intel_runtime_pm_get(dev_priv);
4602
4603 mutex_lock(&dev_priv->drm.struct_mutex);
4604 i915_gem_shrink_all(dev_priv);
4605 mutex_unlock(&dev_priv->drm.struct_mutex);
4606
4607 intel_runtime_pm_put(dev_priv);
4608
4609 return 0;
4610}
4611
4599int i915_gem_freeze_late(struct drm_i915_private *dev_priv) 4612int i915_gem_freeze_late(struct drm_i915_private *dev_priv)
4600{ 4613{
4601 struct drm_i915_gem_object *obj; 4614 struct drm_i915_gem_object *obj;
@@ -4619,7 +4632,8 @@ int i915_gem_freeze_late(struct drm_i915_private *dev_priv)
4619 * the objects as well. 4632 * the objects as well.
4620 */ 4633 */
4621 4634
4622 i915_gem_shrink_all(dev_priv); 4635 mutex_lock(&dev_priv->drm.struct_mutex);
4636 i915_gem_shrink(dev_priv, -1UL, I915_SHRINK_UNBOUND);
4623 4637
4624 for (p = phases; *p; p++) { 4638 for (p = phases; *p; p++) {
4625 list_for_each_entry(obj, *p, global_list) { 4639 list_for_each_entry(obj, *p, global_list) {
@@ -4627,6 +4641,7 @@ int i915_gem_freeze_late(struct drm_i915_private *dev_priv)
4627 obj->base.write_domain = I915_GEM_DOMAIN_CPU; 4641 obj->base.write_domain = I915_GEM_DOMAIN_CPU;
4628 } 4642 }
4629 } 4643 }
4644 mutex_unlock(&dev_priv->drm.struct_mutex);
4630 4645
4631 return 0; 4646 return 0;
4632} 4647}