[PATCH 02/10] scsi/megaraid: Replace adapter->dpc_h tasklet with threaded irq

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Tasklets have long been deprecated as being too heavy on the system
by running in irq context - and this is not a performance critical
path. If a higher priority process wants to run, it must wait for
the tasklet to finish before doing so. A more suitable equivalent
is to converted to threaded irq instead and do the ack sequence
in task context.

Cc: Kashyap Desai <kashyap.desai@xxxxxxxxxxxx>
Cc: Sumit Saxena <sumit.saxena@xxxxxxxxxxxx>
Cc: Shivasharan S <shivasharan.srikanteshwara@xxxxxxxxxxxx>
Cc: megaraidlinux.pdl@xxxxxxxxxxxx
Signed-off-by: Davidlohr Bueso <dave@xxxxxxxxxxxx>
---
 drivers/scsi/megaraid/mega_common.h   |  2 --
 drivers/scsi/megaraid/megaraid_mbox.c | 52 ++++++++++-----------------
 2 files changed, 19 insertions(+), 35 deletions(-)

diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h
index 2ad0aa2f837d..3e56f74061b4 100644
--- a/drivers/scsi/megaraid/mega_common.h
+++ b/drivers/scsi/megaraid/mega_common.h
@@ -95,7 +95,6 @@ typedef struct {
 
 /**
  * struct adapter_t - driver's initialization structure
- * @aram dpc_h			: tasklet handle
  * @pdev			: pci configuration pointer for kernel
  * @host			: pointer to host structure of mid-layer
  * @lock			: synchronization lock for mid-layer and driver
@@ -149,7 +148,6 @@ typedef struct {
 #define VERSION_SIZE	16
 
 typedef struct {
-	struct tasklet_struct	dpc_h;
 	struct pci_dev		*pdev;
 	struct Scsi_Host	*host;
 	spinlock_t		lock;
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 2a339d4a7e9d..b76f67887592 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -118,8 +118,7 @@ static void megaraid_mbox_prepare_epthru(adapter_t *, scb_t *,
 		struct scsi_cmnd *);
 
 static irqreturn_t megaraid_isr(int, void *);
-
-static void megaraid_mbox_dpc(unsigned long);
+static irqreturn_t megaraid_mbox_dpc(int, void *);
 
 static ssize_t megaraid_mbox_app_hndl_show(struct device *, struct device_attribute *attr, char *);
 static ssize_t megaraid_mbox_ld_show(struct device *, struct device_attribute *attr, char *);
@@ -764,9 +763,8 @@ megaraid_init_mbox(adapter_t *adapter)
 	 */
 
 	/* request IRQ and register the interrupt service routine */
-	if (request_irq(adapter->irq, megaraid_isr, IRQF_SHARED, "megaraid",
-		adapter)) {
-
+	if (request_threaded_irq(adapter->irq, megaraid_isr, megaraid_mbox_dpc,
+				 IRQF_SHARED, "megaraid", adapter)) {
 		con_log(CL_ANN, (KERN_WARNING
 			"megaraid: Couldn't register IRQ %d!\n", adapter->irq));
 		goto out_alloc_cmds;
@@ -879,10 +877,6 @@ megaraid_init_mbox(adapter_t *adapter)
 		}
 	}
 
-	// setup tasklet for DPC
-	tasklet_init(&adapter->dpc_h, megaraid_mbox_dpc,
-			(unsigned long)adapter);
-
 	con_log(CL_DLEVEL1, (KERN_INFO
 		"megaraid mbox hba successfully initialized\n"));
 
@@ -917,8 +911,6 @@ megaraid_fini_mbox(adapter_t *adapter)
 	// flush all caches
 	megaraid_mbox_flush_cache(adapter);
 
-	tasklet_kill(&adapter->dpc_h);
-
 	megaraid_sysfs_free_resources(adapter);
 
 	megaraid_free_cmd_packets(adapter);
@@ -2027,7 +2019,7 @@ megaraid_mbox_prepare_epthru(adapter_t *adapter, scb_t *scb,
  *
  * Returns:	1 if the interrupt is valid, 0 otherwise
  */
-static int
+static irqreturn_t
 megaraid_ack_sequence(adapter_t *adapter)
 {
 	mraid_device_t		*raid_dev = ADAP2RAIDDEV(adapter);
@@ -2036,7 +2028,7 @@ megaraid_ack_sequence(adapter_t *adapter)
 	uint8_t			nstatus;
 	uint8_t			completed[MBOX_MAX_FIRMWARE_STATUS];
 	struct list_head	clist;
-	int			handled;
+	int			ret = IRQ_NONE;
 	uint32_t		dword;
 	unsigned long		flags;
 	int			i, j;
@@ -2048,7 +2040,6 @@ megaraid_ack_sequence(adapter_t *adapter)
 	INIT_LIST_HEAD(&clist);
 
 	// loop till F/W has more commands for us to complete
-	handled = 0;
 	spin_lock_irqsave(MAILBOX_LOCK(raid_dev), flags);
 	do {
 		/*
@@ -2056,9 +2047,10 @@ megaraid_ack_sequence(adapter_t *adapter)
 		 * interrupt line low.
 		 */
 		dword = RDOUTDOOR(raid_dev);
-		if (dword != 0x10001234) break;
+		if (dword != 0x10001234)
+			break;
 
-		handled = 1;
+		ret = IRQ_WAKE_THREAD;
 
 		WROUTDOOR(raid_dev, 0x10001234);
 
@@ -2124,12 +2116,7 @@ megaraid_ack_sequence(adapter_t *adapter)
 
 	spin_unlock_irqrestore(COMPLETED_LIST_LOCK(adapter), flags);
 
-
-	// schedule the DPC if there is some work for it
-	if (handled)
-		tasklet_schedule(&adapter->dpc_h);
-
-	return handled;
+	return ret;
 }
 
 
@@ -2144,29 +2131,27 @@ static irqreturn_t
 megaraid_isr(int irq, void *devp)
 {
 	adapter_t	*adapter = devp;
-	int		handled;
+	int		ret;
 
-	handled = megaraid_ack_sequence(adapter);
+	ret = megaraid_ack_sequence(adapter);
 
 	/* Loop through any pending requests */
 	if (!adapter->quiescent) {
 		megaraid_mbox_runpendq(adapter, NULL);
 	}
 
-	return IRQ_RETVAL(handled);
+	return ret;
 }
 
 
 /**
- * megaraid_mbox_dpc - the tasklet to complete the commands from completed list
- * @devp	: pointer to HBA soft state
+ * megaraid_mbox_dpc - complete the commands from completed list
  *
  * Pick up the commands from the completed list and send back to the owners.
  * This is a reentrant function and does not assume any locks are held while
- * it is being called.
+ * it is being called. Runs in process context.
  */
-static void
-megaraid_mbox_dpc(unsigned long devp)
+static irqreturn_t megaraid_mbox_dpc(int irq, void *devp)
 {
 	adapter_t		*adapter = (adapter_t *)devp;
 	mraid_device_t		*raid_dev;
@@ -2188,7 +2173,8 @@ megaraid_mbox_dpc(unsigned long devp)
 	uioc_t			*kioc;
 
 
-	if (!adapter) return;
+	if (!adapter)
+		goto done;
 
 	raid_dev = ADAP2RAIDDEV(adapter);
 
@@ -2361,8 +2347,8 @@ megaraid_mbox_dpc(unsigned long devp)
 		// send the scsi packet back to kernel
 		scsi_done(scp);
 	}
-
-	return;
+done:
+	return IRQ_HANDLED;
 }
 
 
-- 
2.36.1




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux