diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2017-07-11 17:41:52 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-07-12 04:14:42 -0400 |
commit | 19d39a3810e7032f311ef83effdac40339b9d022 (patch) | |
tree | 5a7ee202d0b6eb8e8f34df2f9fb5536007acb4c1 /kernel/irq/manage.c | |
parent | c5c601c4295f89368f4a304cb3ae4aebdf80db22 (diff) |
genirq: Keep chip buslock across irq_request/release_resources()
Moving the irq_request/release_resources() callbacks out of the spinlocked,
irq disabled and bus locked region, unearthed an interesting abuse of the
irq_bus_lock/irq_bus_sync_unlock() callbacks.
The OMAP GPIO driver does merily power management inside of them. The
irq_request_resources() callback of this GPIO irqchip calls a function
which reads a GPIO register. That read aborts now because the clock of the
GPIO block is not magically enabled via the irq_bus_lock() callback.
Move the callbacks under the bus lock again to prevent this. In the
free_irq() path this requires to drop the bus_lock before calling
synchronize_irq() and reaquiring it before calling the
irq_release_resources() callback.
The bus lock can't be held because:
1) The data which has been changed between bus_lock/un_lock is cached in
the irq chip driver private data and needs to go out to the irq chip
via the slow bus (usually SPI or I2C) before calling
synchronize_irq().
That's the reason why this bus_lock/unlock magic exists in the first
place, as you cannot do SPI/I2C transactions while holding desc->lock
with interrupts disabled.
2) synchronize_irq() will actually deadlock, if there is a handler on
flight. These chips use threaded handlers for obvious reasons, as
they allow to do SPI/I2C communication. When the threaded handler
returns then bus_lock needs to be taken in irq_finalize_oneshot() as
we need to talk to the actual irq chip once more. After that the
threaded handler is marked done, which makes synchronize_irq() return.
So if we hold bus_lock accross the synchronize_irq() call, the
handler cannot mark itself done because it blocks on the bus
lock. That in turn makes synchronize_irq() wait forever on the
threaded handler to complete....
Add the missing unlock of desc->request_mutex in the error path of
__free_irq() and add a bunch of comments to explain the locking and
protection rules.
Fixes: 46e48e257360 ("genirq: Move irq resource handling out of spinlocked region")
Reported-and-tested-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Reported-and-tested-by: Tony Lindgren <tony@atomide.com>
Reported-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Not-longer-ranted-at-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Grygorii Strashko <grygorii.strashko@ti.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r-- | kernel/irq/manage.c | 63 |
1 files changed, 53 insertions, 10 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 5624b2dd6b58..1d1a5b945ab4 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -1090,6 +1090,16 @@ setup_irq_thread(struct irqaction *new, unsigned int irq, bool secondary) | |||
1090 | /* | 1090 | /* |
1091 | * Internal function to register an irqaction - typically used to | 1091 | * Internal function to register an irqaction - typically used to |
1092 | * allocate special interrupts that are part of the architecture. | 1092 | * allocate special interrupts that are part of the architecture. |
1093 | * | ||
1094 | * Locking rules: | ||
1095 | * | ||
1096 | * desc->request_mutex Provides serialization against a concurrent free_irq() | ||
1097 | * chip_bus_lock Provides serialization for slow bus operations | ||
1098 | * desc->lock Provides serialization against hard interrupts | ||
1099 | * | ||
1100 | * chip_bus_lock and desc->lock are sufficient for all other management and | ||
1101 | * interrupt related functions. desc->request_mutex solely serializes | ||
1102 | * request/free_irq(). | ||
1093 | */ | 1103 | */ |
1094 | static int | 1104 | static int |
1095 | __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | 1105 | __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) |
@@ -1167,20 +1177,35 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
1167 | if (desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE) | 1177 | if (desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE) |
1168 | new->flags &= ~IRQF_ONESHOT; | 1178 | new->flags &= ~IRQF_ONESHOT; |
1169 | 1179 | ||
1180 | /* | ||
1181 | * Protects against a concurrent __free_irq() call which might wait | ||
1182 | * for synchronize_irq() to complete without holding the optional | ||
1183 | * chip bus lock and desc->lock. | ||
1184 | */ | ||
1170 | mutex_lock(&desc->request_mutex); | 1185 | mutex_lock(&desc->request_mutex); |
1186 | |||
1187 | /* | ||
1188 | * Acquire bus lock as the irq_request_resources() callback below | ||
1189 | * might rely on the serialization or the magic power management | ||
1190 | * functions which are abusing the irq_bus_lock() callback, | ||
1191 | */ | ||
1192 | chip_bus_lock(desc); | ||
1193 | |||
1194 | /* First installed action requests resources. */ | ||
1171 | if (!desc->action) { | 1195 | if (!desc->action) { |
1172 | ret = irq_request_resources(desc); | 1196 | ret = irq_request_resources(desc); |
1173 | if (ret) { | 1197 | if (ret) { |
1174 | pr_err("Failed to request resources for %s (irq %d) on irqchip %s\n", | 1198 | pr_err("Failed to request resources for %s (irq %d) on irqchip %s\n", |
1175 | new->name, irq, desc->irq_data.chip->name); | 1199 | new->name, irq, desc->irq_data.chip->name); |
1176 | goto out_mutex; | 1200 | goto out_bus_unlock; |
1177 | } | 1201 | } |
1178 | } | 1202 | } |
1179 | 1203 | ||
1180 | chip_bus_lock(desc); | ||
1181 | |||
1182 | /* | 1204 | /* |
1183 | * The following block of code has to be executed atomically | 1205 | * The following block of code has to be executed atomically |
1206 | * protected against a concurrent interrupt and any of the other | ||
1207 | * management calls which are not serialized via | ||
1208 | * desc->request_mutex or the optional bus lock. | ||
1184 | */ | 1209 | */ |
1185 | raw_spin_lock_irqsave(&desc->lock, flags); | 1210 | raw_spin_lock_irqsave(&desc->lock, flags); |
1186 | old_ptr = &desc->action; | 1211 | old_ptr = &desc->action; |
@@ -1286,10 +1311,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
1286 | ret = __irq_set_trigger(desc, | 1311 | ret = __irq_set_trigger(desc, |
1287 | new->flags & IRQF_TRIGGER_MASK); | 1312 | new->flags & IRQF_TRIGGER_MASK); |
1288 | 1313 | ||
1289 | if (ret) { | 1314 | if (ret) |
1290 | irq_release_resources(desc); | ||
1291 | goto out_unlock; | 1315 | goto out_unlock; |
1292 | } | ||
1293 | } | 1316 | } |
1294 | 1317 | ||
1295 | desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \ | 1318 | desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \ |
@@ -1385,12 +1408,10 @@ mismatch: | |||
1385 | out_unlock: | 1408 | out_unlock: |
1386 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 1409 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
1387 | 1410 | ||
1388 | chip_bus_sync_unlock(desc); | ||
1389 | |||
1390 | if (!desc->action) | 1411 | if (!desc->action) |
1391 | irq_release_resources(desc); | 1412 | irq_release_resources(desc); |
1392 | 1413 | out_bus_unlock: | |
1393 | out_mutex: | 1414 | chip_bus_sync_unlock(desc); |
1394 | mutex_unlock(&desc->request_mutex); | 1415 | mutex_unlock(&desc->request_mutex); |
1395 | 1416 | ||
1396 | out_thread: | 1417 | out_thread: |
@@ -1472,6 +1493,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) | |||
1472 | WARN(1, "Trying to free already-free IRQ %d\n", irq); | 1493 | WARN(1, "Trying to free already-free IRQ %d\n", irq); |
1473 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 1494 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
1474 | chip_bus_sync_unlock(desc); | 1495 | chip_bus_sync_unlock(desc); |
1496 | mutex_unlock(&desc->request_mutex); | ||
1475 | return NULL; | 1497 | return NULL; |
1476 | } | 1498 | } |
1477 | 1499 | ||
@@ -1498,6 +1520,20 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) | |||
1498 | #endif | 1520 | #endif |
1499 | 1521 | ||
1500 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 1522 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
1523 | /* | ||
1524 | * Drop bus_lock here so the changes which were done in the chip | ||
1525 | * callbacks above are synced out to the irq chips which hang | ||
1526 | * behind a slow bus (I2C, SPI) before calling synchronize_irq(). | ||
1527 | * | ||
1528 | * Aside of that the bus_lock can also be taken from the threaded | ||
1529 | * handler in irq_finalize_oneshot() which results in a deadlock | ||
1530 | * because synchronize_irq() would wait forever for the thread to | ||
1531 | * complete, which is blocked on the bus lock. | ||
1532 | * | ||
1533 | * The still held desc->request_mutex() protects against a | ||
1534 | * concurrent request_irq() of this irq so the release of resources | ||
1535 | * and timing data is properly serialized. | ||
1536 | */ | ||
1501 | chip_bus_sync_unlock(desc); | 1537 | chip_bus_sync_unlock(desc); |
1502 | 1538 | ||
1503 | unregister_handler_proc(irq, action); | 1539 | unregister_handler_proc(irq, action); |
@@ -1530,8 +1566,15 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) | |||
1530 | } | 1566 | } |
1531 | } | 1567 | } |
1532 | 1568 | ||
1569 | /* Last action releases resources */ | ||
1533 | if (!desc->action) { | 1570 | if (!desc->action) { |
1571 | /* | ||
1572 | * Reaquire bus lock as irq_release_resources() might | ||
1573 | * require it to deallocate resources over the slow bus. | ||
1574 | */ | ||
1575 | chip_bus_lock(desc); | ||
1534 | irq_release_resources(desc); | 1576 | irq_release_resources(desc); |
1577 | chip_bus_sync_unlock(desc); | ||
1535 | irq_remove_timings(desc); | 1578 | irq_remove_timings(desc); |
1536 | } | 1579 | } |
1537 | 1580 | ||