Re: [PATCH 28/48] hpsa: use per-controller work queue

2015-01-15 Thread Christoph Hellwig
This should be folded into the previous patch.
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 28/48] hpsa: use per-controller work queue

2015-01-14 Thread Don Brace
From: Webb Scales web...@hp.com

There is a possibility of deadlock if we use the system work queue
for command resubmission since something in the queue may be depending
on the I/O that gets resubmitted, and the resubmitted I/O will be
behind the thing that depends on it in the queue.  Using a driver
specific, per-controller work queue avoids this.

Reviewed-by: Scott Teel scott.t...@pmcs.com
Signed-off-by: Webb Scales web...@hp.com
Signed-off-by: Don Brace don.br...@pmcs.com
---
 drivers/scsi/hpsa.c |   16 +---
 drivers/scsi/hpsa.h |1 +
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index c1166a5..dcacb29 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1651,7 +1651,7 @@ static void process_ioaccel2_completion(struct ctlr_info 
*h,
 
 retry_cmd:
INIT_WORK(c-work, hpsa_command_resubmit_worker);
-   schedule_work_on(raw_smp_processor_id(), c-work);
+   queue_work_on(raw_smp_processor_id(), h-resubmit_wq, c-work);
 }
 
 static void complete_scsi_command(struct CommandList *cp)
@@ -1722,7 +1722,8 @@ static void complete_scsi_command(struct CommandList *cp)
if (ei-CommandStatus == CMD_IOACCEL_DISABLED)
dev-offload_enabled = 0;
INIT_WORK(cp-work, hpsa_command_resubmit_worker);
-   schedule_work_on(raw_smp_processor_id(), cp-work);
+   queue_work_on(raw_smp_processor_id(),
+   h-resubmit_wq, cp-work);
return;
}
}
@@ -6418,6 +6419,7 @@ static void fail_all_outstanding_cmds(struct ctlr_info *h)
int i;
struct CommandList *c = NULL;
 
+   flush_workqueue(h-resubmit_wq); /* ensure all cmds are fully built */
for (i = 0; i  h-nr_cmds; i++) {
if (!test_bit(i  (BITS_PER_LONG - 1),
h-cmd_pool_bits + (i / BITS_PER_LONG)))
@@ -6653,6 +6655,12 @@ reinit_after_soft_reset:
spin_lock_init(h-scan_lock);
spin_lock_init(h-passthru_count_lock);
 
+   h-resubmit_wq = alloc_workqueue(hpsa, WQ_MEM_RECLAIM, 0);
+   if (!h-resubmit_wq) {
+   dev_err(h-pdev-dev, Failed to allocate work queue\n);
+   rc = -ENOMEM;
+   goto clean1;
+   }
/* Allocate and clear per-cpu variable lockup_detected */
h-lockup_detected = alloc_percpu(u32);
if (!h-lockup_detected) {
@@ -6785,6 +6793,8 @@ clean2_and_free_irqs:
hpsa_free_irqs(h);
 clean2:
 clean1:
+   if (h-resubmit_wq)
+   destroy_workqueue(h-resubmit_wq);
if (h-lockup_detected)
free_percpu(h-lockup_detected);
kfree(h);
@@ -6860,9 +6870,9 @@ static void hpsa_remove_one(struct pci_dev *pdev)
h-remove_in_progress = 1;
cancel_delayed_work(h-monitor_ctlr_work);
spin_unlock_irqrestore(h-lock, flags);
-
hpsa_unregister_scsi(h);/* unhook from SCSI subsystem */
hpsa_shutdown(pdev);
+   destroy_workqueue(h-resubmit_wq);
iounmap(h-vaddr);
iounmap(h-transtable);
iounmap(h-cfgtable);
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 06a3e81..a0f4268 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -236,6 +236,7 @@ struct ctlr_info {
struct list_head offline_device_list;
int acciopath_status;
int raid_offload_debug;
+   struct workqueue_struct *resubmit_wq;
 };
 
 struct offline_device_entry {

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html