diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-09 14:10:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-09 14:10:16 -0400 |
commit | d6c7528447dec208f9b742ede047753584528c0a (patch) | |
tree | 9538710890063ca035a16cdb71569185841231f1 | |
parent | eafdca4d7010a0e019aaaace3dd71b432a69b54c (diff) | |
parent | 47b82e88180c3c6db795a43373beab47cb073f7a (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide
Pull IDE updates from David Miller:
"Primarily IRQ disabling avoidance changes from Sebastian Andrzej
Siewior"
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide:
ide: don't enable/disable interrupts in force threaded-IRQ mode
ide: don't disable interrupts during kmap_atomic()
ide: Handle irq disabling consistently
alim15x3: move irq-restore before pci_dev_put()
-rw-r--r-- | drivers/ide/alim15x3.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-io.c | 4 | ||||
-rw-r--r-- | drivers/ide/ide-iops.c | 13 | ||||
-rw-r--r-- | drivers/ide/ide-taskfile.c | 10 | ||||
-rw-r--r-- | kernel/irq/manage.c | 1 |
5 files changed, 14 insertions, 16 deletions
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index 36f76e28a0bf..3265970aee34 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c | |||
@@ -323,9 +323,9 @@ out: | |||
323 | 323 | ||
324 | pci_write_config_byte(dev, 0x53, tmpbyte); | 324 | pci_write_config_byte(dev, 0x53, tmpbyte); |
325 | } | 325 | } |
326 | local_irq_restore(flags); | ||
326 | pci_dev_put(north); | 327 | pci_dev_put(north); |
327 | pci_dev_put(isa_dev); | 328 | pci_dev_put(isa_dev); |
328 | local_irq_restore(flags); | ||
329 | return 0; | 329 | return 0; |
330 | } | 330 | } |
331 | 331 | ||
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 6f25da56a169..a444bad7a2aa 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -659,8 +659,7 @@ void ide_timer_expiry (struct timer_list *t) | |||
659 | spin_unlock(&hwif->lock); | 659 | spin_unlock(&hwif->lock); |
660 | /* disable_irq_nosync ?? */ | 660 | /* disable_irq_nosync ?? */ |
661 | disable_irq(hwif->irq); | 661 | disable_irq(hwif->irq); |
662 | /* local CPU only, as if we were handling an interrupt */ | 662 | |
663 | local_irq_disable(); | ||
664 | if (hwif->polling) { | 663 | if (hwif->polling) { |
665 | startstop = handler(drive); | 664 | startstop = handler(drive); |
666 | } else if (drive_is_ready(drive)) { | 665 | } else if (drive_is_ready(drive)) { |
@@ -679,6 +678,7 @@ void ide_timer_expiry (struct timer_list *t) | |||
679 | startstop = ide_error(drive, "irq timeout", | 678 | startstop = ide_error(drive, "irq timeout", |
680 | hwif->tp_ops->read_status(hwif)); | 679 | hwif->tp_ops->read_status(hwif)); |
681 | } | 680 | } |
681 | /* Disable interrupts again, `handler' might have enabled it */ | ||
682 | spin_lock_irq(&hwif->lock); | 682 | spin_lock_irq(&hwif->lock); |
683 | enable_irq(hwif->irq); | 683 | enable_irq(hwif->irq); |
684 | if (startstop == ide_stopped && hwif->polling == 0) { | 684 | if (startstop == ide_stopped && hwif->polling == 0) { |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 210a0887dd29..d55e9ebd5628 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -108,6 +108,7 @@ int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, | |||
108 | ide_hwif_t *hwif = drive->hwif; | 108 | ide_hwif_t *hwif = drive->hwif; |
109 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 109 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
110 | unsigned long flags; | 110 | unsigned long flags; |
111 | bool irqs_threaded = force_irqthreads; | ||
111 | int i; | 112 | int i; |
112 | u8 stat; | 113 | u8 stat; |
113 | 114 | ||
@@ -115,8 +116,10 @@ int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, | |||
115 | stat = tp_ops->read_status(hwif); | 116 | stat = tp_ops->read_status(hwif); |
116 | 117 | ||
117 | if (stat & ATA_BUSY) { | 118 | if (stat & ATA_BUSY) { |
118 | local_save_flags(flags); | 119 | if (!irqs_threaded) { |
119 | local_irq_enable_in_hardirq(); | 120 | local_save_flags(flags); |
121 | local_irq_enable_in_hardirq(); | ||
122 | } | ||
120 | timeout += jiffies; | 123 | timeout += jiffies; |
121 | while ((stat = tp_ops->read_status(hwif)) & ATA_BUSY) { | 124 | while ((stat = tp_ops->read_status(hwif)) & ATA_BUSY) { |
122 | if (time_after(jiffies, timeout)) { | 125 | if (time_after(jiffies, timeout)) { |
@@ -129,12 +132,14 @@ int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, | |||
129 | if ((stat & ATA_BUSY) == 0) | 132 | if ((stat & ATA_BUSY) == 0) |
130 | break; | 133 | break; |
131 | 134 | ||
132 | local_irq_restore(flags); | 135 | if (!irqs_threaded) |
136 | local_irq_restore(flags); | ||
133 | *rstat = stat; | 137 | *rstat = stat; |
134 | return -EBUSY; | 138 | return -EBUSY; |
135 | } | 139 | } |
136 | } | 140 | } |
137 | local_irq_restore(flags); | 141 | if (!irqs_threaded) |
142 | local_irq_restore(flags); | ||
138 | } | 143 | } |
139 | /* | 144 | /* |
140 | * Allow status to settle, then read it again. | 145 | * Allow status to settle, then read it again. |
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index c034cd965831..89b29028d315 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -237,7 +237,6 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, | |||
237 | 237 | ||
238 | while (len) { | 238 | while (len) { |
239 | unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs); | 239 | unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs); |
240 | int page_is_high; | ||
241 | 240 | ||
242 | page = sg_page(cursg); | 241 | page = sg_page(cursg); |
243 | offset = cursg->offset + cmd->cursg_ofs; | 242 | offset = cursg->offset + cmd->cursg_ofs; |
@@ -248,10 +247,6 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, | |||
248 | 247 | ||
249 | nr_bytes = min_t(unsigned, nr_bytes, (PAGE_SIZE - offset)); | 248 | nr_bytes = min_t(unsigned, nr_bytes, (PAGE_SIZE - offset)); |
250 | 249 | ||
251 | page_is_high = PageHighMem(page); | ||
252 | if (page_is_high) | ||
253 | local_irq_save(flags); | ||
254 | |||
255 | buf = kmap_atomic(page) + offset; | 250 | buf = kmap_atomic(page) + offset; |
256 | 251 | ||
257 | cmd->nleft -= nr_bytes; | 252 | cmd->nleft -= nr_bytes; |
@@ -270,9 +265,6 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, | |||
270 | 265 | ||
271 | kunmap_atomic(buf); | 266 | kunmap_atomic(buf); |
272 | 267 | ||
273 | if (page_is_high) | ||
274 | local_irq_restore(flags); | ||
275 | |||
276 | len -= nr_bytes; | 268 | len -= nr_bytes; |
277 | } | 269 | } |
278 | } | 270 | } |
@@ -413,7 +405,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, | |||
413 | return startstop; | 405 | return startstop; |
414 | } | 406 | } |
415 | 407 | ||
416 | if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0) | 408 | if (!force_irqthreads && (drive->dev_flags & IDE_DFLAG_UNMASK) == 0) |
417 | local_irq_disable(); | 409 | local_irq_disable(); |
418 | 410 | ||
419 | ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE); | 411 | ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE); |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index e3336d904f64..4c2ef8084e32 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #ifdef CONFIG_IRQ_FORCED_THREADING | 25 | #ifdef CONFIG_IRQ_FORCED_THREADING |
26 | __read_mostly bool force_irqthreads; | 26 | __read_mostly bool force_irqthreads; |
27 | EXPORT_SYMBOL_GPL(force_irqthreads); | ||
27 | 28 | ||
28 | static int __init setup_forced_irqthreads(char *arg) | 29 | static int __init setup_forced_irqthreads(char *arg) |
29 | { | 30 | { |