diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-09-21 09:51:07 -0400 |
---|---|---|
committer | Jani Nikula <jani.nikula@intel.com> | 2016-10-10 09:06:36 -0400 |
commit | ec7ce653d9f6eb22404dee468bf63d8fcaff9c42 (patch) | |
tree | 1d601fe3cc590961ca93e5fbe2a5d5914418e6da /drivers/gpu | |
parent | ac75694125f12f3ce92c30584b49533ed710da8e (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.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 17 |
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 */ |
1864 | static int i915_pm_freeze(struct device *kdev) | 1864 | static 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 | ||
1869 | static int i915_pm_freeze_late(struct device *kdev) | 1879 | static 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, | |||
3076 | void i915_gem_load_init(struct drm_device *dev); | 3076 | void i915_gem_load_init(struct drm_device *dev); |
3077 | void i915_gem_load_cleanup(struct drm_device *dev); | 3077 | void i915_gem_load_cleanup(struct drm_device *dev); |
3078 | void i915_gem_load_init_fences(struct drm_i915_private *dev_priv); | 3078 | void i915_gem_load_init_fences(struct drm_i915_private *dev_priv); |
3079 | int i915_gem_freeze(struct drm_i915_private *dev_priv); | ||
3079 | int i915_gem_freeze_late(struct drm_i915_private *dev_priv); | 3080 | int i915_gem_freeze_late(struct drm_i915_private *dev_priv); |
3080 | 3081 | ||
3081 | void *i915_gem_object_alloc(struct drm_device *dev); | 3082 | void *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 | ||
4599 | int 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 | |||
4599 | int i915_gem_freeze_late(struct drm_i915_private *dev_priv) | 4612 | int 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 | } |