aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2012-06-22 02:36:30 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-07-20 03:58:54 -0400
commitf0bf750c2d25c3a2131ececbff63c7878e0e3765 (patch)
treeba967c5d28945e76bee78feb24ade328d5b0b3a6 /drivers/scsi/libsas
parenta494fd5bd98bb35d5a9a274fecb768e14ebf499c (diff)
[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 <yuxiangl@marvell.com> Acked-by: Jack Wang <jack_wang@usish.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/libsas')
-rw-r--r--drivers/scsi/libsas/sas_expander.c20
-rw-r--r--drivers/scsi/libsas/sas_init.c23
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c8
3 files changed, 37 insertions, 14 deletions
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)
51 task->task_state_flags |= SAS_TASK_STATE_ABORTED; 51 task->task_state_flags |= SAS_TASK_STATE_ABORTED;
52 spin_unlock_irqrestore(&task->task_state_lock, flags); 52 spin_unlock_irqrestore(&task->task_state_lock, flags);
53 53
54 complete(&task->completion); 54 complete(&task->slow_task->completion);
55} 55}
56 56
57static void smp_task_done(struct sas_task *task) 57static void smp_task_done(struct sas_task *task)
58{ 58{
59 if (!del_timer(&task->timer)) 59 if (!del_timer(&task->slow_task->timer))
60 return; 60 return;
61 complete(&task->completion); 61 complete(&task->slow_task->completion);
62} 62}
63 63
64/* Give it some long enough timeout. In seconds. */ 64/* 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,
79 break; 79 break;
80 } 80 }
81 81
82 task = sas_alloc_task(GFP_KERNEL); 82 task = sas_alloc_slow_task(GFP_KERNEL);
83 if (!task) { 83 if (!task) {
84 res = -ENOMEM; 84 res = -ENOMEM;
85 break; 85 break;
@@ -91,20 +91,20 @@ static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
91 91
92 task->task_done = smp_task_done; 92 task->task_done = smp_task_done;
93 93
94 task->timer.data = (unsigned long) task; 94 task->slow_task->timer.data = (unsigned long) task;
95 task->timer.function = smp_task_timedout; 95 task->slow_task->timer.function = smp_task_timedout;
96 task->timer.expires = jiffies + SMP_TIMEOUT*HZ; 96 task->slow_task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
97 add_timer(&task->timer); 97 add_timer(&task->slow_task->timer);
98 98
99 res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); 99 res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
100 100
101 if (res) { 101 if (res) {
102 del_timer(&task->timer); 102 del_timer(&task->slow_task->timer);
103 SAS_DPRINTK("executing SMP task failed:%d\n", res); 103 SAS_DPRINTK("executing SMP task failed:%d\n", res);
104 break; 104 break;
105 } 105 }
106 106
107 wait_for_completion(&task->completion); 107 wait_for_completion(&task->slow_task->completion);
108 res = -ECOMM; 108 res = -ECOMM;
109 if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { 109 if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
110 SAS_DPRINTK("smp task timed out or aborted\n"); 110 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)
48 INIT_LIST_HEAD(&task->list); 48 INIT_LIST_HEAD(&task->list);
49 spin_lock_init(&task->task_state_lock); 49 spin_lock_init(&task->task_state_lock);
50 task->task_state_flags = SAS_TASK_STATE_PENDING; 50 task->task_state_flags = SAS_TASK_STATE_PENDING;
51 init_timer(&task->timer);
52 init_completion(&task->completion);
53 } 51 }
54 52
55 return task; 53 return task;
56} 54}
57EXPORT_SYMBOL_GPL(sas_alloc_task); 55EXPORT_SYMBOL_GPL(sas_alloc_task);
58 56
57struct sas_task *sas_alloc_slow_task(gfp_t flags)
58{
59 struct sas_task *task = sas_alloc_task(flags);
60 struct sas_task_slow *slow = kmalloc(sizeof(*slow), flags);
61
62 if (!task || !slow) {
63 if (task)
64 kmem_cache_free(sas_task_cache, task);
65 kfree(slow);
66 return NULL;
67 }
68
69 task->slow_task = slow;
70 init_timer(&slow->timer);
71 init_completion(&slow->completion);
72
73 return task;
74}
75EXPORT_SYMBOL_GPL(sas_alloc_slow_task);
76
59void sas_free_task(struct sas_task *task) 77void sas_free_task(struct sas_task *task)
60{ 78{
61 if (task) { 79 if (task) {
62 BUG_ON(!list_empty(&task->list)); 80 BUG_ON(!list_empty(&task->list));
81 kfree(task->slow_task);
63 kmem_cache_free(sas_task_cache, task); 82 kmem_cache_free(sas_task_cache, task);
64 } 83 }
65} 84}
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)
1134 1134
1135 /* Escape for libsas internal commands */ 1135 /* Escape for libsas internal commands */
1136 if (!sc) { 1136 if (!sc) {
1137 if (!del_timer(&task->timer)) 1137 struct sas_task_slow *slow = task->slow_task;
1138
1139 if (!slow)
1140 return;
1141 if (!del_timer(&slow->timer))
1138 return; 1142 return;
1139 task->timer.function(task->timer.data); 1143 slow->timer.function(slow->timer.data);
1140 return; 1144 return;
1141 } 1145 }
1142 1146