From f0bf750c2d25c3a2131ececbff63c7878e0e3765 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 21 Jun 2012 23:36:30 -0700 Subject: [SCSI] libsas: trim sas_task of slow path infrastructure The timer and the completion are only used for slow path tasks (smp, and lldd tmfs), yet we incur the allocation space and cpu setup time for every fast path task. Cc: Xiangliang Yu Acked-by: Jack Wang Signed-off-by: Dan Williams Signed-off-by: James Bottomley --- drivers/scsi/libsas/sas_expander.c | 20 ++++++++++---------- drivers/scsi/libsas/sas_init.c | 23 +++++++++++++++++++++-- drivers/scsi/libsas/sas_scsi_host.c | 8 ++++++-- 3 files changed, 37 insertions(+), 14 deletions(-) (limited to 'drivers/scsi/libsas') diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 879dbbe69799..efc6e72f09f3 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -51,14 +51,14 @@ static void smp_task_timedout(unsigned long _task) task->task_state_flags |= SAS_TASK_STATE_ABORTED; spin_unlock_irqrestore(&task->task_state_lock, flags); - complete(&task->completion); + complete(&task->slow_task->completion); } static void smp_task_done(struct sas_task *task) { - if (!del_timer(&task->timer)) + if (!del_timer(&task->slow_task->timer)) return; - complete(&task->completion); + complete(&task->slow_task->completion); } /* Give it some long enough timeout. In seconds. */ @@ -79,7 +79,7 @@ static int smp_execute_task(struct domain_device *dev, void *req, int req_size, break; } - task = sas_alloc_task(GFP_KERNEL); + task = sas_alloc_slow_task(GFP_KERNEL); if (!task) { res = -ENOMEM; break; @@ -91,20 +91,20 @@ static int smp_execute_task(struct domain_device *dev, void *req, int req_size, task->task_done = smp_task_done; - task->timer.data = (unsigned long) task; - task->timer.function = smp_task_timedout; - task->timer.expires = jiffies + SMP_TIMEOUT*HZ; - add_timer(&task->timer); + task->slow_task->timer.data = (unsigned long) task; + task->slow_task->timer.function = smp_task_timedout; + task->slow_task->timer.expires = jiffies + SMP_TIMEOUT*HZ; + add_timer(&task->slow_task->timer); res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); if (res) { - del_timer(&task->timer); + del_timer(&task->slow_task->timer); SAS_DPRINTK("executing SMP task failed:%d\n", res); break; } - wait_for_completion(&task->completion); + wait_for_completion(&task->slow_task->completion); res = -ECOMM; if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { SAS_DPRINTK("smp task timed out or aborted\n"); diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 1bbab3d94a20..014297c05880 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -48,18 +48,37 @@ struct sas_task *sas_alloc_task(gfp_t flags) INIT_LIST_HEAD(&task->list); spin_lock_init(&task->task_state_lock); task->task_state_flags = SAS_TASK_STATE_PENDING; - init_timer(&task->timer); - init_completion(&task->completion); } return task; } EXPORT_SYMBOL_GPL(sas_alloc_task); +struct sas_task *sas_alloc_slow_task(gfp_t flags) +{ + struct sas_task *task = sas_alloc_task(flags); + struct sas_task_slow *slow = kmalloc(sizeof(*slow), flags); + + if (!task || !slow) { + if (task) + kmem_cache_free(sas_task_cache, task); + kfree(slow); + return NULL; + } + + task->slow_task = slow; + init_timer(&slow->timer); + init_completion(&slow->completion); + + return task; +} +EXPORT_SYMBOL_GPL(sas_alloc_slow_task); + void sas_free_task(struct sas_task *task) { if (task) { BUG_ON(!list_empty(&task->list)); + kfree(task->slow_task); kmem_cache_free(sas_task_cache, task); } } diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 676414859872..6e795a174a12 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -1134,9 +1134,13 @@ void sas_task_abort(struct sas_task *task) /* Escape for libsas internal commands */ if (!sc) { - if (!del_timer(&task->timer)) + struct sas_task_slow *slow = task->slow_task; + + if (!slow) + return; + if (!del_timer(&slow->timer)) return; - task->timer.function(task->timer.data); + slow->timer.function(slow->timer.data); return; } -- cgit v1.2.3