aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2007-05-08 05:17:54 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-05-08 12:56:50 -0400
commitca2d02c2f9ea476062ae181eec60b8bcd97857d6 (patch)
treedffe33856db601a173a117263b9ee4799d555ac6 /drivers/s390/scsi
parent5f852be9e11d62223ea063f6ceed4f9677f54051 (diff)
[SCSI] zfcp: rework request ID management.
Simplify request ID management and make sure that frequently used functions are inlined. Also fix a memory leak in zfcp_adapter_enqueue() which only gets hit in error handling. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c82
-rw-r--r--drivers/s390/scsi/zfcp_def.h36
-rw-r--r--drivers/s390/scsi/zfcp_erp.c3
-rw-r--r--drivers/s390/scsi/zfcp_ext.h4
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c2
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c17
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c4
7 files changed, 59 insertions, 89 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 49d5fc729bef..324899c96efe 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -118,97 +118,32 @@ _zfcp_hex_dump(char *addr, int count)
118 118
119#define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF 119#define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF
120 120
121static int zfcp_reqlist_init(struct zfcp_adapter *adapter) 121static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter)
122{ 122{
123 int i; 123 int idx;
124 124
125 adapter->req_list = kcalloc(REQUEST_LIST_SIZE, sizeof(struct list_head), 125 adapter->req_list = kcalloc(REQUEST_LIST_SIZE, sizeof(struct list_head),
126 GFP_KERNEL); 126 GFP_KERNEL);
127
128 if (!adapter->req_list) 127 if (!adapter->req_list)
129 return -ENOMEM; 128 return -ENOMEM;
130 129
131 for (i=0; i<REQUEST_LIST_SIZE; i++) 130 for (idx = 0; idx < REQUEST_LIST_SIZE; idx++)
132 INIT_LIST_HEAD(&adapter->req_list[i]); 131 INIT_LIST_HEAD(&adapter->req_list[idx]);
133
134 return 0; 132 return 0;
135} 133}
136 134
137static void zfcp_reqlist_free(struct zfcp_adapter *adapter) 135static void zfcp_reqlist_free(struct zfcp_adapter *adapter)
138{ 136{
139 struct zfcp_fsf_req *request, *tmp;
140 unsigned int i;
141
142 for (i=0; i<REQUEST_LIST_SIZE; i++) {
143 if (list_empty(&adapter->req_list[i]))
144 continue;
145
146 list_for_each_entry_safe(request, tmp,
147 &adapter->req_list[i], list)
148 list_del(&request->list);
149 }
150
151 kfree(adapter->req_list); 137 kfree(adapter->req_list);
152} 138}
153 139
154void zfcp_reqlist_add(struct zfcp_adapter *adapter,
155 struct zfcp_fsf_req *fsf_req)
156{
157 unsigned int i;
158
159 i = fsf_req->req_id % REQUEST_LIST_SIZE;
160 list_add_tail(&fsf_req->list, &adapter->req_list[i]);
161}
162
163void zfcp_reqlist_remove(struct zfcp_adapter *adapter, unsigned long req_id)
164{
165 struct zfcp_fsf_req *request, *tmp;
166 unsigned int i, counter;
167 u64 dbg_tmp[2];
168
169 i = req_id % REQUEST_LIST_SIZE;
170 BUG_ON(list_empty(&adapter->req_list[i]));
171
172 counter = 0;
173 list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list) {
174 if (request->req_id == req_id) {
175 dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active);
176 dbg_tmp[1] = (u64) counter;
177 debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
178 list_del(&request->list);
179 break;
180 }
181 counter++;
182 }
183}
184
185struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *adapter,
186 unsigned long req_id)
187{
188 struct zfcp_fsf_req *request, *tmp;
189 unsigned int i;
190
191 /* 0 is reserved as an invalid req_id */
192 if (req_id == 0)
193 return NULL;
194
195 i = req_id % REQUEST_LIST_SIZE;
196
197 list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list)
198 if (request->req_id == req_id)
199 return request;
200
201 return NULL;
202}
203
204int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) 140int zfcp_reqlist_isempty(struct zfcp_adapter *adapter)
205{ 141{
206 unsigned int i; 142 unsigned int idx;
207 143
208 for (i=0; i<REQUEST_LIST_SIZE; i++) 144 for (idx = 0; idx < REQUEST_LIST_SIZE; idx++)
209 if (!list_empty(&adapter->req_list[i])) 145 if (!list_empty(&adapter->req_list[idx]))
210 return 0; 146 return 0;
211
212 return 1; 147 return 1;
213} 148}
214 149
@@ -1106,7 +1041,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
1106 1041
1107 /* initialize list of fsf requests */ 1042 /* initialize list of fsf requests */
1108 spin_lock_init(&adapter->req_list_lock); 1043 spin_lock_init(&adapter->req_list_lock);
1109 retval = zfcp_reqlist_init(adapter); 1044 retval = zfcp_reqlist_alloc(adapter);
1110 if (retval) { 1045 if (retval) {
1111 ZFCP_LOG_INFO("request list initialization failed\n"); 1046 ZFCP_LOG_INFO("request list initialization failed\n");
1112 goto failed_low_mem_buffers; 1047 goto failed_low_mem_buffers;
@@ -1167,6 +1102,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
1167 zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); 1102 zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
1168 sysfs_failed: 1103 sysfs_failed:
1169 dev_set_drvdata(&ccw_device->dev, NULL); 1104 dev_set_drvdata(&ccw_device->dev, NULL);
1105 zfcp_reqlist_free(adapter);
1170 failed_low_mem_buffers: 1106 failed_low_mem_buffers:
1171 zfcp_free_low_mem_buffers(adapter); 1107 zfcp_free_low_mem_buffers(adapter);
1172 if (qdio_free(ccw_device) != 0) 1108 if (qdio_free(ccw_device) != 0)
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 07b0957b82f3..22649639230b 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -1090,6 +1090,42 @@ extern void _zfcp_hex_dump(char *, int);
1090#define zfcp_get_busid_by_unit(unit) (zfcp_get_busid_by_port(unit->port)) 1090#define zfcp_get_busid_by_unit(unit) (zfcp_get_busid_by_port(unit->port))
1091 1091
1092/* 1092/*
1093 * Helper functions for request ID management.
1094 */
1095static inline int zfcp_reqlist_hash(unsigned long req_id)
1096{
1097 return req_id % REQUEST_LIST_SIZE;
1098}
1099
1100static inline void zfcp_reqlist_add(struct zfcp_adapter *adapter,
1101 struct zfcp_fsf_req *fsf_req)
1102{
1103 unsigned int idx;
1104
1105 idx = zfcp_reqlist_hash(fsf_req->req_id);
1106 list_add_tail(&fsf_req->list, &adapter->req_list[idx]);
1107}
1108
1109static inline void zfcp_reqlist_remove(struct zfcp_adapter *adapter,
1110 struct zfcp_fsf_req *fsf_req)
1111{
1112 list_del(&fsf_req->list);
1113}
1114
1115static inline struct zfcp_fsf_req *
1116zfcp_reqlist_find(struct zfcp_adapter *adapter, unsigned long req_id)
1117{
1118 struct zfcp_fsf_req *request;
1119 unsigned int idx;
1120
1121 idx = zfcp_reqlist_hash(req_id);
1122 list_for_each_entry(request, &adapter->req_list[idx], list)
1123 if (request->req_id == req_id)
1124 return request;
1125 return NULL;
1126}
1127
1128/*
1093 * functions needed for reference/usage counting 1129 * functions needed for reference/usage counting
1094 */ 1130 */
1095 1131
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 885572300589..e2a3d6fe1651 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -847,8 +847,7 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
847 if (erp_action->fsf_req) { 847 if (erp_action->fsf_req) {
848 /* take lock to ensure that request is not deleted meanwhile */ 848 /* take lock to ensure that request is not deleted meanwhile */
849 spin_lock(&adapter->req_list_lock); 849 spin_lock(&adapter->req_list_lock);
850 if (zfcp_reqlist_ismember(adapter, 850 if (zfcp_reqlist_find(adapter, erp_action->fsf_req->req_id)) {
851 erp_action->fsf_req->req_id)) {
852 /* fsf_req still exists */ 851 /* fsf_req still exists */
853 debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); 852 debug_text_event(adapter->erp_dbf, 3, "a_ca_req");
854 debug_event(adapter->erp_dbf, 3, &erp_action->fsf_req, 853 debug_event(adapter->erp_dbf, 3, &erp_action->fsf_req,
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 01386ac688a2..991d45667a44 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -184,10 +184,6 @@ extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *,
184 unsigned long); 184 unsigned long);
185extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, 185extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *,
186 struct scsi_cmnd *); 186 struct scsi_cmnd *);
187extern void zfcp_reqlist_add(struct zfcp_adapter *, struct zfcp_fsf_req *);
188extern void zfcp_reqlist_remove(struct zfcp_adapter *, unsigned long);
189extern struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *,
190 unsigned long);
191extern int zfcp_reqlist_isempty(struct zfcp_adapter *); 187extern int zfcp_reqlist_isempty(struct zfcp_adapter *);
192 188
193#endif /* ZFCP_EXT_H */ 189#endif /* ZFCP_EXT_H */
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 07094c3dc341..083308b1d3e2 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -4787,7 +4787,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req)
4787 retval = -EIO; 4787 retval = -EIO;
4788 del_timer(&fsf_req->timer); 4788 del_timer(&fsf_req->timer);
4789 spin_lock(&adapter->req_list_lock); 4789 spin_lock(&adapter->req_list_lock);
4790 zfcp_reqlist_remove(adapter, fsf_req->req_id); 4790 zfcp_reqlist_remove(adapter, fsf_req);
4791 spin_unlock(&adapter->req_list_lock); 4791 spin_unlock(&adapter->req_list_lock);
4792 /* undo changes in request queue made for this request */ 4792 /* undo changes in request queue made for this request */
4793 zfcp_qdio_zero_sbals(req_queue->buffer, 4793 zfcp_qdio_zero_sbals(req_queue->buffer,
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index e50e6ad4e6cb..cb08ca3cc0f9 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -283,7 +283,7 @@ zfcp_qdio_request_handler(struct ccw_device *ccw_device,
283} 283}
284 284
285/** 285/**
286 * zfcp_qdio_reqid_check - checks for valid reqids or unsolicited status 286 * zfcp_qdio_reqid_check - checks for valid reqids.
287 */ 287 */
288static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, 288static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
289 unsigned long req_id) 289 unsigned long req_id)
@@ -294,14 +294,17 @@ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
294 debug_long_event(adapter->erp_dbf, 4, req_id); 294 debug_long_event(adapter->erp_dbf, 4, req_id);
295 295
296 spin_lock_irqsave(&adapter->req_list_lock, flags); 296 spin_lock_irqsave(&adapter->req_list_lock, flags);
297 fsf_req = zfcp_reqlist_ismember(adapter, req_id); 297 fsf_req = zfcp_reqlist_find(adapter, req_id);
298 298
299 if (!fsf_req) { 299 if (!fsf_req)
300 spin_unlock_irqrestore(&adapter->req_list_lock, flags); 300 /*
301 panic("error: unknown request id (%ld).\n", req_id); 301 * Unknown request means that we have potentially memory
302 } 302 * corruption and must stop the machine immediatly.
303 */
304 panic("error: unknown request id (%ld) on adapter %s.\n",
305 req_id, zfcp_get_busid_by_adapter(adapter));
303 306
304 zfcp_reqlist_remove(adapter, req_id); 307 zfcp_reqlist_remove(adapter, fsf_req);
305 atomic_dec(&adapter->reqs_active); 308 atomic_dec(&adapter->reqs_active);
306 spin_unlock_irqrestore(&adapter->req_list_lock, flags); 309 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
307 310
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index e742b3de16ac..16e2d64658af 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -407,8 +407,8 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
407 407
408 /* Check whether corresponding fsf_req is still pending */ 408 /* Check whether corresponding fsf_req is still pending */
409 spin_lock(&adapter->req_list_lock); 409 spin_lock(&adapter->req_list_lock);
410 fsf_req = zfcp_reqlist_ismember(adapter, (unsigned long) 410 fsf_req = zfcp_reqlist_find(adapter,
411 scpnt->host_scribble); 411 (unsigned long) scpnt->host_scribble);
412 spin_unlock(&adapter->req_list_lock); 412 spin_unlock(&adapter->req_list_lock);
413 if (!fsf_req) { 413 if (!fsf_req) {
414 write_unlock_irqrestore(&adapter->abort_lock, flags); 414 write_unlock_irqrestore(&adapter->abort_lock, flags);