2 * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2013-2014 Mellanox Technologies. All rights reserved.
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 #include <linux/module.h>
34 #include <linux/kernel.h>
35 #include <linux/slab.h>
37 #include <linux/highmem.h>
38 #include <linux/scatterlist.h>
40 #include "iscsi_iser.h"
42 void iser_reg_comp(struct ib_cq
*cq
, struct ib_wc
*wc
)
44 iser_err_comp(wc
, "memreg");
47 static struct iser_fr_desc
*
48 iser_reg_desc_get_fr(struct ib_conn
*ib_conn
)
50 struct iser_fr_pool
*fr_pool
= &ib_conn
->fr_pool
;
51 struct iser_fr_desc
*desc
;
54 spin_lock_irqsave(&fr_pool
->lock
, flags
);
55 desc
= list_first_entry(&fr_pool
->list
,
56 struct iser_fr_desc
, list
);
57 list_del(&desc
->list
);
58 spin_unlock_irqrestore(&fr_pool
->lock
, flags
);
64 iser_reg_desc_put_fr(struct ib_conn
*ib_conn
,
65 struct iser_fr_desc
*desc
)
67 struct iser_fr_pool
*fr_pool
= &ib_conn
->fr_pool
;
70 spin_lock_irqsave(&fr_pool
->lock
, flags
);
71 list_add(&desc
->list
, &fr_pool
->list
);
72 spin_unlock_irqrestore(&fr_pool
->lock
, flags
);
75 int iser_dma_map_task_data(struct iscsi_iser_task
*iser_task
,
76 struct iser_data_buf
*data
,
77 enum iser_data_dir iser_dir
,
78 enum dma_data_direction dma_dir
)
80 struct ib_device
*dev
;
82 iser_task
->dir
[iser_dir
] = 1;
83 dev
= iser_task
->iser_conn
->ib_conn
.device
->ib_device
;
85 data
->dma_nents
= ib_dma_map_sg(dev
, data
->sg
, data
->size
, dma_dir
);
86 if (unlikely(data
->dma_nents
== 0)) {
87 iser_err("dma_map_sg failed!!!\n");
93 void iser_dma_unmap_task_data(struct iscsi_iser_task
*iser_task
,
94 struct iser_data_buf
*data
,
95 enum dma_data_direction dir
)
97 struct ib_device
*dev
;
99 dev
= iser_task
->iser_conn
->ib_conn
.device
->ib_device
;
100 ib_dma_unmap_sg(dev
, data
->sg
, data
->size
, dir
);
104 iser_reg_dma(struct iser_device
*device
, struct iser_data_buf
*mem
,
105 struct iser_mem_reg
*reg
)
107 struct scatterlist
*sg
= mem
->sg
;
109 reg
->sge
.lkey
= device
->pd
->local_dma_lkey
;
111 * FIXME: rework the registration code path to differentiate
112 * rkey/lkey use cases
115 if (device
->pd
->flags
& IB_PD_UNSAFE_GLOBAL_RKEY
)
116 reg
->rkey
= device
->pd
->unsafe_global_rkey
;
119 reg
->sge
.addr
= sg_dma_address(&sg
[0]);
120 reg
->sge
.length
= sg_dma_len(&sg
[0]);
122 iser_dbg("Single DMA entry: lkey=0x%x, rkey=0x%x, addr=0x%llx,"
123 " length=0x%x\n", reg
->sge
.lkey
, reg
->rkey
,
124 reg
->sge
.addr
, reg
->sge
.length
);
129 void iser_unreg_mem_fastreg(struct iscsi_iser_task
*iser_task
,
130 enum iser_data_dir cmd_dir
)
132 struct iser_mem_reg
*reg
= &iser_task
->rdma_reg
[cmd_dir
];
133 struct iser_fr_desc
*desc
;
134 struct ib_mr_status mr_status
;
141 * The signature MR cannot be invalidated and reused without checking.
142 * libiscsi calls the check_protection transport handler only if
143 * SCSI-Response is received. And the signature MR is not checked if
144 * the task is completed for some other reason like a timeout or error
145 * handling. That's why we must check the signature MR here before
146 * putting it to the free pool.
148 if (unlikely(desc
->sig_protected
)) {
149 desc
->sig_protected
= false;
150 ib_check_mr_status(desc
->rsc
.sig_mr
, IB_MR_CHECK_SIG_STATUS
,
153 iser_reg_desc_put_fr(&iser_task
->iser_conn
->ib_conn
, reg
->mem_h
);
158 iser_set_dif_domain(struct scsi_cmnd
*sc
, struct ib_sig_domain
*domain
)
160 domain
->sig_type
= IB_SIG_TYPE_T10_DIF
;
161 domain
->sig
.dif
.pi_interval
= scsi_prot_interval(sc
);
162 domain
->sig
.dif
.ref_tag
= t10_pi_ref_tag(sc
->request
);
164 * At the moment we hard code those, but in the future
165 * we will take them from sc.
167 domain
->sig
.dif
.apptag_check_mask
= 0xffff;
168 domain
->sig
.dif
.app_escape
= true;
169 domain
->sig
.dif
.ref_escape
= true;
170 if (sc
->prot_flags
& SCSI_PROT_REF_INCREMENT
)
171 domain
->sig
.dif
.ref_remap
= true;
175 iser_set_sig_attrs(struct scsi_cmnd
*sc
, struct ib_sig_attrs
*sig_attrs
)
177 switch (scsi_get_prot_op(sc
)) {
178 case SCSI_PROT_WRITE_INSERT
:
179 case SCSI_PROT_READ_STRIP
:
180 sig_attrs
->mem
.sig_type
= IB_SIG_TYPE_NONE
;
181 iser_set_dif_domain(sc
, &sig_attrs
->wire
);
182 sig_attrs
->wire
.sig
.dif
.bg_type
= IB_T10DIF_CRC
;
184 case SCSI_PROT_READ_INSERT
:
185 case SCSI_PROT_WRITE_STRIP
:
186 sig_attrs
->wire
.sig_type
= IB_SIG_TYPE_NONE
;
187 iser_set_dif_domain(sc
, &sig_attrs
->mem
);
188 sig_attrs
->mem
.sig
.dif
.bg_type
= sc
->prot_flags
& SCSI_PROT_IP_CHECKSUM
?
189 IB_T10DIF_CSUM
: IB_T10DIF_CRC
;
191 case SCSI_PROT_READ_PASS
:
192 case SCSI_PROT_WRITE_PASS
:
193 iser_set_dif_domain(sc
, &sig_attrs
->wire
);
194 sig_attrs
->wire
.sig
.dif
.bg_type
= IB_T10DIF_CRC
;
195 iser_set_dif_domain(sc
, &sig_attrs
->mem
);
196 sig_attrs
->mem
.sig
.dif
.bg_type
= sc
->prot_flags
& SCSI_PROT_IP_CHECKSUM
?
197 IB_T10DIF_CSUM
: IB_T10DIF_CRC
;
200 iser_err("Unsupported PI operation %d\n",
201 scsi_get_prot_op(sc
));
209 iser_set_prot_checks(struct scsi_cmnd
*sc
, u8
*mask
)
212 if (sc
->prot_flags
& SCSI_PROT_REF_CHECK
)
213 *mask
|= IB_SIG_CHECK_REFTAG
;
214 if (sc
->prot_flags
& SCSI_PROT_GUARD_CHECK
)
215 *mask
|= IB_SIG_CHECK_GUARD
;
219 iser_inv_rkey(struct ib_send_wr
*inv_wr
,
222 struct ib_send_wr
*next_wr
)
224 inv_wr
->opcode
= IB_WR_LOCAL_INV
;
225 inv_wr
->wr_cqe
= cqe
;
226 inv_wr
->ex
.invalidate_rkey
= mr
->rkey
;
227 inv_wr
->send_flags
= 0;
229 inv_wr
->next
= next_wr
;
233 iser_reg_sig_mr(struct iscsi_iser_task
*iser_task
,
234 struct iser_data_buf
*mem
,
235 struct iser_data_buf
*sig_mem
,
236 struct iser_reg_resources
*rsc
,
237 struct iser_mem_reg
*sig_reg
)
239 struct iser_tx_desc
*tx_desc
= &iser_task
->desc
;
240 struct ib_cqe
*cqe
= &iser_task
->iser_conn
->ib_conn
.reg_cqe
;
241 struct ib_mr
*mr
= rsc
->sig_mr
;
242 struct ib_sig_attrs
*sig_attrs
= mr
->sig_attrs
;
243 struct ib_reg_wr
*wr
= &tx_desc
->reg_wr
;
246 memset(sig_attrs
, 0, sizeof(*sig_attrs
));
247 ret
= iser_set_sig_attrs(iser_task
->sc
, sig_attrs
);
251 iser_set_prot_checks(iser_task
->sc
, &sig_attrs
->check_mask
);
254 iser_inv_rkey(&tx_desc
->inv_wr
, mr
, cqe
, &wr
->wr
);
256 ib_update_fast_reg_key(mr
, ib_inc_rkey(mr
->rkey
));
258 ret
= ib_map_mr_sg_pi(mr
, mem
->sg
, mem
->dma_nents
, NULL
,
259 sig_mem
->sg
, sig_mem
->dma_nents
, NULL
, SZ_4K
);
261 iser_err("failed to map PI sg (%d)\n",
262 mem
->dma_nents
+ sig_mem
->dma_nents
);
266 memset(wr
, 0, sizeof(*wr
));
267 wr
->wr
.next
= &tx_desc
->send_wr
;
268 wr
->wr
.opcode
= IB_WR_REG_MR_INTEGRITY
;
271 wr
->wr
.send_flags
= 0;
274 wr
->access
= IB_ACCESS_LOCAL_WRITE
|
275 IB_ACCESS_REMOTE_READ
|
276 IB_ACCESS_REMOTE_WRITE
;
279 sig_reg
->sge
.lkey
= mr
->lkey
;
280 sig_reg
->rkey
= mr
->rkey
;
281 sig_reg
->sge
.addr
= mr
->iova
;
282 sig_reg
->sge
.length
= mr
->length
;
284 iser_dbg("lkey=0x%x rkey=0x%x addr=0x%llx length=%u\n",
285 sig_reg
->sge
.lkey
, sig_reg
->rkey
, sig_reg
->sge
.addr
,
286 sig_reg
->sge
.length
);
291 static int iser_fast_reg_mr(struct iscsi_iser_task
*iser_task
,
292 struct iser_data_buf
*mem
,
293 struct iser_reg_resources
*rsc
,
294 struct iser_mem_reg
*reg
)
296 struct iser_tx_desc
*tx_desc
= &iser_task
->desc
;
297 struct ib_cqe
*cqe
= &iser_task
->iser_conn
->ib_conn
.reg_cqe
;
298 struct ib_mr
*mr
= rsc
->mr
;
299 struct ib_reg_wr
*wr
= &tx_desc
->reg_wr
;
303 iser_inv_rkey(&tx_desc
->inv_wr
, mr
, cqe
, &wr
->wr
);
305 ib_update_fast_reg_key(mr
, ib_inc_rkey(mr
->rkey
));
307 n
= ib_map_mr_sg(mr
, mem
->sg
, mem
->dma_nents
, NULL
, SZ_4K
);
308 if (unlikely(n
!= mem
->dma_nents
)) {
309 iser_err("failed to map sg (%d/%d)\n",
311 return n
< 0 ? n
: -EINVAL
;
314 wr
->wr
.next
= &tx_desc
->send_wr
;
315 wr
->wr
.opcode
= IB_WR_REG_MR
;
317 wr
->wr
.send_flags
= 0;
321 wr
->access
= IB_ACCESS_LOCAL_WRITE
|
322 IB_ACCESS_REMOTE_WRITE
|
323 IB_ACCESS_REMOTE_READ
;
327 reg
->sge
.lkey
= mr
->lkey
;
328 reg
->rkey
= mr
->rkey
;
329 reg
->sge
.addr
= mr
->iova
;
330 reg
->sge
.length
= mr
->length
;
332 iser_dbg("lkey=0x%x rkey=0x%x addr=0x%llx length=0x%x\n",
333 reg
->sge
.lkey
, reg
->rkey
, reg
->sge
.addr
, reg
->sge
.length
);
339 iser_reg_data_sg(struct iscsi_iser_task
*task
,
340 struct iser_data_buf
*mem
,
341 struct iser_fr_desc
*desc
,
343 struct iser_mem_reg
*reg
)
345 struct iser_device
*device
= task
->iser_conn
->ib_conn
.device
;
348 return iser_reg_dma(device
, mem
, reg
);
350 return iser_fast_reg_mr(task
, mem
, &desc
->rsc
, reg
);
353 int iser_reg_mem_fastreg(struct iscsi_iser_task
*task
,
354 enum iser_data_dir dir
,
357 struct ib_conn
*ib_conn
= &task
->iser_conn
->ib_conn
;
358 struct iser_data_buf
*mem
= &task
->data
[dir
];
359 struct iser_mem_reg
*reg
= &task
->rdma_reg
[dir
];
360 struct iser_fr_desc
*desc
= NULL
;
364 use_dma_key
= mem
->dma_nents
== 1 && (all_imm
|| !iser_always_reg
) &&
365 scsi_get_prot_op(task
->sc
) == SCSI_PROT_NORMAL
;
368 desc
= iser_reg_desc_get_fr(ib_conn
);
372 if (scsi_get_prot_op(task
->sc
) == SCSI_PROT_NORMAL
) {
373 err
= iser_reg_data_sg(task
, mem
, desc
, use_dma_key
, reg
);
377 err
= iser_reg_sig_mr(task
, mem
, &task
->prot
[dir
],
382 desc
->sig_protected
= true;
389 iser_reg_desc_put_fr(ib_conn
, desc
);