summaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-02-03 18:44:36 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-02-03 18:44:36 -0500
commita9306a63631493afc75893a4ac405d4e1cbae6aa (patch)
tree84ad2b2df537b05b0142591c5d016ff0c7262b6e /drivers/base
parent566cf877a1fcb6d6dc0126b076aad062054c2637 (diff)
PM / runtime: Avoid false-positive warnings from might_sleep_if()
The might_sleep_if() assertions in __pm_runtime_idle(), __pm_runtime_suspend() and __pm_runtime_resume() may generate false-positive warnings in some situations. For example, that happens if a nested pm_runtime_get_sync()/pm_runtime_put() pair is executed with disabled interrupts within an outer pm_runtime_get_sync()/pm_runtime_put() section for the same device. [Generally, pm_runtime_get_sync() may sleep, so it should not be called with disabled interrupts, but in this particular case the previous pm_runtime_get_sync() guarantees that the device will not be suspended, so the inner pm_runtime_get_sync() will return immediately after incrementing the device's usage counter.] That started to happen in the i915 driver in 4.10-rc, leading to the following splat: BUG: sleeping function called from invalid context at drivers/base/power/runtime.c:1032 in_atomic(): 1, irqs_disabled(): 0, pid: 1500, name: Xorg 1 lock held by Xorg/1500: #0: (&dev->struct_mutex){+.+.+.}, at: [<ffffffffa0680c13>] i915_mutex_lock_interruptible+0x43/0x140 [i915] CPU: 0 PID: 1500 Comm: Xorg Not tainted Call Trace: dump_stack+0x85/0xc2 ___might_sleep+0x196/0x260 __might_sleep+0x53/0xb0 __pm_runtime_resume+0x7a/0x90 intel_runtime_pm_get+0x25/0x90 [i915] aliasing_gtt_bind_vma+0xaa/0xf0 [i915] i915_vma_bind+0xaf/0x1e0 [i915] i915_gem_execbuffer_relocate_entry+0x513/0x6f0 [i915] i915_gem_execbuffer_relocate_vma.isra.34+0x188/0x250 [i915] ? trace_hardirqs_on+0xd/0x10 ? i915_gem_execbuffer_reserve_vma.isra.31+0x152/0x1f0 [i915] ? i915_gem_execbuffer_reserve.isra.32+0x372/0x3a0 [i915] i915_gem_do_execbuffer.isra.38+0xa70/0x1a40 [i915] ? __might_fault+0x4e/0xb0 i915_gem_execbuffer2+0xc5/0x260 [i915] ? __might_fault+0x4e/0xb0 drm_ioctl+0x206/0x450 [drm] ? i915_gem_execbuffer+0x340/0x340 [i915] ? __fget+0x5/0x200 do_vfs_ioctl+0x91/0x6f0 ? __fget+0x111/0x200 ? __fget+0x5/0x200 SyS_ioctl+0x79/0x90 entry_SYSCALL_64_fastpath+0x23/0xc6 even though the code triggering it is correct. Unfortunately, the might_sleep_if() assertions in question are too coarse-grained to cover such cases correctly, so make them a bit less sensitive in order to avoid the false-positives. Reported-and-tested-by: Sedat Dilek <sedat.dilek@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/power/runtime.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 872eac4cb1df..a14fac6a01d3 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -966,13 +966,13 @@ int __pm_runtime_idle(struct device *dev, int rpmflags)
966 unsigned long flags; 966 unsigned long flags;
967 int retval; 967 int retval;
968 968
969 might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
970
971 if (rpmflags & RPM_GET_PUT) { 969 if (rpmflags & RPM_GET_PUT) {
972 if (!atomic_dec_and_test(&dev->power.usage_count)) 970 if (!atomic_dec_and_test(&dev->power.usage_count))
973 return 0; 971 return 0;
974 } 972 }
975 973
974 might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
975
976 spin_lock_irqsave(&dev->power.lock, flags); 976 spin_lock_irqsave(&dev->power.lock, flags);
977 retval = rpm_idle(dev, rpmflags); 977 retval = rpm_idle(dev, rpmflags);
978 spin_unlock_irqrestore(&dev->power.lock, flags); 978 spin_unlock_irqrestore(&dev->power.lock, flags);
@@ -998,13 +998,13 @@ int __pm_runtime_suspend(struct device *dev, int rpmflags)
998 unsigned long flags; 998 unsigned long flags;
999 int retval; 999 int retval;
1000 1000
1001 might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
1002
1003 if (rpmflags & RPM_GET_PUT) { 1001 if (rpmflags & RPM_GET_PUT) {
1004 if (!atomic_dec_and_test(&dev->power.usage_count)) 1002 if (!atomic_dec_and_test(&dev->power.usage_count))
1005 return 0; 1003 return 0;
1006 } 1004 }
1007 1005
1006 might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
1007
1008 spin_lock_irqsave(&dev->power.lock, flags); 1008 spin_lock_irqsave(&dev->power.lock, flags);
1009 retval = rpm_suspend(dev, rpmflags); 1009 retval = rpm_suspend(dev, rpmflags);
1010 spin_unlock_irqrestore(&dev->power.lock, flags); 1010 spin_unlock_irqrestore(&dev->power.lock, flags);
@@ -1029,7 +1029,8 @@ int __pm_runtime_resume(struct device *dev, int rpmflags)
1029 unsigned long flags; 1029 unsigned long flags;
1030 int retval; 1030 int retval;
1031 1031
1032 might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); 1032 might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe &&
1033 dev->power.runtime_status != RPM_ACTIVE);
1033 1034
1034 if (rpmflags & RPM_GET_PUT) 1035 if (rpmflags & RPM_GET_PUT)
1035 atomic_inc(&dev->power.usage_count); 1036 atomic_inc(&dev->power.usage_count);