diff options
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.h | 9 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_initiator.c | 37 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_memory.c | 40 |
3 files changed, 48 insertions, 38 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index 56607140ff3a..623defa187b2 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h | |||
@@ -410,8 +410,10 @@ void iser_task_rdma_finalize(struct iscsi_iser_task *task); | |||
410 | 410 | ||
411 | void iser_free_rx_descriptors(struct iser_conn *ib_conn); | 411 | void iser_free_rx_descriptors(struct iser_conn *ib_conn); |
412 | 412 | ||
413 | void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *task, | 413 | void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, |
414 | enum iser_data_dir cmd_dir); | 414 | struct iser_data_buf *mem, |
415 | struct iser_data_buf *mem_copy, | ||
416 | enum iser_data_dir cmd_dir); | ||
415 | 417 | ||
416 | int iser_reg_rdma_mem_fmr(struct iscsi_iser_task *task, | 418 | int iser_reg_rdma_mem_fmr(struct iscsi_iser_task *task, |
417 | enum iser_data_dir cmd_dir); | 419 | enum iser_data_dir cmd_dir); |
@@ -441,7 +443,8 @@ int iser_dma_map_task_data(struct iscsi_iser_task *iser_task, | |||
441 | enum iser_data_dir iser_dir, | 443 | enum iser_data_dir iser_dir, |
442 | enum dma_data_direction dma_dir); | 444 | enum dma_data_direction dma_dir); |
443 | 445 | ||
444 | void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task); | 446 | void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task, |
447 | struct iser_data_buf *data); | ||
445 | int iser_initialize_task_headers(struct iscsi_task *task, | 448 | int iser_initialize_task_headers(struct iscsi_task *task, |
446 | struct iser_tx_desc *tx_desc); | 449 | struct iser_tx_desc *tx_desc); |
447 | int iser_alloc_rx_descriptors(struct iser_conn *ib_conn, struct iscsi_session *session); | 450 | int iser_alloc_rx_descriptors(struct iser_conn *ib_conn, struct iscsi_session *session); |
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index 334f34b1cd46..58e14c7705c6 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c | |||
@@ -644,27 +644,42 @@ void iser_task_rdma_init(struct iscsi_iser_task *iser_task) | |||
644 | void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task) | 644 | void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task) |
645 | { | 645 | { |
646 | struct iser_device *device = iser_task->iser_conn->ib_conn->device; | 646 | struct iser_device *device = iser_task->iser_conn->ib_conn->device; |
647 | int is_rdma_aligned = 1; | 647 | int is_rdma_data_aligned = 1; |
648 | 648 | ||
649 | /* if we were reading, copy back to unaligned sglist, | 649 | /* if we were reading, copy back to unaligned sglist, |
650 | * anyway dma_unmap and free the copy | 650 | * anyway dma_unmap and free the copy |
651 | */ | 651 | */ |
652 | if (iser_task->data_copy[ISER_DIR_IN].copy_buf != NULL) { | 652 | if (iser_task->data_copy[ISER_DIR_IN].copy_buf != NULL) { |
653 | is_rdma_aligned = 0; | 653 | is_rdma_data_aligned = 0; |
654 | iser_finalize_rdma_unaligned_sg(iser_task, ISER_DIR_IN); | 654 | iser_finalize_rdma_unaligned_sg(iser_task, |
655 | &iser_task->data[ISER_DIR_IN], | ||
656 | &iser_task->data_copy[ISER_DIR_IN], | ||
657 | ISER_DIR_IN); | ||
655 | } | 658 | } |
659 | |||
656 | if (iser_task->data_copy[ISER_DIR_OUT].copy_buf != NULL) { | 660 | if (iser_task->data_copy[ISER_DIR_OUT].copy_buf != NULL) { |
657 | is_rdma_aligned = 0; | 661 | is_rdma_data_aligned = 0; |
658 | iser_finalize_rdma_unaligned_sg(iser_task, ISER_DIR_OUT); | 662 | iser_finalize_rdma_unaligned_sg(iser_task, |
663 | &iser_task->data[ISER_DIR_OUT], | ||
664 | &iser_task->data_copy[ISER_DIR_OUT], | ||
665 | ISER_DIR_OUT); | ||
659 | } | 666 | } |
660 | 667 | ||
661 | if (iser_task->dir[ISER_DIR_IN]) | 668 | if (iser_task->dir[ISER_DIR_IN]) { |
662 | device->iser_unreg_rdma_mem(iser_task, ISER_DIR_IN); | 669 | device->iser_unreg_rdma_mem(iser_task, ISER_DIR_IN); |
670 | if (is_rdma_data_aligned) | ||
671 | iser_dma_unmap_task_data(iser_task, | ||
672 | &iser_task->data[ISER_DIR_IN]); | ||
663 | 673 | ||
664 | if (iser_task->dir[ISER_DIR_OUT]) | 674 | } |
665 | device->iser_unreg_rdma_mem(iser_task, ISER_DIR_OUT); | ||
666 | 675 | ||
667 | /* if the data was unaligned, it was already unmapped and then copied */ | 676 | if (iser_task->dir[ISER_DIR_OUT]) { |
668 | if (is_rdma_aligned) | 677 | device->iser_unreg_rdma_mem(iser_task, ISER_DIR_OUT); |
669 | iser_dma_unmap_task_data(iser_task); | 678 | if (is_rdma_data_aligned) |
679 | iser_dma_unmap_task_data(iser_task, | ||
680 | &iser_task->data[ISER_DIR_OUT]); | ||
681 | if (prot_count && is_rdma_prot_aligned) | ||
682 | iser_dma_unmap_task_data(iser_task, | ||
683 | &iser_task->prot[ISER_DIR_OUT]); | ||
684 | } | ||
670 | } | 685 | } |
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index a7a0d3e8f822..a9335080ae69 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c | |||
@@ -105,17 +105,18 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, | |||
105 | /** | 105 | /** |
106 | * iser_finalize_rdma_unaligned_sg | 106 | * iser_finalize_rdma_unaligned_sg |
107 | */ | 107 | */ |
108 | |||
108 | void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, | 109 | void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, |
109 | enum iser_data_dir cmd_dir) | 110 | struct iser_data_buf *data, |
111 | struct iser_data_buf *data_copy, | ||
112 | enum iser_data_dir cmd_dir) | ||
110 | { | 113 | { |
111 | struct ib_device *dev; | 114 | struct ib_device *dev; |
112 | struct iser_data_buf *mem_copy; | ||
113 | unsigned long cmd_data_len; | 115 | unsigned long cmd_data_len; |
114 | 116 | ||
115 | dev = iser_task->iser_conn->ib_conn->device->ib_device; | 117 | dev = iser_task->iser_conn->ib_conn->device->ib_device; |
116 | mem_copy = &iser_task->data_copy[cmd_dir]; | ||
117 | 118 | ||
118 | ib_dma_unmap_sg(dev, &mem_copy->sg_single, 1, | 119 | ib_dma_unmap_sg(dev, &data_copy->sg_single, 1, |
119 | (cmd_dir == ISER_DIR_OUT) ? | 120 | (cmd_dir == ISER_DIR_OUT) ? |
120 | DMA_TO_DEVICE : DMA_FROM_DEVICE); | 121 | DMA_TO_DEVICE : DMA_FROM_DEVICE); |
121 | 122 | ||
@@ -127,10 +128,10 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, | |||
127 | int i; | 128 | int i; |
128 | 129 | ||
129 | /* copy back read RDMA to unaligned sg */ | 130 | /* copy back read RDMA to unaligned sg */ |
130 | mem = mem_copy->copy_buf; | 131 | mem = data_copy->copy_buf; |
131 | 132 | ||
132 | sgl = (struct scatterlist *)iser_task->data[ISER_DIR_IN].buf; | 133 | sgl = (struct scatterlist *)data->buf; |
133 | sg_size = iser_task->data[ISER_DIR_IN].size; | 134 | sg_size = data->size; |
134 | 135 | ||
135 | p = mem; | 136 | p = mem; |
136 | for_each_sg(sgl, sg, sg_size, i) { | 137 | for_each_sg(sgl, sg, sg_size, i) { |
@@ -143,15 +144,15 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, | |||
143 | } | 144 | } |
144 | } | 145 | } |
145 | 146 | ||
146 | cmd_data_len = iser_task->data[cmd_dir].data_len; | 147 | cmd_data_len = data->data_len; |
147 | 148 | ||
148 | if (cmd_data_len > ISER_KMALLOC_THRESHOLD) | 149 | if (cmd_data_len > ISER_KMALLOC_THRESHOLD) |
149 | free_pages((unsigned long)mem_copy->copy_buf, | 150 | free_pages((unsigned long)data_copy->copy_buf, |
150 | ilog2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT); | 151 | ilog2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT); |
151 | else | 152 | else |
152 | kfree(mem_copy->copy_buf); | 153 | kfree(data_copy->copy_buf); |
153 | 154 | ||
154 | mem_copy->copy_buf = NULL; | 155 | data_copy->copy_buf = NULL; |
155 | } | 156 | } |
156 | 157 | ||
157 | #define IS_4K_ALIGNED(addr) ((((unsigned long)addr) & ~MASK_4K) == 0) | 158 | #define IS_4K_ALIGNED(addr) ((((unsigned long)addr) & ~MASK_4K) == 0) |
@@ -329,22 +330,13 @@ int iser_dma_map_task_data(struct iscsi_iser_task *iser_task, | |||
329 | return 0; | 330 | return 0; |
330 | } | 331 | } |
331 | 332 | ||
332 | void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task) | 333 | void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task, |
334 | struct iser_data_buf *data) | ||
333 | { | 335 | { |
334 | struct ib_device *dev; | 336 | struct ib_device *dev; |
335 | struct iser_data_buf *data; | ||
336 | 337 | ||
337 | dev = iser_task->iser_conn->ib_conn->device->ib_device; | 338 | dev = iser_task->iser_conn->ib_conn->device->ib_device; |
338 | 339 | ib_dma_unmap_sg(dev, data->buf, data->size, DMA_FROM_DEVICE); | |
339 | if (iser_task->dir[ISER_DIR_IN]) { | ||
340 | data = &iser_task->data[ISER_DIR_IN]; | ||
341 | ib_dma_unmap_sg(dev, data->buf, data->size, DMA_FROM_DEVICE); | ||
342 | } | ||
343 | |||
344 | if (iser_task->dir[ISER_DIR_OUT]) { | ||
345 | data = &iser_task->data[ISER_DIR_OUT]; | ||
346 | ib_dma_unmap_sg(dev, data->buf, data->size, DMA_TO_DEVICE); | ||
347 | } | ||
348 | } | 340 | } |
349 | 341 | ||
350 | static int fall_to_bounce_buf(struct iscsi_iser_task *iser_task, | 342 | static int fall_to_bounce_buf(struct iscsi_iser_task *iser_task, |
@@ -363,7 +355,7 @@ static int fall_to_bounce_buf(struct iscsi_iser_task *iser_task, | |||
363 | iser_data_buf_dump(mem, ibdev); | 355 | iser_data_buf_dump(mem, ibdev); |
364 | 356 | ||
365 | /* unmap the command data before accessing it */ | 357 | /* unmap the command data before accessing it */ |
366 | iser_dma_unmap_task_data(iser_task); | 358 | iser_dma_unmap_task_data(iser_task, &iser_task->data[cmd_dir]); |
367 | 359 | ||
368 | /* allocate copy buf, if we are writing, copy the */ | 360 | /* allocate copy buf, if we are writing, copy the */ |
369 | /* unaligned scatterlist, dma map the copy */ | 361 | /* unaligned scatterlist, dma map the copy */ |