Commit 01192088 authored by Don Brace's avatar Don Brace Committed by Martin K. Petersen
Browse files

scsi: hpsa: use local workqueues instead of system workqueues



Avoid system stalls by switching to local workqueue.

Reviewed-by: default avatarJustin Lindley <justin.lindley@microsemi.com>
Reviewed-by: default avatarDavid Carroll <david.carroll@microsemi.com>
Reviewed-by: default avatarScott Teel <scott.teel@microsemi.com>
Signed-off-by: default avatarDon Brace <don.brace@microsemi.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent a68fdb3a
Loading
Loading
Loading
Loading
+19 −3
Original line number Diff line number Diff line
@@ -8128,6 +8128,11 @@ static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h)
		destroy_workqueue(h->rescan_ctlr_wq);
		h->rescan_ctlr_wq = NULL;
	}
	if (h->monitor_ctlr_wq) {
		destroy_workqueue(h->monitor_ctlr_wq);
		h->monitor_ctlr_wq = NULL;
	}

	kfree(h);				/* init_one 1 */
}

@@ -8463,7 +8468,7 @@ static void hpsa_event_monitor_worker(struct work_struct *work)

	spin_lock_irqsave(&h->lock, flags);
	if (!h->remove_in_progress)
		schedule_delayed_work(&h->event_monitor_work,
		queue_delayed_work(h->monitor_ctlr_wq, &h->event_monitor_work,
				HPSA_EVENT_MONITOR_INTERVAL);
	spin_unlock_irqrestore(&h->lock, flags);
}
@@ -8509,7 +8514,7 @@ static void hpsa_monitor_ctlr_worker(struct work_struct *work)

	spin_lock_irqsave(&h->lock, flags);
	if (!h->remove_in_progress)
		schedule_delayed_work(&h->monitor_ctlr_work,
		queue_delayed_work(h->monitor_ctlr_wq, &h->monitor_ctlr_work,
				h->heartbeat_sample_interval);
	spin_unlock_irqrestore(&h->lock, flags);
}
@@ -8677,6 +8682,12 @@ reinit_after_soft_reset:
		goto clean7;	/* aer/h */
	}

	h->monitor_ctlr_wq = hpsa_create_controller_wq(h, "monitor");
	if (!h->monitor_ctlr_wq) {
		rc = -ENOMEM;
		goto clean7;
	}

	/*
	 * At this point, the controller is ready to take commands.
	 * Now, if reset_devices and the hard reset didn't work, try
@@ -8806,6 +8817,10 @@ clean1: /* wq/aer/h */
		destroy_workqueue(h->rescan_ctlr_wq);
		h->rescan_ctlr_wq = NULL;
	}
	if (h->monitor_ctlr_wq) {
		destroy_workqueue(h->monitor_ctlr_wq);
		h->monitor_ctlr_wq = NULL;
	}
	kfree(h);
	return rc;
}
@@ -8953,6 +8968,7 @@ static void hpsa_remove_one(struct pci_dev *pdev)
	cancel_delayed_work_sync(&h->event_monitor_work);
	destroy_workqueue(h->rescan_ctlr_wq);
	destroy_workqueue(h->resubmit_wq);
	destroy_workqueue(h->monitor_ctlr_wq);

	hpsa_delete_sas_host(h);

+1 −0
Original line number Diff line number Diff line
@@ -300,6 +300,7 @@ struct ctlr_info {
	int	needs_abort_tags_swizzled;
	struct workqueue_struct *resubmit_wq;
	struct workqueue_struct *rescan_ctlr_wq;
	struct workqueue_struct *monitor_ctlr_wq;
	atomic_t abort_cmds_available;
	wait_queue_head_t event_sync_wait_queue;
	struct mutex reset_mutex;