aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@voltaire.com>2010-02-08 08:19:56 -0500
committerRoland Dreier <rolandd@cisco.com>2010-02-24 12:41:12 -0500
commitf19624aa92003969ba822cd3c552800965aa530b (patch)
tree0ee572198ce21da332b9fe25fde7bbe8d8a7cb98 /drivers/infiniband
parent78ad0a34dc138047529058c5f2265664cb70a052 (diff)
IB/iser: Simplify send flow/descriptors
Simplify and shrink the logic/code used for the send descriptors. Changes include removing struct iser_dto (an unnecessary abstraction), using struct iser_regd_buf only for handling SCSI commands, using dma_sync instead of dma_map/unmap, etc. Signed-off-by: Or Gerlitz <ogerlitz@voltaire.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c34
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h48
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c176
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c60
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c75
5 files changed, 115 insertions, 278 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 355470e7e904..331147b71a91 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -128,6 +128,28 @@ static int iscsi_iser_pdu_alloc(struct iscsi_task *task, uint8_t opcode)
128 return 0; 128 return 0;
129} 129}
130 130
131int iser_initialize_task_headers(struct iscsi_task *task,
132 struct iser_tx_desc *tx_desc)
133{
134 struct iscsi_iser_conn *iser_conn = task->conn->dd_data;
135 struct iser_device *device = iser_conn->ib_conn->device;
136 struct iscsi_iser_task *iser_task = task->dd_data;
137 u64 dma_addr;
138
139 dma_addr = ib_dma_map_single(device->ib_device, (void *)tx_desc,
140 ISER_HEADERS_LEN, DMA_TO_DEVICE);
141 if (ib_dma_mapping_error(device->ib_device, dma_addr))
142 return -ENOMEM;
143
144 tx_desc->dma_addr = dma_addr;
145 tx_desc->tx_sg[0].addr = tx_desc->dma_addr;
146 tx_desc->tx_sg[0].length = ISER_HEADERS_LEN;
147 tx_desc->tx_sg[0].lkey = device->mr->lkey;
148
149 iser_task->headers_initialized = 1;
150 iser_task->iser_conn = iser_conn;
151 return 0;
152}
131/** 153/**
132 * iscsi_iser_task_init - Initialize task 154 * iscsi_iser_task_init - Initialize task
133 * @task: iscsi task 155 * @task: iscsi task
@@ -137,17 +159,17 @@ static int iscsi_iser_pdu_alloc(struct iscsi_task *task, uint8_t opcode)
137static int 159static int
138iscsi_iser_task_init(struct iscsi_task *task) 160iscsi_iser_task_init(struct iscsi_task *task)
139{ 161{
140 struct iscsi_iser_conn *iser_conn = task->conn->dd_data;
141 struct iscsi_iser_task *iser_task = task->dd_data; 162 struct iscsi_iser_task *iser_task = task->dd_data;
142 163
164 if (!iser_task->headers_initialized)
165 if (iser_initialize_task_headers(task, &iser_task->desc))
166 return -ENOMEM;
167
143 /* mgmt task */ 168 /* mgmt task */
144 if (!task->sc) { 169 if (!task->sc)
145 iser_task->desc.data = task->data;
146 return 0; 170 return 0;
147 }
148 171
149 iser_task->command_sent = 0; 172 iser_task->command_sent = 0;
150 iser_task->iser_conn = iser_conn;
151 iser_task_rdma_init(iser_task); 173 iser_task_rdma_init(iser_task);
152 return 0; 174 return 0;
153} 175}
@@ -675,7 +697,7 @@ static int __init iser_init(void)
675 memset(&ig, 0, sizeof(struct iser_global)); 697 memset(&ig, 0, sizeof(struct iser_global));
676 698
677 ig.desc_cache = kmem_cache_create("iser_descriptors", 699 ig.desc_cache = kmem_cache_create("iser_descriptors",
678 sizeof (struct iser_desc), 700 sizeof(struct iser_tx_desc),
679 0, SLAB_HWCACHE_ALIGN, 701 0, SLAB_HWCACHE_ALIGN,
680 NULL); 702 NULL);
681 if (ig.desc_cache == NULL) 703 if (ig.desc_cache == NULL)
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index a314576be4bf..269f23f1b6d1 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -193,28 +193,8 @@ struct iser_regd_buf {
193 struct iser_mem_reg reg; /* memory registration info */ 193 struct iser_mem_reg reg; /* memory registration info */
194 void *virt_addr; 194 void *virt_addr;
195 struct iser_device *device; /* device->device for dma_unmap */ 195 struct iser_device *device; /* device->device for dma_unmap */
196 u64 dma_addr; /* if non zero, addr for dma_unmap */
197 enum dma_data_direction direction; /* direction for dma_unmap */ 196 enum dma_data_direction direction; /* direction for dma_unmap */
198 unsigned int data_size; 197 unsigned int data_size;
199 atomic_t ref_count; /* refcount, freed when dec to 0 */
200};
201
202#define MAX_REGD_BUF_VECTOR_LEN 2
203
204struct iser_dto {
205 struct iscsi_iser_task *task;
206 struct iser_conn *ib_conn;
207 int notify_enable;
208
209 /* vector of registered buffers */
210 unsigned int regd_vector_len;
211 struct iser_regd_buf *regd[MAX_REGD_BUF_VECTOR_LEN];
212
213 /* offset into the registered buffer may be specified */
214 unsigned int offset[MAX_REGD_BUF_VECTOR_LEN];
215
216 /* a smaller size may be specified, if 0, then full size is used */
217 unsigned int used_sz[MAX_REGD_BUF_VECTOR_LEN];
218}; 198};
219 199
220enum iser_desc_type { 200enum iser_desc_type {
@@ -223,14 +203,15 @@ enum iser_desc_type {
223 ISCSI_TX_DATAOUT 203 ISCSI_TX_DATAOUT
224}; 204};
225 205
226struct iser_desc { 206struct iser_tx_desc {
227 struct iser_hdr iser_header; 207 struct iser_hdr iser_header;
228 struct iscsi_hdr iscsi_header; 208 struct iscsi_hdr iscsi_header;
229 struct iser_regd_buf hdr_regd_buf;
230 void *data; /* used by RX & TX_CONTROL */
231 struct iser_regd_buf data_regd_buf; /* used by RX & TX_CONTROL */
232 enum iser_desc_type type; 209 enum iser_desc_type type;
233 struct iser_dto dto; 210 u64 dma_addr;
211 /* sg[0] points to iser/iscsi headers, sg[1] optionally points to either
212 of immediate data, unsolicited data-out or control (login,text) */
213 struct ib_sge tx_sg[2];
214 int num_sge;
234}; 215};
235 216
236#define ISER_RX_PAD_SIZE (256 - (ISER_RX_PAYLOAD_SIZE + \ 217#define ISER_RX_PAD_SIZE (256 - (ISER_RX_PAYLOAD_SIZE + \
@@ -287,7 +268,7 @@ struct iscsi_iser_conn {
287}; 268};
288 269
289struct iscsi_iser_task { 270struct iscsi_iser_task {
290 struct iser_desc desc; 271 struct iser_tx_desc desc;
291 struct iscsi_iser_conn *iser_conn; 272 struct iscsi_iser_conn *iser_conn;
292 enum iser_task_status status; 273 enum iser_task_status status;
293 int command_sent; /* set if command sent */ 274 int command_sent; /* set if command sent */
@@ -295,6 +276,7 @@ struct iscsi_iser_task {
295 struct iser_regd_buf rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */ 276 struct iser_regd_buf rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */
296 struct iser_data_buf data[ISER_DIRS_NUM]; /* orig. data des*/ 277 struct iser_data_buf data[ISER_DIRS_NUM]; /* orig. data des*/
297 struct iser_data_buf data_copy[ISER_DIRS_NUM];/* contig. copy */ 278 struct iser_data_buf data_copy[ISER_DIRS_NUM];/* contig. copy */
279 int headers_initialized;
298}; 280};
299 281
300struct iser_page_vec { 282struct iser_page_vec {
@@ -346,22 +328,14 @@ void iser_rcv_completion(struct iser_rx_desc *desc,
346 unsigned long dto_xfer_len, 328 unsigned long dto_xfer_len,
347 struct iser_conn *ib_conn); 329 struct iser_conn *ib_conn);
348 330
349void iser_snd_completion(struct iser_desc *desc); 331void iser_snd_completion(struct iser_tx_desc *desc, struct iser_conn *ib_conn);
350 332
351void iser_task_rdma_init(struct iscsi_iser_task *task); 333void iser_task_rdma_init(struct iscsi_iser_task *task);
352 334
353void iser_task_rdma_finalize(struct iscsi_iser_task *task); 335void iser_task_rdma_finalize(struct iscsi_iser_task *task);
354 336
355void iser_dto_buffs_release(struct iser_dto *dto);
356
357int iser_regd_buff_release(struct iser_regd_buf *regd_buf);
358
359void iser_free_rx_descriptors(struct iser_conn *ib_conn); 337void iser_free_rx_descriptors(struct iser_conn *ib_conn);
360 338
361void iser_reg_single(struct iser_device *device,
362 struct iser_regd_buf *regd_buf,
363 enum dma_data_direction direction);
364
365void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *task, 339void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *task,
366 enum iser_data_dir cmd_dir); 340 enum iser_data_dir cmd_dir);
367 341
@@ -381,7 +355,7 @@ void iser_unreg_mem(struct iser_mem_reg *mem_reg);
381 355
382int iser_post_recvl(struct iser_conn *ib_conn); 356int iser_post_recvl(struct iser_conn *ib_conn);
383int iser_post_recvm(struct iser_conn *ib_conn, int count); 357int iser_post_recvm(struct iser_conn *ib_conn, int count);
384int iser_post_send(struct iser_desc *tx_desc); 358int iser_post_send(struct iser_conn *ib_conn, struct iser_tx_desc *tx_desc);
385 359
386int iser_conn_state_comp(struct iser_conn *ib_conn, 360int iser_conn_state_comp(struct iser_conn *ib_conn,
387 enum iser_ib_conn_state comp); 361 enum iser_ib_conn_state comp);
@@ -392,4 +366,6 @@ int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
392 enum dma_data_direction dma_dir); 366 enum dma_data_direction dma_dir);
393 367
394void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task); 368void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task);
369int iser_initialize_task_headers(struct iscsi_task *task,
370 struct iser_tx_desc *tx_desc);
395#endif 371#endif
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index 3e65a43d2154..3be3a13b5e30 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -39,26 +39,6 @@
39 39
40#include "iscsi_iser.h" 40#include "iscsi_iser.h"
41 41
42
43/* iser_dto_add_regd_buff - increments the reference count for *
44 * the registered buffer & adds it to the DTO object */
45static void iser_dto_add_regd_buff(struct iser_dto *dto,
46 struct iser_regd_buf *regd_buf,
47 unsigned long use_offset,
48 unsigned long use_size)
49{
50 int add_idx;
51
52 atomic_inc(&regd_buf->ref_count);
53
54 add_idx = dto->regd_vector_len;
55 dto->regd[add_idx] = regd_buf;
56 dto->used_sz[add_idx] = use_size;
57 dto->offset[add_idx] = use_offset;
58
59 dto->regd_vector_len++;
60}
61
62/* Register user buffer memory and initialize passive rdma 42/* Register user buffer memory and initialize passive rdma
63 * dto descriptor. Total data size is stored in 43 * dto descriptor. Total data size is stored in
64 * iser_task->data[ISER_DIR_IN].data_len 44 * iser_task->data[ISER_DIR_IN].data_len
@@ -119,9 +99,9 @@ iser_prepare_write_cmd(struct iscsi_task *task,
119 struct iscsi_iser_task *iser_task = task->dd_data; 99 struct iscsi_iser_task *iser_task = task->dd_data;
120 struct iser_regd_buf *regd_buf; 100 struct iser_regd_buf *regd_buf;
121 int err; 101 int err;
122 struct iser_dto *send_dto = &iser_task->desc.dto;
123 struct iser_hdr *hdr = &iser_task->desc.iser_header; 102 struct iser_hdr *hdr = &iser_task->desc.iser_header;
124 struct iser_data_buf *buf_out = &iser_task->data[ISER_DIR_OUT]; 103 struct iser_data_buf *buf_out = &iser_task->data[ISER_DIR_OUT];
104 struct ib_sge *tx_dsg = &iser_task->desc.tx_sg[1];
125 105
126 err = iser_dma_map_task_data(iser_task, 106 err = iser_dma_map_task_data(iser_task,
127 buf_out, 107 buf_out,
@@ -160,37 +140,36 @@ iser_prepare_write_cmd(struct iscsi_task *task,
160 if (imm_sz > 0) { 140 if (imm_sz > 0) {
161 iser_dbg("Cmd itt:%d, WRITE, adding imm.data sz: %d\n", 141 iser_dbg("Cmd itt:%d, WRITE, adding imm.data sz: %d\n",
162 task->itt, imm_sz); 142 task->itt, imm_sz);
163 iser_dto_add_regd_buff(send_dto, 143 tx_dsg->addr = regd_buf->reg.va;
164 regd_buf, 144 tx_dsg->length = imm_sz;
165 0, 145 tx_dsg->lkey = regd_buf->reg.lkey;
166 imm_sz); 146 iser_task->desc.num_sge = 2;
167 } 147 }
168 148
169 return 0; 149 return 0;
170} 150}
171 151
172/* creates a new tx descriptor and adds header regd buffer */ 152/* creates a new tx descriptor and adds header regd buffer */
173static void iser_create_send_desc(struct iscsi_iser_conn *iser_conn, 153static void iser_create_send_desc(struct iser_conn *ib_conn,
174 struct iser_desc *tx_desc) 154 struct iser_tx_desc *tx_desc)
175{ 155{
176 struct iser_regd_buf *regd_hdr = &tx_desc->hdr_regd_buf; 156 struct iser_device *device = ib_conn->device;
177 struct iser_dto *send_dto = &tx_desc->dto;
178
179 memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
180 regd_hdr->device = iser_conn->ib_conn->device;
181 regd_hdr->virt_addr = tx_desc; /* == &tx_desc->iser_header */
182 regd_hdr->data_size = ISER_HEADERS_LEN;
183 157
184 send_dto->ib_conn = iser_conn->ib_conn; 158 ib_dma_sync_single_for_cpu(device->ib_device,
185 send_dto->notify_enable = 1; 159 tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE);
186 send_dto->regd_vector_len = 0;
187 160
188 memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr)); 161 memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr));
189 tx_desc->iser_header.flags = ISER_VER; 162 tx_desc->iser_header.flags = ISER_VER;
190 163
191 iser_dto_add_regd_buff(send_dto, regd_hdr, 0, 0); 164 tx_desc->num_sge = 1;
165
166 if (tx_desc->tx_sg[0].lkey != device->mr->lkey) {
167 tx_desc->tx_sg[0].lkey = device->mr->lkey;
168 iser_dbg("sdesc %p lkey mismatch, fixing\n", tx_desc);
169 }
192} 170}
193 171
172
194int iser_alloc_rx_descriptors(struct iser_conn *ib_conn) 173int iser_alloc_rx_descriptors(struct iser_conn *ib_conn)
195{ 174{
196 int i, j; 175 int i, j;
@@ -303,12 +282,12 @@ int iser_send_command(struct iscsi_conn *conn,
303{ 282{
304 struct iscsi_iser_conn *iser_conn = conn->dd_data; 283 struct iscsi_iser_conn *iser_conn = conn->dd_data;
305 struct iscsi_iser_task *iser_task = task->dd_data; 284 struct iscsi_iser_task *iser_task = task->dd_data;
306 struct iser_dto *send_dto = NULL;
307 unsigned long edtl; 285 unsigned long edtl;
308 int err; 286 int err;
309 struct iser_data_buf *data_buf; 287 struct iser_data_buf *data_buf;
310 struct iscsi_cmd *hdr = (struct iscsi_cmd *)task->hdr; 288 struct iscsi_cmd *hdr = (struct iscsi_cmd *)task->hdr;
311 struct scsi_cmnd *sc = task->sc; 289 struct scsi_cmnd *sc = task->sc;
290 struct iser_tx_desc *tx_desc = &iser_task->desc;
312 291
313 if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { 292 if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
314 iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn); 293 iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
@@ -320,10 +299,8 @@ int iser_send_command(struct iscsi_conn *conn,
320 edtl = ntohl(hdr->data_length); 299 edtl = ntohl(hdr->data_length);
321 300
322 /* build the tx desc regd header and add it to the tx desc dto */ 301 /* build the tx desc regd header and add it to the tx desc dto */
323 iser_task->desc.type = ISCSI_TX_SCSI_COMMAND; 302 tx_desc->type = ISCSI_TX_SCSI_COMMAND;
324 send_dto = &iser_task->desc.dto; 303 iser_create_send_desc(iser_conn->ib_conn, tx_desc);
325 send_dto->task = iser_task;
326 iser_create_send_desc(iser_conn, &iser_task->desc);
327 304
328 if (hdr->flags & ISCSI_FLAG_CMD_READ) 305 if (hdr->flags & ISCSI_FLAG_CMD_READ)
329 data_buf = &iser_task->data[ISER_DIR_IN]; 306 data_buf = &iser_task->data[ISER_DIR_IN];
@@ -352,17 +329,13 @@ int iser_send_command(struct iscsi_conn *conn,
352 goto send_command_error; 329 goto send_command_error;
353 } 330 }
354 331
355 iser_reg_single(iser_conn->ib_conn->device,
356 send_dto->regd[0], DMA_TO_DEVICE);
357
358 iser_task->status = ISER_TASK_STATUS_STARTED; 332 iser_task->status = ISER_TASK_STATUS_STARTED;
359 333
360 err = iser_post_send(&iser_task->desc); 334 err = iser_post_send(iser_conn->ib_conn, tx_desc);
361 if (!err) 335 if (!err)
362 return 0; 336 return 0;
363 337
364send_command_error: 338send_command_error:
365 iser_dto_buffs_release(send_dto);
366 iser_err("conn %p failed task->itt %d err %d\n",conn, task->itt, err); 339 iser_err("conn %p failed task->itt %d err %d\n",conn, task->itt, err);
367 return err; 340 return err;
368} 341}
@@ -376,12 +349,14 @@ int iser_send_data_out(struct iscsi_conn *conn,
376{ 349{
377 struct iscsi_iser_conn *iser_conn = conn->dd_data; 350 struct iscsi_iser_conn *iser_conn = conn->dd_data;
378 struct iscsi_iser_task *iser_task = task->dd_data; 351 struct iscsi_iser_task *iser_task = task->dd_data;
379 struct iser_desc *tx_desc = NULL; 352 struct iser_tx_desc *tx_desc = NULL;
380 struct iser_dto *send_dto = NULL; 353 struct iser_regd_buf *regd_buf;
381 unsigned long buf_offset; 354 unsigned long buf_offset;
382 unsigned long data_seg_len; 355 unsigned long data_seg_len;
383 uint32_t itt; 356 uint32_t itt;
384 int err = 0; 357 int err = 0;
358 struct ib_sge *tx_dsg;
359
385 360
386 if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { 361 if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
387 iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn); 362 iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
@@ -398,28 +373,25 @@ int iser_send_data_out(struct iscsi_conn *conn,
398 iser_dbg("%s itt %d dseg_len %d offset %d\n", 373 iser_dbg("%s itt %d dseg_len %d offset %d\n",
399 __func__,(int)itt,(int)data_seg_len,(int)buf_offset); 374 __func__,(int)itt,(int)data_seg_len,(int)buf_offset);
400 375
401 tx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO); 376 tx_desc = kmem_cache_zalloc(ig.desc_cache, GFP_NOIO);
402 if (tx_desc == NULL) { 377 if (tx_desc == NULL) {
403 iser_err("Failed to alloc desc for post dataout\n"); 378 iser_err("Failed to alloc desc for post dataout\n");
404 return -ENOMEM; 379 return -ENOMEM;
405 } 380 }
406 381
407 tx_desc->type = ISCSI_TX_DATAOUT; 382 tx_desc->type = ISCSI_TX_DATAOUT;
383 tx_desc->iser_header.flags = ISER_VER;
408 memcpy(&tx_desc->iscsi_header, hdr, sizeof(struct iscsi_hdr)); 384 memcpy(&tx_desc->iscsi_header, hdr, sizeof(struct iscsi_hdr));
409 385
410 /* build the tx desc regd header and add it to the tx desc dto */ 386 /* build the tx desc */
411 send_dto = &tx_desc->dto; 387 iser_initialize_task_headers(task, tx_desc);
412 send_dto->task = iser_task;
413 iser_create_send_desc(iser_conn, tx_desc);
414
415 iser_reg_single(iser_conn->ib_conn->device,
416 send_dto->regd[0], DMA_TO_DEVICE);
417 388
418 /* all data was registered for RDMA, we can use the lkey */ 389 regd_buf = &iser_task->rdma_regd[ISER_DIR_OUT];
419 iser_dto_add_regd_buff(send_dto, 390 tx_dsg = &tx_desc->tx_sg[1];
420 &iser_task->rdma_regd[ISER_DIR_OUT], 391 tx_dsg->addr = regd_buf->reg.va + buf_offset;
421 buf_offset, 392 tx_dsg->length = data_seg_len;
422 data_seg_len); 393 tx_dsg->lkey = regd_buf->reg.lkey;
394 tx_desc->num_sge = 2;
423 395
424 if (buf_offset + data_seg_len > iser_task->data[ISER_DIR_OUT].data_len) { 396 if (buf_offset + data_seg_len > iser_task->data[ISER_DIR_OUT].data_len) {
425 iser_err("Offset:%ld & DSL:%ld in Data-Out " 397 iser_err("Offset:%ld & DSL:%ld in Data-Out "
@@ -433,12 +405,11 @@ int iser_send_data_out(struct iscsi_conn *conn,
433 itt, buf_offset, data_seg_len); 405 itt, buf_offset, data_seg_len);
434 406
435 407
436 err = iser_post_send(tx_desc); 408 err = iser_post_send(iser_conn->ib_conn, tx_desc);
437 if (!err) 409 if (!err)
438 return 0; 410 return 0;
439 411
440send_data_out_error: 412send_data_out_error:
441 iser_dto_buffs_release(send_dto);
442 kmem_cache_free(ig.desc_cache, tx_desc); 413 kmem_cache_free(ig.desc_cache, tx_desc);
443 iser_err("conn %p failed err %d\n",conn, err); 414 iser_err("conn %p failed err %d\n",conn, err);
444 return err; 415 return err;
@@ -449,11 +420,9 @@ int iser_send_control(struct iscsi_conn *conn,
449{ 420{
450 struct iscsi_iser_conn *iser_conn = conn->dd_data; 421 struct iscsi_iser_conn *iser_conn = conn->dd_data;
451 struct iscsi_iser_task *iser_task = task->dd_data; 422 struct iscsi_iser_task *iser_task = task->dd_data;
452 struct iser_desc *mdesc = &iser_task->desc; 423 struct iser_tx_desc *mdesc = &iser_task->desc;
453 struct iser_dto *send_dto = NULL;
454 unsigned long data_seg_len; 424 unsigned long data_seg_len;
455 int err; 425 int err = 0;
456 struct iser_regd_buf *regd_buf;
457 struct iser_device *device; 426 struct iser_device *device;
458 427
459 if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { 428 if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
@@ -466,27 +435,24 @@ int iser_send_control(struct iscsi_conn *conn,
466 435
467 /* build the tx desc regd header and add it to the tx desc dto */ 436 /* build the tx desc regd header and add it to the tx desc dto */
468 mdesc->type = ISCSI_TX_CONTROL; 437 mdesc->type = ISCSI_TX_CONTROL;
469 send_dto = &mdesc->dto; 438 iser_create_send_desc(iser_conn->ib_conn, mdesc);
470 send_dto->task = NULL;
471 iser_create_send_desc(iser_conn, mdesc);
472 439
473 device = iser_conn->ib_conn->device; 440 device = iser_conn->ib_conn->device;
474 441
475 iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE);
476
477 data_seg_len = ntoh24(task->hdr->dlength); 442 data_seg_len = ntoh24(task->hdr->dlength);
478 443
479 if (data_seg_len > 0) { 444 if (data_seg_len > 0) {
480 regd_buf = &mdesc->data_regd_buf; 445 struct ib_sge *tx_dsg = &mdesc->tx_sg[1];
481 memset(regd_buf, 0, sizeof(struct iser_regd_buf)); 446 if (task != conn->login_task) {
482 regd_buf->device = device; 447 iser_err("data present on non login task!!!\n");
483 regd_buf->virt_addr = task->data; 448 goto send_control_error;
484 regd_buf->data_size = task->data_count; 449 }
485 iser_reg_single(device, regd_buf, 450 memcpy(iser_conn->ib_conn->login_buf, task->data,
486 DMA_TO_DEVICE); 451 task->data_count);
487 iser_dto_add_regd_buff(send_dto, regd_buf, 452 tx_dsg->addr = iser_conn->ib_conn->login_dma;
488 0, 453 tx_dsg->length = data_seg_len;
489 data_seg_len); 454 tx_dsg->lkey = device->mr->lkey;
455 mdesc->num_sge = 2;
490 } 456 }
491 457
492 if (task == conn->login_task) { 458 if (task == conn->login_task) {
@@ -495,12 +461,11 @@ int iser_send_control(struct iscsi_conn *conn,
495 goto send_control_error; 461 goto send_control_error;
496 } 462 }
497 463
498 err = iser_post_send(mdesc); 464 err = iser_post_send(iser_conn->ib_conn, mdesc);
499 if (!err) 465 if (!err)
500 return 0; 466 return 0;
501 467
502send_control_error: 468send_control_error:
503 iser_dto_buffs_release(send_dto);
504 iser_err("conn %p failed err %d\n",conn, err); 469 iser_err("conn %p failed err %d\n",conn, err);
505 return err; 470 return err;
506} 471}
@@ -584,21 +549,20 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
584 } 549 }
585} 550}
586 551
587void iser_snd_completion(struct iser_desc *tx_desc) 552void iser_snd_completion(struct iser_tx_desc *tx_desc,
553 struct iser_conn *ib_conn)
588{ 554{
589 struct iser_dto *dto = &tx_desc->dto;
590 struct iser_conn *ib_conn = dto->ib_conn;
591 struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn; 555 struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
592 struct iscsi_conn *conn = iser_conn->iscsi_conn; 556 struct iscsi_conn *conn = iser_conn->iscsi_conn;
593 struct iscsi_task *task; 557 struct iscsi_task *task;
594 int resume_tx = 0; 558 int resume_tx = 0;
559 struct iser_device *device = ib_conn->device;
595 560
596 iser_dbg("Initiator, Data sent dto=0x%p\n", dto); 561 if (tx_desc->type == ISCSI_TX_DATAOUT) {
597 562 ib_dma_unmap_single(device->ib_device, tx_desc->dma_addr,
598 iser_dto_buffs_release(dto); 563 ISER_HEADERS_LEN, DMA_TO_DEVICE);
599
600 if (tx_desc->type == ISCSI_TX_DATAOUT)
601 kmem_cache_free(ig.desc_cache, tx_desc); 564 kmem_cache_free(ig.desc_cache, tx_desc);
565 }
602 566
603 if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) == 567 if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
604 ISER_QP_MAX_REQ_DTOS) 568 ISER_QP_MAX_REQ_DTOS)
@@ -639,7 +603,6 @@ void iser_task_rdma_init(struct iscsi_iser_task *iser_task)
639 603
640void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task) 604void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task)
641{ 605{
642 int deferred;
643 int is_rdma_aligned = 1; 606 int is_rdma_aligned = 1;
644 struct iser_regd_buf *regd; 607 struct iser_regd_buf *regd;
645 608
@@ -657,32 +620,17 @@ void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task)
657 620
658 if (iser_task->dir[ISER_DIR_IN]) { 621 if (iser_task->dir[ISER_DIR_IN]) {
659 regd = &iser_task->rdma_regd[ISER_DIR_IN]; 622 regd = &iser_task->rdma_regd[ISER_DIR_IN];
660 deferred = iser_regd_buff_release(regd); 623 if (regd->reg.is_fmr)
661 if (deferred) { 624 iser_unreg_mem(&regd->reg);
662 iser_err("%d references remain for BUF-IN rdma reg\n",
663 atomic_read(&regd->ref_count));
664 }
665 } 625 }
666 626
667 if (iser_task->dir[ISER_DIR_OUT]) { 627 if (iser_task->dir[ISER_DIR_OUT]) {
668 regd = &iser_task->rdma_regd[ISER_DIR_OUT]; 628 regd = &iser_task->rdma_regd[ISER_DIR_OUT];
669 deferred = iser_regd_buff_release(regd); 629 if (regd->reg.is_fmr)
670 if (deferred) { 630 iser_unreg_mem(&regd->reg);
671 iser_err("%d references remain for BUF-OUT rdma reg\n",
672 atomic_read(&regd->ref_count));
673 }
674 } 631 }
675 632
676 /* if the data was unaligned, it was already unmapped and then copied */ 633 /* if the data was unaligned, it was already unmapped and then copied */
677 if (is_rdma_aligned) 634 if (is_rdma_aligned)
678 iser_dma_unmap_task_data(iser_task); 635 iser_dma_unmap_task_data(iser_task);
679} 636}
680
681void iser_dto_buffs_release(struct iser_dto *dto)
682{
683 int i;
684
685 for (i = 0; i < dto->regd_vector_len; i++)
686 iser_regd_buff_release(dto->regd[i]);
687}
688
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index 274c883ef3ea..5e32e8f1edf5 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -41,62 +41,6 @@
41#define ISER_KMALLOC_THRESHOLD 0x20000 /* 128K - kmalloc limit */ 41#define ISER_KMALLOC_THRESHOLD 0x20000 /* 128K - kmalloc limit */
42 42
43/** 43/**
44 * Decrements the reference count for the
45 * registered buffer & releases it
46 *
47 * returns 0 if released, 1 if deferred
48 */
49int iser_regd_buff_release(struct iser_regd_buf *regd_buf)
50{
51 struct ib_device *dev;
52
53 if ((atomic_read(&regd_buf->ref_count) == 0) ||
54 atomic_dec_and_test(&regd_buf->ref_count)) {
55 /* if we used the dma mr, unreg is just NOP */
56 if (regd_buf->reg.is_fmr)
57 iser_unreg_mem(&regd_buf->reg);
58
59 if (regd_buf->dma_addr) {
60 dev = regd_buf->device->ib_device;
61 ib_dma_unmap_single(dev,
62 regd_buf->dma_addr,
63 regd_buf->data_size,
64 regd_buf->direction);
65 }
66 /* else this regd buf is associated with task which we */
67 /* dma_unmap_single/sg later */
68 return 0;
69 } else {
70 iser_dbg("Release deferred, regd.buff: 0x%p\n", regd_buf);
71 return 1;
72 }
73}
74
75/**
76 * iser_reg_single - fills registered buffer descriptor with
77 * registration information
78 */
79void iser_reg_single(struct iser_device *device,
80 struct iser_regd_buf *regd_buf,
81 enum dma_data_direction direction)
82{
83 u64 dma_addr;
84
85 dma_addr = ib_dma_map_single(device->ib_device,
86 regd_buf->virt_addr,
87 regd_buf->data_size, direction);
88 BUG_ON(ib_dma_mapping_error(device->ib_device, dma_addr));
89
90 regd_buf->reg.lkey = device->mr->lkey;
91 regd_buf->reg.len = regd_buf->data_size;
92 regd_buf->reg.va = dma_addr;
93 regd_buf->reg.is_fmr = 0;
94
95 regd_buf->dma_addr = dma_addr;
96 regd_buf->direction = direction;
97}
98
99/**
100 * iser_start_rdma_unaligned_sg 44 * iser_start_rdma_unaligned_sg
101 */ 45 */
102static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, 46static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
@@ -474,9 +418,5 @@ int iser_reg_rdma_mem(struct iscsi_iser_task *iser_task,
474 return err; 418 return err;
475 } 419 }
476 } 420 }
477
478 /* take a reference on this regd buf such that it will not be released *
479 * (eg in send dto completion) before we get the scsi response */
480 atomic_inc(&regd_buf->ref_count);
481 return 0; 421 return 0;
482} 422}
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 218aa10939a0..18cf65f092e8 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -194,7 +194,7 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
194 init_attr.recv_cq = device->rx_cq; 194 init_attr.recv_cq = device->rx_cq;
195 init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS; 195 init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS;
196 init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS; 196 init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS;
197 init_attr.cap.max_send_sge = MAX_REGD_BUF_VECTOR_LEN; 197 init_attr.cap.max_send_sge = 2;
198 init_attr.cap.max_recv_sge = 1; 198 init_attr.cap.max_recv_sge = 1;
199 init_attr.sq_sig_type = IB_SIGNAL_REQ_WR; 199 init_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
200 init_attr.qp_type = IB_QPT_RC; 200 init_attr.qp_type = IB_QPT_RC;
@@ -702,85 +702,36 @@ int iser_post_recvm(struct iser_conn *ib_conn, int count)
702 702
703 703
704/** 704/**
705 * iser_dto_to_iov - builds IOV from a dto descriptor
706 */
707static void iser_dto_to_iov(struct iser_dto *dto, struct ib_sge *iov, int iov_len)
708{
709 int i;
710 struct ib_sge *sge;
711 struct iser_regd_buf *regd_buf;
712
713 if (dto->regd_vector_len > iov_len) {
714 iser_err("iov size %d too small for posting dto of len %d\n",
715 iov_len, dto->regd_vector_len);
716 BUG();
717 }
718
719 for (i = 0; i < dto->regd_vector_len; i++) {
720 sge = &iov[i];
721 regd_buf = dto->regd[i];
722
723 sge->addr = regd_buf->reg.va;
724 sge->length = regd_buf->reg.len;
725 sge->lkey = regd_buf->reg.lkey;
726
727 if (dto->used_sz[i] > 0) /* Adjust size */
728 sge->length = dto->used_sz[i];
729
730 /* offset and length should not exceed the regd buf length */
731 if (sge->length + dto->offset[i] > regd_buf->reg.len) {
732 iser_err("Used len:%ld + offset:%d, exceed reg.buf.len:"
733 "%ld in dto:0x%p [%d], va:0x%08lX\n",
734 (unsigned long)sge->length, dto->offset[i],
735 (unsigned long)regd_buf->reg.len, dto, i,
736 (unsigned long)sge->addr);
737 BUG();
738 }
739
740 sge->addr += dto->offset[i]; /* Adjust offset */
741 }
742}
743
744
745/**
746 * iser_start_send - Initiate a Send DTO operation 705 * iser_start_send - Initiate a Send DTO operation
747 * 706 *
748 * returns 0 on success, -1 on failure 707 * returns 0 on success, -1 on failure
749 */ 708 */
750int iser_post_send(struct iser_desc *tx_desc) 709int iser_post_send(struct iser_conn *ib_conn, struct iser_tx_desc *tx_desc)
751{ 710{
752 int ib_ret, ret_val = 0; 711 int ib_ret;
753 struct ib_send_wr send_wr, *send_wr_failed; 712 struct ib_send_wr send_wr, *send_wr_failed;
754 struct ib_sge iov[MAX_REGD_BUF_VECTOR_LEN];
755 struct iser_conn *ib_conn;
756 struct iser_dto *dto = &tx_desc->dto;
757 713
758 ib_conn = dto->ib_conn; 714 ib_dma_sync_single_for_device(ib_conn->device->ib_device,
759 715 tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE);
760 iser_dto_to_iov(dto, iov, MAX_REGD_BUF_VECTOR_LEN);
761 716
762 send_wr.next = NULL; 717 send_wr.next = NULL;
763 send_wr.wr_id = (unsigned long)tx_desc; 718 send_wr.wr_id = (unsigned long)tx_desc;
764 send_wr.sg_list = iov; 719 send_wr.sg_list = tx_desc->tx_sg;
765 send_wr.num_sge = dto->regd_vector_len; 720 send_wr.num_sge = tx_desc->num_sge;
766 send_wr.opcode = IB_WR_SEND; 721 send_wr.opcode = IB_WR_SEND;
767 send_wr.send_flags = dto->notify_enable ? IB_SEND_SIGNALED : 0; 722 send_wr.send_flags = IB_SEND_SIGNALED;
768 723
769 atomic_inc(&ib_conn->post_send_buf_count); 724 atomic_inc(&ib_conn->post_send_buf_count);
770 725
771 ib_ret = ib_post_send(ib_conn->qp, &send_wr, &send_wr_failed); 726 ib_ret = ib_post_send(ib_conn->qp, &send_wr, &send_wr_failed);
772 if (ib_ret) { 727 if (ib_ret) {
773 iser_err("Failed to start SEND DTO, dto: 0x%p, IOV len: %d\n",
774 dto, dto->regd_vector_len);
775 iser_err("ib_post_send failed, ret:%d\n", ib_ret); 728 iser_err("ib_post_send failed, ret:%d\n", ib_ret);
776 atomic_dec(&ib_conn->post_send_buf_count); 729 atomic_dec(&ib_conn->post_send_buf_count);
777 ret_val = -1;
778 } 730 }
779 731 return ib_ret;
780 return ret_val;
781} 732}
782 733
783static void iser_handle_comp_error(struct iser_desc *desc, 734static void iser_handle_comp_error(struct iser_tx_desc *desc,
784 struct iser_conn *ib_conn) 735 struct iser_conn *ib_conn)
785{ 736{
786 if (desc && desc->type == ISCSI_TX_DATAOUT) 737 if (desc && desc->type == ISCSI_TX_DATAOUT)
@@ -809,16 +760,16 @@ static int iser_drain_tx_cq(struct iser_device *device)
809{ 760{
810 struct ib_cq *cq = device->tx_cq; 761 struct ib_cq *cq = device->tx_cq;
811 struct ib_wc wc; 762 struct ib_wc wc;
812 struct iser_desc *tx_desc; 763 struct iser_tx_desc *tx_desc;
813 struct iser_conn *ib_conn; 764 struct iser_conn *ib_conn;
814 int completed_tx = 0; 765 int completed_tx = 0;
815 766
816 while (ib_poll_cq(cq, 1, &wc) == 1) { 767 while (ib_poll_cq(cq, 1, &wc) == 1) {
817 tx_desc = (struct iser_desc *) (unsigned long) wc.wr_id; 768 tx_desc = (struct iser_tx_desc *) (unsigned long) wc.wr_id;
818 ib_conn = wc.qp->qp_context; 769 ib_conn = wc.qp->qp_context;
819 if (wc.status == IB_WC_SUCCESS) { 770 if (wc.status == IB_WC_SUCCESS) {
820 if (wc.opcode == IB_WC_SEND) 771 if (wc.opcode == IB_WC_SEND)
821 iser_snd_completion(tx_desc); 772 iser_snd_completion(tx_desc, ib_conn);
822 else 773 else
823 iser_err("expected opcode %d got %d\n", 774 iser_err("expected opcode %d got %d\n",
824 IB_WC_SEND, wc.opcode); 775 IB_WC_SEND, wc.opcode);