aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-07-02 04:03:52 -0400
committerTejun Heo <tj@kernel.org>2010-07-02 04:59:24 -0400
commitad72cf9885c536e3adae03f8337557ac9dd1e4bb (patch)
treee93af7f241987ffe365792c0130d182b0ac890d1 /drivers/ata/libata-core.c
parentd313dd85ad846bc768d58e9ceb28588f917f4c9a (diff)
libata: take advantage of cmwq and remove concurrency limitations
libata has two concurrency related limitations. a. ata_wq which is used for polling PIO has single thread per CPU. If there are multiple devices doing polling PIO on the same CPU, they can't be executed simultaneously. b. ata_aux_wq which is used for SCSI probing has single thread. In cases where SCSI probing is stalled for extended period of time which is possible for ATAPI devices, this will stall all probing. #a is solved by increasing maximum concurrency of ata_wq. Please note that polling PIO might be used under allocation path and thus needs to be served by a separate wq with a rescuer. #b is solved by using the default wq instead and achieving exclusion via per-port mutex. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c20
1 files changed, 5 insertions, 15 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index ddf8e4862787..4f78741692dc 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -98,8 +98,6 @@ static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
98 98
99unsigned int ata_print_id = 1; 99unsigned int ata_print_id = 1;
100 100
101struct workqueue_struct *ata_aux_wq;
102
103struct ata_force_param { 101struct ata_force_param {
104 const char *name; 102 const char *name;
105 unsigned int cbl; 103 unsigned int cbl;
@@ -5611,6 +5609,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
5611 ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN; 5609 ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN;
5612#endif 5610#endif
5613 5611
5612 mutex_init(&ap->scsi_scan_mutex);
5614 INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug); 5613 INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
5615 INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); 5614 INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
5616 INIT_LIST_HEAD(&ap->eh_done_q); 5615 INIT_LIST_HEAD(&ap->eh_done_q);
@@ -6549,29 +6548,20 @@ static int __init ata_init(void)
6549 6548
6550 ata_parse_force_param(); 6549 ata_parse_force_param();
6551 6550
6552 ata_aux_wq = create_singlethread_workqueue("ata_aux");
6553 if (!ata_aux_wq)
6554 goto fail;
6555
6556 rc = ata_sff_init(); 6551 rc = ata_sff_init();
6557 if (rc) 6552 if (rc) {
6558 goto fail; 6553 kfree(ata_force_tbl);
6554 return rc;
6555 }
6559 6556
6560 printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n"); 6557 printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n");
6561 return 0; 6558 return 0;
6562
6563fail:
6564 kfree(ata_force_tbl);
6565 if (ata_aux_wq)
6566 destroy_workqueue(ata_aux_wq);
6567 return rc;
6568} 6559}
6569 6560
6570static void __exit ata_exit(void) 6561static void __exit ata_exit(void)
6571{ 6562{
6572 ata_sff_exit(); 6563 ata_sff_exit();
6573 kfree(ata_force_tbl); 6564 kfree(ata_force_tbl);
6574 destroy_workqueue(ata_aux_wq);
6575} 6565}
6576 6566
6577subsys_initcall(ata_init); 6567subsys_initcall(ata_init);