Skip to content

Commit 0b089c1

Browse files
sagigrimbergjgunthorpe
authored andcommitted
IB/isert: Fix unaligned immediate-data handling
Currently we allocate rx buffers in a single contiguous buffers for headers (iser and iscsi) and data trailer. This means that most likely the data starting offset is aligned to 76 bytes (size of both headers). This worked fine for years, but at some point this broke, resulting in data corruptions in isert when a command comes with immediate data and the underlying backend device assumes 512 bytes buffer alignment. We assume a hard-requirement for all direct I/O buffers to be 512 bytes aligned. To fix this, we should avoid passing unaligned buffers for I/O. Instead, we allocate our recv buffers with some extra space such that we can have the data portion align to 512 byte boundary. This also means that we cannot reference headers or data using structure but rather accessors (as they may move based on alignment). Also, get rid of the wrong __packed annotation from iser_rx_desc as this has only harmful effects (not aligned to anything). This affects the rx descriptors for iscsi login and data plane. Fixes: 3d75ca0 ("block: introduce multi-page bvec helpers") Link: https://lore.kernel.org/r/[email protected] Reported-by: Stephen Rust <[email protected]> Tested-by: Doug Dumitru <[email protected]> Signed-off-by: Sagi Grimberg <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 39c2d63 commit 0b089c1

File tree

2 files changed

+78
-56
lines changed

2 files changed

+78
-56
lines changed

drivers/infiniband/ulp/isert/ib_isert.c

Lines changed: 47 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,15 @@ isert_alloc_rx_descriptors(struct isert_conn *isert_conn)
140140
rx_desc = isert_conn->rx_descs;
141141

142142
for (i = 0; i < ISERT_QP_MAX_RECV_DTOS; i++, rx_desc++) {
143-
dma_addr = ib_dma_map_single(ib_dev, (void *)rx_desc,
144-
ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
143+
dma_addr = ib_dma_map_single(ib_dev, rx_desc->buf,
144+
ISER_RX_SIZE, DMA_FROM_DEVICE);
145145
if (ib_dma_mapping_error(ib_dev, dma_addr))
146146
goto dma_map_fail;
147147

148148
rx_desc->dma_addr = dma_addr;
149149

150150
rx_sg = &rx_desc->rx_sg;
151-
rx_sg->addr = rx_desc->dma_addr;
151+
rx_sg->addr = rx_desc->dma_addr + isert_get_hdr_offset(rx_desc);
152152
rx_sg->length = ISER_RX_PAYLOAD_SIZE;
153153
rx_sg->lkey = device->pd->local_dma_lkey;
154154
rx_desc->rx_cqe.done = isert_recv_done;
@@ -160,7 +160,7 @@ isert_alloc_rx_descriptors(struct isert_conn *isert_conn)
160160
rx_desc = isert_conn->rx_descs;
161161
for (j = 0; j < i; j++, rx_desc++) {
162162
ib_dma_unmap_single(ib_dev, rx_desc->dma_addr,
163-
ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
163+
ISER_RX_SIZE, DMA_FROM_DEVICE);
164164
}
165165
kfree(isert_conn->rx_descs);
166166
isert_conn->rx_descs = NULL;
@@ -181,7 +181,7 @@ isert_free_rx_descriptors(struct isert_conn *isert_conn)
181181
rx_desc = isert_conn->rx_descs;
182182
for (i = 0; i < ISERT_QP_MAX_RECV_DTOS; i++, rx_desc++) {
183183
ib_dma_unmap_single(ib_dev, rx_desc->dma_addr,
184-
ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
184+
ISER_RX_SIZE, DMA_FROM_DEVICE);
185185
}
186186

187187
kfree(isert_conn->rx_descs);
@@ -299,10 +299,9 @@ isert_free_login_buf(struct isert_conn *isert_conn)
299299
ISER_RX_PAYLOAD_SIZE, DMA_TO_DEVICE);
300300
kfree(isert_conn->login_rsp_buf);
301301

302-
ib_dma_unmap_single(ib_dev, isert_conn->login_req_dma,
303-
ISER_RX_PAYLOAD_SIZE,
304-
DMA_FROM_DEVICE);
305-
kfree(isert_conn->login_req_buf);
302+
ib_dma_unmap_single(ib_dev, isert_conn->login_desc->dma_addr,
303+
ISER_RX_SIZE, DMA_FROM_DEVICE);
304+
kfree(isert_conn->login_desc);
306305
}
307306

308307
static int
@@ -311,25 +310,25 @@ isert_alloc_login_buf(struct isert_conn *isert_conn,
311310
{
312311
int ret;
313312

314-
isert_conn->login_req_buf = kzalloc(sizeof(*isert_conn->login_req_buf),
313+
isert_conn->login_desc = kzalloc(sizeof(*isert_conn->login_desc),
315314
GFP_KERNEL);
316-
if (!isert_conn->login_req_buf)
315+
if (!isert_conn->login_desc)
317316
return -ENOMEM;
318317

319-
isert_conn->login_req_dma = ib_dma_map_single(ib_dev,
320-
isert_conn->login_req_buf,
321-
ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
322-
ret = ib_dma_mapping_error(ib_dev, isert_conn->login_req_dma);
318+
isert_conn->login_desc->dma_addr = ib_dma_map_single(ib_dev,
319+
isert_conn->login_desc->buf,
320+
ISER_RX_SIZE, DMA_FROM_DEVICE);
321+
ret = ib_dma_mapping_error(ib_dev, isert_conn->login_desc->dma_addr);
323322
if (ret) {
324-
isert_err("login_req_dma mapping error: %d\n", ret);
325-
isert_conn->login_req_dma = 0;
326-
goto out_free_login_req_buf;
323+
isert_err("login_desc dma mapping error: %d\n", ret);
324+
isert_conn->login_desc->dma_addr = 0;
325+
goto out_free_login_desc;
327326
}
328327

329328
isert_conn->login_rsp_buf = kzalloc(ISER_RX_PAYLOAD_SIZE, GFP_KERNEL);
330329
if (!isert_conn->login_rsp_buf) {
331330
ret = -ENOMEM;
332-
goto out_unmap_login_req_buf;
331+
goto out_unmap_login_desc;
333332
}
334333

335334
isert_conn->login_rsp_dma = ib_dma_map_single(ib_dev,
@@ -346,11 +345,11 @@ isert_alloc_login_buf(struct isert_conn *isert_conn,
346345

347346
out_free_login_rsp_buf:
348347
kfree(isert_conn->login_rsp_buf);
349-
out_unmap_login_req_buf:
350-
ib_dma_unmap_single(ib_dev, isert_conn->login_req_dma,
351-
ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
352-
out_free_login_req_buf:
353-
kfree(isert_conn->login_req_buf);
348+
out_unmap_login_desc:
349+
ib_dma_unmap_single(ib_dev, isert_conn->login_desc->dma_addr,
350+
ISER_RX_SIZE, DMA_FROM_DEVICE);
351+
out_free_login_desc:
352+
kfree(isert_conn->login_desc);
354353
return ret;
355354
}
356355

@@ -476,7 +475,7 @@ isert_connect_release(struct isert_conn *isert_conn)
476475
if (isert_conn->qp)
477476
isert_destroy_qp(isert_conn);
478477

479-
if (isert_conn->login_req_buf)
478+
if (isert_conn->login_desc)
480479
isert_free_login_buf(isert_conn);
481480

482481
isert_device_put(device);
@@ -862,17 +861,18 @@ isert_login_post_recv(struct isert_conn *isert_conn)
862861
int ret;
863862

864863
memset(&sge, 0, sizeof(struct ib_sge));
865-
sge.addr = isert_conn->login_req_dma;
864+
sge.addr = isert_conn->login_desc->dma_addr +
865+
isert_get_hdr_offset(isert_conn->login_desc);
866866
sge.length = ISER_RX_PAYLOAD_SIZE;
867867
sge.lkey = isert_conn->device->pd->local_dma_lkey;
868868

869869
isert_dbg("Setup sge: addr: %llx length: %d 0x%08x\n",
870870
sge.addr, sge.length, sge.lkey);
871871

872-
isert_conn->login_req_buf->rx_cqe.done = isert_login_recv_done;
872+
isert_conn->login_desc->rx_cqe.done = isert_login_recv_done;
873873

874874
memset(&rx_wr, 0, sizeof(struct ib_recv_wr));
875-
rx_wr.wr_cqe = &isert_conn->login_req_buf->rx_cqe;
875+
rx_wr.wr_cqe = &isert_conn->login_desc->rx_cqe;
876876
rx_wr.sg_list = &sge;
877877
rx_wr.num_sge = 1;
878878

@@ -949,7 +949,7 @@ isert_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login,
949949
static void
950950
isert_rx_login_req(struct isert_conn *isert_conn)
951951
{
952-
struct iser_rx_desc *rx_desc = isert_conn->login_req_buf;
952+
struct iser_rx_desc *rx_desc = isert_conn->login_desc;
953953
int rx_buflen = isert_conn->login_req_len;
954954
struct iscsi_conn *conn = isert_conn->conn;
955955
struct iscsi_login *login = conn->conn_login;
@@ -961,7 +961,7 @@ isert_rx_login_req(struct isert_conn *isert_conn)
961961

962962
if (login->first_request) {
963963
struct iscsi_login_req *login_req =
964-
(struct iscsi_login_req *)&rx_desc->iscsi_header;
964+
(struct iscsi_login_req *)isert_get_iscsi_hdr(rx_desc);
965965
/*
966966
* Setup the initial iscsi_login values from the leading
967967
* login request PDU.
@@ -980,13 +980,13 @@ isert_rx_login_req(struct isert_conn *isert_conn)
980980
login->tsih = be16_to_cpu(login_req->tsih);
981981
}
982982

983-
memcpy(&login->req[0], (void *)&rx_desc->iscsi_header, ISCSI_HDR_LEN);
983+
memcpy(&login->req[0], isert_get_iscsi_hdr(rx_desc), ISCSI_HDR_LEN);
984984

985985
size = min(rx_buflen, MAX_KEY_VALUE_PAIRS);
986986
isert_dbg("Using login payload size: %d, rx_buflen: %d "
987987
"MAX_KEY_VALUE_PAIRS: %d\n", size, rx_buflen,
988988
MAX_KEY_VALUE_PAIRS);
989-
memcpy(login->req_buf, &rx_desc->data[0], size);
989+
memcpy(login->req_buf, isert_get_data(rx_desc), size);
990990

991991
if (login->first_request) {
992992
complete(&isert_conn->login_comp);
@@ -1051,14 +1051,15 @@ isert_handle_scsi_cmd(struct isert_conn *isert_conn,
10511051
if (imm_data_len != data_len) {
10521052
sg_nents = max(1UL, DIV_ROUND_UP(imm_data_len, PAGE_SIZE));
10531053
sg_copy_from_buffer(cmd->se_cmd.t_data_sg, sg_nents,
1054-
&rx_desc->data[0], imm_data_len);
1054+
isert_get_data(rx_desc), imm_data_len);
10551055
isert_dbg("Copy Immediate sg_nents: %u imm_data_len: %d\n",
10561056
sg_nents, imm_data_len);
10571057
} else {
10581058
sg_init_table(&isert_cmd->sg, 1);
10591059
cmd->se_cmd.t_data_sg = &isert_cmd->sg;
10601060
cmd->se_cmd.t_data_nents = 1;
1061-
sg_set_buf(&isert_cmd->sg, &rx_desc->data[0], imm_data_len);
1061+
sg_set_buf(&isert_cmd->sg, isert_get_data(rx_desc),
1062+
imm_data_len);
10621063
isert_dbg("Transfer Immediate imm_data_len: %d\n",
10631064
imm_data_len);
10641065
}
@@ -1127,9 +1128,9 @@ isert_handle_iscsi_dataout(struct isert_conn *isert_conn,
11271128
}
11281129
isert_dbg("Copying DataOut: sg_start: %p, sg_off: %u "
11291130
"sg_nents: %u from %p %u\n", sg_start, sg_off,
1130-
sg_nents, &rx_desc->data[0], unsol_data_len);
1131+
sg_nents, isert_get_data(rx_desc), unsol_data_len);
11311132

1132-
sg_copy_from_buffer(sg_start, sg_nents, &rx_desc->data[0],
1133+
sg_copy_from_buffer(sg_start, sg_nents, isert_get_data(rx_desc),
11331134
unsol_data_len);
11341135

11351136
rc = iscsit_check_dataout_payload(cmd, hdr, false);
@@ -1188,7 +1189,7 @@ isert_handle_text_cmd(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd
11881189
}
11891190
cmd->text_in_ptr = text_in;
11901191

1191-
memcpy(cmd->text_in_ptr, &rx_desc->data[0], payload_length);
1192+
memcpy(cmd->text_in_ptr, isert_get_data(rx_desc), payload_length);
11921193

11931194
return iscsit_process_text_cmd(conn, cmd, hdr);
11941195
}
@@ -1198,7 +1199,7 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc,
11981199
uint32_t read_stag, uint64_t read_va,
11991200
uint32_t write_stag, uint64_t write_va)
12001201
{
1201-
struct iscsi_hdr *hdr = &rx_desc->iscsi_header;
1202+
struct iscsi_hdr *hdr = isert_get_iscsi_hdr(rx_desc);
12021203
struct iscsi_conn *conn = isert_conn->conn;
12031204
struct iscsi_cmd *cmd;
12041205
struct isert_cmd *isert_cmd;
@@ -1296,8 +1297,8 @@ isert_recv_done(struct ib_cq *cq, struct ib_wc *wc)
12961297
struct isert_conn *isert_conn = wc->qp->qp_context;
12971298
struct ib_device *ib_dev = isert_conn->cm_id->device;
12981299
struct iser_rx_desc *rx_desc = cqe_to_rx_desc(wc->wr_cqe);
1299-
struct iscsi_hdr *hdr = &rx_desc->iscsi_header;
1300-
struct iser_ctrl *iser_ctrl = &rx_desc->iser_header;
1300+
struct iscsi_hdr *hdr = isert_get_iscsi_hdr(rx_desc);
1301+
struct iser_ctrl *iser_ctrl = isert_get_iser_hdr(rx_desc);
13011302
uint64_t read_va = 0, write_va = 0;
13021303
uint32_t read_stag = 0, write_stag = 0;
13031304

@@ -1311,7 +1312,7 @@ isert_recv_done(struct ib_cq *cq, struct ib_wc *wc)
13111312
rx_desc->in_use = true;
13121313

13131314
ib_dma_sync_single_for_cpu(ib_dev, rx_desc->dma_addr,
1314-
ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
1315+
ISER_RX_SIZE, DMA_FROM_DEVICE);
13151316

13161317
isert_dbg("DMA: 0x%llx, iSCSI opcode: 0x%02x, ITT: 0x%08x, flags: 0x%02x dlen: %d\n",
13171318
rx_desc->dma_addr, hdr->opcode, hdr->itt, hdr->flags,
@@ -1346,7 +1347,7 @@ isert_recv_done(struct ib_cq *cq, struct ib_wc *wc)
13461347
read_stag, read_va, write_stag, write_va);
13471348

13481349
ib_dma_sync_single_for_device(ib_dev, rx_desc->dma_addr,
1349-
ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
1350+
ISER_RX_SIZE, DMA_FROM_DEVICE);
13501351
}
13511352

13521353
static void
@@ -1360,8 +1361,8 @@ isert_login_recv_done(struct ib_cq *cq, struct ib_wc *wc)
13601361
return;
13611362
}
13621363

1363-
ib_dma_sync_single_for_cpu(ib_dev, isert_conn->login_req_dma,
1364-
ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
1364+
ib_dma_sync_single_for_cpu(ib_dev, isert_conn->login_desc->dma_addr,
1365+
ISER_RX_SIZE, DMA_FROM_DEVICE);
13651366

13661367
isert_conn->login_req_len = wc->byte_len - ISER_HEADERS_LEN;
13671368

@@ -1376,8 +1377,8 @@ isert_login_recv_done(struct ib_cq *cq, struct ib_wc *wc)
13761377
complete(&isert_conn->login_req_comp);
13771378
mutex_unlock(&isert_conn->mutex);
13781379

1379-
ib_dma_sync_single_for_device(ib_dev, isert_conn->login_req_dma,
1380-
ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
1380+
ib_dma_sync_single_for_device(ib_dev, isert_conn->login_desc->dma_addr,
1381+
ISER_RX_SIZE, DMA_FROM_DEVICE);
13811382
}
13821383

13831384
static void

drivers/infiniband/ulp/isert/ib_isert.h

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,11 @@
5959
ISERT_MAX_TX_MISC_PDUS + \
6060
ISERT_MAX_RX_MISC_PDUS)
6161

62-
#define ISER_RX_PAD_SIZE (ISCSI_DEF_MAX_RECV_SEG_LEN + 4096 - \
63-
(ISER_RX_PAYLOAD_SIZE + sizeof(u64) + sizeof(struct ib_sge) + \
64-
sizeof(struct ib_cqe) + sizeof(bool)))
62+
/*
63+
* RX size is default of 8k plus headers, but data needs to align to
64+
* 512 boundary, so use 1024 to have the extra space for alignment.
65+
*/
66+
#define ISER_RX_SIZE (ISCSI_DEF_MAX_RECV_SEG_LEN + 1024)
6567

6668
/* Maximum support is 16MB I/O size */
6769
#define ISCSI_ISER_MAX_SG_TABLESIZE 4096
@@ -81,21 +83,41 @@ enum iser_conn_state {
8183
};
8284

8385
struct iser_rx_desc {
84-
struct iser_ctrl iser_header;
85-
struct iscsi_hdr iscsi_header;
86-
char data[ISCSI_DEF_MAX_RECV_SEG_LEN];
86+
char buf[ISER_RX_SIZE];
8787
u64 dma_addr;
8888
struct ib_sge rx_sg;
8989
struct ib_cqe rx_cqe;
9090
bool in_use;
91-
char pad[ISER_RX_PAD_SIZE];
92-
} __packed;
91+
};
9392

9493
static inline struct iser_rx_desc *cqe_to_rx_desc(struct ib_cqe *cqe)
9594
{
9695
return container_of(cqe, struct iser_rx_desc, rx_cqe);
9796
}
9897

98+
static void *isert_get_iser_hdr(struct iser_rx_desc *desc)
99+
{
100+
return PTR_ALIGN(desc->buf + ISER_HEADERS_LEN, 512) - ISER_HEADERS_LEN;
101+
}
102+
103+
static size_t isert_get_hdr_offset(struct iser_rx_desc *desc)
104+
{
105+
return isert_get_iser_hdr(desc) - (void *)desc->buf;
106+
}
107+
108+
static void *isert_get_iscsi_hdr(struct iser_rx_desc *desc)
109+
{
110+
return isert_get_iser_hdr(desc) + sizeof(struct iser_ctrl);
111+
}
112+
113+
static void *isert_get_data(struct iser_rx_desc *desc)
114+
{
115+
void *data = isert_get_iser_hdr(desc) + ISER_HEADERS_LEN;
116+
117+
WARN_ON((uintptr_t)data & 511);
118+
return data;
119+
}
120+
99121
struct iser_tx_desc {
100122
struct iser_ctrl iser_header;
101123
struct iscsi_hdr iscsi_header;
@@ -142,9 +164,8 @@ struct isert_conn {
142164
u32 responder_resources;
143165
u32 initiator_depth;
144166
bool pi_support;
145-
struct iser_rx_desc *login_req_buf;
167+
struct iser_rx_desc *login_desc;
146168
char *login_rsp_buf;
147-
u64 login_req_dma;
148169
int login_req_len;
149170
u64 login_rsp_dma;
150171
struct iser_rx_desc *rx_descs;

0 commit comments

Comments
 (0)