@@ -220,7 +220,7 @@ irqreturn_t isci_msix_isr(int vec, void *data)
struct isci_host *ihost = data;
if (sci_controller_isr(ihost))
- tasklet_schedule(&ihost->completion_tasklet);
+ return IRQ_WAKE_THREAD;
return IRQ_HANDLED;
}
@@ -610,8 +610,7 @@ irqreturn_t isci_intx_isr(int vec, void *data)
if (sci_controller_isr(ihost)) {
writel(SMU_ISR_COMPLETION, &ihost->smu_registers->interrupt_status);
- tasklet_schedule(&ihost->completion_tasklet);
- ret = IRQ_HANDLED;
+ ret = IRQ_WAKE_THREAD;
} else if (sci_controller_error_isr(ihost)) {
spin_lock(&ihost->scic_lock);
sci_controller_error_handler(ihost);
@@ -1106,12 +1105,11 @@ void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_ta
/**
* isci_host_completion_routine() - This function is the delayed service
* routine that calls the sci core library's completion handler. It's
- * scheduled as a tasklet from the interrupt service routine when interrupts
+ * scheduled as a task from the interrupt service routine when interrupts
* in use, or set as the timeout function in polled mode.
* @data: This parameter specifies the ISCI host object
- *
*/
-void isci_host_completion_routine(unsigned long data)
+irqreturn_t isci_host_completion_routine(int vector, void *data)
{
struct isci_host *ihost = (struct isci_host *)data;
u16 active;
@@ -1133,6 +1131,8 @@ void isci_host_completion_routine(unsigned long data)
writel(SMU_ICC_GEN_VAL(NUMBER, active) |
SMU_ICC_GEN_VAL(TIMER, ISCI_COALESCE_BASE + ilog2(active)),
&ihost->smu_registers->interrupt_coalesce_control);
+
+ return IRQ_HANDLED;
}
/**
@@ -203,7 +203,6 @@ struct isci_host {
#define IHOST_IRQ_ENABLED 2
unsigned long flags;
wait_queue_head_t eventq;
- struct tasklet_struct completion_tasklet;
spinlock_t scic_lock;
struct isci_request *reqs[SCI_MAX_IO_REQUESTS];
struct isci_remote_device devices[SCI_MAX_REMOTE_DEVICES];
@@ -478,7 +477,7 @@ void isci_tci_free(struct isci_host *ihost, u16 tci);
void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_task *task);
int isci_host_init(struct isci_host *);
-void isci_host_completion_routine(unsigned long data);
+irqreturn_t isci_host_completion_routine(int vec, void *data);
void isci_host_deinit(struct isci_host *);
void sci_controller_disable_interrupts(struct isci_host *ihost);
bool sci_controller_has_remote_devices_stopping(struct isci_host *ihost);
@@ -358,8 +358,10 @@ static int isci_setup_interrupts(struct pci_dev *pdev)
else
isr = isci_msix_isr;
- err = devm_request_irq(&pdev->dev, pci_irq_vector(pdev, i),
- isr, 0, DRV_NAME"-msix", ihost);
+ err = devm_request_threaded_irq(&pdev->dev,
+ pci_irq_vector(pdev, i), isr,
+ isci_host_completion_routine,
+ 0, DRV_NAME"-msix", ihost);
if (!err)
continue;
@@ -377,9 +379,12 @@ static int isci_setup_interrupts(struct pci_dev *pdev)
intx:
for_each_isci_host(i, ihost, pdev) {
- err = devm_request_irq(&pdev->dev, pci_irq_vector(pdev, 0),
- isci_intx_isr, IRQF_SHARED, DRV_NAME"-intx",
- ihost);
+ err = devm_request_threaded_irq(&pdev->dev,
+ pci_irq_vector(pdev, 0),
+ isci_intx_isr,
+ isci_host_completion_routine,
+ IRQF_SHARED, DRV_NAME"-intx",
+ ihost);
if (err)
break;
}
@@ -513,8 +518,6 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
init_waitqueue_head(&ihost->eventq);
ihost->sas_ha.dev = &ihost->pdev->dev;
ihost->sas_ha.lldd_ha = ihost;
- tasklet_init(&ihost->completion_tasklet,
- isci_host_completion_routine, (unsigned long)ihost);
/* validate module parameters */
/* TODO: kill struct sci_user_parameters and reference directly */
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 run in regular task context. Cc: Artur Paszkiewicz <artur.paszkiewicz@intel.com> Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> --- drivers/scsi/isci/host.c | 12 ++++++------ drivers/scsi/isci/host.h | 3 +-- drivers/scsi/isci/init.c | 17 ++++++++++------- 3 files changed, 17 insertions(+), 15 deletions(-)