Commit 2efa5929 authored by Robert Elliott's avatar Robert Elliott Committed by James Bottomley

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: default avatarScott Teel <scott.teel@pmcs.com>
Reviewed-by: default avatarKevin Barnett <kevin.barnett@pmcs.com>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Reviewed-by: default avatarHannes Reinecke <hare@Suse.de>
Signed-off-by: default avatarRobert Elliott <elliott@hp.com>
Signed-off-by: default avatarDon Brace <don.brace@pmcs.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJames Bottomley <JBottomley@Odin.com>
parent b2ef480c
......@@ -7674,30 +7674,18 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
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 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
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 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
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 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
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 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
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 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
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 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment