summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Elliott <elliott@hp.com>2015-04-23 09:34:53 -0500
committerJames Bottomley <JBottomley@Odin.com>2015-05-31 11:41:39 -0700
commit2efa5929cb448266fcfc19d50cb6cd32c59524ef (patch)
treec8372373a01e32370a6298f4d28401ca3cdb0d70
parentb2ef480c4b6548e8287dd231256f7d5eccd0279d (diff)
downloadlinux-stable-2efa5929cb448266fcfc19d50cb6cd32c59524ef.tar.gz
linux-stable-2efa5929cb448266fcfc19d50cb6cd32c59524ef.tar.bz2
linux-stable-2efa5929cb448266fcfc19d50cb6cd32c59524ef.zip
hpsa: create workqueue after the driver is ready for use
Don't create the resubmit workqueue in hpsa_init_one until everything else is ready to use, so everything can be freed in reverse order of when they were allocated without risking freeing things while workqueue items are still active. Destroy the workqueue in the right order in hpsa_undo_allocations_after_kdump_soft_reset too. Reviewed-by: Scott Teel <scott.teel@pmcs.com> Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Reviewed-by: Hannes Reinecke <hare@Suse.de> Signed-off-by: Robert Elliott <elliott@hp.com> Signed-off-by: Don Brace <don.brace@pmcs.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Bottomley <JBottomley@Odin.com>
-rw-r--r--drivers/scsi/hpsa.c60
1 files changed, 31 insertions, 29 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 0b8b8808b944..8ef908cc1a2c 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -7674,30 +7674,18 @@ reinit_after_soft_reset:
atomic_set(&h->passthru_cmds_avail, HPSA_MAX_CONCURRENT_PASSTHRUS);
atomic_set(&h->abort_cmds_available, HPSA_CMDS_RESERVED_FOR_ABORTS);
- h->rescan_ctlr_wq = hpsa_create_controller_wq(h, "rescan");
- if (!h->rescan_ctlr_wq) {
- rc = -ENOMEM;
- goto clean1;
- }
-
- h->resubmit_wq = hpsa_create_controller_wq(h, "resubmit");
- if (!h->resubmit_wq) {
- rc = -ENOMEM;
- goto clean1; /* aer/h */
- }
-
/* Allocate and clear per-cpu variable lockup_detected */
h->lockup_detected = alloc_percpu(u32);
if (!h->lockup_detected) {
dev_err(&h->pdev->dev, "Failed to allocate lockup detector\n");
rc = -ENOMEM;
- goto clean1; /* wq/aer/h */
+ goto clean1; /* aer/h */
}
set_lockup_detected_for_all_cpus(h, 0);
rc = hpsa_pci_init(h);
if (rc)
- goto clean2; /* lockup, wq/aer/h */
+ goto clean2; /* lockup, aer/h */
sprintf(h->devname, HPSA "%d", number_of_controllers);
h->ctlr = number_of_controllers;
@@ -7713,7 +7701,7 @@ reinit_after_soft_reset:
dac = 0;
} else {
dev_err(&pdev->dev, "no suitable DMA available\n");
- goto clean3; /* pci, lockup, wq/aer/h */
+ goto clean3; /* pci, lockup, aer/h */
}
}
@@ -7722,16 +7710,16 @@ reinit_after_soft_reset:
rc = hpsa_request_irqs(h, do_hpsa_intr_msi, do_hpsa_intr_intx);
if (rc)
- goto clean3; /* pci, lockup, wq/aer/h */
+ goto clean3; /* pci, lockup, aer/h */
dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n",
h->devname, pdev->device,
h->intr[h->intr_mode], dac ? "" : " not");
rc = hpsa_alloc_cmd_pool(h);
if (rc)
- goto clean4; /* irq, pci, lockup, wq/aer/h */
+ goto clean4; /* irq, pci, lockup, aer/h */
rc = hpsa_alloc_sg_chain_blocks(h);
if (rc)
- goto clean5; /* cmd, irq, pci, lockup, wq/aer/h */
+ goto clean5; /* cmd, irq, pci, lockup, aer/h */
init_waitqueue_head(&h->scan_wait_queue);
init_waitqueue_head(&h->abort_cmd_wait_queue);
init_waitqueue_head(&h->abort_sync_wait_queue);
@@ -7744,7 +7732,20 @@ reinit_after_soft_reset:
spin_lock_init(&h->devlock);
rc = hpsa_put_ctlr_into_performant_mode(h);
if (rc)
- goto clean6; /* sg, cmd, irq, pci, lockup, wq/aer/h */
+ goto clean6; /* sg, cmd, irq, pci, lockup, aer/h */
+
+ /* create the resubmit workqueue */
+ h->rescan_ctlr_wq = hpsa_create_controller_wq(h, "rescan");
+ if (!h->rescan_ctlr_wq) {
+ rc = -ENOMEM;
+ goto clean7;
+ }
+
+ h->resubmit_wq = hpsa_create_controller_wq(h, "resubmit");
+ if (!h->resubmit_wq) {
+ rc = -ENOMEM;
+ goto clean7; /* aer/h */
+ }
/*
* At this point, the controller is ready to take commands.
@@ -7786,7 +7787,7 @@ reinit_after_soft_reset:
rc = hpsa_kdump_soft_reset(h);
if (rc)
/* Neither hard nor soft reset worked, we're hosed. */
- goto clean7;
+ goto clean8;
dev_info(&h->pdev->dev, "Board READY.\n");
dev_info(&h->pdev->dev,
@@ -7823,7 +7824,7 @@ reinit_after_soft_reset:
hpsa_hba_inquiry(h);
rc = hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */
if (rc)
- goto clean7;
+ goto clean8; /* wq, perf, sg, cmd, irq, pci, lockup, aer/h */
/* Monitor the controller for firmware lockups */
h->heartbeat_sample_interval = HEARTBEAT_SAMPLE_INTERVAL;
@@ -7835,19 +7836,20 @@ reinit_after_soft_reset:
h->heartbeat_sample_interval);
return 0;
-clean7: /* perf, sg, cmd, irq, pci, lockup, wq/aer/h */
+clean8: /* perf, sg, cmd, irq, pci, lockup, aer/h */
kfree(h->hba_inquiry_data);
+clean7: /* perf, sg, cmd, irq, pci, lockup, aer/h */
hpsa_free_performant_mode(h);
h->access.set_intr_mask(h, HPSA_INTR_OFF);
clean6: /* sg, cmd, irq, pci, lockup, wq/aer/h */
hpsa_free_sg_chain_blocks(h);
-clean5: /* cmd, irq, pci, lockup, wq/aer/h */
+clean5: /* cmd, irq, pci, lockup, aer/h */
hpsa_free_cmd_pool(h);
-clean4: /* irq, pci, lockup, wq/aer/h */
+clean4: /* irq, pci, lockup, aer/h */
hpsa_free_irqs(h);
-clean3: /* pci, lockup, wq/aer/h */
+clean3: /* pci, lockup, aer/h */
hpsa_free_pci_init(h);
-clean2: /* lockup, wq/aer/h */
+clean2: /* lockup, aer/h */
if (h->lockup_detected) {
free_percpu(h->lockup_detected);
h->lockup_detected = NULL;
@@ -7946,9 +7948,9 @@ static void hpsa_remove_one(struct pci_dev *pdev)
hpsa_free_device_info(h); /* scan */
- hpsa_unregister_scsi(h); /* init_one "8" */
- kfree(h->hba_inquiry_data); /* init_one "8" */
- h->hba_inquiry_data = NULL; /* init_one "8" */
+ hpsa_unregister_scsi(h); /* init_one 9 */
+ kfree(h->hba_inquiry_data); /* init_one 9 */
+ h->hba_inquiry_data = NULL; /* init_one 9 */
hpsa_free_performant_mode(h); /* init_one 7 */
hpsa_free_sg_chain_blocks(h); /* init_one 6 */
hpsa_free_cmd_pool(h); /* init_one 5 */