]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.4.73/pm-runtime-avoid-false-positive-warnings-from-might_sleep_if.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.73 / pm-runtime-avoid-false-positive-warnings-from-might_sleep_if.patch
1 From foo@baz Thu Jun 15 11:39:37 CEST 2017
2 From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
3 Date: Tue, 23 May 2017 21:53:54 -0400
4 Subject: PM / runtime: Avoid false-positive warnings from might_sleep_if()
5
6 From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
7
8
9 [ Upstream commit a9306a63631493afc75893a4ac405d4e1cbae6aa ]
10
11 The might_sleep_if() assertions in __pm_runtime_idle(),
12 __pm_runtime_suspend() and __pm_runtime_resume() may generate
13 false-positive warnings in some situations. For example, that
14 happens if a nested pm_runtime_get_sync()/pm_runtime_put() pair
15 is executed with disabled interrupts within an outer
16 pm_runtime_get_sync()/pm_runtime_put() section for the same device.
17 [Generally, pm_runtime_get_sync() may sleep, so it should not be
18 called with disabled interrupts, but in this particular case the
19 previous pm_runtime_get_sync() guarantees that the device will not
20 be suspended, so the inner pm_runtime_get_sync() will return
21 immediately after incrementing the device's usage counter.]
22
23 That started to happen in the i915 driver in 4.10-rc, leading to
24 the following splat:
25
26 BUG: sleeping function called from invalid context at drivers/base/power/runtime.c:1032
27 in_atomic(): 1, irqs_disabled(): 0, pid: 1500, name: Xorg
28 1 lock held by Xorg/1500:
29 #0: (&dev->struct_mutex){+.+.+.}, at:
30 [<ffffffffa0680c13>] i915_mutex_lock_interruptible+0x43/0x140 [i915]
31 CPU: 0 PID: 1500 Comm: Xorg Not tainted
32 Call Trace:
33 dump_stack+0x85/0xc2
34 ___might_sleep+0x196/0x260
35 __might_sleep+0x53/0xb0
36 __pm_runtime_resume+0x7a/0x90
37 intel_runtime_pm_get+0x25/0x90 [i915]
38 aliasing_gtt_bind_vma+0xaa/0xf0 [i915]
39 i915_vma_bind+0xaf/0x1e0 [i915]
40 i915_gem_execbuffer_relocate_entry+0x513/0x6f0 [i915]
41 i915_gem_execbuffer_relocate_vma.isra.34+0x188/0x250 [i915]
42 ? trace_hardirqs_on+0xd/0x10
43 ? i915_gem_execbuffer_reserve_vma.isra.31+0x152/0x1f0 [i915]
44 ? i915_gem_execbuffer_reserve.isra.32+0x372/0x3a0 [i915]
45 i915_gem_do_execbuffer.isra.38+0xa70/0x1a40 [i915]
46 ? __might_fault+0x4e/0xb0
47 i915_gem_execbuffer2+0xc5/0x260 [i915]
48 ? __might_fault+0x4e/0xb0
49 drm_ioctl+0x206/0x450 [drm]
50 ? i915_gem_execbuffer+0x340/0x340 [i915]
51 ? __fget+0x5/0x200
52 do_vfs_ioctl+0x91/0x6f0
53 ? __fget+0x111/0x200
54 ? __fget+0x5/0x200
55 SyS_ioctl+0x79/0x90
56 entry_SYSCALL_64_fastpath+0x23/0xc6
57
58 even though the code triggering it is correct.
59
60 Unfortunately, the might_sleep_if() assertions in question are
61 too coarse-grained to cover such cases correctly, so make them
62 a bit less sensitive in order to avoid the false-positives.
63
64 Reported-and-tested-by: Sedat Dilek <sedat.dilek@gmail.com>
65 Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
66 Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
67 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
68 ---
69 drivers/base/power/runtime.c | 11 ++++++-----
70 1 file changed, 6 insertions(+), 5 deletions(-)
71
72 --- a/drivers/base/power/runtime.c
73 +++ b/drivers/base/power/runtime.c
74 @@ -889,13 +889,13 @@ int __pm_runtime_idle(struct device *dev
75 unsigned long flags;
76 int retval;
77
78 - might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
79 -
80 if (rpmflags & RPM_GET_PUT) {
81 if (!atomic_dec_and_test(&dev->power.usage_count))
82 return 0;
83 }
84
85 + might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
86 +
87 spin_lock_irqsave(&dev->power.lock, flags);
88 retval = rpm_idle(dev, rpmflags);
89 spin_unlock_irqrestore(&dev->power.lock, flags);
90 @@ -921,13 +921,13 @@ int __pm_runtime_suspend(struct device *
91 unsigned long flags;
92 int retval;
93
94 - might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
95 -
96 if (rpmflags & RPM_GET_PUT) {
97 if (!atomic_dec_and_test(&dev->power.usage_count))
98 return 0;
99 }
100
101 + might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
102 +
103 spin_lock_irqsave(&dev->power.lock, flags);
104 retval = rpm_suspend(dev, rpmflags);
105 spin_unlock_irqrestore(&dev->power.lock, flags);
106 @@ -952,7 +952,8 @@ int __pm_runtime_resume(struct device *d
107 unsigned long flags;
108 int retval;
109
110 - might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
111 + might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe &&
112 + dev->power.runtime_status != RPM_ACTIVE);
113
114 if (rpmflags & RPM_GET_PUT)
115 atomic_inc(&dev->power.usage_count);