Commit 4955070974ecfa0b1ae9d2506f529460fd3a4b0b
Committed by
Rafael J. Wysocki
1 parent
5834ec3aea
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
PM / wakeup: Use irqsave/irqrestore for events_lock
Jon Medhurst (Tixy) recently noticed a problem with the events_lock usage. One of the Android patches that uses wakeup_sources calls wakeup_source_add() with irqs disabled. However, the event_lock usage in wakeup_source_add() uses spin_lock_irq()/spin_unlock_irq(), which reenables interrupts. This results in lockdep warnings. The fix is to use spin_lock_irqsave()/spin_lock_irqrestore() instead for the events_lock. References: https://bugs.launchpad.net/linaro-landing-team-arm/+bug/1037565 Reported-and-debugged-by: Jon Medhurst (Tixy) <tixy@linaro.org> Signed-off-by: John Stultz <john.stultz@linaro.org> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Showing 1 changed file with 11 additions and 6 deletions Side-by-side Diff
drivers/base/power/wakeup.c
... | ... | @@ -127,6 +127,8 @@ |
127 | 127 | */ |
128 | 128 | void wakeup_source_add(struct wakeup_source *ws) |
129 | 129 | { |
130 | + unsigned long flags; | |
131 | + | |
130 | 132 | if (WARN_ON(!ws)) |
131 | 133 | return; |
132 | 134 | |
133 | 135 | |
... | ... | @@ -135,9 +137,9 @@ |
135 | 137 | ws->active = false; |
136 | 138 | ws->last_time = ktime_get(); |
137 | 139 | |
138 | - spin_lock_irq(&events_lock); | |
140 | + spin_lock_irqsave(&events_lock, flags); | |
139 | 141 | list_add_rcu(&ws->entry, &wakeup_sources); |
140 | - spin_unlock_irq(&events_lock); | |
142 | + spin_unlock_irqrestore(&events_lock, flags); | |
141 | 143 | } |
142 | 144 | EXPORT_SYMBOL_GPL(wakeup_source_add); |
143 | 145 | |
144 | 146 | |
145 | 147 | |
... | ... | @@ -147,12 +149,14 @@ |
147 | 149 | */ |
148 | 150 | void wakeup_source_remove(struct wakeup_source *ws) |
149 | 151 | { |
152 | + unsigned long flags; | |
153 | + | |
150 | 154 | if (WARN_ON(!ws)) |
151 | 155 | return; |
152 | 156 | |
153 | - spin_lock_irq(&events_lock); | |
157 | + spin_lock_irqsave(&events_lock, flags); | |
154 | 158 | list_del_rcu(&ws->entry); |
155 | - spin_unlock_irq(&events_lock); | |
159 | + spin_unlock_irqrestore(&events_lock, flags); | |
156 | 160 | synchronize_rcu(); |
157 | 161 | } |
158 | 162 | EXPORT_SYMBOL_GPL(wakeup_source_remove); |
159 | 163 | |
160 | 164 | |
... | ... | @@ -752,15 +756,16 @@ |
752 | 756 | bool pm_save_wakeup_count(unsigned int count) |
753 | 757 | { |
754 | 758 | unsigned int cnt, inpr; |
759 | + unsigned long flags; | |
755 | 760 | |
756 | 761 | events_check_enabled = false; |
757 | - spin_lock_irq(&events_lock); | |
762 | + spin_lock_irqsave(&events_lock, flags); | |
758 | 763 | split_counters(&cnt, &inpr); |
759 | 764 | if (cnt == count && inpr == 0) { |
760 | 765 | saved_count = count; |
761 | 766 | events_check_enabled = true; |
762 | 767 | } |
763 | - spin_unlock_irq(&events_lock); | |
768 | + spin_unlock_irqrestore(&events_lock, flags); | |
764 | 769 | return events_check_enabled; |
765 | 770 | } |
766 | 771 |