aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-09 14:10:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-09 14:10:16 -0400
commitd6c7528447dec208f9b742ede047753584528c0a (patch)
tree9538710890063ca035a16cdb71569185841231f1
parenteafdca4d7010a0e019aaaace3dd71b432a69b54c (diff)
parent47b82e88180c3c6db795a43373beab47cb073f7a (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.c2
-rw-r--r--drivers/ide/ide-io.c4
-rw-r--r--drivers/ide/ide-iops.c13
-rw-r--r--drivers/ide/ide-taskfile.c10
-rw-r--r--kernel/irq/manage.c1
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;
27EXPORT_SYMBOL_GPL(force_irqthreads);
27 28
28static int __init setup_forced_irqthreads(char *arg) 29static int __init setup_forced_irqthreads(char *arg)
29{ 30{