Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iser-target: Change the recv buffers posting logic

iser target batches post recv operations to avoid
the overhead of acquiring the recv queue lock and
posting a HW doorbell for each command.

We change it to be per command in order to support
zcopy immediate data for IOs that fits in the 8K
transfer boundary (in the next patch).

(Fix minor patch fuzz due to ib_mr removal - nab)

Signed-off-by: Jenny Derzhavetz <jennyf@mellanox.com>
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

authored by

Jenny Derzhavetz and committed by
Nicholas Bellinger
4366b19c bd379220

+67 -48
+65 -46
drivers/infiniband/ulp/isert/ib_isert.c
··· 238 238 rx_sg->lkey = device->pd->local_dma_lkey; 239 239 } 240 240 241 - isert_conn->rx_desc_head = 0; 242 - 243 241 return 0; 244 242 245 243 dma_map_fail: ··· 1000 1002 } 1001 1003 1002 1004 static int 1003 - isert_post_recv(struct isert_conn *isert_conn, u32 count) 1005 + isert_post_recvm(struct isert_conn *isert_conn, u32 count) 1004 1006 { 1005 1007 struct ib_recv_wr *rx_wr, *rx_wr_failed; 1006 1008 int i, ret; 1007 - unsigned int rx_head = isert_conn->rx_desc_head; 1008 1009 struct iser_rx_desc *rx_desc; 1009 1010 1010 1011 for (rx_wr = isert_conn->rx_wr, i = 0; i < count; i++, rx_wr++) { 1011 - rx_desc = &isert_conn->rx_descs[rx_head]; 1012 - rx_wr->wr_id = (uintptr_t)rx_desc; 1013 - rx_wr->sg_list = &rx_desc->rx_sg; 1014 - rx_wr->num_sge = 1; 1015 - rx_wr->next = rx_wr + 1; 1016 - rx_head = (rx_head + 1) & (ISERT_QP_MAX_RECV_DTOS - 1); 1012 + rx_desc = &isert_conn->rx_descs[i]; 1013 + rx_wr->wr_id = (uintptr_t)rx_desc; 1014 + rx_wr->sg_list = &rx_desc->rx_sg; 1015 + rx_wr->num_sge = 1; 1016 + rx_wr->next = rx_wr + 1; 1017 1017 } 1018 - 1019 1018 rx_wr--; 1020 1019 rx_wr->next = NULL; /* mark end of work requests list */ 1021 1020 1022 1021 isert_conn->post_recv_buf_count += count; 1023 1022 ret = ib_post_recv(isert_conn->qp, isert_conn->rx_wr, 1024 - &rx_wr_failed); 1023 + &rx_wr_failed); 1025 1024 if (ret) { 1026 1025 isert_err("ib_post_recv() failed with ret: %d\n", ret); 1027 1026 isert_conn->post_recv_buf_count -= count; 1028 - } else { 1029 - isert_dbg("Posted %d RX buffers\n", count); 1030 - isert_conn->rx_desc_head = rx_head; 1031 1027 } 1028 + 1029 + return ret; 1030 + } 1031 + 1032 + static int 1033 + isert_post_recv(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc) 1034 + { 1035 + struct ib_recv_wr *rx_wr_failed, rx_wr; 1036 + int ret; 1037 + 1038 + rx_wr.wr_id = (uintptr_t)rx_desc; 1039 + rx_wr.sg_list = &rx_desc->rx_sg; 1040 + rx_wr.num_sge = 1; 1041 + rx_wr.next = NULL; 1042 + 1043 + isert_conn->post_recv_buf_count++; 1044 + ret = ib_post_recv(isert_conn->qp, &rx_wr, &rx_wr_failed); 1045 + if (ret) { 1046 + isert_err("ib_post_recv() failed with ret: %d\n", ret); 1047 + isert_conn->post_recv_buf_count--; 1048 + } 1049 + 1032 1050 return ret; 1033 1051 } 1034 1052 ··· 1215 1201 if (ret) 1216 1202 return ret; 1217 1203 1218 - ret = isert_post_recv(isert_conn, ISERT_MIN_POSTED_RX); 1204 + ret = isert_post_recvm(isert_conn, 1205 + ISERT_QP_MAX_RECV_DTOS); 1219 1206 if (ret) 1220 1207 return ret; 1221 1208 ··· 1289 1274 } 1290 1275 1291 1276 static struct iscsi_cmd 1292 - *isert_allocate_cmd(struct iscsi_conn *conn) 1277 + *isert_allocate_cmd(struct iscsi_conn *conn, struct iser_rx_desc *rx_desc) 1293 1278 { 1294 1279 struct isert_conn *isert_conn = conn->context; 1295 1280 struct isert_cmd *isert_cmd; ··· 1303 1288 isert_cmd = iscsit_priv_cmd(cmd); 1304 1289 isert_cmd->conn = isert_conn; 1305 1290 isert_cmd->iscsi_cmd = cmd; 1291 + isert_cmd->rx_desc = rx_desc; 1306 1292 1307 1293 return cmd; 1308 1294 } ··· 1419 1403 if (rc < 0) 1420 1404 return rc; 1421 1405 1406 + /* 1407 + * multiple data-outs on the same command can arrive - 1408 + * so post the buffer before hand 1409 + */ 1410 + rc = isert_post_recv(isert_conn, rx_desc); 1411 + if (rc) { 1412 + isert_err("ib_post_recv failed with %d\n", rc); 1413 + return rc; 1414 + } 1422 1415 return 0; 1423 1416 } 1424 1417 ··· 1500 1475 1501 1476 switch (opcode) { 1502 1477 case ISCSI_OP_SCSI_CMD: 1503 - cmd = isert_allocate_cmd(conn); 1478 + cmd = isert_allocate_cmd(conn, rx_desc); 1504 1479 if (!cmd) 1505 1480 break; 1506 1481 ··· 1514 1489 rx_desc, (unsigned char *)hdr); 1515 1490 break; 1516 1491 case ISCSI_OP_NOOP_OUT: 1517 - cmd = isert_allocate_cmd(conn); 1492 + cmd = isert_allocate_cmd(conn, rx_desc); 1518 1493 if (!cmd) 1519 1494 break; 1520 1495 ··· 1527 1502 (unsigned char *)hdr); 1528 1503 break; 1529 1504 case ISCSI_OP_SCSI_TMFUNC: 1530 - cmd = isert_allocate_cmd(conn); 1505 + cmd = isert_allocate_cmd(conn, rx_desc); 1531 1506 if (!cmd) 1532 1507 break; 1533 1508 ··· 1535 1510 (unsigned char *)hdr); 1536 1511 break; 1537 1512 case ISCSI_OP_LOGOUT: 1538 - cmd = isert_allocate_cmd(conn); 1513 + cmd = isert_allocate_cmd(conn, rx_desc); 1539 1514 if (!cmd) 1540 1515 break; 1541 1516 1542 1517 ret = iscsit_handle_logout_cmd(conn, cmd, (unsigned char *)hdr); 1543 1518 break; 1544 1519 case ISCSI_OP_TEXT: 1545 - if (be32_to_cpu(hdr->ttt) != 0xFFFFFFFF) { 1520 + if (be32_to_cpu(hdr->ttt) != 0xFFFFFFFF) 1546 1521 cmd = iscsit_find_cmd_from_itt(conn, hdr->itt); 1547 - if (!cmd) 1548 - break; 1549 - } else { 1550 - cmd = isert_allocate_cmd(conn); 1551 - if (!cmd) 1552 - break; 1553 - } 1522 + else 1523 + cmd = isert_allocate_cmd(conn, rx_desc); 1524 + 1525 + if (!cmd) 1526 + break; 1554 1527 1555 1528 isert_cmd = iscsit_priv_cmd(cmd); 1556 1529 ret = isert_handle_text_cmd(isert_conn, isert_cmd, cmd, ··· 1608 1585 struct ib_device *ib_dev = isert_conn->cm_id->device; 1609 1586 struct iscsi_hdr *hdr; 1610 1587 u64 rx_dma; 1611 - int rx_buflen, outstanding; 1588 + int rx_buflen; 1612 1589 1613 1590 if ((char *)desc == isert_conn->login_req_buf) { 1614 1591 rx_dma = isert_conn->login_req_dma; ··· 1648 1625 DMA_FROM_DEVICE); 1649 1626 1650 1627 isert_conn->post_recv_buf_count--; 1651 - isert_dbg("Decremented post_recv_buf_count: %d\n", 1652 - isert_conn->post_recv_buf_count); 1653 - 1654 - if ((char *)desc == isert_conn->login_req_buf) 1655 - return; 1656 - 1657 - outstanding = isert_conn->post_recv_buf_count; 1658 - if (outstanding + ISERT_MIN_POSTED_RX <= ISERT_QP_MAX_RECV_DTOS) { 1659 - int err, count = min(ISERT_QP_MAX_RECV_DTOS - outstanding, 1660 - ISERT_MIN_POSTED_RX); 1661 - err = isert_post_recv(isert_conn, count); 1662 - if (err) { 1663 - isert_err("isert_post_recv() count: %d failed, %d\n", 1664 - count, err); 1665 - } 1666 - } 1667 1628 } 1668 1629 1669 1630 static int ··· 2158 2151 { 2159 2152 struct ib_send_wr *wr_failed; 2160 2153 int ret; 2154 + 2155 + ret = isert_post_recv(isert_conn, isert_cmd->rx_desc); 2156 + if (ret) { 2157 + isert_err("ib_post_recv failed with %d\n", ret); 2158 + return ret; 2159 + } 2161 2160 2162 2161 ret = ib_post_send(isert_conn->qp, &isert_cmd->tx_desc.send_wr, 2163 2162 &wr_failed); ··· 2959 2946 &isert_cmd->tx_desc.send_wr); 2960 2947 isert_cmd->rdma_wr.s_send_wr.next = &isert_cmd->tx_desc.send_wr; 2961 2948 wr->send_wr_num += 1; 2949 + 2950 + rc = isert_post_recv(isert_conn, isert_cmd->rx_desc); 2951 + if (rc) { 2952 + isert_err("ib_post_recv failed with %d\n", rc); 2953 + return rc; 2954 + } 2962 2955 } 2963 2956 2964 2957 rc = ib_post_send(isert_conn->qp, wr->send_wr, &wr_failed);
+2 -2
drivers/infiniband/ulp/isert/ib_isert.h
··· 136 136 struct isert_conn *conn; 137 137 struct iscsi_cmd *iscsi_cmd; 138 138 struct iser_tx_desc tx_desc; 139 + struct iser_rx_desc *rx_desc; 139 140 struct isert_rdma_wr rdma_wr; 140 141 struct work_struct comp_work; 141 142 }; ··· 156 155 u64 login_req_dma; 157 156 int login_req_len; 158 157 u64 login_rsp_dma; 159 - unsigned int rx_desc_head; 160 158 struct iser_rx_desc *rx_descs; 161 - struct ib_recv_wr rx_wr[ISERT_MIN_POSTED_RX]; 159 + struct ib_recv_wr rx_wr[ISERT_QP_MAX_RECV_DTOS]; 162 160 struct iscsi_conn *conn; 163 161 struct list_head node; 164 162 struct completion login_comp;