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

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma

Pull rdma updates from Jason Gunthorpe:
"Small cycle, with some typical driver updates:

- General code tidying in siw, hfi1, idrdma, usnic, hns rtrs and
bnxt_re

- Many small siw cleanups without an overeaching theme

- Debugfs stats for hns

- Fix a TX queue timeout in IPoIB and missed locking of the mcast
list

- Support more features of P7 devices in bnxt_re including a new work
submission protocol

- CQ interrupts for MANA

- netlink stats for erdma

- EFA multipath PCI support

- Fix Incorrect MR invalidation in iser"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (66 commits)
RDMA/bnxt_re: Fix error code in bnxt_re_create_cq()
RDMA/efa: Add EFA query MR support
IB/iser: Prevent invalidating wrong MR
RDMA/erdma: Add hardware statistics support
RDMA/erdma: Introduce dma pool for hardware responses of CMDQ requests
IB/iser: iscsi_iser.h: fix kernel-doc warning and spellos
RDMA/mana_ib: Add CQ interrupt support for RAW QP
RDMA/mana_ib: query device capabilities
RDMA/mana_ib: register RDMA device with GDMA
RDMA/bnxt_re: Fix the sparse warnings
RDMA/bnxt_re: Fix the offset for GenP7 adapters for user applications
RDMA/bnxt_re: Share a page to expose per CQ info with userspace
RDMA/bnxt_re: Add UAPI to share a page with user space
IB/ipoib: Fix mcast list locking
RDMA/mlx5: Expose register c0 for RDMA device
net/mlx5: E-Switch, expose eswitch manager vport
net/mlx5: Manage ICM type of SW encap
RDMA/mlx5: Support handling of SW encap ICM area
net/mlx5: Introduce indirect-sw-encap ICM properties
RDMA/bnxt_re: Adds MSN table capability for Gen P7 adapters
...

+1922 -639
+3
drivers/infiniband/hw/bnxt_re/bnxt_re.h
··· 41 41 #define __BNXT_RE_H__ 42 42 #include <rdma/uverbs_ioctl.h> 43 43 #include "hw_counters.h" 44 + #include <linux/hashtable.h> 44 45 #define ROCE_DRV_MODULE_NAME "bnxt_re" 45 46 46 47 #define BNXT_RE_DESC "Broadcom NetXtreme-C/E RoCE Driver" ··· 136 135 #define BNXT_RE_DB_FIFO_ROOM_SHIFT 15 137 136 #define BNXT_RE_GRC_FIFO_REG_BASE 0x2000 138 137 138 + #define MAX_CQ_HASH_BITS (16) 139 139 struct bnxt_re_dev { 140 140 struct ib_device ibdev; 141 141 struct list_head list; ··· 191 189 struct bnxt_re_pacing pacing; 192 190 struct work_struct dbq_fifo_check_work; 193 191 struct delayed_work dbq_pacing_work; 192 + DECLARE_HASHTABLE(cq_hash, MAX_CQ_HASH_BITS); 194 193 }; 195 194 196 195 #define to_bnxt_re_dev(ptr, member) \
+2 -2
drivers/infiniband/hw/bnxt_re/hw_counters.c
··· 371 371 } 372 372 373 373 done: 374 - return bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ? 374 + return bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx) ? 375 375 BNXT_RE_NUM_EXT_COUNTERS : BNXT_RE_NUM_STD_COUNTERS; 376 376 } 377 377 ··· 381 381 struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev); 382 382 int num_counters = 0; 383 383 384 - if (bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) 384 + if (bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)) 385 385 num_counters = BNXT_RE_NUM_EXT_COUNTERS; 386 386 else 387 387 num_counters = BNXT_RE_NUM_STD_COUNTERS;
+204 -31
drivers/infiniband/hw/bnxt_re/ib_verbs.c
··· 50 50 #include <rdma/ib_mad.h> 51 51 #include <rdma/ib_cache.h> 52 52 #include <rdma/uverbs_ioctl.h> 53 + #include <linux/hashtable.h> 53 54 54 55 #include "bnxt_ulp.h" 55 56 ··· 568 567 case BNXT_RE_MMAP_WC_DB: 569 568 case BNXT_RE_MMAP_DBR_BAR: 570 569 case BNXT_RE_MMAP_DBR_PAGE: 570 + case BNXT_RE_MMAP_TOGGLE_PAGE: 571 571 ret = rdma_user_mmap_entry_insert(&uctx->ib_uctx, 572 572 &entry->rdma_entry, PAGE_SIZE); 573 573 break; ··· 1025 1023 bytes = (qplib_qp->sq.max_wqe * qplib_qp->sq.wqe_size); 1026 1024 /* Consider mapping PSN search memory only for RC QPs. */ 1027 1025 if (qplib_qp->type == CMDQ_CREATE_QP_TYPE_RC) { 1028 - psn_sz = bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ? 1026 + psn_sz = bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx) ? 1029 1027 sizeof(struct sq_psn_search_ext) : 1030 1028 sizeof(struct sq_psn_search); 1031 1029 psn_nume = (qplib_qp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ? ··· 1186 1184 } 1187 1185 1188 1186 static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp, 1189 - struct ib_qp_init_attr *init_attr) 1187 + struct ib_qp_init_attr *init_attr, 1188 + struct bnxt_re_ucontext *uctx) 1190 1189 { 1191 1190 struct bnxt_qplib_dev_attr *dev_attr; 1192 1191 struct bnxt_qplib_qp *qplqp; ··· 1216 1213 /* Allocate 1 more than what's provided so posting max doesn't 1217 1214 * mean empty. 1218 1215 */ 1219 - entries = roundup_pow_of_two(init_attr->cap.max_recv_wr + 1); 1216 + entries = bnxt_re_init_depth(init_attr->cap.max_recv_wr + 1, uctx); 1220 1217 rq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + 1); 1221 1218 rq->q_full_delta = 0; 1222 1219 rq->sg_info.pgsize = PAGE_SIZE; ··· 1236 1233 qplqp = &qp->qplib_qp; 1237 1234 dev_attr = &rdev->dev_attr; 1238 1235 1239 - if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) { 1236 + if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)) { 1240 1237 qplqp->rq.max_sge = dev_attr->max_qp_sges; 1241 1238 if (qplqp->rq.max_sge > dev_attr->max_qp_sges) 1242 1239 qplqp->rq.max_sge = dev_attr->max_qp_sges; ··· 1246 1243 1247 1244 static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp, 1248 1245 struct ib_qp_init_attr *init_attr, 1249 - struct ib_udata *udata) 1246 + struct bnxt_re_ucontext *uctx) 1250 1247 { 1251 1248 struct bnxt_qplib_dev_attr *dev_attr; 1252 1249 struct bnxt_qplib_qp *qplqp; ··· 1275 1272 /* Allocate 128 + 1 more than what's provided */ 1276 1273 diff = (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE) ? 1277 1274 0 : BNXT_QPLIB_RESERVED_QP_WRS; 1278 - entries = roundup_pow_of_two(entries + diff + 1); 1275 + entries = bnxt_re_init_depth(entries + diff + 1, uctx); 1279 1276 sq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + diff + 1); 1280 1277 sq->q_full_delta = diff + 1; 1281 1278 /* ··· 1291 1288 } 1292 1289 1293 1290 static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp, 1294 - struct ib_qp_init_attr *init_attr) 1291 + struct ib_qp_init_attr *init_attr, 1292 + struct bnxt_re_ucontext *uctx) 1295 1293 { 1296 1294 struct bnxt_qplib_dev_attr *dev_attr; 1297 1295 struct bnxt_qplib_qp *qplqp; ··· 1303 1299 qplqp = &qp->qplib_qp; 1304 1300 dev_attr = &rdev->dev_attr; 1305 1301 1306 - if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) { 1307 - entries = roundup_pow_of_two(init_attr->cap.max_send_wr + 1); 1302 + if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)) { 1303 + entries = bnxt_re_init_depth(init_attr->cap.max_send_wr + 1, uctx); 1308 1304 qplqp->sq.max_wqe = min_t(u32, entries, 1309 1305 dev_attr->max_qp_wqes + 1); 1310 1306 qplqp->sq.q_full_delta = qplqp->sq.max_wqe - ··· 1330 1326 goto out; 1331 1327 } 1332 1328 1333 - if (bnxt_qplib_is_chip_gen_p5(chip_ctx) && 1329 + if (bnxt_qplib_is_chip_gen_p5_p7(chip_ctx) && 1334 1330 init_attr->qp_type == IB_QPT_GSI) 1335 1331 qptype = CMDQ_CREATE_QP_TYPE_GSI; 1336 1332 out: ··· 1342 1338 struct ib_udata *udata) 1343 1339 { 1344 1340 struct bnxt_qplib_dev_attr *dev_attr; 1341 + struct bnxt_re_ucontext *uctx; 1345 1342 struct bnxt_qplib_qp *qplqp; 1346 1343 struct bnxt_re_dev *rdev; 1347 1344 struct bnxt_re_cq *cq; ··· 1352 1347 qplqp = &qp->qplib_qp; 1353 1348 dev_attr = &rdev->dev_attr; 1354 1349 1350 + uctx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx); 1355 1351 /* Setup misc params */ 1356 1352 ether_addr_copy(qplqp->smac, rdev->netdev->dev_addr); 1357 1353 qplqp->pd = &pd->qplib_pd; ··· 1394 1388 } 1395 1389 1396 1390 /* Setup RQ/SRQ */ 1397 - rc = bnxt_re_init_rq_attr(qp, init_attr); 1391 + rc = bnxt_re_init_rq_attr(qp, init_attr, uctx); 1398 1392 if (rc) 1399 1393 goto out; 1400 1394 if (init_attr->qp_type == IB_QPT_GSI) 1401 1395 bnxt_re_adjust_gsi_rq_attr(qp); 1402 1396 1403 1397 /* Setup SQ */ 1404 - rc = bnxt_re_init_sq_attr(qp, init_attr, udata); 1398 + rc = bnxt_re_init_sq_attr(qp, init_attr, uctx); 1405 1399 if (rc) 1406 1400 goto out; 1407 1401 if (init_attr->qp_type == IB_QPT_GSI) 1408 - bnxt_re_adjust_gsi_sq_attr(qp, init_attr); 1402 + bnxt_re_adjust_gsi_sq_attr(qp, init_attr, uctx); 1409 1403 1410 1404 if (udata) /* This will update DPI and qp_handle */ 1411 1405 rc = bnxt_re_init_user_qp(rdev, pd, qp, udata); ··· 1529 1523 goto fail; 1530 1524 1531 1525 if (qp_init_attr->qp_type == IB_QPT_GSI && 1532 - !(bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx))) { 1526 + !(bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx))) { 1533 1527 rc = bnxt_re_create_gsi_qp(qp, pd, qp_init_attr); 1534 1528 if (rc == -ENODEV) 1535 1529 goto qp_destroy; ··· 1721 1715 { 1722 1716 struct bnxt_qplib_dev_attr *dev_attr; 1723 1717 struct bnxt_qplib_nq *nq = NULL; 1718 + struct bnxt_re_ucontext *uctx; 1724 1719 struct bnxt_re_dev *rdev; 1725 1720 struct bnxt_re_srq *srq; 1726 1721 struct bnxt_re_pd *pd; ··· 1746 1739 goto exit; 1747 1740 } 1748 1741 1742 + uctx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx); 1749 1743 srq->rdev = rdev; 1750 1744 srq->qplib_srq.pd = &pd->qplib_pd; 1751 1745 srq->qplib_srq.dpi = &rdev->dpi_privileged; 1752 1746 /* Allocate 1 more than what's provided so posting max doesn't 1753 1747 * mean empty 1754 1748 */ 1755 - entries = roundup_pow_of_two(srq_init_attr->attr.max_wr + 1); 1749 + entries = bnxt_re_init_depth(srq_init_attr->attr.max_wr + 1, uctx); 1756 1750 if (entries > dev_attr->max_srq_wqes + 1) 1757 1751 entries = dev_attr->max_srq_wqes + 1; 1758 1752 srq->qplib_srq.max_wqe = entries; ··· 2111 2103 qp->qplib_qp.max_dest_rd_atomic = qp_attr->max_dest_rd_atomic; 2112 2104 } 2113 2105 if (qp_attr_mask & IB_QP_CAP) { 2106 + struct bnxt_re_ucontext *uctx = 2107 + rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx); 2108 + 2114 2109 qp->qplib_qp.modify_flags |= 2115 2110 CMDQ_MODIFY_QP_MODIFY_MASK_SQ_SIZE | 2116 2111 CMDQ_MODIFY_QP_MODIFY_MASK_RQ_SIZE | ··· 2130 2119 "Create QP failed - max exceeded"); 2131 2120 return -EINVAL; 2132 2121 } 2133 - entries = roundup_pow_of_two(qp_attr->cap.max_send_wr); 2122 + entries = bnxt_re_init_depth(qp_attr->cap.max_send_wr, uctx); 2134 2123 qp->qplib_qp.sq.max_wqe = min_t(u32, entries, 2135 2124 dev_attr->max_qp_wqes + 1); 2136 2125 qp->qplib_qp.sq.q_full_delta = qp->qplib_qp.sq.max_wqe - ··· 2143 2132 qp->qplib_qp.sq.q_full_delta -= 1; 2144 2133 qp->qplib_qp.sq.max_sge = qp_attr->cap.max_send_sge; 2145 2134 if (qp->qplib_qp.rq.max_wqe) { 2146 - entries = roundup_pow_of_two(qp_attr->cap.max_recv_wr); 2135 + entries = bnxt_re_init_depth(qp_attr->cap.max_recv_wr, uctx); 2147 2136 qp->qplib_qp.rq.max_wqe = 2148 2137 min_t(u32, entries, dev_attr->max_qp_wqes + 1); 2149 2138 qp->qplib_qp.rq.q_full_delta = qp->qplib_qp.rq.max_wqe - ··· 2911 2900 /* Completion Queues */ 2912 2901 int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata) 2913 2902 { 2914 - struct bnxt_re_cq *cq; 2903 + struct bnxt_qplib_chip_ctx *cctx; 2915 2904 struct bnxt_qplib_nq *nq; 2916 2905 struct bnxt_re_dev *rdev; 2906 + struct bnxt_re_cq *cq; 2917 2907 2918 2908 cq = container_of(ib_cq, struct bnxt_re_cq, ib_cq); 2919 2909 rdev = cq->rdev; 2920 2910 nq = cq->qplib_cq.nq; 2911 + cctx = rdev->chip_ctx; 2921 2912 2913 + if (cctx->modes.toggle_bits & BNXT_QPLIB_CQ_TOGGLE_BIT) { 2914 + free_page((unsigned long)cq->uctx_cq_page); 2915 + hash_del(&cq->hash_entry); 2916 + } 2922 2917 bnxt_qplib_destroy_cq(&rdev->qplib_res, &cq->qplib_cq); 2923 2918 ib_umem_release(cq->umem); 2924 2919 ··· 2937 2920 int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, 2938 2921 struct ib_udata *udata) 2939 2922 { 2940 - struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibcq->device, ibdev); 2941 - struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr; 2942 2923 struct bnxt_re_cq *cq = container_of(ibcq, struct bnxt_re_cq, ib_cq); 2943 - int rc, entries; 2944 - int cqe = attr->cqe; 2924 + struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibcq->device, ibdev); 2925 + struct bnxt_re_ucontext *uctx = 2926 + rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx); 2927 + struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr; 2928 + struct bnxt_qplib_chip_ctx *cctx; 2945 2929 struct bnxt_qplib_nq *nq = NULL; 2946 2930 unsigned int nq_alloc_cnt; 2931 + int cqe = attr->cqe; 2932 + int rc, entries; 2947 2933 u32 active_cqs; 2948 2934 2949 2935 if (attr->flags) ··· 2959 2939 } 2960 2940 2961 2941 cq->rdev = rdev; 2942 + cctx = rdev->chip_ctx; 2962 2943 cq->qplib_cq.cq_handle = (u64)(unsigned long)(&cq->qplib_cq); 2963 2944 2964 - entries = roundup_pow_of_two(cqe + 1); 2945 + entries = bnxt_re_init_depth(cqe + 1, uctx); 2965 2946 if (entries > dev_attr->max_cq_wqes + 1) 2966 2947 entries = dev_attr->max_cq_wqes + 1; 2967 2948 ··· 2970 2949 cq->qplib_cq.sg_info.pgshft = PAGE_SHIFT; 2971 2950 if (udata) { 2972 2951 struct bnxt_re_cq_req req; 2973 - struct bnxt_re_ucontext *uctx = rdma_udata_to_drv_context( 2974 - udata, struct bnxt_re_ucontext, ib_uctx); 2975 2952 if (ib_copy_from_udata(&req, udata, sizeof(req))) { 2976 2953 rc = -EFAULT; 2977 2954 goto fail; ··· 3021 3002 spin_lock_init(&cq->cq_lock); 3022 3003 3023 3004 if (udata) { 3024 - struct bnxt_re_cq_resp resp; 3005 + struct bnxt_re_cq_resp resp = {}; 3025 3006 3007 + if (cctx->modes.toggle_bits & BNXT_QPLIB_CQ_TOGGLE_BIT) { 3008 + hash_add(rdev->cq_hash, &cq->hash_entry, cq->qplib_cq.id); 3009 + /* Allocate a page */ 3010 + cq->uctx_cq_page = (void *)get_zeroed_page(GFP_KERNEL); 3011 + if (!cq->uctx_cq_page) { 3012 + rc = -ENOMEM; 3013 + goto c2fail; 3014 + } 3015 + resp.comp_mask |= BNXT_RE_CQ_TOGGLE_PAGE_SUPPORT; 3016 + } 3026 3017 resp.cqid = cq->qplib_cq.id; 3027 3018 resp.tail = cq->qplib_cq.hwq.cons; 3028 3019 resp.phase = cq->qplib_cq.period; 3029 3020 resp.rsvd = 0; 3030 - rc = ib_copy_to_udata(udata, &resp, sizeof(resp)); 3021 + rc = ib_copy_to_udata(udata, &resp, min(sizeof(resp), udata->outlen)); 3031 3022 if (rc) { 3032 3023 ibdev_err(&rdev->ibdev, "Failed to copy CQ udata"); 3033 3024 bnxt_qplib_destroy_cq(&rdev->qplib_res, &cq->qplib_cq); 3034 - goto c2fail; 3025 + goto free_mem; 3035 3026 } 3036 3027 } 3037 3028 3038 3029 return 0; 3039 3030 3031 + free_mem: 3032 + free_page((unsigned long)cq->uctx_cq_page); 3040 3033 c2fail: 3041 3034 ib_umem_release(cq->umem); 3042 3035 fail: ··· 3103 3072 return -EINVAL; 3104 3073 } 3105 3074 3106 - entries = roundup_pow_of_two(cqe + 1); 3075 + uctx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx); 3076 + entries = bnxt_re_init_depth(cqe + 1, uctx); 3107 3077 if (entries > dev_attr->max_cq_wqes + 1) 3108 3078 entries = dev_attr->max_cq_wqes + 1; 3109 3079 3110 - uctx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, 3111 - ib_uctx); 3112 3080 /* uverbs consumer */ 3113 3081 if (ib_copy_from_udata(&req, udata, sizeof(req))) { 3114 3082 rc = -EFAULT; ··· 4138 4108 struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr; 4139 4109 struct bnxt_re_user_mmap_entry *entry; 4140 4110 struct bnxt_re_uctx_resp resp = {}; 4111 + struct bnxt_re_uctx_req ureq = {}; 4141 4112 u32 chip_met_rev_num = 0; 4142 4113 int rc; 4143 4114 ··· 4188 4157 if (rdev->pacing.dbr_pacing) 4189 4158 resp.comp_mask |= BNXT_RE_UCNTX_CMASK_DBR_PACING_ENABLED; 4190 4159 4160 + if (udata->inlen >= sizeof(ureq)) { 4161 + rc = ib_copy_from_udata(&ureq, udata, min(udata->inlen, sizeof(ureq))); 4162 + if (rc) 4163 + goto cfail; 4164 + if (ureq.comp_mask & BNXT_RE_COMP_MASK_REQ_UCNTX_POW2_SUPPORT) { 4165 + resp.comp_mask |= BNXT_RE_UCNTX_CMASK_POW2_DISABLED; 4166 + uctx->cmask |= BNXT_RE_UCNTX_CMASK_POW2_DISABLED; 4167 + } 4168 + } 4169 + 4191 4170 rc = ib_copy_to_udata(udata, &resp, min(udata->outlen, sizeof(resp))); 4192 4171 if (rc) { 4193 4172 ibdev_err(ibdev, "Failed to copy user context"); ··· 4233 4192 bnxt_qplib_dealloc_dpi(&rdev->qplib_res, &uctx->dpi); 4234 4193 uctx->dpi.dbr = NULL; 4235 4194 } 4195 + } 4196 + 4197 + static struct bnxt_re_cq *bnxt_re_search_for_cq(struct bnxt_re_dev *rdev, u32 cq_id) 4198 + { 4199 + struct bnxt_re_cq *cq = NULL, *tmp_cq; 4200 + 4201 + hash_for_each_possible(rdev->cq_hash, tmp_cq, hash_entry, cq_id) { 4202 + if (tmp_cq->qplib_cq.id == cq_id) { 4203 + cq = tmp_cq; 4204 + break; 4205 + } 4206 + } 4207 + return cq; 4236 4208 } 4237 4209 4238 4210 /* Helper function to mmap the virtual memory from user app */ ··· 4289 4235 rdma_entry); 4290 4236 break; 4291 4237 case BNXT_RE_MMAP_DBR_PAGE: 4238 + case BNXT_RE_MMAP_TOGGLE_PAGE: 4292 4239 /* Driver doesn't expect write access for user space */ 4293 4240 if (vma->vm_flags & VM_WRITE) 4294 4241 return -EFAULT; ··· 4466 4411 DECLARE_UVERBS_GLOBAL_METHODS(BNXT_RE_OBJECT_NOTIFY_DRV, 4467 4412 &UVERBS_METHOD(BNXT_RE_METHOD_NOTIFY_DRV)); 4468 4413 4414 + /* Toggle MEM */ 4415 + static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bundle *attrs) 4416 + { 4417 + struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, BNXT_RE_TOGGLE_MEM_HANDLE); 4418 + enum bnxt_re_mmap_flag mmap_flag = BNXT_RE_MMAP_TOGGLE_PAGE; 4419 + enum bnxt_re_get_toggle_mem_type res_type; 4420 + struct bnxt_re_user_mmap_entry *entry; 4421 + struct bnxt_re_ucontext *uctx; 4422 + struct ib_ucontext *ib_uctx; 4423 + struct bnxt_re_dev *rdev; 4424 + struct bnxt_re_cq *cq; 4425 + u64 mem_offset; 4426 + u64 addr = 0; 4427 + u32 length; 4428 + u32 offset; 4429 + u32 cq_id; 4430 + int err; 4431 + 4432 + ib_uctx = ib_uverbs_get_ucontext(attrs); 4433 + if (IS_ERR(ib_uctx)) 4434 + return PTR_ERR(ib_uctx); 4435 + 4436 + err = uverbs_get_const(&res_type, attrs, BNXT_RE_TOGGLE_MEM_TYPE); 4437 + if (err) 4438 + return err; 4439 + 4440 + uctx = container_of(ib_uctx, struct bnxt_re_ucontext, ib_uctx); 4441 + rdev = uctx->rdev; 4442 + 4443 + switch (res_type) { 4444 + case BNXT_RE_CQ_TOGGLE_MEM: 4445 + err = uverbs_copy_from(&cq_id, attrs, BNXT_RE_TOGGLE_MEM_RES_ID); 4446 + if (err) 4447 + return err; 4448 + 4449 + cq = bnxt_re_search_for_cq(rdev, cq_id); 4450 + if (!cq) 4451 + return -EINVAL; 4452 + 4453 + length = PAGE_SIZE; 4454 + addr = (u64)cq->uctx_cq_page; 4455 + mmap_flag = BNXT_RE_MMAP_TOGGLE_PAGE; 4456 + offset = 0; 4457 + break; 4458 + case BNXT_RE_SRQ_TOGGLE_MEM: 4459 + break; 4460 + 4461 + default: 4462 + return -EOPNOTSUPP; 4463 + } 4464 + 4465 + entry = bnxt_re_mmap_entry_insert(uctx, addr, mmap_flag, &mem_offset); 4466 + if (!entry) 4467 + return -ENOMEM; 4468 + 4469 + uobj->object = entry; 4470 + uverbs_finalize_uobj_create(attrs, BNXT_RE_TOGGLE_MEM_HANDLE); 4471 + err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_PAGE, 4472 + &mem_offset, sizeof(mem_offset)); 4473 + if (err) 4474 + return err; 4475 + 4476 + err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_LENGTH, 4477 + &length, sizeof(length)); 4478 + if (err) 4479 + return err; 4480 + 4481 + err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_OFFSET, 4482 + &offset, sizeof(length)); 4483 + if (err) 4484 + return err; 4485 + 4486 + return 0; 4487 + } 4488 + 4489 + static int get_toggle_mem_obj_cleanup(struct ib_uobject *uobject, 4490 + enum rdma_remove_reason why, 4491 + struct uverbs_attr_bundle *attrs) 4492 + { 4493 + struct bnxt_re_user_mmap_entry *entry = uobject->object; 4494 + 4495 + rdma_user_mmap_entry_remove(&entry->rdma_entry); 4496 + return 0; 4497 + } 4498 + 4499 + DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_GET_TOGGLE_MEM, 4500 + UVERBS_ATTR_IDR(BNXT_RE_TOGGLE_MEM_HANDLE, 4501 + BNXT_RE_OBJECT_GET_TOGGLE_MEM, 4502 + UVERBS_ACCESS_NEW, 4503 + UA_MANDATORY), 4504 + UVERBS_ATTR_CONST_IN(BNXT_RE_TOGGLE_MEM_TYPE, 4505 + enum bnxt_re_get_toggle_mem_type, 4506 + UA_MANDATORY), 4507 + UVERBS_ATTR_PTR_IN(BNXT_RE_TOGGLE_MEM_RES_ID, 4508 + UVERBS_ATTR_TYPE(u32), 4509 + UA_MANDATORY), 4510 + UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_PAGE, 4511 + UVERBS_ATTR_TYPE(u64), 4512 + UA_MANDATORY), 4513 + UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_OFFSET, 4514 + UVERBS_ATTR_TYPE(u32), 4515 + UA_MANDATORY), 4516 + UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_LENGTH, 4517 + UVERBS_ATTR_TYPE(u32), 4518 + UA_MANDATORY)); 4519 + 4520 + DECLARE_UVERBS_NAMED_METHOD_DESTROY(BNXT_RE_METHOD_RELEASE_TOGGLE_MEM, 4521 + UVERBS_ATTR_IDR(BNXT_RE_RELEASE_TOGGLE_MEM_HANDLE, 4522 + BNXT_RE_OBJECT_GET_TOGGLE_MEM, 4523 + UVERBS_ACCESS_DESTROY, 4524 + UA_MANDATORY)); 4525 + 4526 + DECLARE_UVERBS_NAMED_OBJECT(BNXT_RE_OBJECT_GET_TOGGLE_MEM, 4527 + UVERBS_TYPE_ALLOC_IDR(get_toggle_mem_obj_cleanup), 4528 + &UVERBS_METHOD(BNXT_RE_METHOD_GET_TOGGLE_MEM), 4529 + &UVERBS_METHOD(BNXT_RE_METHOD_RELEASE_TOGGLE_MEM)); 4530 + 4469 4531 const struct uapi_definition bnxt_re_uapi_defs[] = { 4470 4532 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_ALLOC_PAGE), 4471 4533 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_NOTIFY_DRV), 4534 + UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_GET_TOGGLE_MEM), 4472 4535 {} 4473 4536 };
+10
drivers/infiniband/hw/bnxt_re/ib_verbs.h
··· 108 108 struct ib_umem *umem; 109 109 struct ib_umem *resize_umem; 110 110 int resize_cqe; 111 + void *uctx_cq_page; 112 + struct hlist_node hash_entry; 111 113 }; 112 114 113 115 struct bnxt_re_mr { ··· 142 140 void *shpg; 143 141 spinlock_t sh_lock; /* protect shpg */ 144 142 struct rdma_user_mmap_entry *shpage_mmap; 143 + u64 cmask; 145 144 }; 146 145 147 146 enum bnxt_re_mmap_flag { ··· 151 148 BNXT_RE_MMAP_WC_DB, 152 149 BNXT_RE_MMAP_DBR_PAGE, 153 150 BNXT_RE_MMAP_DBR_BAR, 151 + BNXT_RE_MMAP_TOGGLE_PAGE, 154 152 }; 155 153 156 154 struct bnxt_re_user_mmap_entry { ··· 169 165 static inline u16 bnxt_re_get_rwqe_size(int nsge) 170 166 { 171 167 return sizeof(struct rq_wqe_hdr) + (nsge * sizeof(struct sq_sge)); 168 + } 169 + 170 + static inline u32 bnxt_re_init_depth(u32 ent, struct bnxt_re_ucontext *uctx) 171 + { 172 + return uctx ? (uctx->cmask & BNXT_RE_UCNTX_CMASK_POW2_DISABLED) ? 173 + ent : roundup_pow_of_two(ent) : ent; 172 174 } 173 175 174 176 int bnxt_re_query_device(struct ib_device *ibdev,
+25 -22
drivers/infiniband/hw/bnxt_re/main.c
··· 54 54 #include <rdma/ib_user_verbs.h> 55 55 #include <rdma/ib_umem.h> 56 56 #include <rdma/ib_addr.h> 57 + #include <linux/hashtable.h> 57 58 58 59 #include "bnxt_ulp.h" 59 60 #include "roce_hsi.h" ··· 108 107 dev_info(rdev_to_dev(rdev), 109 108 "Couldn't get DB bar size, Low latency framework is disabled\n"); 110 109 /* set register offsets for both UC and WC */ 111 - res->dpi_tbl.ucreg.offset = res->is_vf ? BNXT_QPLIB_DBR_VF_DB_OFFSET : 112 - BNXT_QPLIB_DBR_PF_DB_OFFSET; 113 - res->dpi_tbl.wcreg.offset = res->dpi_tbl.ucreg.offset; 110 + if (bnxt_qplib_is_chip_gen_p7(cctx)) { 111 + res->dpi_tbl.ucreg.offset = offset; 112 + res->dpi_tbl.wcreg.offset = en_dev->l2_db_size; 113 + } else { 114 + res->dpi_tbl.ucreg.offset = res->is_vf ? BNXT_QPLIB_DBR_VF_DB_OFFSET : 115 + BNXT_QPLIB_DBR_PF_DB_OFFSET; 116 + res->dpi_tbl.wcreg.offset = res->dpi_tbl.ucreg.offset; 117 + } 114 118 115 119 /* If WC mapping is disabled by L2 driver then en_dev->l2_db_size 116 120 * is equal to the DB-Bar actual size. This indicates that L2 ··· 134 128 struct bnxt_qplib_chip_ctx *cctx; 135 129 136 130 cctx = rdev->chip_ctx; 137 - cctx->modes.wqe_mode = bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ? 131 + cctx->modes.wqe_mode = bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx) ? 138 132 mode : BNXT_QPLIB_WQE_MODE_STATIC; 139 133 if (bnxt_re_hwrm_qcaps(rdev)) 140 134 dev_err(rdev_to_dev(rdev), 141 135 "Failed to query hwrm qcaps\n"); 136 + if (bnxt_qplib_is_chip_gen_p7(rdev->chip_ctx)) 137 + cctx->modes.toggle_bits |= BNXT_QPLIB_CQ_TOGGLE_BIT; 142 138 } 143 139 144 140 static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev) ··· 223 215 ctx->srqc_count = min_t(u32, BNXT_RE_MAX_SRQC_COUNT, 224 216 attr->max_srq); 225 217 ctx->cq_count = min_t(u32, BNXT_RE_MAX_CQ_COUNT, attr->max_cq); 226 - if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) 218 + if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)) 227 219 for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) 228 220 rdev->qplib_ctx.tqm_ctx.qcount[i] = 229 221 rdev->dev_attr.tqm_alloc_reqs[i]; ··· 272 264 memset(&rdev->qplib_ctx.vf_res, 0, sizeof(struct bnxt_qplib_vf_res)); 273 265 bnxt_re_limit_pf_res(rdev); 274 266 275 - num_vfs = bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ? 267 + num_vfs = bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx) ? 276 268 BNXT_RE_GEN_P5_MAX_VF : rdev->num_vfs; 277 269 if (num_vfs) 278 270 bnxt_re_limit_vf_res(&rdev->qplib_ctx, num_vfs); ··· 284 276 if (test_bit(BNXT_RE_FLAG_ERR_DEVICE_DETACHED, &rdev->flags)) 285 277 return; 286 278 rdev->num_vfs = pci_sriov_get_totalvfs(rdev->en_dev->pdev); 287 - if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) { 279 + if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)) { 288 280 bnxt_re_set_resource_limits(rdev); 289 281 bnxt_qplib_set_func_resources(&rdev->qplib_res, &rdev->rcfw, 290 282 &rdev->qplib_ctx); ··· 1211 1203 { 1212 1204 struct bnxt_re_cq *cq = container_of(handle, struct bnxt_re_cq, 1213 1205 qplib_cq); 1206 + u32 *cq_ptr; 1214 1207 1215 1208 if (cq->ib_cq.comp_handler) { 1216 - /* Lock comp_handler? */ 1209 + if (cq->uctx_cq_page) { 1210 + cq_ptr = (u32 *)cq->uctx_cq_page; 1211 + *cq_ptr = cq->qplib_cq.toggle; 1212 + } 1217 1213 (*cq->ib_cq.comp_handler)(&cq->ib_cq, cq->ib_cq.cq_context); 1218 1214 } 1219 1215 1220 1216 return 0; 1221 - } 1222 - 1223 - #define BNXT_RE_GEN_P5_PF_NQ_DB 0x10000 1224 - #define BNXT_RE_GEN_P5_VF_NQ_DB 0x4000 1225 - static u32 bnxt_re_get_nqdb_offset(struct bnxt_re_dev *rdev, u16 indx) 1226 - { 1227 - return bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ? 1228 - (rdev->is_virtfn ? BNXT_RE_GEN_P5_VF_NQ_DB : 1229 - BNXT_RE_GEN_P5_PF_NQ_DB) : 1230 - rdev->en_dev->msix_entries[indx].db_offset; 1231 1217 } 1232 1218 1233 1219 static void bnxt_re_cleanup_res(struct bnxt_re_dev *rdev) ··· 1244 1242 bnxt_qplib_init_res(&rdev->qplib_res); 1245 1243 1246 1244 for (i = 1; i < rdev->num_msix ; i++) { 1247 - db_offt = bnxt_re_get_nqdb_offset(rdev, i); 1245 + db_offt = rdev->en_dev->msix_entries[i].db_offset; 1248 1246 rc = bnxt_qplib_enable_nq(rdev->en_dev->pdev, &rdev->nq[i - 1], 1249 1247 i - 1, rdev->en_dev->msix_entries[i].vector, 1250 1248 db_offt, &bnxt_re_cqn_handler, ··· 1655 1653 ibdev_err(&rdev->ibdev, "Failed to allocate CREQ: %#x\n", rc); 1656 1654 goto free_rcfw; 1657 1655 } 1658 - db_offt = bnxt_re_get_nqdb_offset(rdev, BNXT_RE_AEQ_IDX); 1656 + db_offt = rdev->en_dev->msix_entries[BNXT_RE_AEQ_IDX].db_offset; 1659 1657 vid = rdev->en_dev->msix_entries[BNXT_RE_AEQ_IDX].vector; 1660 1658 rc = bnxt_qplib_enable_rcfw_channel(&rdev->rcfw, 1661 1659 vid, db_offt, ··· 1683 1681 bnxt_re_set_resource_limits(rdev); 1684 1682 1685 1683 rc = bnxt_qplib_alloc_ctx(&rdev->qplib_res, &rdev->qplib_ctx, 0, 1686 - bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)); 1684 + bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)); 1687 1685 if (rc) { 1688 1686 ibdev_err(&rdev->ibdev, 1689 1687 "Failed to allocate QPLIB context: %#x\n", rc); ··· 1739 1737 */ 1740 1738 bnxt_re_vf_res_config(rdev); 1741 1739 } 1740 + hash_init(rdev->cq_hash); 1742 1741 1743 1742 return 0; 1744 1743 free_sctx: ··· 1807 1804 return; 1808 1805 1809 1806 /* Currently enabling only for GenP5 adapters */ 1810 - if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) 1807 + if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)) 1811 1808 return; 1812 1809 1813 1810 if (enable) {
+138 -77
drivers/infiniband/hw/bnxt_re/qplib_fp.c
··· 237 237 struct bnxt_qplib_hwq *hwq = &nq->hwq; 238 238 struct nq_base *nqe, **nq_ptr; 239 239 int budget = nq->budget; 240 - u32 sw_cons, raw_cons; 241 240 uintptr_t q_handle; 242 241 u16 type; 243 242 244 243 spin_lock_bh(&hwq->lock); 245 244 /* Service the NQ until empty */ 246 - raw_cons = hwq->cons; 247 245 while (budget--) { 248 - sw_cons = HWQ_CMP(raw_cons, hwq); 249 246 nq_ptr = (struct nq_base **)hwq->pbl_ptr; 250 - nqe = &nq_ptr[NQE_PG(sw_cons)][NQE_IDX(sw_cons)]; 251 - if (!NQE_CMP_VALID(nqe, raw_cons, hwq->max_elements)) 247 + nqe = &nq_ptr[NQE_PG(hwq->cons)][NQE_IDX(hwq->cons)]; 248 + if (!NQE_CMP_VALID(nqe, nq->nq_db.dbinfo.flags)) 252 249 break; 253 250 254 251 /* ··· 273 276 default: 274 277 break; 275 278 } 276 - raw_cons++; 279 + bnxt_qplib_hwq_incr_cons(hwq->max_elements, &hwq->cons, 280 + 1, &nq->nq_db.dbinfo.flags); 277 281 } 278 282 spin_unlock_bh(&hwq->lock); 279 283 } ··· 300 302 struct bnxt_qplib_hwq *hwq = &nq->hwq; 301 303 struct bnxt_qplib_cq *cq; 302 304 int budget = nq->budget; 303 - u32 sw_cons, raw_cons; 304 305 struct nq_base *nqe; 305 306 uintptr_t q_handle; 307 + u32 hw_polled = 0; 306 308 u16 type; 307 309 308 310 spin_lock_bh(&hwq->lock); 309 311 /* Service the NQ until empty */ 310 - raw_cons = hwq->cons; 311 312 while (budget--) { 312 - sw_cons = HWQ_CMP(raw_cons, hwq); 313 - nqe = bnxt_qplib_get_qe(hwq, sw_cons, NULL); 314 - if (!NQE_CMP_VALID(nqe, raw_cons, hwq->max_elements)) 313 + nqe = bnxt_qplib_get_qe(hwq, hwq->cons, NULL); 314 + if (!NQE_CMP_VALID(nqe, nq->nq_db.dbinfo.flags)) 315 315 break; 316 316 317 317 /* ··· 330 334 cq = (struct bnxt_qplib_cq *)(unsigned long)q_handle; 331 335 if (!cq) 332 336 break; 337 + cq->toggle = (le16_to_cpu(nqe->info10_type) & 338 + NQ_CN_TOGGLE_MASK) >> NQ_CN_TOGGLE_SFT; 339 + cq->dbinfo.toggle = cq->toggle; 333 340 bnxt_qplib_armen_db(&cq->dbinfo, 334 341 DBC_DBC_TYPE_CQ_ARMENA); 335 342 spin_lock_bh(&cq->compl_lock); ··· 371 372 "nqe with type = 0x%x not handled\n", type); 372 373 break; 373 374 } 374 - raw_cons++; 375 + hw_polled++; 376 + bnxt_qplib_hwq_incr_cons(hwq->max_elements, &hwq->cons, 377 + 1, &nq->nq_db.dbinfo.flags); 375 378 } 376 - if (hwq->cons != raw_cons) { 377 - hwq->cons = raw_cons; 379 + if (hw_polled) 378 380 bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, true); 379 - } 380 381 spin_unlock_bh(&hwq->lock); 381 382 } 382 383 ··· 504 505 pdev = nq->pdev; 505 506 nq_db = &nq->nq_db; 506 507 508 + nq_db->dbinfo.flags = 0; 507 509 nq_db->reg.bar_id = NQ_CONS_PCI_BAR_REGION; 508 510 nq_db->reg.bar_base = pci_resource_start(pdev, nq_db->reg.bar_id); 509 511 if (!nq_db->reg.bar_base) { ··· 649 649 rc = -ENOMEM; 650 650 goto fail; 651 651 } 652 - 652 + srq->dbinfo.flags = 0; 653 653 bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, 654 654 CMDQ_BASE_OPCODE_CREATE_SRQ, 655 655 sizeof(req)); ··· 703 703 struct bnxt_qplib_srq *srq) 704 704 { 705 705 struct bnxt_qplib_hwq *srq_hwq = &srq->hwq; 706 - u32 sw_prod, sw_cons, count = 0; 706 + u32 count; 707 707 708 - sw_prod = HWQ_CMP(srq_hwq->prod, srq_hwq); 709 - sw_cons = HWQ_CMP(srq_hwq->cons, srq_hwq); 710 - 711 - count = sw_prod > sw_cons ? sw_prod - sw_cons : 712 - srq_hwq->max_elements - sw_cons + sw_prod; 708 + count = __bnxt_qplib_get_avail(srq_hwq); 713 709 if (count > srq->threshold) { 714 710 srq->arm_req = false; 715 711 bnxt_qplib_srq_arm_db(&srq->dbinfo, srq->threshold); ··· 757 761 struct bnxt_qplib_hwq *srq_hwq = &srq->hwq; 758 762 struct rq_wqe *srqe; 759 763 struct sq_sge *hw_sge; 760 - u32 sw_prod, sw_cons, count = 0; 764 + u32 count = 0; 761 765 int i, next; 762 766 763 767 spin_lock(&srq_hwq->lock); ··· 771 775 srq->start_idx = srq->swq[next].next_idx; 772 776 spin_unlock(&srq_hwq->lock); 773 777 774 - sw_prod = HWQ_CMP(srq_hwq->prod, srq_hwq); 775 - srqe = bnxt_qplib_get_qe(srq_hwq, sw_prod, NULL); 778 + srqe = bnxt_qplib_get_qe(srq_hwq, srq_hwq->prod, NULL); 776 779 memset(srqe, 0, srq->wqe_size); 777 780 /* Calculate wqe_size16 and data_len */ 778 781 for (i = 0, hw_sge = (struct sq_sge *)srqe->data; ··· 787 792 srqe->wr_id[0] = cpu_to_le32((u32)next); 788 793 srq->swq[next].wr_id = wqe->wr_id; 789 794 790 - srq_hwq->prod++; 795 + bnxt_qplib_hwq_incr_prod(&srq->dbinfo, srq_hwq, srq->dbinfo.max_slot); 791 796 792 797 spin_lock(&srq_hwq->lock); 793 - sw_prod = HWQ_CMP(srq_hwq->prod, srq_hwq); 794 - /* retaining srq_hwq->cons for this logic 795 - * actually the lock is only required to 796 - * read srq_hwq->cons. 797 - */ 798 - sw_cons = HWQ_CMP(srq_hwq->cons, srq_hwq); 799 - count = sw_prod > sw_cons ? sw_prod - sw_cons : 800 - srq_hwq->max_elements - sw_cons + sw_prod; 798 + count = __bnxt_qplib_get_avail(srq_hwq); 801 799 spin_unlock(&srq_hwq->lock); 802 800 /* Ring DB */ 803 801 bnxt_qplib_ring_prod_db(&srq->dbinfo, DBC_DBC_TYPE_SRQ); ··· 837 849 u32 tbl_indx; 838 850 int rc; 839 851 852 + sq->dbinfo.flags = 0; 840 853 bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, 841 854 CMDQ_BASE_OPCODE_CREATE_QP1, 842 855 sizeof(req)); ··· 874 885 875 886 /* RQ */ 876 887 if (rq->max_wqe) { 888 + rq->dbinfo.flags = 0; 877 889 hwq_attr.res = res; 878 890 hwq_attr.sginfo = &rq->sg_info; 879 891 hwq_attr.stride = sizeof(struct sq_sge); ··· 982 992 u32 tbl_indx; 983 993 u16 nsge; 984 994 995 + if (res->dattr) 996 + qp->dev_cap_flags = res->dattr->dev_cap_flags; 997 + 998 + sq->dbinfo.flags = 0; 985 999 bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, 986 1000 CMDQ_BASE_OPCODE_CREATE_QP, 987 1001 sizeof(req)); ··· 997 1003 998 1004 /* SQ */ 999 1005 if (qp->type == CMDQ_CREATE_QP_TYPE_RC) { 1000 - psn_sz = bnxt_qplib_is_chip_gen_p5(res->cctx) ? 1006 + psn_sz = bnxt_qplib_is_chip_gen_p5_p7(res->cctx) ? 1001 1007 sizeof(struct sq_psn_search_ext) : 1002 1008 sizeof(struct sq_psn_search); 1009 + 1010 + if (BNXT_RE_HW_RETX(qp->dev_cap_flags)) { 1011 + psn_sz = sizeof(struct sq_msn_search); 1012 + qp->msn = 0; 1013 + } 1003 1014 } 1004 1015 1005 1016 hwq_attr.res = res; ··· 1013 1014 hwq_attr.depth = bnxt_qplib_get_depth(sq); 1014 1015 hwq_attr.aux_stride = psn_sz; 1015 1016 hwq_attr.aux_depth = bnxt_qplib_set_sq_size(sq, qp->wqe_mode); 1017 + /* Update msn tbl size */ 1018 + if (BNXT_RE_HW_RETX(qp->dev_cap_flags) && psn_sz) { 1019 + hwq_attr.aux_depth = roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, qp->wqe_mode)); 1020 + qp->msn_tbl_sz = hwq_attr.aux_depth; 1021 + qp->msn = 0; 1022 + } 1023 + 1016 1024 hwq_attr.type = HWQ_TYPE_QUEUE; 1017 1025 rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr); 1018 1026 if (rc) ··· 1046 1040 1047 1041 /* RQ */ 1048 1042 if (!qp->srq) { 1043 + rq->dbinfo.flags = 0; 1049 1044 hwq_attr.res = res; 1050 1045 hwq_attr.sginfo = &rq->sg_info; 1051 1046 hwq_attr.stride = sizeof(struct sq_sge); ··· 1461 1454 static void __clean_cq(struct bnxt_qplib_cq *cq, u64 qp) 1462 1455 { 1463 1456 struct bnxt_qplib_hwq *cq_hwq = &cq->hwq; 1457 + u32 peek_flags, peek_cons; 1464 1458 struct cq_base *hw_cqe; 1465 1459 int i; 1466 1460 1461 + peek_flags = cq->dbinfo.flags; 1462 + peek_cons = cq_hwq->cons; 1467 1463 for (i = 0; i < cq_hwq->max_elements; i++) { 1468 - hw_cqe = bnxt_qplib_get_qe(cq_hwq, i, NULL); 1469 - if (!CQE_CMP_VALID(hw_cqe, i, cq_hwq->max_elements)) 1464 + hw_cqe = bnxt_qplib_get_qe(cq_hwq, peek_cons, NULL); 1465 + if (!CQE_CMP_VALID(hw_cqe, peek_flags)) 1470 1466 continue; 1471 1467 /* 1472 1468 * The valid test of the entry must be done first before ··· 1499 1489 default: 1500 1490 break; 1501 1491 } 1492 + bnxt_qplib_hwq_incr_cons(cq_hwq->max_elements, &peek_cons, 1493 + 1, &peek_flags); 1502 1494 } 1503 1495 } 1504 1496 ··· 1602 1590 return NULL; 1603 1591 } 1604 1592 1593 + /* Fil the MSN table into the next psn row */ 1594 + static void bnxt_qplib_fill_msn_search(struct bnxt_qplib_qp *qp, 1595 + struct bnxt_qplib_swqe *wqe, 1596 + struct bnxt_qplib_swq *swq) 1597 + { 1598 + struct sq_msn_search *msns; 1599 + u32 start_psn, next_psn; 1600 + u16 start_idx; 1601 + 1602 + msns = (struct sq_msn_search *)swq->psn_search; 1603 + msns->start_idx_next_psn_start_psn = 0; 1604 + 1605 + start_psn = swq->start_psn; 1606 + next_psn = swq->next_psn; 1607 + start_idx = swq->slot_idx; 1608 + msns->start_idx_next_psn_start_psn |= 1609 + bnxt_re_update_msn_tbl(start_idx, next_psn, start_psn); 1610 + qp->msn++; 1611 + qp->msn %= qp->msn_tbl_sz; 1612 + } 1613 + 1605 1614 static void bnxt_qplib_fill_psn_search(struct bnxt_qplib_qp *qp, 1606 1615 struct bnxt_qplib_swqe *wqe, 1607 1616 struct bnxt_qplib_swq *swq) ··· 1634 1601 1635 1602 if (!swq->psn_search) 1636 1603 return; 1604 + /* Handle MSN differently on cap flags */ 1605 + if (BNXT_RE_HW_RETX(qp->dev_cap_flags)) { 1606 + bnxt_qplib_fill_msn_search(qp, wqe, swq); 1607 + return; 1608 + } 1609 + psns = (struct sq_psn_search *)swq->psn_search; 1637 1610 psns = swq->psn_search; 1638 1611 psns_ext = swq->psn_ext; 1639 1612 ··· 1650 1611 flg_npsn = ((swq->next_psn << SQ_PSN_SEARCH_NEXT_PSN_SFT) & 1651 1612 SQ_PSN_SEARCH_NEXT_PSN_MASK); 1652 1613 1653 - if (bnxt_qplib_is_chip_gen_p5(qp->cctx)) { 1614 + if (bnxt_qplib_is_chip_gen_p5_p7(qp->cctx)) { 1654 1615 psns_ext->opcode_start_psn = cpu_to_le32(op_spsn); 1655 1616 psns_ext->flags_next_psn = cpu_to_le32(flg_npsn); 1656 1617 psns_ext->start_slot_idx = cpu_to_le16(swq->slot_idx); ··· 1748 1709 return slot; 1749 1710 } 1750 1711 1751 - static void bnxt_qplib_pull_psn_buff(struct bnxt_qplib_q *sq, 1752 - struct bnxt_qplib_swq *swq) 1712 + static void bnxt_qplib_pull_psn_buff(struct bnxt_qplib_qp *qp, struct bnxt_qplib_q *sq, 1713 + struct bnxt_qplib_swq *swq, bool hw_retx) 1753 1714 { 1754 1715 struct bnxt_qplib_hwq *hwq; 1755 1716 u32 pg_num, pg_indx; ··· 1760 1721 if (!hwq->pad_pg) 1761 1722 return; 1762 1723 tail = swq->slot_idx / sq->dbinfo.max_slot; 1724 + if (hw_retx) { 1725 + /* For HW retx use qp msn index */ 1726 + tail = qp->msn; 1727 + tail %= qp->msn_tbl_sz; 1728 + } 1763 1729 pg_num = (tail + hwq->pad_pgofft) / (PAGE_SIZE / hwq->pad_stride); 1764 1730 pg_indx = (tail + hwq->pad_pgofft) % (PAGE_SIZE / hwq->pad_stride); 1765 1731 buff = (void *)(hwq->pad_pg[pg_num] + pg_indx * hwq->pad_stride); ··· 1789 1745 struct bnxt_qplib_swq *swq; 1790 1746 bool sch_handler = false; 1791 1747 u16 wqe_sz, qdf = 0; 1748 + bool msn_update; 1792 1749 void *base_hdr; 1793 1750 void *ext_hdr; 1794 1751 __le32 temp32; ··· 1817 1772 } 1818 1773 1819 1774 swq = bnxt_qplib_get_swqe(sq, &wqe_idx); 1820 - bnxt_qplib_pull_psn_buff(sq, swq); 1775 + bnxt_qplib_pull_psn_buff(qp, sq, swq, BNXT_RE_HW_RETX(qp->dev_cap_flags)); 1821 1776 1822 1777 idx = 0; 1823 1778 swq->slot_idx = hwq->prod; ··· 1849 1804 &idx); 1850 1805 if (data_len < 0) 1851 1806 goto queue_err; 1807 + /* Make sure we update MSN table only for wired wqes */ 1808 + msn_update = true; 1852 1809 /* Specifics */ 1853 1810 switch (wqe->type) { 1854 1811 case BNXT_QPLIB_SWQE_TYPE_SEND: ··· 1891 1844 SQ_SEND_DST_QP_MASK); 1892 1845 ext_sqe->avid = cpu_to_le32(wqe->send.avid & 1893 1846 SQ_SEND_AVID_MASK); 1847 + msn_update = false; 1894 1848 } else { 1895 1849 sqe->length = cpu_to_le32(data_len); 1896 1850 if (qp->mtu) ··· 1949 1901 sqe->wqe_type = wqe->type; 1950 1902 sqe->flags = wqe->flags; 1951 1903 sqe->inv_l_key = cpu_to_le32(wqe->local_inv.inv_l_key); 1952 - 1904 + msn_update = false; 1953 1905 break; 1954 1906 } 1955 1907 case BNXT_QPLIB_SWQE_TYPE_FAST_REG_MR: ··· 1981 1933 PTU_PTE_VALID); 1982 1934 ext_sqe->pblptr = cpu_to_le64(wqe->frmr.pbl_dma_ptr); 1983 1935 ext_sqe->va = cpu_to_le64(wqe->frmr.va); 1936 + msn_update = false; 1984 1937 1985 1938 break; 1986 1939 } ··· 1999 1950 sqe->l_key = cpu_to_le32(wqe->bind.r_key); 2000 1951 ext_sqe->va = cpu_to_le64(wqe->bind.va); 2001 1952 ext_sqe->length_lo = cpu_to_le32(wqe->bind.length); 1953 + msn_update = false; 2002 1954 break; 2003 1955 } 2004 1956 default: ··· 2007 1957 rc = -EINVAL; 2008 1958 goto done; 2009 1959 } 2010 - swq->next_psn = sq->psn & BTH_PSN_MASK; 2011 - bnxt_qplib_fill_psn_search(qp, wqe, swq); 1960 + if (!BNXT_RE_HW_RETX(qp->dev_cap_flags) || msn_update) { 1961 + swq->next_psn = sq->psn & BTH_PSN_MASK; 1962 + bnxt_qplib_fill_psn_search(qp, wqe, swq); 1963 + } 2012 1964 queue_err: 2013 1965 bnxt_qplib_swq_mod_start(sq, wqe_idx); 2014 - bnxt_qplib_hwq_incr_prod(hwq, swq->slots); 1966 + bnxt_qplib_hwq_incr_prod(&sq->dbinfo, hwq, swq->slots); 2015 1967 qp->wqe_cnt++; 2016 1968 done: 2017 1969 if (sch_handler) { ··· 2101 2049 base_hdr->wr_id[0] = cpu_to_le32(wqe_idx); 2102 2050 queue_err: 2103 2051 bnxt_qplib_swq_mod_start(rq, wqe_idx); 2104 - bnxt_qplib_hwq_incr_prod(hwq, swq->slots); 2052 + bnxt_qplib_hwq_incr_prod(&rq->dbinfo, hwq, swq->slots); 2105 2053 done: 2106 2054 if (sch_handler) { 2107 2055 nq_work = kzalloc(sizeof(*nq_work), GFP_ATOMIC); ··· 2138 2086 return -EINVAL; 2139 2087 } 2140 2088 2089 + cq->dbinfo.flags = 0; 2141 2090 hwq_attr.res = res; 2142 2091 hwq_attr.depth = cq->max_wqe; 2143 2092 hwq_attr.stride = sizeof(struct cq_base); ··· 2154 2101 2155 2102 req.dpi = cpu_to_le32(cq->dpi->dpi); 2156 2103 req.cq_handle = cpu_to_le64(cq->cq_handle); 2157 - req.cq_size = cpu_to_le32(cq->hwq.max_elements); 2104 + req.cq_size = cpu_to_le32(cq->max_wqe); 2158 2105 pbl = &cq->hwq.pbl[PBL_LVL_0]; 2159 2106 pg_sz_lvl = (bnxt_qplib_base_pg_size(&cq->hwq) << 2160 2107 CMDQ_CREATE_CQ_PG_SIZE_SFT); ··· 2182 2129 cq->dbinfo.xid = cq->id; 2183 2130 cq->dbinfo.db = cq->dpi->dbr; 2184 2131 cq->dbinfo.priv_db = res->dpi_tbl.priv_db; 2132 + cq->dbinfo.flags = 0; 2133 + cq->dbinfo.toggle = 0; 2185 2134 2186 2135 bnxt_qplib_armen_db(&cq->dbinfo, DBC_DBC_TYPE_CQ_ARMENA); 2187 2136 ··· 2199 2144 { 2200 2145 bnxt_qplib_free_hwq(res, &cq->hwq); 2201 2146 memcpy(&cq->hwq, &cq->resize_hwq, sizeof(cq->hwq)); 2147 + /* Reset only the cons bit in the flags */ 2148 + cq->dbinfo.flags &= ~(1UL << BNXT_QPLIB_FLAG_EPOCH_CONS_SHIFT); 2202 2149 } 2203 2150 2204 2151 int bnxt_qplib_resize_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq, ··· 2297 2240 cqe++; 2298 2241 (*budget)--; 2299 2242 skip_compl: 2300 - bnxt_qplib_hwq_incr_cons(&sq->hwq, sq->swq[last].slots); 2243 + bnxt_qplib_hwq_incr_cons(sq->hwq.max_elements, &sq->hwq.cons, 2244 + sq->swq[last].slots, &sq->dbinfo.flags); 2301 2245 sq->swq_last = sq->swq[last].next_idx; 2302 2246 } 2303 2247 *pcqe = cqe; ··· 2345 2287 cqe->wr_id = rq->swq[last].wr_id; 2346 2288 cqe++; 2347 2289 (*budget)--; 2348 - bnxt_qplib_hwq_incr_cons(&rq->hwq, rq->swq[last].slots); 2290 + bnxt_qplib_hwq_incr_cons(rq->hwq.max_elements, &rq->hwq.cons, 2291 + rq->swq[last].slots, &rq->dbinfo.flags); 2349 2292 rq->swq_last = rq->swq[last].next_idx; 2350 2293 } 2351 2294 *pcqe = cqe; ··· 2375 2316 static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq, 2376 2317 u32 cq_cons, u32 swq_last, u32 cqe_sq_cons) 2377 2318 { 2378 - u32 peek_sw_cq_cons, peek_raw_cq_cons, peek_sq_cons_idx; 2319 + u32 peek_sw_cq_cons, peek_sq_cons_idx, peek_flags; 2379 2320 struct bnxt_qplib_q *sq = &qp->sq; 2380 2321 struct cq_req *peek_req_hwcqe; 2381 2322 struct bnxt_qplib_qp *peek_qp; ··· 2406 2347 } 2407 2348 if (sq->condition) { 2408 2349 /* Peek at the completions */ 2409 - peek_raw_cq_cons = cq->hwq.cons; 2350 + peek_flags = cq->dbinfo.flags; 2410 2351 peek_sw_cq_cons = cq_cons; 2411 2352 i = cq->hwq.max_elements; 2412 2353 while (i--) { 2413 - peek_sw_cq_cons = HWQ_CMP((peek_sw_cq_cons), &cq->hwq); 2414 2354 peek_hwcqe = bnxt_qplib_get_qe(&cq->hwq, 2415 2355 peek_sw_cq_cons, NULL); 2416 2356 /* If the next hwcqe is VALID */ 2417 - if (CQE_CMP_VALID(peek_hwcqe, peek_raw_cq_cons, 2418 - cq->hwq.max_elements)) { 2357 + if (CQE_CMP_VALID(peek_hwcqe, peek_flags)) { 2419 2358 /* 2420 2359 * The valid test of the entry must be done first before 2421 2360 * reading any further. ··· 2456 2399 rc = -EINVAL; 2457 2400 goto out; 2458 2401 } 2459 - peek_sw_cq_cons++; 2460 - peek_raw_cq_cons++; 2402 + bnxt_qplib_hwq_incr_cons(cq->hwq.max_elements, 2403 + &peek_sw_cq_cons, 2404 + 1, &peek_flags); 2461 2405 } 2462 2406 dev_err(&cq->hwq.pdev->dev, 2463 2407 "Should not have come here! cq_cons=0x%x qp=0x%x sq cons sw=0x%x hw=0x%x\n", ··· 2545 2487 } 2546 2488 } 2547 2489 skip: 2548 - bnxt_qplib_hwq_incr_cons(&sq->hwq, swq->slots); 2490 + bnxt_qplib_hwq_incr_cons(sq->hwq.max_elements, &sq->hwq.cons, 2491 + swq->slots, &sq->dbinfo.flags); 2549 2492 sq->swq_last = swq->next_idx; 2550 2493 if (sq->single) 2551 2494 break; ··· 2573 2514 srq->swq[srq->last_idx].next_idx = (int)tag; 2574 2515 srq->last_idx = (int)tag; 2575 2516 srq->swq[srq->last_idx].next_idx = -1; 2576 - srq->hwq.cons++; /* Support for SRQE counter */ 2517 + bnxt_qplib_hwq_incr_cons(srq->hwq.max_elements, &srq->hwq.cons, 2518 + srq->dbinfo.max_slot, &srq->dbinfo.flags); 2577 2519 spin_unlock(&srq->hwq.lock); 2578 2520 } 2579 2521 ··· 2643 2583 cqe->wr_id = swq->wr_id; 2644 2584 cqe++; 2645 2585 (*budget)--; 2646 - bnxt_qplib_hwq_incr_cons(&rq->hwq, swq->slots); 2586 + bnxt_qplib_hwq_incr_cons(rq->hwq.max_elements, &rq->hwq.cons, 2587 + swq->slots, &rq->dbinfo.flags); 2647 2588 rq->swq_last = swq->next_idx; 2648 2589 *pcqe = cqe; 2649 2590 ··· 2730 2669 cqe->wr_id = swq->wr_id; 2731 2670 cqe++; 2732 2671 (*budget)--; 2733 - bnxt_qplib_hwq_incr_cons(&rq->hwq, swq->slots); 2672 + bnxt_qplib_hwq_incr_cons(rq->hwq.max_elements, &rq->hwq.cons, 2673 + swq->slots, &rq->dbinfo.flags); 2734 2674 rq->swq_last = swq->next_idx; 2735 2675 *pcqe = cqe; 2736 2676 ··· 2748 2686 bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq) 2749 2687 { 2750 2688 struct cq_base *hw_cqe; 2751 - u32 sw_cons, raw_cons; 2752 2689 bool rc = true; 2753 2690 2754 - raw_cons = cq->hwq.cons; 2755 - sw_cons = HWQ_CMP(raw_cons, &cq->hwq); 2756 - hw_cqe = bnxt_qplib_get_qe(&cq->hwq, sw_cons, NULL); 2691 + hw_cqe = bnxt_qplib_get_qe(&cq->hwq, cq->hwq.cons, NULL); 2757 2692 /* Check for Valid bit. If the CQE is valid, return false */ 2758 - rc = !CQE_CMP_VALID(hw_cqe, raw_cons, cq->hwq.max_elements); 2693 + rc = !CQE_CMP_VALID(hw_cqe, cq->dbinfo.flags); 2759 2694 return rc; 2760 2695 } 2761 2696 ··· 2834 2775 cqe->wr_id = swq->wr_id; 2835 2776 cqe++; 2836 2777 (*budget)--; 2837 - bnxt_qplib_hwq_incr_cons(&rq->hwq, swq->slots); 2778 + bnxt_qplib_hwq_incr_cons(rq->hwq.max_elements, &rq->hwq.cons, 2779 + swq->slots, &rq->dbinfo.flags); 2838 2780 rq->swq_last = swq->next_idx; 2839 2781 *pcqe = cqe; 2840 2782 ··· 2908 2848 cqe++; 2909 2849 (*budget)--; 2910 2850 } 2911 - bnxt_qplib_hwq_incr_cons(&sq->hwq, sq->swq[swq_last].slots); 2851 + bnxt_qplib_hwq_incr_cons(sq->hwq.max_elements, &sq->hwq.cons, 2852 + sq->swq[swq_last].slots, &sq->dbinfo.flags); 2912 2853 sq->swq_last = sq->swq[swq_last].next_idx; 2913 2854 } 2914 2855 *pcqe = cqe; ··· 2994 2933 int num_cqes, struct bnxt_qplib_qp **lib_qp) 2995 2934 { 2996 2935 struct cq_base *hw_cqe; 2997 - u32 sw_cons, raw_cons; 2998 2936 int budget, rc = 0; 2937 + u32 hw_polled = 0; 2999 2938 u8 type; 3000 2939 3001 - raw_cons = cq->hwq.cons; 3002 2940 budget = num_cqes; 3003 2941 3004 2942 while (budget) { 3005 - sw_cons = HWQ_CMP(raw_cons, &cq->hwq); 3006 - hw_cqe = bnxt_qplib_get_qe(&cq->hwq, sw_cons, NULL); 2943 + hw_cqe = bnxt_qplib_get_qe(&cq->hwq, cq->hwq.cons, NULL); 3007 2944 3008 2945 /* Check for Valid bit */ 3009 - if (!CQE_CMP_VALID(hw_cqe, raw_cons, cq->hwq.max_elements)) 2946 + if (!CQE_CMP_VALID(hw_cqe, cq->dbinfo.flags)) 3010 2947 break; 3011 2948 3012 2949 /* ··· 3019 2960 rc = bnxt_qplib_cq_process_req(cq, 3020 2961 (struct cq_req *)hw_cqe, 3021 2962 &cqe, &budget, 3022 - sw_cons, lib_qp); 2963 + cq->hwq.cons, lib_qp); 3023 2964 break; 3024 2965 case CQ_BASE_CQE_TYPE_RES_RC: 3025 2966 rc = bnxt_qplib_cq_process_res_rc(cq, ··· 3065 3006 dev_err(&cq->hwq.pdev->dev, 3066 3007 "process_cqe error rc = 0x%x\n", rc); 3067 3008 } 3068 - raw_cons++; 3009 + hw_polled++; 3010 + bnxt_qplib_hwq_incr_cons(cq->hwq.max_elements, &cq->hwq.cons, 3011 + 1, &cq->dbinfo.flags); 3012 + 3069 3013 } 3070 - if (cq->hwq.cons != raw_cons) { 3071 - cq->hwq.cons = raw_cons; 3014 + if (hw_polled) 3072 3015 bnxt_qplib_ring_db(&cq->dbinfo, DBC_DBC_TYPE_CQ); 3073 - } 3074 3016 exit: 3075 3017 return num_cqes - budget; 3076 3018 } 3077 3019 3078 3020 void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type) 3079 3021 { 3022 + cq->dbinfo.toggle = cq->toggle; 3080 3023 if (arm_type) 3081 3024 bnxt_qplib_ring_db(&cq->dbinfo, arm_type); 3082 3025 /* Using cq->arm_state variable to track whether to issue cq handler */
+31 -4
drivers/infiniband/hw/bnxt_re/qplib_fp.h
··· 338 338 dma_addr_t rq_hdr_buf_map; 339 339 struct list_head sq_flush; 340 340 struct list_head rq_flush; 341 + u32 msn; 342 + u32 msn_tbl_sz; 343 + u16 dev_cap_flags; 341 344 }; 342 345 343 346 #define BNXT_QPLIB_MAX_CQE_ENTRY_SIZE sizeof(struct cq_base) ··· 351 348 #define CQE_IDX(x) ((x) & CQE_MAX_IDX_PER_PG) 352 349 353 350 #define ROCE_CQE_CMP_V 0 354 - #define CQE_CMP_VALID(hdr, raw_cons, cp_bit) \ 351 + #define CQE_CMP_VALID(hdr, pass) \ 355 352 (!!((hdr)->cqe_type_toggle & CQ_BASE_TOGGLE) == \ 356 - !((raw_cons) & (cp_bit))) 353 + !((pass) & BNXT_QPLIB_FLAG_EPOCH_CONS_MASK)) 354 + 355 + static inline u32 __bnxt_qplib_get_avail(struct bnxt_qplib_hwq *hwq) 356 + { 357 + int cons, prod, avail; 358 + 359 + cons = hwq->cons; 360 + prod = hwq->prod; 361 + avail = cons - prod; 362 + if (cons <= prod) 363 + avail += hwq->depth; 364 + return avail; 365 + } 357 366 358 367 static inline bool bnxt_qplib_queue_full(struct bnxt_qplib_q *que, 359 368 u8 slots) ··· 421 406 bool resize_in_progress; 422 407 struct bnxt_qplib_sg_info sg_info; 423 408 u64 cq_handle; 409 + u8 toggle; 424 410 425 411 #define CQ_RESIZE_WAIT_TIME_MS 500 426 412 unsigned long flags; ··· 459 443 #define NQE_PG(x) (((x) & ~NQE_MAX_IDX_PER_PG) / NQE_CNT_PER_PG) 460 444 #define NQE_IDX(x) ((x) & NQE_MAX_IDX_PER_PG) 461 445 462 - #define NQE_CMP_VALID(hdr, raw_cons, cp_bit) \ 446 + #define NQE_CMP_VALID(hdr, pass) \ 463 447 (!!(le32_to_cpu((hdr)->info63_v[0]) & NQ_BASE_V) == \ 464 - !((raw_cons) & (cp_bit))) 448 + !((pass) & BNXT_QPLIB_FLAG_EPOCH_CONS_MASK)) 465 449 466 450 #define BNXT_QPLIB_NQE_MAX_CNT (128 * 1024) 467 451 ··· 629 613 size = max; 630 614 631 615 return size; 616 + } 617 + 618 + /* MSN table update inlin */ 619 + static inline __le64 bnxt_re_update_msn_tbl(u32 st_idx, u32 npsn, u32 start_psn) 620 + { 621 + return cpu_to_le64((((u64)(st_idx) << SQ_MSN_SEARCH_START_IDX_SFT) & 622 + SQ_MSN_SEARCH_START_IDX_MASK) | 623 + (((u64)(npsn) << SQ_MSN_SEARCH_NEXT_PSN_SFT) & 624 + SQ_MSN_SEARCH_NEXT_PSN_MASK) | 625 + (((start_psn) << SQ_MSN_SEARCH_START_PSN_SFT) & 626 + SQ_MSN_SEARCH_START_PSN_MASK)); 632 627 } 633 628 #endif /* __BNXT_QPLIB_FP_H__ */
+11 -10
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
··· 734 734 u32 type, budget = CREQ_ENTRY_POLL_BUDGET; 735 735 struct bnxt_qplib_hwq *hwq = &creq->hwq; 736 736 struct creq_base *creqe; 737 - u32 sw_cons, raw_cons; 738 737 unsigned long flags; 739 738 u32 num_wakeup = 0; 739 + u32 hw_polled = 0; 740 740 741 741 /* Service the CREQ until budget is over */ 742 742 spin_lock_irqsave(&hwq->lock, flags); 743 - raw_cons = hwq->cons; 744 743 while (budget > 0) { 745 - sw_cons = HWQ_CMP(raw_cons, hwq); 746 - creqe = bnxt_qplib_get_qe(hwq, sw_cons, NULL); 747 - if (!CREQ_CMP_VALID(creqe, raw_cons, hwq->max_elements)) 744 + creqe = bnxt_qplib_get_qe(hwq, hwq->cons, NULL); 745 + if (!CREQ_CMP_VALID(creqe, creq->creq_db.dbinfo.flags)) 748 746 break; 749 747 /* The valid test of the entry must be done first before 750 748 * reading any further. ··· 773 775 type); 774 776 break; 775 777 } 776 - raw_cons++; 777 778 budget--; 779 + hw_polled++; 780 + bnxt_qplib_hwq_incr_cons(hwq->max_elements, &hwq->cons, 781 + 1, &creq->creq_db.dbinfo.flags); 778 782 } 779 783 780 - if (hwq->cons != raw_cons) { 781 - hwq->cons = raw_cons; 784 + if (hw_polled) 782 785 bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, 783 786 rcfw->res->cctx, true); 784 - } 785 787 spin_unlock_irqrestore(&hwq->lock, flags); 786 788 if (num_wakeup) 787 789 wake_up_nr(&rcfw->cmdq.waitq, num_wakeup); ··· 852 854 */ 853 855 if (is_virtfn) 854 856 goto skip_ctx_setup; 855 - if (bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx)) 857 + if (bnxt_qplib_is_chip_gen_p5_p7(rcfw->res->cctx)) 856 858 goto config_vf_res; 857 859 858 860 lvl = ctx->qpc_tbl.level; ··· 905 907 req.max_gid_per_vf = cpu_to_le32(ctx->vf_res.max_gid_per_vf); 906 908 907 909 skip_ctx_setup: 910 + if (BNXT_RE_HW_RETX(rcfw->res->dattr->dev_cap_flags)) 911 + req.flags |= cpu_to_le16(CMDQ_INITIALIZE_FW_FLAGS_HW_REQUESTER_RETX_SUPPORTED); 908 912 req.stat_ctx_id = cpu_to_le32(ctx->stats.fw_id); 909 913 bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req), sizeof(resp), 0); 910 914 rc = bnxt_qplib_rcfw_send_message(rcfw, &msg); ··· 1113 1113 pdev = rcfw->pdev; 1114 1114 creq_db = &rcfw->creq.creq_db; 1115 1115 1116 + creq_db->dbinfo.flags = 0; 1116 1117 creq_db->reg.bar_id = RCFW_COMM_CONS_PCI_BAR_REGION; 1117 1118 creq_db->reg.bar_base = pci_resource_start(pdev, creq_db->reg.bar_id); 1118 1119 if (!creq_db->reg.bar_id)
+2 -2
drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
··· 141 141 /* Allocate 1 per QP for async error notification for now */ 142 142 #define BNXT_QPLIB_CREQE_MAX_CNT (64 * 1024) 143 143 #define BNXT_QPLIB_CREQE_UNITS 16 /* 16-Bytes per prod unit */ 144 - #define CREQ_CMP_VALID(hdr, raw_cons, cp_bit) \ 144 + #define CREQ_CMP_VALID(hdr, pass) \ 145 145 (!!((hdr)->v & CREQ_BASE_V) == \ 146 - !((raw_cons) & (cp_bit))) 146 + !((pass) & BNXT_QPLIB_FLAG_EPOCH_CONS_MASK)) 147 147 #define CREQ_ENTRY_POLL_BUDGET 0x100 148 148 149 149 /* HWQ */
+2 -2
drivers/infiniband/hw/bnxt_re/qplib_res.c
··· 343 343 hwq->cons = 0; 344 344 hwq->pdev = pdev; 345 345 hwq->depth = hwq_attr->depth; 346 - hwq->max_elements = depth; 346 + hwq->max_elements = hwq->depth; 347 347 hwq->element_size = stride; 348 348 hwq->qe_ppg = pg_size / stride; 349 349 /* For direct access to the elements */ ··· 805 805 dpit = &res->dpi_tbl; 806 806 reg = &dpit->wcreg; 807 807 808 - if (!bnxt_qplib_is_chip_gen_p5(res->cctx)) { 808 + if (!bnxt_qplib_is_chip_gen_p5_p7(res->cctx)) { 809 809 /* Offest should come from L2 driver */ 810 810 dbr_offset = dev_attr->l2_db_size; 811 811 dpit->ucreg.offset = dbr_offset;
+94 -23
drivers/infiniband/hw/bnxt_re/qplib_res.h
··· 44 44 #define CHIP_NUM_57508 0x1750 45 45 #define CHIP_NUM_57504 0x1751 46 46 #define CHIP_NUM_57502 0x1752 47 + #define CHIP_NUM_58818 0xd818 48 + #define CHIP_NUM_57608 0x1760 49 + 50 + #define BNXT_QPLIB_DBR_VALID (0x1UL << 26) 51 + #define BNXT_QPLIB_DBR_EPOCH_SHIFT 24 52 + #define BNXT_QPLIB_DBR_TOGGLE_SHIFT 25 47 53 48 54 struct bnxt_qplib_drv_modes { 49 55 u8 wqe_mode; 50 56 bool db_push; 51 57 bool dbr_pacing; 58 + u32 toggle_bits; 59 + }; 60 + 61 + enum bnxt_re_toggle_modes { 62 + BNXT_QPLIB_CQ_TOGGLE_BIT = 0x1, 63 + BNXT_QPLIB_SRQ_TOGGLE_BIT = 0x2, 52 64 }; 53 65 54 66 struct bnxt_qplib_chip_ctx { ··· 198 186 struct bnxt_qplib_hwq *hwq; 199 187 u32 xid; 200 188 u32 max_slot; 189 + u32 flags; 190 + u8 toggle; 191 + }; 192 + 193 + enum bnxt_qplib_db_info_flags_mask { 194 + BNXT_QPLIB_FLAG_EPOCH_CONS_SHIFT = 0x0UL, 195 + BNXT_QPLIB_FLAG_EPOCH_PROD_SHIFT = 0x1UL, 196 + BNXT_QPLIB_FLAG_EPOCH_CONS_MASK = 0x1UL, 197 + BNXT_QPLIB_FLAG_EPOCH_PROD_MASK = 0x2UL, 198 + }; 199 + 200 + enum bnxt_qplib_db_epoch_flag_shift { 201 + BNXT_QPLIB_DB_EPOCH_CONS_SHIFT = BNXT_QPLIB_DBR_EPOCH_SHIFT, 202 + BNXT_QPLIB_DB_EPOCH_PROD_SHIFT = (BNXT_QPLIB_DBR_EPOCH_SHIFT - 1), 201 203 }; 202 204 203 205 /* Tables */ ··· 314 288 struct bnxt_qplib_db_pacing_data *pacing_data; 315 289 }; 316 290 291 + static inline bool bnxt_qplib_is_chip_gen_p7(struct bnxt_qplib_chip_ctx *cctx) 292 + { 293 + return (cctx->chip_num == CHIP_NUM_58818 || 294 + cctx->chip_num == CHIP_NUM_57608); 295 + } 296 + 317 297 static inline bool bnxt_qplib_is_chip_gen_p5(struct bnxt_qplib_chip_ctx *cctx) 318 298 { 319 299 return (cctx->chip_num == CHIP_NUM_57508 || ··· 327 295 cctx->chip_num == CHIP_NUM_57502); 328 296 } 329 297 298 + static inline bool bnxt_qplib_is_chip_gen_p5_p7(struct bnxt_qplib_chip_ctx *cctx) 299 + { 300 + return bnxt_qplib_is_chip_gen_p5(cctx) || bnxt_qplib_is_chip_gen_p7(cctx); 301 + } 302 + 330 303 static inline u8 bnxt_qplib_get_hwq_type(struct bnxt_qplib_res *res) 331 304 { 332 - return bnxt_qplib_is_chip_gen_p5(res->cctx) ? 305 + return bnxt_qplib_is_chip_gen_p5_p7(res->cctx) ? 333 306 HWQ_TYPE_QUEUE : HWQ_TYPE_L2_CMPL; 334 307 } 335 308 336 309 static inline u8 bnxt_qplib_get_ring_type(struct bnxt_qplib_chip_ctx *cctx) 337 310 { 338 - return bnxt_qplib_is_chip_gen_p5(cctx) ? 311 + return bnxt_qplib_is_chip_gen_p5_p7(cctx) ? 339 312 RING_ALLOC_REQ_RING_TYPE_NQ : 340 313 RING_ALLOC_REQ_RING_TYPE_ROCE_CMPL; 341 314 } ··· 433 396 434 397 int bnxt_qplib_determine_atomics(struct pci_dev *dev); 435 398 436 - static inline void bnxt_qplib_hwq_incr_prod(struct bnxt_qplib_hwq *hwq, u32 cnt) 399 + static inline void bnxt_qplib_hwq_incr_prod(struct bnxt_qplib_db_info *dbinfo, 400 + struct bnxt_qplib_hwq *hwq, u32 cnt) 437 401 { 438 - hwq->prod = (hwq->prod + cnt) % hwq->depth; 402 + /* move prod and update toggle/epoch if wrap around */ 403 + hwq->prod += cnt; 404 + if (hwq->prod >= hwq->depth) { 405 + hwq->prod %= hwq->depth; 406 + dbinfo->flags ^= 1UL << BNXT_QPLIB_FLAG_EPOCH_PROD_SHIFT; 407 + } 439 408 } 440 409 441 - static inline void bnxt_qplib_hwq_incr_cons(struct bnxt_qplib_hwq *hwq, 442 - u32 cnt) 410 + static inline void bnxt_qplib_hwq_incr_cons(u32 max_elements, u32 *cons, u32 cnt, 411 + u32 *dbinfo_flags) 443 412 { 444 - hwq->cons = (hwq->cons + cnt) % hwq->depth; 413 + /* move cons and update toggle/epoch if wrap around */ 414 + *cons += cnt; 415 + if (*cons >= max_elements) { 416 + *cons %= max_elements; 417 + *dbinfo_flags ^= 1UL << BNXT_QPLIB_FLAG_EPOCH_CONS_SHIFT; 418 + } 445 419 } 446 420 447 421 static inline void bnxt_qplib_ring_db32(struct bnxt_qplib_db_info *info, 448 422 bool arm) 449 423 { 450 - u32 key; 424 + u32 key = 0; 451 425 452 - key = info->hwq->cons & (info->hwq->max_elements - 1); 453 - key |= (CMPL_DOORBELL_IDX_VALID | 426 + key |= info->hwq->cons | (CMPL_DOORBELL_IDX_VALID | 454 427 (CMPL_DOORBELL_KEY_CMPL & CMPL_DOORBELL_KEY_MASK)); 455 428 if (!arm) 456 429 key |= CMPL_DOORBELL_MASK; 457 430 writel(key, info->db); 458 431 } 459 432 433 + #define BNXT_QPLIB_INIT_DBHDR(xid, type, indx, toggle) \ 434 + (((u64)(((xid) & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | \ 435 + (type) | BNXT_QPLIB_DBR_VALID) << 32) | (indx) | \ 436 + (((u32)(toggle)) << (BNXT_QPLIB_DBR_TOGGLE_SHIFT))) 437 + 460 438 static inline void bnxt_qplib_ring_db(struct bnxt_qplib_db_info *info, 461 439 u32 type) 462 440 { 463 441 u64 key = 0; 442 + u32 indx; 443 + u8 toggle = 0; 464 444 465 - key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type; 466 - key <<= 32; 467 - key |= (info->hwq->cons & (info->hwq->max_elements - 1)) & 468 - DBC_DBC_INDEX_MASK; 445 + if (type == DBC_DBC_TYPE_CQ_ARMALL || 446 + type == DBC_DBC_TYPE_CQ_ARMSE) 447 + toggle = info->toggle; 448 + 449 + indx = (info->hwq->cons & DBC_DBC_INDEX_MASK) | 450 + ((info->flags & BNXT_QPLIB_FLAG_EPOCH_CONS_MASK) << 451 + BNXT_QPLIB_DB_EPOCH_CONS_SHIFT); 452 + 453 + key = BNXT_QPLIB_INIT_DBHDR(info->xid, type, indx, toggle); 469 454 writeq(key, info->db); 470 455 } 471 456 ··· 495 436 u32 type) 496 437 { 497 438 u64 key = 0; 439 + u32 indx; 498 440 499 - key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type; 500 - key <<= 32; 501 - key |= ((info->hwq->prod / info->max_slot)) & DBC_DBC_INDEX_MASK; 441 + indx = (((info->hwq->prod / info->max_slot) & DBC_DBC_INDEX_MASK) | 442 + ((info->flags & BNXT_QPLIB_FLAG_EPOCH_PROD_MASK) << 443 + BNXT_QPLIB_DB_EPOCH_PROD_SHIFT)); 444 + key = BNXT_QPLIB_INIT_DBHDR(info->xid, type, indx, 0); 502 445 writeq(key, info->db); 503 446 } 504 447 ··· 508 447 u32 type) 509 448 { 510 449 u64 key = 0; 450 + u8 toggle = 0; 511 451 512 - key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type; 513 - key <<= 32; 452 + if (type == DBC_DBC_TYPE_CQ_ARMENA || type == DBC_DBC_TYPE_SRQ_ARMENA) 453 + toggle = info->toggle; 454 + /* Index always at 0 */ 455 + key = BNXT_QPLIB_INIT_DBHDR(info->xid, type, 0, toggle); 514 456 writeq(key, info->priv_db); 515 457 } 516 458 ··· 522 458 { 523 459 u64 key = 0; 524 460 525 - key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | th; 526 - key <<= 32; 527 - key |= th & DBC_DBC_INDEX_MASK; 461 + key = BNXT_QPLIB_INIT_DBHDR(info->xid, DBC_DBC_TYPE_SRQ_ARM, th, info->toggle); 528 462 writeq(key, info->priv_db); 529 463 } 530 464 ··· 533 471 u32 type; 534 472 535 473 type = arm ? DBC_DBC_TYPE_NQ_ARM : DBC_DBC_TYPE_NQ; 536 - if (bnxt_qplib_is_chip_gen_p5(cctx)) 474 + if (bnxt_qplib_is_chip_gen_p5_p7(cctx)) 537 475 bnxt_qplib_ring_db(info, type); 538 476 else 539 477 bnxt_qplib_ring_db32(info, arm); ··· 544 482 return dev_cap_flags & 545 483 CREQ_QUERY_FUNC_RESP_SB_EXT_STATS; 546 484 } 485 + 486 + static inline bool _is_hw_retx_supported(u16 dev_cap_flags) 487 + { 488 + return dev_cap_flags & 489 + (CREQ_QUERY_FUNC_RESP_SB_HW_REQUESTER_RETX_ENABLED | 490 + CREQ_QUERY_FUNC_RESP_SB_HW_RESPONDER_RETX_ENABLED); 491 + } 492 + 493 + #define BNXT_RE_HW_RETX(a) _is_hw_retx_supported((a)) 547 494 548 495 static inline u8 bnxt_qplib_dbr_pacing_en(struct bnxt_qplib_chip_ctx *cctx) 549 496 {
+6 -5
drivers/infiniband/hw/bnxt_re/qplib_sp.c
··· 59 59 { 60 60 u16 pcie_ctl2 = 0; 61 61 62 - if (!bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx)) 62 + if (!bnxt_qplib_is_chip_gen_p5_p7(rcfw->res->cctx)) 63 63 return false; 64 64 65 65 pcie_capability_read_word(rcfw->pdev, PCI_EXP_DEVCTL2, &pcie_ctl2); ··· 133 133 * reporting the max number 134 134 */ 135 135 attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS + 1; 136 - attr->max_qp_sges = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx) ? 136 + attr->max_qp_sges = bnxt_qplib_is_chip_gen_p5_p7(rcfw->res->cctx) ? 137 137 6 : sb->max_sge; 138 138 attr->max_cq = le32_to_cpu(sb->max_cq); 139 139 attr->max_cq_wqes = le32_to_cpu(sb->max_cqe); ··· 151 151 attr->max_srq_sges = sb->max_srq_sge; 152 152 attr->max_pkey = 1; 153 153 attr->max_inline_data = le32_to_cpu(sb->max_inline_data); 154 - attr->l2_db_size = (sb->l2_db_space_size + 1) * 155 - (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); 154 + if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) 155 + attr->l2_db_size = (sb->l2_db_space_size + 1) * 156 + (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); 156 157 attr->max_sgid = BNXT_QPLIB_NUM_GIDS_SUPPORTED; 157 158 attr->dev_cap_flags = le16_to_cpu(sb->dev_cap_flags); 158 159 ··· 935 934 req->inactivity_th = cpu_to_le16(cc_param->inact_th); 936 935 937 936 /* For chip gen P5 onwards fill extended cmd and header */ 938 - if (bnxt_qplib_is_chip_gen_p5(res->cctx)) { 937 + if (bnxt_qplib_is_chip_gen_p5_p7(res->cctx)) { 939 938 struct roce_tlv *hdr; 940 939 u32 payload; 941 940 u32 chunks;
+57 -10
drivers/infiniband/hw/bnxt_re/roce_hsi.h
··· 555 555 __le16 flags; 556 556 __le16 cookie; 557 557 u8 resp_size; 558 - u8 reserved8; 558 + u8 qp_type; 559 + #define CMDQ_MODIFY_QP_QP_TYPE_RC 0x2UL 560 + #define CMDQ_MODIFY_QP_QP_TYPE_UD 0x4UL 561 + #define CMDQ_MODIFY_QP_QP_TYPE_RAW_ETHERTYPE 0x6UL 562 + #define CMDQ_MODIFY_QP_QP_TYPE_GSI 0x7UL 563 + #define CMDQ_MODIFY_QP_QP_TYPE_LAST CMDQ_MODIFY_QP_QP_TYPE_GSI 559 564 __le64 resp_addr; 560 565 __le32 modify_mask; 561 566 #define CMDQ_MODIFY_QP_MODIFY_MASK_STATE 0x1UL ··· 616 611 #define CMDQ_MODIFY_QP_NETWORK_TYPE_ROCEV2_IPV6 (0x3UL << 6) 617 612 #define CMDQ_MODIFY_QP_NETWORK_TYPE_LAST CMDQ_MODIFY_QP_NETWORK_TYPE_ROCEV2_IPV6 618 613 u8 access; 619 - #define CMDQ_MODIFY_QP_ACCESS_REMOTE_ATOMIC_REMOTE_READ_REMOTE_WRITE_LOCAL_WRITE_MASK \ 620 - 0xffUL 621 - #define CMDQ_MODIFY_QP_ACCESS_REMOTE_ATOMIC_REMOTE_READ_REMOTE_WRITE_LOCAL_WRITE_SFT \ 622 - 0 623 - #define CMDQ_MODIFY_QP_ACCESS_LOCAL_WRITE 0x1UL 624 - #define CMDQ_MODIFY_QP_ACCESS_REMOTE_WRITE 0x2UL 625 - #define CMDQ_MODIFY_QP_ACCESS_REMOTE_READ 0x4UL 626 - #define CMDQ_MODIFY_QP_ACCESS_REMOTE_ATOMIC 0x8UL 614 + #define CMDQ_MODIFY_QP_ACCESS_REMOTE_ATOMIC_REMOTE_READ_REMOTE_WRITE_LOCAL_WRITE_MASK 0xffUL 615 + #define CMDQ_MODIFY_QP_ACCESS_REMOTE_ATOMIC_REMOTE_READ_REMOTE_WRITE_LOCAL_WRITE_SFT 0 616 + #define CMDQ_MODIFY_QP_ACCESS_LOCAL_WRITE 0x1UL 617 + #define CMDQ_MODIFY_QP_ACCESS_REMOTE_WRITE 0x2UL 618 + #define CMDQ_MODIFY_QP_ACCESS_REMOTE_READ 0x4UL 619 + #define CMDQ_MODIFY_QP_ACCESS_REMOTE_ATOMIC 0x8UL 627 620 __le16 pkey; 628 621 __le32 qkey; 629 622 __le32 dgid[4]; ··· 676 673 #define CMDQ_MODIFY_QP_VLAN_PCP_SFT 13 677 674 __le64 irrq_addr; 678 675 __le64 orrq_addr; 676 + __le32 ext_modify_mask; 677 + #define CMDQ_MODIFY_QP_EXT_MODIFY_MASK_EXT_STATS_CTX 0x1UL 678 + #define CMDQ_MODIFY_QP_EXT_MODIFY_MASK_SCHQ_ID_VALID 0x2UL 679 + __le32 ext_stats_ctx_id; 680 + __le16 schq_id; 681 + __le16 unused_0; 682 + __le32 reserved32; 679 683 }; 680 684 681 685 /* creq_modify_qp_resp (size:128b/16B) */ ··· 3085 3075 __le32 reserved32; 3086 3076 }; 3087 3077 3078 + /* sq_msn_search (size:64b/8B) */ 3079 + struct sq_msn_search { 3080 + __le64 start_idx_next_psn_start_psn; 3081 + #define SQ_MSN_SEARCH_START_PSN_MASK 0xffffffUL 3082 + #define SQ_MSN_SEARCH_START_PSN_SFT 0 3083 + #define SQ_MSN_SEARCH_NEXT_PSN_MASK 0xffffff000000ULL 3084 + #define SQ_MSN_SEARCH_NEXT_PSN_SFT 24 3085 + #define SQ_MSN_SEARCH_START_IDX_MASK 0xffff000000000000ULL 3086 + #define SQ_MSN_SEARCH_START_IDX_SFT 48 3087 + }; 3088 + 3088 3089 /* sq_send (size:1024b/128B) */ 3089 3090 struct sq_send { 3090 3091 u8 wqe_type; ··· 3784 3763 #define CQ_BASE_CQE_TYPE_RES_UD (0x2UL << 1) 3785 3764 #define CQ_BASE_CQE_TYPE_RES_RAWETH_QP1 (0x3UL << 1) 3786 3765 #define CQ_BASE_CQE_TYPE_RES_UD_CFA (0x4UL << 1) 3766 + #define CQ_BASE_CQE_TYPE_REQ_V3 (0x8UL << 1) 3767 + #define CQ_BASE_CQE_TYPE_RES_RC_V3 (0x9UL << 1) 3768 + #define CQ_BASE_CQE_TYPE_RES_UD_V3 (0xaUL << 1) 3769 + #define CQ_BASE_CQE_TYPE_RES_RAWETH_QP1_V3 (0xbUL << 1) 3770 + #define CQ_BASE_CQE_TYPE_RES_UD_CFA_V3 (0xcUL << 1) 3787 3771 #define CQ_BASE_CQE_TYPE_NO_OP (0xdUL << 1) 3788 3772 #define CQ_BASE_CQE_TYPE_TERMINAL (0xeUL << 1) 3789 3773 #define CQ_BASE_CQE_TYPE_CUT_OFF (0xfUL << 1) 3790 3774 #define CQ_BASE_CQE_TYPE_LAST CQ_BASE_CQE_TYPE_CUT_OFF 3791 3775 u8 status; 3776 + #define CQ_BASE_STATUS_OK 0x0UL 3777 + #define CQ_BASE_STATUS_BAD_RESPONSE_ERR 0x1UL 3778 + #define CQ_BASE_STATUS_LOCAL_LENGTH_ERR 0x2UL 3779 + #define CQ_BASE_STATUS_HW_LOCAL_LENGTH_ERR 0x3UL 3780 + #define CQ_BASE_STATUS_LOCAL_QP_OPERATION_ERR 0x4UL 3781 + #define CQ_BASE_STATUS_LOCAL_PROTECTION_ERR 0x5UL 3782 + #define CQ_BASE_STATUS_LOCAL_ACCESS_ERROR 0x6UL 3783 + #define CQ_BASE_STATUS_MEMORY_MGT_OPERATION_ERR 0x7UL 3784 + #define CQ_BASE_STATUS_REMOTE_INVALID_REQUEST_ERR 0x8UL 3785 + #define CQ_BASE_STATUS_REMOTE_ACCESS_ERR 0x9UL 3786 + #define CQ_BASE_STATUS_REMOTE_OPERATION_ERR 0xaUL 3787 + #define CQ_BASE_STATUS_RNR_NAK_RETRY_CNT_ERR 0xbUL 3788 + #define CQ_BASE_STATUS_TRANSPORT_RETRY_CNT_ERR 0xcUL 3789 + #define CQ_BASE_STATUS_WORK_REQUEST_FLUSHED_ERR 0xdUL 3790 + #define CQ_BASE_STATUS_HW_FLUSH_ERR 0xeUL 3791 + #define CQ_BASE_STATUS_OVERFLOW_ERR 0xfUL 3792 + #define CQ_BASE_STATUS_LAST CQ_BASE_STATUS_OVERFLOW_ERR 3792 3793 __le16 reserved16; 3793 - __le32 reserved32; 3794 + __le32 opaque; 3794 3795 }; 3795 3796 3796 3797 /* cq_req (size:256b/32B) */ ··· 4427 4384 #define CQ_CUTOFF_CQE_TYPE_SFT 1 4428 4385 #define CQ_CUTOFF_CQE_TYPE_CUT_OFF (0xfUL << 1) 4429 4386 #define CQ_CUTOFF_CQE_TYPE_LAST CQ_CUTOFF_CQE_TYPE_CUT_OFF 4387 + #define CQ_CUTOFF_RESIZE_TOGGLE_MASK 0x60UL 4388 + #define CQ_CUTOFF_RESIZE_TOGGLE_SFT 5 4430 4389 u8 status; 4431 4390 #define CQ_CUTOFF_STATUS_OK 0x0UL 4432 4391 #define CQ_CUTOFF_STATUS_LAST CQ_CUTOFF_STATUS_OK ··· 4480 4435 #define NQ_SRQ_EVENT_TYPE_SFT 0 4481 4436 #define NQ_SRQ_EVENT_TYPE_SRQ_EVENT 0x32UL 4482 4437 #define NQ_SRQ_EVENT_TYPE_LAST NQ_SRQ_EVENT_TYPE_SRQ_EVENT 4438 + #define NQ_SRQ_EVENT_TOGGLE_MASK 0xc0UL 4439 + #define NQ_SRQ_EVENT_TOGGLE_SFT 6 4483 4440 u8 event; 4484 4441 #define NQ_SRQ_EVENT_EVENT_SRQ_THRESHOLD_EVENT 0x1UL 4485 4442 #define NQ_SRQ_EVENT_EVENT_LAST NQ_SRQ_EVENT_EVENT_SRQ_THRESHOLD_EVENT
+11 -1
drivers/infiniband/hw/efa/efa.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ 2 2 /* 3 - * Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved. 3 + * Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved. 4 4 */ 5 5 6 6 #ifndef _EFA_H_ ··· 80 80 u16 pdn; 81 81 }; 82 82 83 + struct efa_mr_interconnect_info { 84 + u16 recv_ic_id; 85 + u16 rdma_read_ic_id; 86 + u16 rdma_recv_ic_id; 87 + u8 recv_ic_id_valid : 1; 88 + u8 rdma_read_ic_id_valid : 1; 89 + u8 rdma_recv_ic_id_valid : 1; 90 + }; 91 + 83 92 struct efa_mr { 84 93 struct ib_mr ibmr; 85 94 struct ib_umem *umem; 95 + struct efa_mr_interconnect_info ic_info; 86 96 }; 87 97 88 98 struct efa_cq {
+32 -1
drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ 2 2 /* 3 - * Copyright 2018-2023 Amazon.com, Inc. or its affiliates. All rights reserved. 3 + * Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved. 4 4 */ 5 5 6 6 #ifndef _EFA_ADMIN_CMDS_H_ ··· 415 415 * memory region 416 416 */ 417 417 u32 r_key; 418 + 419 + /* 420 + * Mask indicating which fields have valid values 421 + * 0 : recv_ic_id 422 + * 1 : rdma_read_ic_id 423 + * 2 : rdma_recv_ic_id 424 + */ 425 + u8 validity; 426 + 427 + /* 428 + * Physical interconnect used by the device to reach the MR for receive 429 + * operation 430 + */ 431 + u8 recv_ic_id; 432 + 433 + /* 434 + * Physical interconnect used by the device to reach the MR for RDMA 435 + * read operation 436 + */ 437 + u8 rdma_read_ic_id; 438 + 439 + /* 440 + * Physical interconnect used by the device to reach the MR for RDMA 441 + * write receive 442 + */ 443 + u8 rdma_recv_ic_id; 418 444 }; 419 445 420 446 struct efa_admin_dereg_mr_cmd { ··· 1024 998 #define EFA_ADMIN_REG_MR_CMD_LOCAL_WRITE_ENABLE_MASK BIT(0) 1025 999 #define EFA_ADMIN_REG_MR_CMD_REMOTE_WRITE_ENABLE_MASK BIT(1) 1026 1000 #define EFA_ADMIN_REG_MR_CMD_REMOTE_READ_ENABLE_MASK BIT(2) 1001 + 1002 + /* reg_mr_resp */ 1003 + #define EFA_ADMIN_REG_MR_RESP_RECV_IC_ID_MASK BIT(0) 1004 + #define EFA_ADMIN_REG_MR_RESP_RDMA_READ_IC_ID_MASK BIT(1) 1005 + #define EFA_ADMIN_REG_MR_RESP_RDMA_RECV_IC_ID_MASK BIT(2) 1027 1006 1028 1007 /* create_cq_cmd */ 1029 1008 #define EFA_ADMIN_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED_MASK BIT(5)
+10 -1
drivers/infiniband/hw/efa/efa_com_cmd.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 2 2 /* 3 - * Copyright 2018-2023 Amazon.com, Inc. or its affiliates. All rights reserved. 3 + * Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved. 4 4 */ 5 5 6 6 #include "efa_com.h" ··· 270 270 271 271 result->l_key = cmd_completion.l_key; 272 272 result->r_key = cmd_completion.r_key; 273 + result->ic_info.recv_ic_id = cmd_completion.recv_ic_id; 274 + result->ic_info.rdma_read_ic_id = cmd_completion.rdma_read_ic_id; 275 + result->ic_info.rdma_recv_ic_id = cmd_completion.rdma_recv_ic_id; 276 + result->ic_info.recv_ic_id_valid = EFA_GET(&cmd_completion.validity, 277 + EFA_ADMIN_REG_MR_RESP_RECV_IC_ID); 278 + result->ic_info.rdma_read_ic_id_valid = EFA_GET(&cmd_completion.validity, 279 + EFA_ADMIN_REG_MR_RESP_RDMA_READ_IC_ID); 280 + result->ic_info.rdma_recv_ic_id_valid = EFA_GET(&cmd_completion.validity, 281 + EFA_ADMIN_REG_MR_RESP_RDMA_RECV_IC_ID); 273 282 274 283 return 0; 275 284 }
+11 -1
drivers/infiniband/hw/efa/efa_com_cmd.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ 2 2 /* 3 - * Copyright 2018-2023 Amazon.com, Inc. or its affiliates. All rights reserved. 3 + * Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved. 4 4 */ 5 5 6 6 #ifndef _EFA_COM_CMD_H_ ··· 199 199 u8 indirect; 200 200 }; 201 201 202 + struct efa_com_mr_interconnect_info { 203 + u16 recv_ic_id; 204 + u16 rdma_read_ic_id; 205 + u16 rdma_recv_ic_id; 206 + u8 recv_ic_id_valid : 1; 207 + u8 rdma_read_ic_id_valid : 1; 208 + u8 rdma_recv_ic_id_valid : 1; 209 + }; 210 + 202 211 struct efa_com_reg_mr_result { 203 212 /* 204 213 * To be used in conjunction with local buffers references in SQ and ··· 219 210 * accessed memory region 220 211 */ 221 212 u32 r_key; 213 + struct efa_com_mr_interconnect_info ic_info; 222 214 }; 223 215 224 216 struct efa_com_dereg_mr_params {
+6 -1
drivers/infiniband/hw/efa/efa_main.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 2 2 /* 3 - * Copyright 2018-2022 Amazon.com, Inc. or its affiliates. All rights reserved. 3 + * Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved. 4 4 */ 5 5 6 6 #include <linux/module.h> ··· 9 9 #include <linux/version.h> 10 10 11 11 #include <rdma/ib_user_verbs.h> 12 + #include <rdma/uverbs_ioctl.h> 12 13 13 14 #include "efa.h" 14 15 ··· 36 35 #define EFA_AENQ_ENABLED_GROUPS \ 37 36 (BIT(EFA_ADMIN_FATAL_ERROR) | BIT(EFA_ADMIN_WARNING) | \ 38 37 BIT(EFA_ADMIN_NOTIFICATION) | BIT(EFA_ADMIN_KEEP_ALIVE)) 38 + 39 + extern const struct uapi_definition efa_uapi_defs[]; 39 40 40 41 /* This handler will called for unknown event group or unimplemented handlers */ 41 42 static void unimplemented_aenq_handler(void *data, ··· 434 431 dev->ibdev.dev.parent = &pdev->dev; 435 432 436 433 ib_set_device_ops(&dev->ibdev, &efa_dev_ops); 434 + 435 + dev->ibdev.driver_def = efa_uapi_defs; 437 436 438 437 err = ib_register_device(&dev->ibdev, "efa_%d", &pdev->dev); 439 438 if (err)
+70 -1
drivers/infiniband/hw/efa/efa_verbs.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 2 /* 3 - * Copyright 2018-2023 Amazon.com, Inc. or its affiliates. All rights reserved. 3 + * Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved. 4 4 */ 5 5 6 6 #include <linux/dma-buf.h> ··· 13 13 #include <rdma/ib_user_verbs.h> 14 14 #include <rdma/ib_verbs.h> 15 15 #include <rdma/uverbs_ioctl.h> 16 + #define UVERBS_MODULE_NAME efa_ib 17 + #include <rdma/uverbs_named_ioctl.h> 18 + #include <rdma/ib_user_ioctl_cmds.h> 16 19 17 20 #include "efa.h" 18 21 #include "efa_io_defs.h" ··· 1656 1653 mr->ibmr.lkey = result.l_key; 1657 1654 mr->ibmr.rkey = result.r_key; 1658 1655 mr->ibmr.length = length; 1656 + mr->ic_info.recv_ic_id = result.ic_info.recv_ic_id; 1657 + mr->ic_info.rdma_read_ic_id = result.ic_info.rdma_read_ic_id; 1658 + mr->ic_info.rdma_recv_ic_id = result.ic_info.rdma_recv_ic_id; 1659 + mr->ic_info.recv_ic_id_valid = result.ic_info.recv_ic_id_valid; 1660 + mr->ic_info.rdma_read_ic_id_valid = result.ic_info.rdma_read_ic_id_valid; 1661 + mr->ic_info.rdma_recv_ic_id_valid = result.ic_info.rdma_recv_ic_id_valid; 1659 1662 ibdev_dbg(&dev->ibdev, "Registered mr[%d]\n", mr->ibmr.lkey); 1660 1663 1661 1664 return 0; ··· 1742 1733 err_out: 1743 1734 atomic64_inc(&dev->stats.reg_mr_err); 1744 1735 return ERR_PTR(err); 1736 + } 1737 + 1738 + static int UVERBS_HANDLER(EFA_IB_METHOD_MR_QUERY)(struct uverbs_attr_bundle *attrs) 1739 + { 1740 + struct ib_mr *ibmr = uverbs_attr_get_obj(attrs, EFA_IB_ATTR_QUERY_MR_HANDLE); 1741 + struct efa_mr *mr = to_emr(ibmr); 1742 + u16 ic_id_validity = 0; 1743 + int ret; 1744 + 1745 + ret = uverbs_copy_to(attrs, EFA_IB_ATTR_QUERY_MR_RESP_RECV_IC_ID, 1746 + &mr->ic_info.recv_ic_id, sizeof(mr->ic_info.recv_ic_id)); 1747 + if (ret) 1748 + return ret; 1749 + 1750 + ret = uverbs_copy_to(attrs, EFA_IB_ATTR_QUERY_MR_RESP_RDMA_READ_IC_ID, 1751 + &mr->ic_info.rdma_read_ic_id, sizeof(mr->ic_info.rdma_read_ic_id)); 1752 + if (ret) 1753 + return ret; 1754 + 1755 + ret = uverbs_copy_to(attrs, EFA_IB_ATTR_QUERY_MR_RESP_RDMA_RECV_IC_ID, 1756 + &mr->ic_info.rdma_recv_ic_id, sizeof(mr->ic_info.rdma_recv_ic_id)); 1757 + if (ret) 1758 + return ret; 1759 + 1760 + if (mr->ic_info.recv_ic_id_valid) 1761 + ic_id_validity |= EFA_QUERY_MR_VALIDITY_RECV_IC_ID; 1762 + if (mr->ic_info.rdma_read_ic_id_valid) 1763 + ic_id_validity |= EFA_QUERY_MR_VALIDITY_RDMA_READ_IC_ID; 1764 + if (mr->ic_info.rdma_recv_ic_id_valid) 1765 + ic_id_validity |= EFA_QUERY_MR_VALIDITY_RDMA_RECV_IC_ID; 1766 + 1767 + return uverbs_copy_to(attrs, EFA_IB_ATTR_QUERY_MR_RESP_IC_ID_VALIDITY, 1768 + &ic_id_validity, sizeof(ic_id_validity)); 1745 1769 } 1746 1770 1747 1771 int efa_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) ··· 2199 2157 return IB_LINK_LAYER_UNSPECIFIED; 2200 2158 } 2201 2159 2160 + DECLARE_UVERBS_NAMED_METHOD(EFA_IB_METHOD_MR_QUERY, 2161 + UVERBS_ATTR_IDR(EFA_IB_ATTR_QUERY_MR_HANDLE, 2162 + UVERBS_OBJECT_MR, 2163 + UVERBS_ACCESS_READ, 2164 + UA_MANDATORY), 2165 + UVERBS_ATTR_PTR_OUT(EFA_IB_ATTR_QUERY_MR_RESP_IC_ID_VALIDITY, 2166 + UVERBS_ATTR_TYPE(u16), 2167 + UA_MANDATORY), 2168 + UVERBS_ATTR_PTR_OUT(EFA_IB_ATTR_QUERY_MR_RESP_RECV_IC_ID, 2169 + UVERBS_ATTR_TYPE(u16), 2170 + UA_MANDATORY), 2171 + UVERBS_ATTR_PTR_OUT(EFA_IB_ATTR_QUERY_MR_RESP_RDMA_READ_IC_ID, 2172 + UVERBS_ATTR_TYPE(u16), 2173 + UA_MANDATORY), 2174 + UVERBS_ATTR_PTR_OUT(EFA_IB_ATTR_QUERY_MR_RESP_RDMA_RECV_IC_ID, 2175 + UVERBS_ATTR_TYPE(u16), 2176 + UA_MANDATORY)); 2177 + 2178 + ADD_UVERBS_METHODS(efa_mr, 2179 + UVERBS_OBJECT_MR, 2180 + &UVERBS_METHOD(EFA_IB_METHOD_MR_QUERY)); 2181 + 2182 + const struct uapi_definition efa_uapi_defs[] = { 2183 + UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_MR, 2184 + &efa_mr), 2185 + {}, 2186 + };
+2
drivers/infiniband/hw/erdma/erdma.h
··· 212 212 213 213 atomic_t num_ctx; 214 214 struct list_head cep_list; 215 + 216 + struct dma_pool *resp_pool; 215 217 }; 216 218 217 219 static inline void *get_queue_entry(void *qbuf, u32 idx, u32 depth, u32 shift)
+39
drivers/infiniband/hw/erdma/erdma_hw.h
··· 144 144 CMDQ_OPCODE_DESTROY_EQ = 1, 145 145 CMDQ_OPCODE_QUERY_FW_INFO = 2, 146 146 CMDQ_OPCODE_CONF_MTU = 3, 147 + CMDQ_OPCODE_GET_STATS = 4, 147 148 CMDQ_OPCODE_CONF_DEVICE = 5, 148 149 CMDQ_OPCODE_ALLOC_DB = 8, 149 150 CMDQ_OPCODE_FREE_DB = 9, ··· 354 353 u32 qpn; 355 354 u32 sq_pi; 356 355 u32 rq_pi; 356 + }; 357 + 358 + #define ERDMA_HW_RESP_SIZE 256 359 + 360 + struct erdma_cmdq_query_req { 361 + u64 hdr; 362 + u32 rsvd; 363 + u32 index; 364 + 365 + u64 target_addr; 366 + u32 target_length; 367 + }; 368 + 369 + #define ERDMA_HW_RESP_MAGIC 0x5566 370 + 371 + struct erdma_cmdq_query_resp_hdr { 372 + u16 magic; 373 + u8 ver; 374 + u8 length; 375 + 376 + u32 index; 377 + u32 rsvd[2]; 378 + }; 379 + 380 + struct erdma_cmdq_query_stats_resp { 381 + struct erdma_cmdq_query_resp_hdr hdr; 382 + 383 + u64 tx_req_cnt; 384 + u64 tx_packets_cnt; 385 + u64 tx_bytes_cnt; 386 + u64 tx_drop_packets_cnt; 387 + u64 tx_bps_meter_drop_packets_cnt; 388 + u64 tx_pps_meter_drop_packets_cnt; 389 + u64 rx_packets_cnt; 390 + u64 rx_bytes_cnt; 391 + u64 rx_drop_packets_cnt; 392 + u64 rx_bps_meter_drop_packets_cnt; 393 + u64 rx_pps_meter_drop_packets_cnt; 357 394 }; 358 395 359 396 /* cap qword 0 definition */
+24 -2
drivers/infiniband/hw/erdma/erdma_main.c
··· 172 172 { 173 173 int ret; 174 174 175 + dev->resp_pool = dma_pool_create("erdma_resp_pool", &pdev->dev, 176 + ERDMA_HW_RESP_SIZE, ERDMA_HW_RESP_SIZE, 177 + 0); 178 + if (!dev->resp_pool) 179 + return -ENOMEM; 180 + 175 181 ret = dma_set_mask_and_coherent(&pdev->dev, 176 182 DMA_BIT_MASK(ERDMA_PCI_WIDTH)); 177 183 if (ret) 178 - return ret; 184 + goto destroy_pool; 179 185 180 186 dma_set_max_seg_size(&pdev->dev, UINT_MAX); 181 187 182 188 return 0; 189 + 190 + destroy_pool: 191 + dma_pool_destroy(dev->resp_pool); 192 + 193 + return ret; 194 + } 195 + 196 + static void erdma_device_uninit(struct erdma_dev *dev) 197 + { 198 + dma_pool_destroy(dev->resp_pool); 183 199 } 184 200 185 201 static void erdma_hw_reset(struct erdma_dev *dev) ··· 289 273 290 274 err = erdma_request_vectors(dev); 291 275 if (err) 292 - goto err_iounmap_func_bar; 276 + goto err_uninit_device; 293 277 294 278 err = erdma_comm_irq_init(dev); 295 279 if (err) ··· 330 314 err_free_vectors: 331 315 pci_free_irq_vectors(dev->pdev); 332 316 317 + err_uninit_device: 318 + erdma_device_uninit(dev); 319 + 333 320 err_iounmap_func_bar: 334 321 devm_iounmap(&pdev->dev, dev->func_bar); 335 322 ··· 358 339 erdma_aeq_destroy(dev); 359 340 erdma_comm_irq_uninit(dev); 360 341 pci_free_irq_vectors(dev->pdev); 342 + erdma_device_uninit(dev); 361 343 362 344 devm_iounmap(&pdev->dev, dev->func_bar); 363 345 pci_release_selected_regions(pdev, ERDMA_BAR_MASK); ··· 468 448 .driver_id = RDMA_DRIVER_ERDMA, 469 449 .uverbs_abi_ver = ERDMA_ABI_VERSION, 470 450 451 + .alloc_hw_port_stats = erdma_alloc_hw_port_stats, 471 452 .alloc_mr = erdma_ib_alloc_mr, 472 453 .alloc_pd = erdma_alloc_pd, 473 454 .alloc_ucontext = erdma_alloc_ucontext, ··· 480 459 .destroy_cq = erdma_destroy_cq, 481 460 .destroy_qp = erdma_destroy_qp, 482 461 .get_dma_mr = erdma_get_dma_mr, 462 + .get_hw_stats = erdma_get_hw_stats, 483 463 .get_port_immutable = erdma_get_port_immutable, 484 464 .iw_accept = erdma_accept, 485 465 .iw_add_ref = erdma_qp_get_ref,
+90
drivers/infiniband/hw/erdma/erdma_verbs.c
··· 1708 1708 1709 1709 ib_dispatch_event(&event); 1710 1710 } 1711 + 1712 + enum counters { 1713 + ERDMA_STATS_TX_REQS_CNT, 1714 + ERDMA_STATS_TX_PACKETS_CNT, 1715 + ERDMA_STATS_TX_BYTES_CNT, 1716 + ERDMA_STATS_TX_DISABLE_DROP_CNT, 1717 + ERDMA_STATS_TX_BPS_METER_DROP_CNT, 1718 + ERDMA_STATS_TX_PPS_METER_DROP_CNT, 1719 + 1720 + ERDMA_STATS_RX_PACKETS_CNT, 1721 + ERDMA_STATS_RX_BYTES_CNT, 1722 + ERDMA_STATS_RX_DISABLE_DROP_CNT, 1723 + ERDMA_STATS_RX_BPS_METER_DROP_CNT, 1724 + ERDMA_STATS_RX_PPS_METER_DROP_CNT, 1725 + 1726 + ERDMA_STATS_MAX 1727 + }; 1728 + 1729 + static const struct rdma_stat_desc erdma_descs[] = { 1730 + [ERDMA_STATS_TX_REQS_CNT].name = "tx_reqs_cnt", 1731 + [ERDMA_STATS_TX_PACKETS_CNT].name = "tx_packets_cnt", 1732 + [ERDMA_STATS_TX_BYTES_CNT].name = "tx_bytes_cnt", 1733 + [ERDMA_STATS_TX_DISABLE_DROP_CNT].name = "tx_disable_drop_cnt", 1734 + [ERDMA_STATS_TX_BPS_METER_DROP_CNT].name = "tx_bps_limit_drop_cnt", 1735 + [ERDMA_STATS_TX_PPS_METER_DROP_CNT].name = "tx_pps_limit_drop_cnt", 1736 + [ERDMA_STATS_RX_PACKETS_CNT].name = "rx_packets_cnt", 1737 + [ERDMA_STATS_RX_BYTES_CNT].name = "rx_bytes_cnt", 1738 + [ERDMA_STATS_RX_DISABLE_DROP_CNT].name = "rx_disable_drop_cnt", 1739 + [ERDMA_STATS_RX_BPS_METER_DROP_CNT].name = "rx_bps_limit_drop_cnt", 1740 + [ERDMA_STATS_RX_PPS_METER_DROP_CNT].name = "rx_pps_limit_drop_cnt", 1741 + }; 1742 + 1743 + struct rdma_hw_stats *erdma_alloc_hw_port_stats(struct ib_device *device, 1744 + u32 port_num) 1745 + { 1746 + return rdma_alloc_hw_stats_struct(erdma_descs, ERDMA_STATS_MAX, 1747 + RDMA_HW_STATS_DEFAULT_LIFESPAN); 1748 + } 1749 + 1750 + static int erdma_query_hw_stats(struct erdma_dev *dev, 1751 + struct rdma_hw_stats *stats) 1752 + { 1753 + struct erdma_cmdq_query_stats_resp *resp; 1754 + struct erdma_cmdq_query_req req; 1755 + dma_addr_t dma_addr; 1756 + int err; 1757 + 1758 + erdma_cmdq_build_reqhdr(&req.hdr, CMDQ_SUBMOD_COMMON, 1759 + CMDQ_OPCODE_GET_STATS); 1760 + 1761 + resp = dma_pool_zalloc(dev->resp_pool, GFP_KERNEL, &dma_addr); 1762 + if (!resp) 1763 + return -ENOMEM; 1764 + 1765 + req.target_addr = dma_addr; 1766 + req.target_length = ERDMA_HW_RESP_SIZE; 1767 + 1768 + err = erdma_post_cmd_wait(&dev->cmdq, &req, sizeof(req), NULL, NULL); 1769 + if (err) 1770 + goto out; 1771 + 1772 + if (resp->hdr.magic != ERDMA_HW_RESP_MAGIC) { 1773 + err = -EINVAL; 1774 + goto out; 1775 + } 1776 + 1777 + memcpy(&stats->value[0], &resp->tx_req_cnt, 1778 + sizeof(u64) * stats->num_counters); 1779 + 1780 + out: 1781 + dma_pool_free(dev->resp_pool, resp, dma_addr); 1782 + 1783 + return err; 1784 + } 1785 + 1786 + int erdma_get_hw_stats(struct ib_device *ibdev, struct rdma_hw_stats *stats, 1787 + u32 port, int index) 1788 + { 1789 + struct erdma_dev *dev = to_edev(ibdev); 1790 + int ret; 1791 + 1792 + if (port == 0) 1793 + return 0; 1794 + 1795 + ret = erdma_query_hw_stats(dev, stats); 1796 + if (ret) 1797 + return ret; 1798 + 1799 + return stats->num_counters; 1800 + }
+4
drivers/infiniband/hw/erdma/erdma_verbs.h
··· 361 361 unsigned int *sg_offset); 362 362 void erdma_port_event(struct erdma_dev *dev, enum ib_event_type reason); 363 363 void erdma_set_mtu(struct erdma_dev *dev, u32 mtu); 364 + struct rdma_hw_stats *erdma_alloc_hw_port_stats(struct ib_device *device, 365 + u32 port_num); 366 + int erdma_get_hw_stats(struct ib_device *ibdev, struct rdma_hw_stats *stats, 367 + u32 port, int index); 364 368 365 369 #endif
+2 -2
drivers/infiniband/hw/hfi1/user_exp_rcv.c
··· 491 491 if (unlikely(tinfo->tidcnt > fd->tid_used)) 492 492 return -EINVAL; 493 493 494 - tidinfo = memdup_user(u64_to_user_ptr(tinfo->tidlist), 495 - sizeof(tidinfo[0]) * tinfo->tidcnt); 494 + tidinfo = memdup_array_user(u64_to_user_ptr(tinfo->tidlist), 495 + tinfo->tidcnt, sizeof(tidinfo[0])); 496 496 if (IS_ERR(tidinfo)) 497 497 return PTR_ERR(tidinfo); 498 498
+2 -2
drivers/infiniband/hw/hfi1/user_sdma.c
··· 494 494 * equal to the pkt count. However, there is no way to 495 495 * tell at this point. 496 496 */ 497 - tmp = memdup_user(iovec[idx].iov_base, 498 - ntids * sizeof(*req->tids)); 497 + tmp = memdup_array_user(iovec[idx].iov_base, 498 + ntids, sizeof(*req->tids)); 499 499 if (IS_ERR(tmp)) { 500 500 ret = PTR_ERR(tmp); 501 501 SDMA_DBG(req, "Failed to copy %d TIDs (%d)",
+2 -1
drivers/infiniband/hw/hns/Makefile
··· 7 7 8 8 hns-roce-objs := hns_roce_main.o hns_roce_cmd.o hns_roce_pd.o \ 9 9 hns_roce_ah.o hns_roce_hem.o hns_roce_mr.o hns_roce_qp.o \ 10 - hns_roce_cq.o hns_roce_alloc.o hns_roce_db.o hns_roce_srq.o hns_roce_restrack.o 10 + hns_roce_cq.o hns_roce_alloc.o hns_roce_db.o hns_roce_srq.o hns_roce_restrack.o \ 11 + hns_roce_debugfs.o 11 12 12 13 ifdef CONFIG_INFINIBAND_HNS_HIP08 13 14 hns-roce-hw-v2-objs := hns_roce_hw_v2.o $(hns-roce-objs)
+12 -1
drivers/infiniband/hw/hns/hns_roce_ah.c
··· 57 57 struct rdma_ah_attr *ah_attr = init_attr->ah_attr; 58 58 const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr); 59 59 struct hns_roce_dev *hr_dev = to_hr_dev(ibah->device); 60 + struct hns_roce_ib_create_ah_resp resp = {}; 60 61 struct hns_roce_ah *ah = to_hr_ah(ibah); 61 62 int ret = 0; 62 63 u32 max_sl; ··· 93 92 ret = rdma_read_gid_l2_fields(ah_attr->grh.sgid_attr, 94 93 &ah->av.vlan_id, NULL); 95 94 if (ret) 96 - return ret; 95 + goto err_out; 97 96 98 97 ah->av.vlan_en = ah->av.vlan_id < VLAN_N_VID; 99 98 } 99 + 100 + if (udata) { 101 + memcpy(resp.dmac, ah_attr->roce.dmac, ETH_ALEN); 102 + ret = ib_copy_to_udata(udata, &resp, 103 + min(udata->outlen, sizeof(resp))); 104 + } 105 + 106 + err_out: 107 + if (ret) 108 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_AH_CREATE_ERR_CNT]); 100 109 101 110 return ret; 102 111 }
+17 -2
drivers/infiniband/hw/hns/hns_roce_cmd.c
··· 41 41 static int hns_roce_cmd_mbox_post_hw(struct hns_roce_dev *hr_dev, 42 42 struct hns_roce_mbox_msg *mbox_msg) 43 43 { 44 - return hr_dev->hw->post_mbox(hr_dev, mbox_msg); 44 + int ret; 45 + 46 + ret = hr_dev->hw->post_mbox(hr_dev, mbox_msg); 47 + if (ret) 48 + return ret; 49 + 50 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_MBX_POSTED_CNT]); 51 + 52 + return 0; 45 53 } 46 54 47 55 /* this should be called with "poll_sem" */ ··· 66 58 return ret; 67 59 } 68 60 69 - return hr_dev->hw->poll_mbox_done(hr_dev); 61 + ret = hr_dev->hw->poll_mbox_done(hr_dev); 62 + if (ret) 63 + return ret; 64 + 65 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_MBX_POLLED_CNT]); 66 + 67 + return 0; 70 68 } 71 69 72 70 static int hns_roce_cmd_mbox_poll(struct hns_roce_dev *hr_dev, ··· 103 89 context->result = (status == HNS_ROCE_CMD_SUCCESS) ? 0 : (-EIO); 104 90 context->out_param = out_param; 105 91 complete(&context->done); 92 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_MBX_EVENT_CNT]); 106 93 } 107 94 108 95 static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev,
+11 -6
drivers/infiniband/hw/hns/hns_roce_cq.c
··· 363 363 struct hns_roce_ib_create_cq ucmd = {}; 364 364 int ret; 365 365 366 - if (attr->flags) 367 - return -EOPNOTSUPP; 366 + if (attr->flags) { 367 + ret = -EOPNOTSUPP; 368 + goto err_out; 369 + } 368 370 369 371 ret = verify_cq_create_attr(hr_dev, attr); 370 372 if (ret) 371 - return ret; 373 + goto err_out; 372 374 373 375 if (udata) { 374 376 ret = get_cq_ucmd(hr_cq, udata, &ucmd); 375 377 if (ret) 376 - return ret; 378 + goto err_out; 377 379 } 378 380 379 381 set_cq_param(hr_cq, attr->cqe, attr->comp_vector, &ucmd); 380 382 381 383 ret = set_cqe_size(hr_cq, udata, &ucmd); 382 384 if (ret) 383 - return ret; 385 + goto err_out; 384 386 385 387 ret = alloc_cq_buf(hr_dev, hr_cq, udata, ucmd.buf_addr); 386 388 if (ret) { 387 389 ibdev_err(ibdev, "failed to alloc CQ buf, ret = %d.\n", ret); 388 - return ret; 390 + goto err_out; 389 391 } 390 392 391 393 ret = alloc_cq_db(hr_dev, hr_cq, udata, ucmd.db_addr, &resp); ··· 432 430 free_cq_db(hr_dev, hr_cq, udata); 433 431 err_cq_buf: 434 432 free_cq_buf(hr_dev, hr_cq); 433 + err_out: 434 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CQ_CREATE_ERR_CNT]); 435 + 435 436 return ret; 436 437 } 437 438
+110
drivers/infiniband/hw/hns/hns_roce_debugfs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright (c) 2023 Hisilicon Limited. 4 + */ 5 + 6 + #include <linux/debugfs.h> 7 + #include <linux/device.h> 8 + 9 + #include "hns_roce_device.h" 10 + 11 + static struct dentry *hns_roce_dbgfs_root; 12 + 13 + static int hns_debugfs_seqfile_open(struct inode *inode, struct file *f) 14 + { 15 + struct hns_debugfs_seqfile *seqfile = inode->i_private; 16 + 17 + return single_open(f, seqfile->read, seqfile->data); 18 + } 19 + 20 + static const struct file_operations hns_debugfs_seqfile_fops = { 21 + .owner = THIS_MODULE, 22 + .open = hns_debugfs_seqfile_open, 23 + .release = single_release, 24 + .read = seq_read, 25 + .llseek = seq_lseek 26 + }; 27 + 28 + static void init_debugfs_seqfile(struct hns_debugfs_seqfile *seq, 29 + const char *name, struct dentry *parent, 30 + int (*read_fn)(struct seq_file *, void *), 31 + void *data) 32 + { 33 + debugfs_create_file(name, 0400, parent, seq, &hns_debugfs_seqfile_fops); 34 + 35 + seq->read = read_fn; 36 + seq->data = data; 37 + } 38 + 39 + static const char * const sw_stat_info[] = { 40 + [HNS_ROCE_DFX_AEQE_CNT] = "aeqe", 41 + [HNS_ROCE_DFX_CEQE_CNT] = "ceqe", 42 + [HNS_ROCE_DFX_CMDS_CNT] = "cmds", 43 + [HNS_ROCE_DFX_CMDS_ERR_CNT] = "cmds_err", 44 + [HNS_ROCE_DFX_MBX_POSTED_CNT] = "posted_mbx", 45 + [HNS_ROCE_DFX_MBX_POLLED_CNT] = "polled_mbx", 46 + [HNS_ROCE_DFX_MBX_EVENT_CNT] = "mbx_event", 47 + [HNS_ROCE_DFX_QP_CREATE_ERR_CNT] = "qp_create_err", 48 + [HNS_ROCE_DFX_QP_MODIFY_ERR_CNT] = "qp_modify_err", 49 + [HNS_ROCE_DFX_CQ_CREATE_ERR_CNT] = "cq_create_err", 50 + [HNS_ROCE_DFX_CQ_MODIFY_ERR_CNT] = "cq_modify_err", 51 + [HNS_ROCE_DFX_SRQ_CREATE_ERR_CNT] = "srq_create_err", 52 + [HNS_ROCE_DFX_SRQ_MODIFY_ERR_CNT] = "srq_modify_err", 53 + [HNS_ROCE_DFX_XRCD_ALLOC_ERR_CNT] = "xrcd_alloc_err", 54 + [HNS_ROCE_DFX_MR_REG_ERR_CNT] = "mr_reg_err", 55 + [HNS_ROCE_DFX_MR_REREG_ERR_CNT] = "mr_rereg_err", 56 + [HNS_ROCE_DFX_AH_CREATE_ERR_CNT] = "ah_create_err", 57 + [HNS_ROCE_DFX_MMAP_ERR_CNT] = "mmap_err", 58 + [HNS_ROCE_DFX_UCTX_ALLOC_ERR_CNT] = "uctx_alloc_err", 59 + }; 60 + 61 + static int sw_stat_debugfs_show(struct seq_file *file, void *offset) 62 + { 63 + struct hns_roce_dev *hr_dev = file->private; 64 + int i; 65 + 66 + for (i = 0; i < HNS_ROCE_DFX_CNT_TOTAL; i++) 67 + seq_printf(file, "%-20s --- %lld\n", sw_stat_info[i], 68 + atomic64_read(&hr_dev->dfx_cnt[i])); 69 + 70 + return 0; 71 + } 72 + 73 + static void create_sw_stat_debugfs(struct hns_roce_dev *hr_dev, 74 + struct dentry *parent) 75 + { 76 + struct hns_sw_stat_debugfs *dbgfs = &hr_dev->dbgfs.sw_stat_root; 77 + 78 + dbgfs->root = debugfs_create_dir("sw_stat", parent); 79 + 80 + init_debugfs_seqfile(&dbgfs->sw_stat, "sw_stat", dbgfs->root, 81 + sw_stat_debugfs_show, hr_dev); 82 + } 83 + 84 + /* debugfs for device */ 85 + void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev) 86 + { 87 + struct hns_roce_dev_debugfs *dbgfs = &hr_dev->dbgfs; 88 + 89 + dbgfs->root = debugfs_create_dir(dev_name(&hr_dev->ib_dev.dev), 90 + hns_roce_dbgfs_root); 91 + 92 + create_sw_stat_debugfs(hr_dev, dbgfs->root); 93 + } 94 + 95 + void hns_roce_unregister_debugfs(struct hns_roce_dev *hr_dev) 96 + { 97 + debugfs_remove_recursive(hr_dev->dbgfs.root); 98 + } 99 + 100 + /* debugfs for hns module */ 101 + void hns_roce_init_debugfs(void) 102 + { 103 + hns_roce_dbgfs_root = debugfs_create_dir("hns_roce", NULL); 104 + } 105 + 106 + void hns_roce_cleanup_debugfs(void) 107 + { 108 + debugfs_remove_recursive(hns_roce_dbgfs_root); 109 + hns_roce_dbgfs_root = NULL; 110 + }
+33
drivers/infiniband/hw/hns/hns_roce_debugfs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Copyright (c) 2023 Hisilicon Limited. 4 + */ 5 + 6 + #ifndef __HNS_ROCE_DEBUGFS_H 7 + #define __HNS_ROCE_DEBUGFS_H 8 + 9 + /* debugfs seqfile */ 10 + struct hns_debugfs_seqfile { 11 + int (*read)(struct seq_file *seq, void *data); 12 + void *data; 13 + }; 14 + 15 + struct hns_sw_stat_debugfs { 16 + struct dentry *root; 17 + struct hns_debugfs_seqfile sw_stat; 18 + }; 19 + 20 + /* Debugfs for device */ 21 + struct hns_roce_dev_debugfs { 22 + struct dentry *root; 23 + struct hns_sw_stat_debugfs sw_stat_root; 24 + }; 25 + 26 + struct hns_roce_dev; 27 + 28 + void hns_roce_init_debugfs(void); 29 + void hns_roce_cleanup_debugfs(void); 30 + void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev); 31 + void hns_roce_unregister_debugfs(struct hns_roce_dev *hr_dev); 32 + 33 + #endif
+26
drivers/infiniband/hw/hns/hns_roce_device.h
··· 35 35 36 36 #include <rdma/ib_verbs.h> 37 37 #include <rdma/hns-abi.h> 38 + #include "hns_roce_debugfs.h" 38 39 39 40 #define PCI_REVISION_ID_HIP08 0x21 40 41 #define PCI_REVISION_ID_HIP09 0x30 ··· 870 869 HNS_ROCE_HW_CNT_TOTAL 871 870 }; 872 871 872 + enum hns_roce_sw_dfx_stat_index { 873 + HNS_ROCE_DFX_AEQE_CNT, 874 + HNS_ROCE_DFX_CEQE_CNT, 875 + HNS_ROCE_DFX_CMDS_CNT, 876 + HNS_ROCE_DFX_CMDS_ERR_CNT, 877 + HNS_ROCE_DFX_MBX_POSTED_CNT, 878 + HNS_ROCE_DFX_MBX_POLLED_CNT, 879 + HNS_ROCE_DFX_MBX_EVENT_CNT, 880 + HNS_ROCE_DFX_QP_CREATE_ERR_CNT, 881 + HNS_ROCE_DFX_QP_MODIFY_ERR_CNT, 882 + HNS_ROCE_DFX_CQ_CREATE_ERR_CNT, 883 + HNS_ROCE_DFX_CQ_MODIFY_ERR_CNT, 884 + HNS_ROCE_DFX_SRQ_CREATE_ERR_CNT, 885 + HNS_ROCE_DFX_SRQ_MODIFY_ERR_CNT, 886 + HNS_ROCE_DFX_XRCD_ALLOC_ERR_CNT, 887 + HNS_ROCE_DFX_MR_REG_ERR_CNT, 888 + HNS_ROCE_DFX_MR_REREG_ERR_CNT, 889 + HNS_ROCE_DFX_AH_CREATE_ERR_CNT, 890 + HNS_ROCE_DFX_MMAP_ERR_CNT, 891 + HNS_ROCE_DFX_UCTX_ALLOC_ERR_CNT, 892 + HNS_ROCE_DFX_CNT_TOTAL 893 + }; 894 + 873 895 struct hns_roce_hw { 874 896 int (*cmq_init)(struct hns_roce_dev *hr_dev); 875 897 void (*cmq_exit)(struct hns_roce_dev *hr_dev); ··· 1003 979 u32 is_vf; 1004 980 u32 cong_algo_tmpl_id; 1005 981 u64 dwqe_page; 982 + struct hns_roce_dev_debugfs dbgfs; 983 + atomic64_t *dfx_cnt; 1006 984 }; 1007 985 1008 986 static inline struct hns_roce_dev *to_hr_dev(struct ib_device *ib_dev)
+53 -18
drivers/infiniband/hw/hns/hns_roce_hw_v2.c
··· 1297 1297 /* Write to hardware */ 1298 1298 roce_write(hr_dev, ROCEE_TX_CMQ_PI_REG, csq->head); 1299 1299 1300 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CMDS_CNT]); 1301 + 1300 1302 do { 1301 1303 if (hns_roce_cmq_csq_done(hr_dev)) 1302 1304 break; ··· 1335 1333 } 1336 1334 1337 1335 spin_unlock_bh(&csq->lock); 1336 + 1337 + if (ret) 1338 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CMDS_ERR_CNT]); 1338 1339 1339 1340 return ret; 1340 1341 } ··· 2060 2055 /* Apply all loaded caps before setting to hardware */ 2061 2056 static void apply_func_caps(struct hns_roce_dev *hr_dev) 2062 2057 { 2058 + #define MAX_GID_TBL_LEN 256 2063 2059 struct hns_roce_caps *caps = &hr_dev->caps; 2064 2060 struct hns_roce_v2_priv *priv = hr_dev->priv; 2065 2061 ··· 2096 2090 caps->gmv_entry_sz = HNS_ROCE_V3_GMV_ENTRY_SZ; 2097 2091 2098 2092 caps->gmv_hop_num = HNS_ROCE_HOP_NUM_0; 2099 - caps->gid_table_len[0] = caps->gmv_bt_num * 2100 - (HNS_HW_PAGE_SIZE / caps->gmv_entry_sz); 2093 + 2094 + /* It's meaningless to support excessively large gid_table_len, 2095 + * as the type of sgid_index in kernel struct ib_global_route 2096 + * and userspace struct ibv_global_route are u8/uint8_t (0-255). 2097 + */ 2098 + caps->gid_table_len[0] = min_t(u32, MAX_GID_TBL_LEN, 2099 + caps->gmv_bt_num * 2100 + (HNS_HW_PAGE_SIZE / caps->gmv_entry_sz)); 2101 2101 2102 2102 caps->gmv_entry_num = caps->gmv_bt_num * (PAGE_SIZE / 2103 2103 caps->gmv_entry_sz); ··· 2710 2698 return 0; 2711 2699 2712 2700 create_failed_qp: 2701 + for (i--; i >= 0; i--) { 2702 + hns_roce_v2_destroy_qp(&free_mr->rsv_qp[i]->ibqp, NULL); 2703 + kfree(free_mr->rsv_qp[i]); 2704 + } 2713 2705 hns_roce_destroy_cq(cq, NULL); 2714 2706 kfree(cq); 2715 2707 ··· 5683 5667 struct hns_roce_srq_context *srq_context; 5684 5668 struct hns_roce_srq_context *srqc_mask; 5685 5669 struct hns_roce_cmd_mailbox *mailbox; 5686 - int ret; 5670 + int ret = 0; 5687 5671 5688 5672 /* Resizing SRQs is not supported yet */ 5689 - if (srq_attr_mask & IB_SRQ_MAX_WR) 5690 - return -EINVAL; 5673 + if (srq_attr_mask & IB_SRQ_MAX_WR) { 5674 + ret = -EOPNOTSUPP; 5675 + goto out; 5676 + } 5691 5677 5692 5678 if (srq_attr_mask & IB_SRQ_LIMIT) { 5693 - if (srq_attr->srq_limit > srq->wqe_cnt) 5694 - return -EINVAL; 5679 + if (srq_attr->srq_limit > srq->wqe_cnt) { 5680 + ret = -EINVAL; 5681 + goto out; 5682 + } 5695 5683 5696 5684 mailbox = hns_roce_alloc_cmd_mailbox(hr_dev); 5697 - if (IS_ERR(mailbox)) 5698 - return PTR_ERR(mailbox); 5685 + if (IS_ERR(mailbox)) { 5686 + ret = PTR_ERR(mailbox); 5687 + goto out; 5688 + } 5699 5689 5700 5690 srq_context = mailbox->buf; 5701 5691 srqc_mask = (struct hns_roce_srq_context *)mailbox->buf + 1; ··· 5714 5692 ret = hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, 5715 5693 HNS_ROCE_CMD_MODIFY_SRQC, srq->srqn); 5716 5694 hns_roce_free_cmd_mailbox(hr_dev, mailbox); 5717 - if (ret) { 5695 + if (ret) 5718 5696 ibdev_err(&hr_dev->ib_dev, 5719 5697 "failed to handle cmd of modifying SRQ, ret = %d.\n", 5720 5698 ret); 5721 - return ret; 5722 - } 5723 5699 } 5724 5700 5725 - return 0; 5701 + out: 5702 + if (ret) 5703 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_SRQ_MODIFY_ERR_CNT]); 5704 + 5705 + return ret; 5726 5706 } 5727 5707 5728 5708 static int hns_roce_v2_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr) ··· 5768 5744 int ret; 5769 5745 5770 5746 mailbox = hns_roce_alloc_cmd_mailbox(hr_dev); 5771 - if (IS_ERR(mailbox)) 5772 - return PTR_ERR(mailbox); 5747 + ret = PTR_ERR_OR_ZERO(mailbox); 5748 + if (ret) 5749 + goto err_out; 5773 5750 5774 5751 cq_context = mailbox->buf; 5775 5752 cqc_mask = (struct hns_roce_v2_cq_context *)mailbox->buf + 1; ··· 5799 5774 ibdev_err(&hr_dev->ib_dev, 5800 5775 "failed to process cmd when modifying CQ, ret = %d.\n", 5801 5776 ret); 5777 + 5778 + err_out: 5779 + if (ret) 5780 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CQ_MODIFY_ERR_CNT]); 5802 5781 5803 5782 return ret; 5804 5783 } ··· 6043 6014 ++eq->cons_index; 6044 6015 aeqe_found = IRQ_HANDLED; 6045 6016 6017 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_AEQE_CNT]); 6018 + 6046 6019 hns_roce_v2_init_irq_work(hr_dev, eq, queue_num); 6047 6020 6048 6021 aeqe = next_aeqe_sw_v2(eq); ··· 6086 6055 6087 6056 ++eq->cons_index; 6088 6057 ceqe_found = IRQ_HANDLED; 6058 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CEQE_CNT]); 6089 6059 6090 6060 ceqe = next_ceqe_sw_v2(eq); 6091 6061 } ··· 6489 6457 /* irq contains: abnormal + AEQ + CEQ */ 6490 6458 for (j = 0; j < other_num; j++) 6491 6459 snprintf((char *)hr_dev->irq_names[j], HNS_ROCE_INT_NAME_LEN, 6492 - "hns-abn-%d", j); 6460 + "hns-%s-abn-%d", pci_name(hr_dev->pci_dev), j); 6493 6461 6494 6462 for (j = other_num; j < (other_num + aeq_num); j++) 6495 6463 snprintf((char *)hr_dev->irq_names[j], HNS_ROCE_INT_NAME_LEN, 6496 - "hns-aeq-%d", j - other_num); 6464 + "hns-%s-aeq-%d", pci_name(hr_dev->pci_dev), j - other_num); 6497 6465 6498 6466 for (j = (other_num + aeq_num); j < irq_num; j++) 6499 6467 snprintf((char *)hr_dev->irq_names[j], HNS_ROCE_INT_NAME_LEN, 6500 - "hns-ceq-%d", j - other_num - aeq_num); 6468 + "hns-%s-ceq-%d", pci_name(hr_dev->pci_dev), 6469 + j - other_num - aeq_num); 6501 6470 6502 6471 for (j = 0; j < irq_num; j++) { 6503 6472 if (j < other_num) ··· 6996 6963 6997 6964 static int __init hns_roce_hw_v2_init(void) 6998 6965 { 6966 + hns_roce_init_debugfs(); 6999 6967 return hnae3_register_client(&hns_roce_hw_v2_client); 7000 6968 } 7001 6969 7002 6970 static void __exit hns_roce_hw_v2_exit(void) 7003 6971 { 7004 6972 hnae3_unregister_client(&hns_roce_hw_v2_client); 6973 + hns_roce_cleanup_debugfs(); 7005 6974 } 7006 6975 7007 6976 module_init(hns_roce_hw_v2_init);
+41 -7
drivers/infiniband/hw/hns/hns_roce_main.c
··· 361 361 struct hns_roce_dev *hr_dev = to_hr_dev(uctx->device); 362 362 struct hns_roce_ib_alloc_ucontext_resp resp = {}; 363 363 struct hns_roce_ib_alloc_ucontext ucmd = {}; 364 - int ret; 364 + int ret = -EAGAIN; 365 365 366 366 if (!hr_dev->active) 367 - return -EAGAIN; 367 + goto error_out; 368 368 369 369 resp.qp_tab_size = hr_dev->caps.num_qps; 370 370 resp.srq_tab_size = hr_dev->caps.num_srqs; ··· 372 372 ret = ib_copy_from_udata(&ucmd, udata, 373 373 min(udata->inlen, sizeof(ucmd))); 374 374 if (ret) 375 - return ret; 375 + goto error_out; 376 376 377 377 if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) 378 378 context->config = ucmd.config & HNS_ROCE_EXSGE_FLAGS; ··· 396 396 397 397 ret = hns_roce_uar_alloc(hr_dev, &context->uar); 398 398 if (ret) 399 - goto error_fail_uar_alloc; 399 + goto error_out; 400 400 401 401 ret = hns_roce_alloc_uar_entry(uctx); 402 402 if (ret) ··· 423 423 error_fail_uar_entry: 424 424 ida_free(&hr_dev->uar_ida.ida, (int)context->uar.logic_idx); 425 425 426 - error_fail_uar_alloc: 426 + error_out: 427 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_UCTX_ALLOC_ERR_CNT]); 428 + 427 429 return ret; 428 430 } 429 431 ··· 441 439 442 440 static int hns_roce_mmap(struct ib_ucontext *uctx, struct vm_area_struct *vma) 443 441 { 442 + struct hns_roce_dev *hr_dev = to_hr_dev(uctx->device); 444 443 struct rdma_user_mmap_entry *rdma_entry; 445 444 struct hns_user_mmap_entry *entry; 446 445 phys_addr_t pfn; ··· 449 446 int ret; 450 447 451 448 rdma_entry = rdma_user_mmap_entry_get_pgoff(uctx, vma->vm_pgoff); 452 - if (!rdma_entry) 449 + if (!rdma_entry) { 450 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_MMAP_ERR_CNT]); 453 451 return -EINVAL; 452 + } 454 453 455 454 entry = to_hns_mmap(rdma_entry); 456 455 pfn = entry->address >> PAGE_SHIFT; ··· 472 467 473 468 out: 474 469 rdma_user_mmap_entry_put(rdma_entry); 470 + if (ret) 471 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_MMAP_ERR_CNT]); 472 + 475 473 return ret; 476 474 } 477 475 ··· 1017 1009 spin_unlock_irqrestore(&hr_dev->qp_list_lock, flags); 1018 1010 } 1019 1011 1012 + static int hns_roce_alloc_dfx_cnt(struct hns_roce_dev *hr_dev) 1013 + { 1014 + hr_dev->dfx_cnt = kvcalloc(HNS_ROCE_DFX_CNT_TOTAL, sizeof(atomic64_t), 1015 + GFP_KERNEL); 1016 + if (!hr_dev->dfx_cnt) 1017 + return -ENOMEM; 1018 + 1019 + return 0; 1020 + } 1021 + 1022 + static void hns_roce_dealloc_dfx_cnt(struct hns_roce_dev *hr_dev) 1023 + { 1024 + kvfree(hr_dev->dfx_cnt); 1025 + } 1026 + 1020 1027 int hns_roce_init(struct hns_roce_dev *hr_dev) 1021 1028 { 1022 1029 struct device *dev = hr_dev->dev; ··· 1039 1016 1040 1017 hr_dev->is_reset = false; 1041 1018 1019 + ret = hns_roce_alloc_dfx_cnt(hr_dev); 1020 + if (ret) 1021 + return ret; 1022 + 1042 1023 if (hr_dev->hw->cmq_init) { 1043 1024 ret = hr_dev->hw->cmq_init(hr_dev); 1044 1025 if (ret) { 1045 1026 dev_err(dev, "init RoCE Command Queue failed!\n"); 1046 - return ret; 1027 + goto error_failed_alloc_dfx_cnt; 1047 1028 } 1048 1029 } 1049 1030 ··· 1106 1079 if (ret) 1107 1080 goto error_failed_register_device; 1108 1081 1082 + hns_roce_register_debugfs(hr_dev); 1083 + 1109 1084 return 0; 1110 1085 1111 1086 error_failed_register_device: ··· 1132 1103 if (hr_dev->hw->cmq_exit) 1133 1104 hr_dev->hw->cmq_exit(hr_dev); 1134 1105 1106 + error_failed_alloc_dfx_cnt: 1107 + hns_roce_dealloc_dfx_cnt(hr_dev); 1108 + 1135 1109 return ret; 1136 1110 } 1137 1111 1138 1112 void hns_roce_exit(struct hns_roce_dev *hr_dev) 1139 1113 { 1114 + hns_roce_unregister_debugfs(hr_dev); 1140 1115 hns_roce_unregister_device(hr_dev); 1141 1116 1142 1117 if (hr_dev->hw->hw_exit) ··· 1155 1122 hns_roce_cmd_cleanup(hr_dev); 1156 1123 if (hr_dev->hw->cmq_exit) 1157 1124 hr_dev->hw->cmq_exit(hr_dev); 1125 + hns_roce_dealloc_dfx_cnt(hr_dev); 1158 1126 } 1159 1127 1160 1128 MODULE_LICENSE("Dual BSD/GPL");
+20 -8
drivers/infiniband/hw/hns/hns_roce_mr.c
··· 228 228 int ret; 229 229 230 230 mr = kzalloc(sizeof(*mr), GFP_KERNEL); 231 - if (!mr) 232 - return ERR_PTR(-ENOMEM); 231 + if (!mr) { 232 + ret = -ENOMEM; 233 + goto err_out; 234 + } 233 235 234 236 mr->iova = virt_addr; 235 237 mr->size = length; ··· 261 259 free_mr_key(hr_dev, mr); 262 260 err_alloc_mr: 263 261 kfree(mr); 262 + err_out: 263 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_MR_REG_ERR_CNT]); 264 + 264 265 return ERR_PTR(ret); 265 266 } 266 267 ··· 279 274 unsigned long mtpt_idx; 280 275 int ret; 281 276 282 - if (!mr->enabled) 283 - return ERR_PTR(-EINVAL); 277 + if (!mr->enabled) { 278 + ret = -EINVAL; 279 + goto err_out; 280 + } 284 281 285 282 mailbox = hns_roce_alloc_cmd_mailbox(hr_dev); 286 - if (IS_ERR(mailbox)) 287 - return ERR_CAST(mailbox); 283 + ret = PTR_ERR_OR_ZERO(mailbox); 284 + if (ret) 285 + goto err_out; 288 286 289 287 mtpt_idx = key_to_hw_index(mr->key) & (hr_dev->caps.num_mtpts - 1); 290 288 ··· 339 331 free_cmd_mbox: 340 332 hns_roce_free_cmd_mailbox(hr_dev, mailbox); 341 333 342 - if (ret) 334 + err_out: 335 + if (ret) { 336 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_MR_REREG_ERR_CNT]); 343 337 return ERR_PTR(ret); 338 + } 339 + 344 340 return NULL; 345 341 } 346 342 ··· 686 674 mtr->kmem = NULL; 687 675 mtr->umem = ib_umem_get(ibdev, user_addr, total_size, 688 676 buf_attr->user_access); 689 - if (IS_ERR_OR_NULL(mtr->umem)) { 677 + if (IS_ERR(mtr->umem)) { 690 678 ibdev_err(ibdev, "failed to get umem, ret = %ld.\n", 691 679 PTR_ERR(mtr->umem)); 692 680 return -ENOMEM;
+9 -5
drivers/infiniband/hw/hns/hns_roce_pd.c
··· 149 149 struct hns_roce_xrcd *xrcd = to_hr_xrcd(ib_xrcd); 150 150 int ret; 151 151 152 - if (!(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC)) 153 - return -EINVAL; 152 + if (!(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC)) { 153 + ret = -EOPNOTSUPP; 154 + goto err_out; 155 + } 154 156 155 157 ret = hns_roce_xrcd_alloc(hr_dev, &xrcd->xrcdn); 156 - if (ret) 157 - return ret; 158 158 159 - return 0; 159 + err_out: 160 + if (ret) 161 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_XRCD_ALLOC_ERR_CNT]); 162 + 163 + return ret; 160 164 } 161 165 162 166 int hns_roce_dealloc_xrcd(struct ib_xrcd *ib_xrcd, struct ib_udata *udata)
+7 -1
drivers/infiniband/hw/hns/hns_roce_qp.c
··· 1216 1216 1217 1217 ret = check_qp_type(hr_dev, init_attr->qp_type, !!udata); 1218 1218 if (ret) 1219 - return ret; 1219 + goto err_out; 1220 1220 1221 1221 if (init_attr->qp_type == IB_QPT_XRC_TGT) 1222 1222 hr_qp->xrcdn = to_hr_xrcd(init_attr->xrcd)->xrcdn; ··· 1230 1230 if (ret) 1231 1231 ibdev_err(ibdev, "create QP type 0x%x failed(%d)\n", 1232 1232 init_attr->qp_type, ret); 1233 + 1234 + err_out: 1235 + if (ret) 1236 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_QP_CREATE_ERR_CNT]); 1233 1237 1234 1238 return ret; 1235 1239 } ··· 1370 1366 1371 1367 out: 1372 1368 mutex_unlock(&hr_qp->mutex); 1369 + if (ret) 1370 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_QP_MODIFY_ERR_CNT]); 1373 1371 1374 1372 return ret; 1375 1373 }
+4 -2
drivers/infiniband/hw/hns/hns_roce_srq.c
··· 475 475 476 476 ret = set_srq_param(srq, init_attr, udata); 477 477 if (ret) 478 - return ret; 478 + goto err_out; 479 479 480 480 ret = alloc_srq_buf(hr_dev, srq, udata); 481 481 if (ret) 482 - return ret; 482 + goto err_out; 483 483 484 484 ret = alloc_srq_db(hr_dev, srq, udata, &resp); 485 485 if (ret) ··· 517 517 free_srq_db(hr_dev, srq, udata); 518 518 err_srq_buf: 519 519 free_srq_buf(hr_dev, srq); 520 + err_out: 521 + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_SRQ_CREATE_ERR_CNT]); 520 522 521 523 return ret; 522 524 }
+3 -8
drivers/infiniband/hw/irdma/utils.c
··· 1393 1393 u32 val) 1394 1394 { 1395 1395 u32 crc = 0; 1396 - int ret; 1397 - int ret_code = 0; 1398 1396 1399 - crypto_shash_init(desc); 1400 - ret = crypto_shash_update(desc, addr, len); 1401 - if (!ret) 1402 - crypto_shash_final(desc, (u8 *)&crc); 1397 + crypto_shash_digest(desc, addr, len, (u8 *)&crc); 1403 1398 if (crc != val) 1404 - ret_code = -EINVAL; 1399 + return -EINVAL; 1405 1400 1406 - return ret_code; 1401 + return 0; 1407 1402 } 1408 1403 1409 1404 /**
+32 -2
drivers/infiniband/hw/mana/cq.c
··· 12 12 struct ib_device *ibdev = ibcq->device; 13 13 struct mana_ib_create_cq ucmd = {}; 14 14 struct mana_ib_dev *mdev; 15 + struct gdma_context *gc; 15 16 int err; 16 17 17 18 mdev = container_of(ibdev, struct mana_ib_dev, ib_dev); 19 + gc = mdev->gdma_dev->gdma_context; 18 20 19 21 if (udata->inlen < sizeof(ucmd)) 20 22 return -EINVAL; 23 + 24 + if (attr->comp_vector > gc->max_num_queues) 25 + return -EINVAL; 26 + 27 + cq->comp_vector = attr->comp_vector; 21 28 22 29 err = ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen)); 23 30 if (err) { ··· 33 26 return err; 34 27 } 35 28 36 - if (attr->cqe > MAX_SEND_BUFFERS_PER_QUEUE) { 29 + if (attr->cqe > mdev->adapter_caps.max_qp_wr) { 37 30 ibdev_dbg(ibdev, "CQE %d exceeding limit\n", attr->cqe); 38 31 return -EINVAL; 39 32 } ··· 63 56 /* 64 57 * The CQ ID is not known at this time. The ID is generated at create_qp 65 58 */ 59 + cq->id = INVALID_QUEUE_ID; 66 60 67 61 return 0; 68 62 ··· 77 69 struct mana_ib_cq *cq = container_of(ibcq, struct mana_ib_cq, ibcq); 78 70 struct ib_device *ibdev = ibcq->device; 79 71 struct mana_ib_dev *mdev; 72 + struct gdma_context *gc; 73 + int err; 80 74 81 75 mdev = container_of(ibdev, struct mana_ib_dev, ib_dev); 76 + gc = mdev->gdma_dev->gdma_context; 82 77 83 - mana_ib_gd_destroy_dma_region(mdev, cq->gdma_region); 78 + err = mana_ib_gd_destroy_dma_region(mdev, cq->gdma_region); 79 + if (err) { 80 + ibdev_dbg(ibdev, 81 + "Failed to destroy dma region, %d\n", err); 82 + return err; 83 + } 84 + 85 + if (cq->id != INVALID_QUEUE_ID) { 86 + kfree(gc->cq_table[cq->id]); 87 + gc->cq_table[cq->id] = NULL; 88 + } 89 + 84 90 ib_umem_release(cq->umem); 85 91 86 92 return 0; 93 + } 94 + 95 + void mana_ib_cq_handler(void *ctx, struct gdma_queue *gdma_cq) 96 + { 97 + struct mana_ib_cq *cq = ctx; 98 + 99 + if (cq->ibcq.comp_handler) 100 + cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); 87 101 }
+26 -5
drivers/infiniband/hw/mana/device.c
··· 68 68 ibdev_dbg(&dev->ib_dev, "mdev=%p id=%d num_ports=%d\n", mdev, 69 69 mdev->dev_id.as_uint32, dev->ib_dev.phys_port_cnt); 70 70 71 - dev->gdma_dev = mdev; 72 71 dev->ib_dev.node_type = RDMA_NODE_IB_CA; 73 72 74 73 /* ··· 77 78 dev->ib_dev.num_comp_vectors = 1; 78 79 dev->ib_dev.dev.parent = mdev->gdma_context->dev; 79 80 81 + ret = mana_gd_register_device(&mdev->gdma_context->mana_ib); 82 + if (ret) { 83 + ibdev_err(&dev->ib_dev, "Failed to register device, ret %d", 84 + ret); 85 + goto free_ib_device; 86 + } 87 + dev->gdma_dev = &mdev->gdma_context->mana_ib; 88 + 89 + ret = mana_ib_gd_query_adapter_caps(dev); 90 + if (ret) { 91 + ibdev_err(&dev->ib_dev, "Failed to query device caps, ret %d", 92 + ret); 93 + goto deregister_device; 94 + } 95 + 80 96 ret = ib_register_device(&dev->ib_dev, "mana_%d", 81 97 mdev->gdma_context->dev); 82 - if (ret) { 83 - ib_dealloc_device(&dev->ib_dev); 84 - return ret; 85 - } 98 + if (ret) 99 + goto deregister_device; 86 100 87 101 dev_set_drvdata(&adev->dev, dev); 88 102 89 103 return 0; 104 + 105 + deregister_device: 106 + mana_gd_deregister_device(dev->gdma_dev); 107 + free_ib_device: 108 + ib_dealloc_device(&dev->ib_dev); 109 + return ret; 90 110 } 91 111 92 112 static void mana_ib_remove(struct auxiliary_device *adev) ··· 113 95 struct mana_ib_dev *dev = dev_get_drvdata(&adev->dev); 114 96 115 97 ib_unregister_device(&dev->ib_dev); 98 + 99 + mana_gd_deregister_device(dev->gdma_dev); 100 + 116 101 ib_dealloc_device(&dev->ib_dev); 117 102 } 118 103
+53 -14
drivers/infiniband/hw/mana/main.c
··· 8 8 void mana_ib_uncfg_vport(struct mana_ib_dev *dev, struct mana_ib_pd *pd, 9 9 u32 port) 10 10 { 11 - struct gdma_dev *gd = dev->gdma_dev; 11 + struct gdma_dev *gd = &dev->gdma_dev->gdma_context->mana; 12 12 struct mana_port_context *mpc; 13 13 struct net_device *ndev; 14 14 struct mana_context *mc; ··· 31 31 int mana_ib_cfg_vport(struct mana_ib_dev *dev, u32 port, struct mana_ib_pd *pd, 32 32 u32 doorbell_id) 33 33 { 34 - struct gdma_dev *mdev = dev->gdma_dev; 34 + struct gdma_dev *mdev = &dev->gdma_dev->gdma_context->mana; 35 35 struct mana_port_context *mpc; 36 36 struct mana_context *mc; 37 37 struct net_device *ndev; ··· 486 486 int mana_ib_query_device(struct ib_device *ibdev, struct ib_device_attr *props, 487 487 struct ib_udata *uhw) 488 488 { 489 - props->max_qp = MANA_MAX_NUM_QUEUES; 490 - props->max_qp_wr = MAX_SEND_BUFFERS_PER_QUEUE; 489 + struct mana_ib_dev *dev = container_of(ibdev, 490 + struct mana_ib_dev, ib_dev); 491 491 492 - /* 493 - * max_cqe could be potentially much bigger. 494 - * As this version of driver only support RAW QP, set it to the same 495 - * value as max_qp_wr 496 - */ 497 - props->max_cqe = MAX_SEND_BUFFERS_PER_QUEUE; 498 - 492 + props->max_qp = dev->adapter_caps.max_qp_count; 493 + props->max_qp_wr = dev->adapter_caps.max_qp_wr; 494 + props->max_cq = dev->adapter_caps.max_cq_count; 495 + props->max_cqe = dev->adapter_caps.max_qp_wr; 496 + props->max_mr = dev->adapter_caps.max_mr_count; 499 497 props->max_mr_size = MANA_IB_MAX_MR_SIZE; 500 - props->max_mr = MANA_IB_MAX_MR; 501 - props->max_send_sge = MAX_TX_WQE_SGL_ENTRIES; 502 - props->max_recv_sge = MAX_RX_WQE_SGL_ENTRIES; 498 + props->max_send_sge = dev->adapter_caps.max_send_sge_count; 499 + props->max_recv_sge = dev->adapter_caps.max_recv_sge_count; 503 500 504 501 return 0; 505 502 } ··· 517 520 518 521 void mana_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) 519 522 { 523 + } 524 + 525 + int mana_ib_gd_query_adapter_caps(struct mana_ib_dev *dev) 526 + { 527 + struct mana_ib_adapter_caps *caps = &dev->adapter_caps; 528 + struct mana_ib_query_adapter_caps_resp resp = {}; 529 + struct mana_ib_query_adapter_caps_req req = {}; 530 + int err; 531 + 532 + mana_gd_init_req_hdr(&req.hdr, MANA_IB_GET_ADAPTER_CAP, sizeof(req), 533 + sizeof(resp)); 534 + req.hdr.resp.msg_version = GDMA_MESSAGE_V3; 535 + req.hdr.dev_id = dev->gdma_dev->dev_id; 536 + 537 + err = mana_gd_send_request(dev->gdma_dev->gdma_context, sizeof(req), 538 + &req, sizeof(resp), &resp); 539 + 540 + if (err) { 541 + ibdev_err(&dev->ib_dev, 542 + "Failed to query adapter caps err %d", err); 543 + return err; 544 + } 545 + 546 + caps->max_sq_id = resp.max_sq_id; 547 + caps->max_rq_id = resp.max_rq_id; 548 + caps->max_cq_id = resp.max_cq_id; 549 + caps->max_qp_count = resp.max_qp_count; 550 + caps->max_cq_count = resp.max_cq_count; 551 + caps->max_mr_count = resp.max_mr_count; 552 + caps->max_pd_count = resp.max_pd_count; 553 + caps->max_inbound_read_limit = resp.max_inbound_read_limit; 554 + caps->max_outbound_read_limit = resp.max_outbound_read_limit; 555 + caps->mw_count = resp.mw_count; 556 + caps->max_srq_count = resp.max_srq_count; 557 + caps->max_qp_wr = min_t(u32, 558 + resp.max_requester_sq_size / GDMA_MAX_SQE_SIZE, 559 + resp.max_requester_rq_size / GDMA_MAX_RQE_SIZE); 560 + caps->max_inline_data_size = resp.max_inline_data_size; 561 + caps->max_send_sge_count = resp.max_send_sge_count; 562 + caps->max_recv_sge_count = resp.max_recv_sge_count; 563 + 564 + return 0; 520 565 }
+53
drivers/infiniband/hw/mana/mana_ib.h
··· 27 27 */ 28 28 #define MANA_IB_MAX_MR 0xFFFFFFu 29 29 30 + struct mana_ib_adapter_caps { 31 + u32 max_sq_id; 32 + u32 max_rq_id; 33 + u32 max_cq_id; 34 + u32 max_qp_count; 35 + u32 max_cq_count; 36 + u32 max_mr_count; 37 + u32 max_pd_count; 38 + u32 max_inbound_read_limit; 39 + u32 max_outbound_read_limit; 40 + u32 mw_count; 41 + u32 max_srq_count; 42 + u32 max_qp_wr; 43 + u32 max_send_sge_count; 44 + u32 max_recv_sge_count; 45 + u32 max_inline_data_size; 46 + }; 47 + 30 48 struct mana_ib_dev { 31 49 struct ib_device ib_dev; 32 50 struct gdma_dev *gdma_dev; 51 + struct mana_ib_adapter_caps adapter_caps; 33 52 }; 34 53 35 54 struct mana_ib_wq { ··· 86 67 int cqe; 87 68 u64 gdma_region; 88 69 u64 id; 70 + u32 comp_vector; 89 71 }; 90 72 91 73 struct mana_ib_qp { ··· 111 91 struct mana_ib_rwq_ind_table { 112 92 struct ib_rwq_ind_table ib_ind_table; 113 93 }; 94 + 95 + enum mana_ib_command_code { 96 + MANA_IB_GET_ADAPTER_CAP = 0x30001, 97 + }; 98 + 99 + struct mana_ib_query_adapter_caps_req { 100 + struct gdma_req_hdr hdr; 101 + }; /*HW Data */ 102 + 103 + struct mana_ib_query_adapter_caps_resp { 104 + struct gdma_resp_hdr hdr; 105 + u32 max_sq_id; 106 + u32 max_rq_id; 107 + u32 max_cq_id; 108 + u32 max_qp_count; 109 + u32 max_cq_count; 110 + u32 max_mr_count; 111 + u32 max_pd_count; 112 + u32 max_inbound_read_limit; 113 + u32 max_outbound_read_limit; 114 + u32 mw_count; 115 + u32 max_srq_count; 116 + u32 max_requester_sq_size; 117 + u32 max_responder_sq_size; 118 + u32 max_requester_rq_size; 119 + u32 max_responder_rq_size; 120 + u32 max_send_sge_count; 121 + u32 max_recv_sge_count; 122 + u32 max_inline_data_size; 123 + }; /* HW Data */ 114 124 115 125 int mana_ib_gd_create_dma_region(struct mana_ib_dev *dev, struct ib_umem *umem, 116 126 mana_handle_t *gdma_region); ··· 209 159 210 160 void mana_ib_disassociate_ucontext(struct ib_ucontext *ibcontext); 211 161 162 + int mana_ib_gd_query_adapter_caps(struct mana_ib_dev *mdev); 163 + 164 + void mana_ib_cq_handler(void *ctx, struct gdma_queue *gdma_cq); 212 165 #endif
+77 -14
drivers/infiniband/hw/mana/qp.c
··· 21 21 u32 req_buf_size; 22 22 int i, err; 23 23 24 - mdev = dev->gdma_dev; 25 - gc = mdev->gdma_context; 24 + gc = dev->gdma_dev->gdma_context; 25 + mdev = &gc->mana; 26 26 27 27 req_buf_size = 28 28 sizeof(*req) + sizeof(mana_handle_t) * MANA_INDIRECT_TABLE_SIZE; ··· 102 102 struct ib_rwq_ind_table *ind_tbl = attr->rwq_ind_tbl; 103 103 struct mana_ib_create_qp_rss_resp resp = {}; 104 104 struct mana_ib_create_qp_rss ucmd = {}; 105 - struct gdma_dev *gd = mdev->gdma_dev; 105 + struct gdma_queue **gdma_cq_allocated; 106 106 mana_handle_t *mana_ind_table; 107 107 struct mana_port_context *mpc; 108 + struct gdma_queue *gdma_cq; 109 + unsigned int ind_tbl_size; 108 110 struct mana_context *mc; 109 111 struct net_device *ndev; 112 + struct gdma_context *gc; 110 113 struct mana_ib_cq *cq; 111 114 struct mana_ib_wq *wq; 112 - unsigned int ind_tbl_size; 115 + struct gdma_dev *gd; 116 + struct mana_eq *eq; 113 117 struct ib_cq *ibcq; 114 118 struct ib_wq *ibwq; 115 119 int i = 0; 116 120 u32 port; 117 121 int ret; 118 122 123 + gc = mdev->gdma_dev->gdma_context; 124 + gd = &gc->mana; 119 125 mc = gd->driver_data; 120 126 121 127 if (!udata || udata->inlen < sizeof(ucmd)) ··· 135 129 return ret; 136 130 } 137 131 138 - if (attr->cap.max_recv_wr > MAX_SEND_BUFFERS_PER_QUEUE) { 132 + if (attr->cap.max_recv_wr > mdev->adapter_caps.max_qp_wr) { 139 133 ibdev_dbg(&mdev->ib_dev, 140 134 "Requested max_recv_wr %d exceeding limit\n", 141 135 attr->cap.max_recv_wr); ··· 184 178 goto fail; 185 179 } 186 180 181 + gdma_cq_allocated = kcalloc(ind_tbl_size, sizeof(*gdma_cq_allocated), 182 + GFP_KERNEL); 183 + if (!gdma_cq_allocated) { 184 + ret = -ENOMEM; 185 + goto fail; 186 + } 187 + 187 188 qp->port = port; 188 189 189 190 for (i = 0; i < ind_tbl_size; i++) { ··· 209 196 cq_spec.gdma_region = cq->gdma_region; 210 197 cq_spec.queue_size = cq->cqe * COMP_ENTRY_SIZE; 211 198 cq_spec.modr_ctx_id = 0; 212 - cq_spec.attached_eq = GDMA_CQ_NO_EQ; 199 + eq = &mc->eqs[cq->comp_vector % gc->max_num_queues]; 200 + cq_spec.attached_eq = eq->eq->id; 213 201 214 202 ret = mana_create_wq_obj(mpc, mpc->port_handle, GDMA_RQ, 215 203 &wq_spec, &cq_spec, &wq->rx_object); 216 - if (ret) 204 + if (ret) { 205 + /* Do cleanup starting with index i-1 */ 206 + i--; 217 207 goto fail; 208 + } 218 209 219 210 /* The GDMA regions are now owned by the WQ object */ 220 211 wq->gdma_region = GDMA_INVALID_DMA_REGION; ··· 235 218 resp.entries[i].wqid = wq->id; 236 219 237 220 mana_ind_table[i] = wq->rx_object; 221 + 222 + /* Create CQ table entry */ 223 + WARN_ON(gc->cq_table[cq->id]); 224 + gdma_cq = kzalloc(sizeof(*gdma_cq), GFP_KERNEL); 225 + if (!gdma_cq) { 226 + ret = -ENOMEM; 227 + goto fail; 228 + } 229 + gdma_cq_allocated[i] = gdma_cq; 230 + 231 + gdma_cq->cq.context = cq; 232 + gdma_cq->type = GDMA_CQ; 233 + gdma_cq->cq.callback = mana_ib_cq_handler; 234 + gdma_cq->id = cq->id; 235 + gc->cq_table[cq->id] = gdma_cq; 238 236 } 239 237 resp.num_entries = i; 240 238 ··· 269 237 goto fail; 270 238 } 271 239 240 + kfree(gdma_cq_allocated); 272 241 kfree(mana_ind_table); 273 242 274 243 return 0; ··· 277 244 fail: 278 245 while (i-- > 0) { 279 246 ibwq = ind_tbl->ind_tbl[i]; 247 + ibcq = ibwq->cq; 280 248 wq = container_of(ibwq, struct mana_ib_wq, ibwq); 249 + cq = container_of(ibcq, struct mana_ib_cq, ibcq); 250 + 251 + gc->cq_table[cq->id] = NULL; 252 + kfree(gdma_cq_allocated[i]); 253 + 281 254 mana_destroy_wq_obj(mpc, GDMA_RQ, wq->rx_object); 282 255 } 283 256 257 + kfree(gdma_cq_allocated); 284 258 kfree(mana_ind_table); 285 259 286 260 return ret; ··· 306 266 struct mana_ib_ucontext *mana_ucontext = 307 267 rdma_udata_to_drv_context(udata, struct mana_ib_ucontext, 308 268 ibucontext); 269 + struct gdma_dev *gd = &mdev->gdma_dev->gdma_context->mana; 309 270 struct mana_ib_create_qp_resp resp = {}; 310 - struct gdma_dev *gd = mdev->gdma_dev; 311 271 struct mana_ib_create_qp ucmd = {}; 272 + struct gdma_queue *gdma_cq = NULL; 312 273 struct mana_obj_spec wq_spec = {}; 313 274 struct mana_obj_spec cq_spec = {}; 314 275 struct mana_port_context *mpc; 315 276 struct mana_context *mc; 316 277 struct net_device *ndev; 317 278 struct ib_umem *umem; 318 - int err; 279 + struct mana_eq *eq; 280 + int eq_vec; 319 281 u32 port; 282 + int err; 320 283 321 284 mc = gd->driver_data; 322 285 ··· 338 295 if (port < 1 || port > mc->num_ports) 339 296 return -EINVAL; 340 297 341 - if (attr->cap.max_send_wr > MAX_SEND_BUFFERS_PER_QUEUE) { 298 + if (attr->cap.max_send_wr > mdev->adapter_caps.max_qp_wr) { 342 299 ibdev_dbg(&mdev->ib_dev, 343 300 "Requested max_send_wr %d exceeding limit\n", 344 301 attr->cap.max_send_wr); ··· 396 353 cq_spec.gdma_region = send_cq->gdma_region; 397 354 cq_spec.queue_size = send_cq->cqe * COMP_ENTRY_SIZE; 398 355 cq_spec.modr_ctx_id = 0; 399 - cq_spec.attached_eq = GDMA_CQ_NO_EQ; 356 + eq_vec = send_cq->comp_vector % gd->gdma_context->max_num_queues; 357 + eq = &mc->eqs[eq_vec]; 358 + cq_spec.attached_eq = eq->eq->id; 400 359 401 360 err = mana_create_wq_obj(mpc, mpc->port_handle, GDMA_SQ, &wq_spec, 402 361 &cq_spec, &qp->tx_object); ··· 416 371 qp->sq_id = wq_spec.queue_index; 417 372 send_cq->id = cq_spec.queue_index; 418 373 374 + /* Create CQ table entry */ 375 + WARN_ON(gd->gdma_context->cq_table[send_cq->id]); 376 + gdma_cq = kzalloc(sizeof(*gdma_cq), GFP_KERNEL); 377 + if (!gdma_cq) { 378 + err = -ENOMEM; 379 + goto err_destroy_wq_obj; 380 + } 381 + 382 + gdma_cq->cq.context = send_cq; 383 + gdma_cq->type = GDMA_CQ; 384 + gdma_cq->cq.callback = mana_ib_cq_handler; 385 + gdma_cq->id = send_cq->id; 386 + gd->gdma_context->cq_table[send_cq->id] = gdma_cq; 387 + 419 388 ibdev_dbg(&mdev->ib_dev, 420 389 "ret %d qp->tx_object 0x%llx sq id %llu cq id %llu\n", err, 421 390 qp->tx_object, qp->sq_id, send_cq->id); ··· 443 384 ibdev_dbg(&mdev->ib_dev, 444 385 "Failed copy udata for create qp-raw, %d\n", 445 386 err); 446 - goto err_destroy_wq_obj; 387 + goto err_release_gdma_cq; 447 388 } 448 389 449 390 return 0; 391 + 392 + err_release_gdma_cq: 393 + kfree(gdma_cq); 394 + gd->gdma_context->cq_table[send_cq->id] = NULL; 450 395 451 396 err_destroy_wq_obj: 452 397 mana_destroy_wq_obj(mpc, GDMA_SQ, qp->tx_object); ··· 500 437 { 501 438 struct mana_ib_dev *mdev = 502 439 container_of(qp->ibqp.device, struct mana_ib_dev, ib_dev); 503 - struct gdma_dev *gd = mdev->gdma_dev; 440 + struct gdma_dev *gd = &mdev->gdma_dev->gdma_context->mana; 504 441 struct mana_port_context *mpc; 505 442 struct mana_context *mc; 506 443 struct net_device *ndev; ··· 527 464 { 528 465 struct mana_ib_dev *mdev = 529 466 container_of(qp->ibqp.device, struct mana_ib_dev, ib_dev); 530 - struct gdma_dev *gd = mdev->gdma_dev; 467 + struct gdma_dev *gd = &mdev->gdma_dev->gdma_context->mana; 531 468 struct ib_pd *ibpd = qp->ibqp.pd; 532 469 struct mana_port_context *mpc; 533 470 struct mana_context *mc;
+5
drivers/infiniband/hw/mlx5/dm.c
··· 341 341 return MLX5_SW_ICM_TYPE_HEADER_MODIFY; 342 342 case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_PATTERN_SW_ICM: 343 343 return MLX5_SW_ICM_TYPE_HEADER_MODIFY_PATTERN; 344 + case MLX5_IB_UAPI_DM_TYPE_ENCAP_SW_ICM: 345 + return MLX5_SW_ICM_TYPE_SW_ENCAP; 344 346 case MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM: 345 347 default: 346 348 return MLX5_SW_ICM_TYPE_STEERING; ··· 366 364 switch (type) { 367 365 case MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM: 368 366 case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_SW_ICM: 367 + case MLX5_IB_UAPI_DM_TYPE_ENCAP_SW_ICM: 369 368 if (!(MLX5_CAP_FLOWTABLE_NIC_RX(dev, sw_owner) || 370 369 MLX5_CAP_FLOWTABLE_NIC_TX(dev, sw_owner) || 371 370 MLX5_CAP_FLOWTABLE_NIC_RX(dev, sw_owner_v2) || ··· 441 438 case MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM: 442 439 case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_SW_ICM: 443 440 case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_PATTERN_SW_ICM: 441 + case MLX5_IB_UAPI_DM_TYPE_ENCAP_SW_ICM: 444 442 return handle_alloc_dm_sw_icm(context, attr, attrs, type); 445 443 default: 446 444 return ERR_PTR(-EOPNOTSUPP); ··· 495 491 case MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM: 496 492 case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_SW_ICM: 497 493 case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_PATTERN_SW_ICM: 494 + case MLX5_IB_UAPI_DM_TYPE_ENCAP_SW_ICM: 498 495 return mlx5_dm_icm_dealloc(ctx, to_icm(ibdm)); 499 496 default: 500 497 return -EOPNOTSUPP;
+24
drivers/infiniband/hw/mlx5/main.c
··· 818 818 MLX5_REG_NODE_DESC, 0, 0); 819 819 } 820 820 821 + static void fill_esw_mgr_reg_c0(struct mlx5_core_dev *mdev, 822 + struct mlx5_ib_query_device_resp *resp) 823 + { 824 + struct mlx5_eswitch *esw = mdev->priv.eswitch; 825 + u16 vport = mlx5_eswitch_manager_vport(mdev); 826 + 827 + resp->reg_c0.value = mlx5_eswitch_get_vport_metadata_for_match(esw, 828 + vport); 829 + resp->reg_c0.mask = mlx5_eswitch_get_vport_metadata_mask(); 830 + } 831 + 821 832 static int mlx5_ib_query_device(struct ib_device *ibdev, 822 833 struct ib_device_attr *props, 823 834 struct ib_udata *uhw) ··· 1218 1207 1219 1208 resp.dci_streams_caps.max_log_num_errored = 1220 1209 MLX5_CAP_GEN(mdev, log_max_dci_errored_streams); 1210 + } 1211 + 1212 + if (offsetofend(typeof(resp), reserved) <= uhw_outlen) 1213 + resp.response_length += sizeof(resp.reserved); 1214 + 1215 + if (offsetofend(typeof(resp), reg_c0) <= uhw_outlen) { 1216 + struct mlx5_eswitch *esw = mdev->priv.eswitch; 1217 + 1218 + resp.response_length += sizeof(resp.reg_c0); 1219 + 1220 + if (mlx5_eswitch_mode(mdev) == MLX5_ESWITCH_OFFLOADS && 1221 + mlx5_eswitch_vport_match_metadata_enabled(esw)) 1222 + fill_esw_mgr_reg_c0(mdev, &resp); 1221 1223 } 1222 1224 1223 1225 if (uhw_outlen) {
+1
drivers/infiniband/hw/mlx5/mr.c
··· 1347 1347 case MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM: 1348 1348 case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_SW_ICM: 1349 1349 case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_PATTERN_SW_ICM: 1350 + case MLX5_IB_UAPI_DM_TYPE_ENCAP_SW_ICM: 1350 1351 if (attr->access_flags & ~MLX5_IB_DM_SW_ICM_ALLOWED_ACCESS) 1351 1352 return ERR_PTR(-EINVAL); 1352 1353
+2 -2
drivers/infiniband/hw/mthca/mthca_cmd.c
··· 635 635 636 636 int mthca_SYS_EN(struct mthca_dev *dev) 637 637 { 638 - u64 out; 638 + u64 out = 0; 639 639 int ret; 640 640 641 641 ret = mthca_cmd_imm(dev, 0, &out, 0, 0, CMD_SYS_EN, CMD_TIME_CLASS_D); ··· 1955 1955 int mthca_MGID_HASH(struct mthca_dev *dev, struct mthca_mailbox *mailbox, 1956 1956 u16 *hash) 1957 1957 { 1958 - u64 imm; 1958 + u64 imm = 0; 1959 1959 int err; 1960 1960 1961 1961 err = mthca_cmd_imm(dev, mailbox->dma, &imm, 0, 0, CMD_MGID_HASH,
+1 -1
drivers/infiniband/hw/mthca/mthca_main.c
··· 382 382 struct mthca_init_hca_param *init_hca, 383 383 u64 icm_size) 384 384 { 385 - u64 aux_pages; 385 + u64 aux_pages = 0; 386 386 int err; 387 387 388 388 err = mthca_SET_ICM_SIZE(mdev, icm_size, &aux_pages);
+6 -8
drivers/infiniband/sw/siw/siw.h
··· 121 121 }; 122 122 123 123 struct siw_umem { 124 + struct ib_umem *base_mem; 124 125 struct siw_page_chunk *page_chunk; 125 126 int num_pages; 126 - bool writable; 127 127 u64 fp_addr; /* First page base address */ 128 - struct mm_struct *owning_mm; 129 128 }; 130 129 131 130 struct siw_pble { ··· 288 289 int skb_offset; /* offset in skb */ 289 290 int skb_copied; /* processed bytes in skb */ 290 291 292 + enum siw_rx_state state; 293 + 291 294 union iwarp_hdr hdr; 292 295 struct mpa_trailer trailer; 293 - 294 - enum siw_rx_state state; 296 + struct shash_desc *mpa_crc_hd; 295 297 296 298 /* 297 299 * For each FPDU, main RX loop runs through 3 stages: ··· 314 314 u64 ddp_to; 315 315 u32 inval_stag; /* Stag to be invalidated */ 316 316 317 - struct shash_desc *mpa_crc_hd; 318 317 u8 rx_suspend : 1; 319 318 u8 pad : 2; /* # of pad bytes expected */ 320 319 u8 rdmap_op : 4; /* opcode of current frame */ ··· 417 418 struct siw_qp { 418 419 struct ib_qp base_qp; 419 420 struct siw_device *sdev; 421 + int tx_cpu; 420 422 struct kref ref; 421 423 struct completion qp_free; 422 424 struct list_head devq; 423 - int tx_cpu; 424 425 struct siw_qp_attrs attrs; 425 426 426 427 struct siw_cep *cep; ··· 465 466 } term_info; 466 467 struct rdma_user_mmap_entry *sq_entry; /* mmap info for SQE array */ 467 468 struct rdma_user_mmap_entry *rq_entry; /* mmap info for RQE array */ 468 - struct rcu_head rcu; 469 469 }; 470 470 471 471 /* helper macros */ ··· 657 659 658 660 static inline int siw_orq_empty(struct siw_qp *qp) 659 661 { 660 - return qp->orq[qp->orq_get % qp->attrs.orq_size].flags == 0 ? 1 : 0; 662 + return orq_get_current(qp)->flags == 0 ? 1 : 0; 661 663 } 662 664 663 665 static inline struct siw_sqe *irq_alloc_free(struct siw_qp *qp)
+59 -86
drivers/infiniband/sw/siw/siw_cm.c
··· 41 41 42 42 static void siw_sk_assign_cm_upcalls(struct sock *sk) 43 43 { 44 - write_lock_bh(&sk->sk_callback_lock); 45 - sk->sk_state_change = siw_cm_llp_state_change; 46 - sk->sk_data_ready = siw_cm_llp_data_ready; 47 - sk->sk_write_space = siw_cm_llp_write_space; 48 - sk->sk_error_report = siw_cm_llp_error_report; 49 - write_unlock_bh(&sk->sk_callback_lock); 50 - } 51 - 52 - static void siw_sk_save_upcalls(struct sock *sk) 53 - { 54 44 struct siw_cep *cep = sk_to_cep(sk); 55 45 56 46 write_lock_bh(&sk->sk_callback_lock); ··· 48 58 cep->sk_data_ready = sk->sk_data_ready; 49 59 cep->sk_write_space = sk->sk_write_space; 50 60 cep->sk_error_report = sk->sk_error_report; 61 + 62 + sk->sk_state_change = siw_cm_llp_state_change; 63 + sk->sk_data_ready = siw_cm_llp_data_ready; 64 + sk->sk_write_space = siw_cm_llp_write_space; 65 + sk->sk_error_report = siw_cm_llp_error_report; 51 66 write_unlock_bh(&sk->sk_callback_lock); 52 67 } 53 68 ··· 151 156 siw_cep_get(cep); 152 157 s->sk->sk_user_data = cep; 153 158 154 - siw_sk_save_upcalls(s->sk); 155 159 siw_sk_assign_cm_upcalls(s->sk); 156 160 } 157 161 ··· 358 364 return id->event_handler(id, &event); 359 365 } 360 366 367 + static void siw_free_cm_id(struct siw_cep *cep) 368 + { 369 + if (!cep->cm_id) 370 + return; 371 + 372 + cep->cm_id->rem_ref(cep->cm_id); 373 + cep->cm_id = NULL; 374 + } 375 + 376 + static void siw_destroy_cep_sock(struct siw_cep *cep) 377 + { 378 + if (cep->sock) { 379 + siw_socket_disassoc(cep->sock); 380 + sock_release(cep->sock); 381 + cep->sock = NULL; 382 + } 383 + } 384 + 361 385 /* 362 386 * siw_qp_cm_drop() 363 387 * ··· 405 393 } 406 394 siw_dbg_cep(cep, "immediate close, state %d\n", cep->state); 407 395 408 - if (qp->term_info.valid) 409 - siw_send_terminate(qp); 396 + siw_send_terminate(qp); 410 397 411 398 if (cep->cm_id) { 412 399 switch (cep->state) { ··· 427 416 default: 428 417 break; 429 418 } 430 - cep->cm_id->rem_ref(cep->cm_id); 431 - cep->cm_id = NULL; 419 + siw_free_cm_id(cep); 432 420 siw_cep_put(cep); 433 421 } 434 422 cep->state = SIW_EPSTATE_CLOSED; 435 423 436 - if (cep->sock) { 437 - siw_socket_disassoc(cep->sock); 438 - /* 439 - * Immediately close socket 440 - */ 441 - sock_release(cep->sock); 442 - cep->sock = NULL; 443 - } 424 + siw_destroy_cep_sock(cep); 444 425 if (cep->qp) { 445 426 cep->qp = NULL; 446 427 siw_qp_put(qp); ··· 446 443 { 447 444 WARN_ON(kref_read(&cep->ref) < 1); 448 445 kref_put(&cep->ref, __siw_cep_dealloc); 446 + } 447 + 448 + static void siw_cep_set_free_and_put(struct siw_cep *cep) 449 + { 450 + siw_cep_set_free(cep); 451 + siw_cep_put(cep); 449 452 } 450 453 451 454 void siw_cep_get(struct siw_cep *cep) ··· 1070 1061 /* 1071 1062 * QP scheduled LLP close 1072 1063 */ 1073 - if (cep->qp && cep->qp->term_info.valid) 1064 + if (cep->qp) 1074 1065 siw_send_terminate(cep->qp); 1075 1066 1076 1067 if (cep->cm_id) ··· 1184 1175 cep->sock = NULL; 1185 1176 } 1186 1177 if (cep->cm_id) { 1187 - cep->cm_id->rem_ref(cep->cm_id); 1188 - cep->cm_id = NULL; 1178 + siw_free_cm_id(cep); 1189 1179 siw_cep_put(cep); 1190 1180 } 1191 1181 } ··· 1523 1515 1524 1516 cep->state = SIW_EPSTATE_CLOSED; 1525 1517 1526 - siw_cep_set_free(cep); 1527 - 1528 - siw_cep_put(cep); 1518 + siw_cep_set_free_and_put(cep); 1529 1519 1530 1520 } else if (s) { 1531 1521 sock_release(s); ··· 1554 1548 struct siw_cep *cep = (struct siw_cep *)id->provider_data; 1555 1549 struct siw_qp *qp; 1556 1550 struct siw_qp_attrs qp_attrs; 1557 - int rv, max_priv_data = MPA_MAX_PRIVDATA; 1551 + int rv = -EINVAL, max_priv_data = MPA_MAX_PRIVDATA; 1558 1552 bool wait_for_peer_rts = false; 1559 1553 1560 1554 siw_cep_set_inuse(cep); ··· 1570 1564 1571 1565 if (cep->state != SIW_EPSTATE_RECVD_MPAREQ) { 1572 1566 siw_dbg_cep(cep, "out of state\n"); 1573 - 1574 - siw_cep_set_free(cep); 1575 - siw_cep_put(cep); 1576 - 1577 - return -ECONNRESET; 1567 + rv = -ECONNRESET; 1568 + goto free_cep; 1578 1569 } 1579 1570 qp = siw_qp_id2obj(sdev, params->qpn); 1580 1571 if (!qp) { 1581 1572 WARN(1, "[QP %d] does not exist\n", params->qpn); 1582 - siw_cep_set_free(cep); 1583 - siw_cep_put(cep); 1584 - 1585 - return -EINVAL; 1573 + goto free_cep; 1586 1574 } 1587 1575 down_write(&qp->state_lock); 1588 - if (qp->attrs.state > SIW_QP_STATE_RTR) { 1589 - rv = -EINVAL; 1590 - up_write(&qp->state_lock); 1591 - goto error; 1592 - } 1576 + if (qp->attrs.state > SIW_QP_STATE_RTR) 1577 + goto error_unlock; 1593 1578 siw_dbg_cep(cep, "[QP %d]\n", params->qpn); 1594 1579 1595 1580 if (try_gso && cep->mpa.hdr.params.bits & MPA_RR_FLAG_GSO_EXP) { ··· 1594 1597 "[QP %u]: ord %d (max %d), ird %d (max %d)\n", 1595 1598 qp_id(qp), params->ord, sdev->attrs.max_ord, 1596 1599 params->ird, sdev->attrs.max_ird); 1597 - rv = -EINVAL; 1598 - up_write(&qp->state_lock); 1599 - goto error; 1600 + goto error_unlock; 1600 1601 } 1601 1602 if (cep->enhanced_rdma_conn_est) 1602 1603 max_priv_data -= sizeof(struct mpa_v2_data); ··· 1604 1609 cep, 1605 1610 "[QP %u]: private data length: %d (max %d)\n", 1606 1611 qp_id(qp), params->private_data_len, max_priv_data); 1607 - rv = -EINVAL; 1608 - up_write(&qp->state_lock); 1609 - goto error; 1612 + goto error_unlock; 1610 1613 } 1611 1614 if (cep->enhanced_rdma_conn_est) { 1612 1615 if (params->ord > cep->ord) { ··· 1613 1620 } else { 1614 1621 cep->ird = params->ird; 1615 1622 cep->ord = params->ord; 1616 - rv = -EINVAL; 1617 - up_write(&qp->state_lock); 1618 - goto error; 1623 + goto error_unlock; 1619 1624 } 1620 1625 } 1621 1626 if (params->ird < cep->ird) { ··· 1622 1631 params->ird = cep->ird; 1623 1632 else { 1624 1633 rv = -ENOMEM; 1625 - up_write(&qp->state_lock); 1626 - goto error; 1634 + goto error_unlock; 1627 1635 } 1628 1636 } 1629 1637 if (cep->mpa.v2_ctrl.ord & ··· 1669 1679 SIW_QP_ATTR_ORD | SIW_QP_ATTR_IRD | 1670 1680 SIW_QP_ATTR_MPA); 1671 1681 up_write(&qp->state_lock); 1672 - 1673 1682 if (rv) 1674 1683 goto error; 1675 1684 ··· 1691 1702 siw_cep_set_free(cep); 1692 1703 1693 1704 return 0; 1705 + 1706 + error_unlock: 1707 + up_write(&qp->state_lock); 1694 1708 error: 1695 - siw_socket_disassoc(cep->sock); 1696 - sock_release(cep->sock); 1697 - cep->sock = NULL; 1709 + siw_destroy_cep_sock(cep); 1698 1710 1699 1711 cep->state = SIW_EPSTATE_CLOSED; 1700 1712 1701 - if (cep->cm_id) { 1702 - cep->cm_id->rem_ref(id); 1703 - cep->cm_id = NULL; 1704 - } 1713 + siw_free_cm_id(cep); 1705 1714 if (qp->cep) { 1706 1715 siw_cep_put(cep); 1707 1716 qp->cep = NULL; 1708 1717 } 1709 1718 cep->qp = NULL; 1710 1719 siw_qp_put(qp); 1711 - 1712 - siw_cep_set_free(cep); 1713 - siw_cep_put(cep); 1714 - 1720 + free_cep: 1721 + siw_cep_set_free_and_put(cep); 1715 1722 return rv; 1716 1723 } 1717 1724 ··· 1729 1744 if (cep->state != SIW_EPSTATE_RECVD_MPAREQ) { 1730 1745 siw_dbg_cep(cep, "out of state\n"); 1731 1746 1732 - siw_cep_set_free(cep); 1733 - siw_cep_put(cep); /* put last reference */ 1747 + siw_cep_set_free_and_put(cep); /* put last reference */ 1734 1748 1735 1749 return -ECONNRESET; 1736 1750 } ··· 1740 1756 cep->mpa.hdr.params.bits |= MPA_RR_FLAG_REJECT; /* reject */ 1741 1757 siw_send_mpareqrep(cep, pdata, pd_len); 1742 1758 } 1743 - siw_socket_disassoc(cep->sock); 1744 - sock_release(cep->sock); 1745 - cep->sock = NULL; 1759 + siw_destroy_cep_sock(cep); 1746 1760 1747 1761 cep->state = SIW_EPSTATE_CLOSED; 1748 1762 1749 - siw_cep_set_free(cep); 1750 - siw_cep_put(cep); 1763 + siw_cep_set_free_and_put(cep); 1751 1764 1752 1765 return 0; 1753 1766 } ··· 1871 1890 if (cep) { 1872 1891 siw_cep_set_inuse(cep); 1873 1892 1874 - if (cep->cm_id) { 1875 - cep->cm_id->rem_ref(cep->cm_id); 1876 - cep->cm_id = NULL; 1877 - } 1893 + siw_free_cm_id(cep); 1878 1894 cep->sock = NULL; 1879 1895 siw_socket_disassoc(s); 1880 1896 cep->state = SIW_EPSTATE_CLOSED; 1881 1897 1882 - siw_cep_set_free(cep); 1883 - siw_cep_put(cep); 1898 + siw_cep_set_free_and_put(cep); 1884 1899 } 1885 1900 sock_release(s); 1886 1901 ··· 1900 1923 1901 1924 siw_cep_set_inuse(cep); 1902 1925 1903 - if (cep->cm_id) { 1904 - cep->cm_id->rem_ref(cep->cm_id); 1905 - cep->cm_id = NULL; 1906 - } 1926 + siw_free_cm_id(cep); 1907 1927 if (cep->sock) { 1908 1928 siw_socket_disassoc(cep->sock); 1909 1929 sock_release(cep->sock); 1910 1930 cep->sock = NULL; 1911 1931 } 1912 1932 cep->state = SIW_EPSTATE_CLOSED; 1913 - siw_cep_set_free(cep); 1914 - siw_cep_put(cep); 1933 + siw_cep_set_free_and_put(cep); 1915 1934 } 1916 1935 } 1917 1936
+14 -16
drivers/infiniband/sw/siw/siw_main.c
··· 109 109 int num_nodes; 110 110 } siw_cpu_info; 111 111 112 + static void siw_destroy_cpulist(int number) 113 + { 114 + int i = 0; 115 + 116 + while (i < number) 117 + kfree(siw_cpu_info.tx_valid_cpus[i++]); 118 + 119 + kfree(siw_cpu_info.tx_valid_cpus); 120 + siw_cpu_info.tx_valid_cpus = NULL; 121 + } 122 + 112 123 static int siw_init_cpulist(void) 113 124 { 114 125 int i, num_nodes = nr_node_ids; ··· 149 138 150 139 out_err: 151 140 siw_cpu_info.num_nodes = 0; 152 - while (--i >= 0) 153 - kfree(siw_cpu_info.tx_valid_cpus[i]); 154 - kfree(siw_cpu_info.tx_valid_cpus); 155 - siw_cpu_info.tx_valid_cpus = NULL; 141 + siw_destroy_cpulist(i); 156 142 157 143 return -ENOMEM; 158 - } 159 - 160 - static void siw_destroy_cpulist(void) 161 - { 162 - int i = 0; 163 - 164 - while (i < siw_cpu_info.num_nodes) 165 - kfree(siw_cpu_info.tx_valid_cpus[i++]); 166 - 167 - kfree(siw_cpu_info.tx_valid_cpus); 168 144 } 169 145 170 146 /* ··· 556 558 pr_info("SoftIWARP attach failed. Error: %d\n", rv); 557 559 558 560 siw_cm_exit(); 559 - siw_destroy_cpulist(); 561 + siw_destroy_cpulist(siw_cpu_info.num_nodes); 560 562 561 563 return rv; 562 564 } ··· 571 573 572 574 siw_cm_exit(); 573 575 574 - siw_destroy_cpulist(); 576 + siw_destroy_cpulist(siw_cpu_info.num_nodes); 575 577 576 578 if (siw_crypto_shash) 577 579 crypto_free_shash(siw_crypto_shash);
+48 -73
drivers/infiniband/sw/siw/siw_mem.c
··· 5 5 6 6 #include <linux/gfp.h> 7 7 #include <rdma/ib_verbs.h> 8 + #include <rdma/ib_umem.h> 8 9 #include <linux/dma-mapping.h> 9 10 #include <linux/slab.h> 10 11 #include <linux/sched/mm.h> ··· 14 13 #include "siw.h" 15 14 #include "siw_mem.h" 16 15 16 + /* Stag lookup is based on its index part only (24 bits). */ 17 + #define SIW_STAG_MAX_INDEX 0x00ffffff 18 + 17 19 /* 18 - * Stag lookup is based on its index part only (24 bits). 19 20 * The code avoids special Stag of zero and tries to randomize 20 21 * STag values between 1 and SIW_STAG_MAX_INDEX. 21 22 */ 22 23 int siw_mem_add(struct siw_device *sdev, struct siw_mem *m) 23 24 { 24 - struct xa_limit limit = XA_LIMIT(1, 0x00ffffff); 25 + struct xa_limit limit = XA_LIMIT(1, SIW_STAG_MAX_INDEX); 25 26 u32 id, next; 26 27 27 28 get_random_bytes(&next, 4); 28 - next &= 0x00ffffff; 29 + next &= SIW_STAG_MAX_INDEX; 29 30 30 31 if (xa_alloc_cyclic(&sdev->mem_xa, &id, m, limit, &next, 31 32 GFP_KERNEL) < 0) ··· 63 60 return NULL; 64 61 } 65 62 66 - static void siw_free_plist(struct siw_page_chunk *chunk, int num_pages, 67 - bool dirty) 63 + void siw_umem_release(struct siw_umem *umem) 68 64 { 69 - unpin_user_pages_dirty_lock(chunk->plist, num_pages, dirty); 70 - } 71 - 72 - void siw_umem_release(struct siw_umem *umem, bool dirty) 73 - { 74 - struct mm_struct *mm_s = umem->owning_mm; 75 65 int i, num_pages = umem->num_pages; 76 66 77 - for (i = 0; num_pages; i++) { 78 - int to_free = min_t(int, PAGES_PER_CHUNK, num_pages); 67 + if (umem->base_mem) 68 + ib_umem_release(umem->base_mem); 79 69 80 - siw_free_plist(&umem->page_chunk[i], to_free, 81 - umem->writable && dirty); 70 + for (i = 0; num_pages > 0; i++) { 82 71 kfree(umem->page_chunk[i].plist); 83 - num_pages -= to_free; 72 + num_pages -= PAGES_PER_CHUNK; 84 73 } 85 - atomic64_sub(umem->num_pages, &mm_s->pinned_vm); 86 - 87 - mmdrop(mm_s); 88 74 kfree(umem->page_chunk); 89 75 kfree(umem); 90 76 } ··· 83 91 { 84 92 struct siw_device *sdev = to_siw_dev(pd->device); 85 93 struct siw_mem *mem = kzalloc(sizeof(*mem), GFP_KERNEL); 86 - struct xa_limit limit = XA_LIMIT(1, 0x00ffffff); 94 + struct xa_limit limit = XA_LIMIT(1, SIW_STAG_MAX_INDEX); 87 95 u32 id, next; 88 96 89 97 if (!mem) ··· 99 107 kref_init(&mem->ref); 100 108 101 109 get_random_bytes(&next, 4); 102 - next &= 0x00ffffff; 110 + next &= SIW_STAG_MAX_INDEX; 103 111 104 112 if (xa_alloc_cyclic(&sdev->mem_xa, &id, mem, limit, &next, 105 113 GFP_KERNEL) < 0) { ··· 137 145 138 146 if (!mem->is_mw && mem->mem_obj) { 139 147 if (mem->is_pbl == 0) 140 - siw_umem_release(mem->umem, true); 148 + siw_umem_release(mem->umem); 141 149 else 142 150 kfree(mem->pbl); 143 151 } ··· 354 362 return pbl; 355 363 } 356 364 357 - struct siw_umem *siw_umem_get(u64 start, u64 len, bool writable) 365 + struct siw_umem *siw_umem_get(struct ib_device *base_dev, u64 start, 366 + u64 len, int rights) 358 367 { 359 368 struct siw_umem *umem; 360 - struct mm_struct *mm_s; 369 + struct ib_umem *base_mem; 370 + struct sg_page_iter sg_iter; 371 + struct sg_table *sgt; 361 372 u64 first_page_va; 362 - unsigned long mlock_limit; 363 - unsigned int foll_flags = FOLL_LONGTERM; 364 373 int num_pages, num_chunks, i, rv = 0; 365 - 366 - if (!can_do_mlock()) 367 - return ERR_PTR(-EPERM); 368 374 369 375 if (!len) 370 376 return ERR_PTR(-EINVAL); ··· 375 385 if (!umem) 376 386 return ERR_PTR(-ENOMEM); 377 387 378 - mm_s = current->mm; 379 - umem->owning_mm = mm_s; 380 - umem->writable = writable; 381 - 382 - mmgrab(mm_s); 383 - 384 - if (writable) 385 - foll_flags |= FOLL_WRITE; 386 - 387 - mmap_read_lock(mm_s); 388 - 389 - mlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; 390 - 391 - if (atomic64_add_return(num_pages, &mm_s->pinned_vm) > mlock_limit) { 392 - rv = -ENOMEM; 393 - goto out_sem_up; 394 - } 395 - umem->fp_addr = first_page_va; 396 - 397 388 umem->page_chunk = 398 389 kcalloc(num_chunks, sizeof(struct siw_page_chunk), GFP_KERNEL); 399 390 if (!umem->page_chunk) { 400 391 rv = -ENOMEM; 401 - goto out_sem_up; 392 + goto err_out; 402 393 } 403 - for (i = 0; num_pages; i++) { 394 + base_mem = ib_umem_get(base_dev, start, len, rights); 395 + if (IS_ERR(base_mem)) { 396 + rv = PTR_ERR(base_mem); 397 + siw_dbg(base_dev, "Cannot pin user memory: %d\n", rv); 398 + goto err_out; 399 + } 400 + umem->fp_addr = first_page_va; 401 + umem->base_mem = base_mem; 402 + 403 + sgt = &base_mem->sgt_append.sgt; 404 + __sg_page_iter_start(&sg_iter, sgt->sgl, sgt->orig_nents, 0); 405 + 406 + if (!__sg_page_iter_next(&sg_iter)) { 407 + rv = -EINVAL; 408 + goto err_out; 409 + } 410 + for (i = 0; num_pages > 0; i++) { 404 411 int nents = min_t(int, num_pages, PAGES_PER_CHUNK); 405 412 struct page **plist = 406 413 kcalloc(nents, sizeof(struct page *), GFP_KERNEL); 407 414 408 415 if (!plist) { 409 416 rv = -ENOMEM; 410 - goto out_sem_up; 417 + goto err_out; 411 418 } 412 419 umem->page_chunk[i].plist = plist; 413 - while (nents) { 414 - rv = pin_user_pages(first_page_va, nents, foll_flags, 415 - plist); 416 - if (rv < 0) 417 - goto out_sem_up; 418 - 419 - umem->num_pages += rv; 420 - first_page_va += rv * PAGE_SIZE; 421 - plist += rv; 422 - nents -= rv; 423 - num_pages -= rv; 420 + while (nents--) { 421 + *plist = sg_page_iter_page(&sg_iter); 422 + umem->num_pages++; 423 + num_pages--; 424 + plist++; 425 + if (!__sg_page_iter_next(&sg_iter)) 426 + break; 424 427 } 425 428 } 426 - out_sem_up: 427 - mmap_read_unlock(mm_s); 428 - 429 - if (rv > 0) 430 - return umem; 431 - 432 - /* Adjust accounting for pages not pinned */ 433 - if (num_pages) 434 - atomic64_sub(num_pages, &mm_s->pinned_vm); 435 - 436 - siw_umem_release(umem, false); 429 + return umem; 430 + err_out: 431 + siw_umem_release(umem); 437 432 438 433 return ERR_PTR(rv); 439 434 }
+3 -2
drivers/infiniband/sw/siw/siw_mem.h
··· 6 6 #ifndef _SIW_MEM_H 7 7 #define _SIW_MEM_H 8 8 9 - struct siw_umem *siw_umem_get(u64 start, u64 len, bool writable); 10 - void siw_umem_release(struct siw_umem *umem, bool dirty); 9 + struct siw_umem *siw_umem_get(struct ib_device *base_dave, u64 start, 10 + u64 len, int rights); 11 + void siw_umem_release(struct siw_umem *umem); 11 12 struct siw_pbl *siw_pbl_alloc(u32 num_buf); 12 13 dma_addr_t siw_pbl_get_buffer(struct siw_pbl *pbl, u64 off, int *len, int *idx); 13 14 struct siw_mem *siw_mem_id2obj(struct siw_device *sdev, int stag_index);
+1 -1
drivers/infiniband/sw/siw/siw_qp.c
··· 1183 1183 /* 1184 1184 * siw_sq_flush() 1185 1185 * 1186 - * Flush SQ and ORRQ entries to CQ. 1186 + * Flush SQ and ORQ entries to CQ. 1187 1187 * 1188 1188 * Must be called with QP state write lock held. 1189 1189 * Therefore, SQ and ORQ lock must not be taken.
+32 -52
drivers/infiniband/sw/siw/siw_qp_rx.c
··· 405 405 return wqe; 406 406 } 407 407 408 + static int siw_rx_data(struct siw_mem *mem_p, struct siw_rx_stream *srx, 409 + unsigned int *pbl_idx, u64 addr, int bytes) 410 + { 411 + int rv; 412 + 413 + if (mem_p->mem_obj == NULL) 414 + rv = siw_rx_kva(srx, ib_virt_dma_to_ptr(addr), bytes); 415 + else if (!mem_p->is_pbl) 416 + rv = siw_rx_umem(srx, mem_p->umem, addr, bytes); 417 + else 418 + rv = siw_rx_pbl(srx, pbl_idx, mem_p, addr, bytes); 419 + return rv; 420 + } 421 + 408 422 /* 409 423 * siw_proc_send: 410 424 * ··· 499 485 break; 500 486 } 501 487 mem_p = *mem; 502 - if (mem_p->mem_obj == NULL) 503 - rv = siw_rx_kva(srx, 504 - ib_virt_dma_to_ptr(sge->laddr + frx->sge_off), 505 - sge_bytes); 506 - else if (!mem_p->is_pbl) 507 - rv = siw_rx_umem(srx, mem_p->umem, 508 - sge->laddr + frx->sge_off, sge_bytes); 509 - else 510 - rv = siw_rx_pbl(srx, &frx->pbl_idx, mem_p, 511 - sge->laddr + frx->sge_off, sge_bytes); 512 - 488 + rv = siw_rx_data(mem_p, srx, &frx->pbl_idx, 489 + sge->laddr + frx->sge_off, sge_bytes); 513 490 if (unlikely(rv != sge_bytes)) { 514 491 wqe->processed += rcvd_bytes; 515 492 ··· 603 598 return -EINVAL; 604 599 } 605 600 606 - if (mem->mem_obj == NULL) 607 - rv = siw_rx_kva(srx, 608 - (void *)(uintptr_t)(srx->ddp_to + srx->fpdu_part_rcvd), 609 - bytes); 610 - else if (!mem->is_pbl) 611 - rv = siw_rx_umem(srx, mem->umem, 612 - srx->ddp_to + srx->fpdu_part_rcvd, bytes); 613 - else 614 - rv = siw_rx_pbl(srx, &frx->pbl_idx, mem, 615 - srx->ddp_to + srx->fpdu_part_rcvd, bytes); 616 - 601 + rv = siw_rx_data(mem, srx, &frx->pbl_idx, 602 + srx->ddp_to + srx->fpdu_part_rcvd, bytes); 617 603 if (unlikely(rv != bytes)) { 618 604 siw_init_terminate(qp, TERM_ERROR_LAYER_DDP, 619 605 DDP_ETYPE_CATASTROPHIC, ··· 845 849 mem_p = *mem; 846 850 847 851 bytes = min(srx->fpdu_part_rem, srx->skb_new); 848 - 849 - if (mem_p->mem_obj == NULL) 850 - rv = siw_rx_kva(srx, 851 - ib_virt_dma_to_ptr(sge->laddr + wqe->processed), 852 - bytes); 853 - else if (!mem_p->is_pbl) 854 - rv = siw_rx_umem(srx, mem_p->umem, sge->laddr + wqe->processed, 855 - bytes); 856 - else 857 - rv = siw_rx_pbl(srx, &frx->pbl_idx, mem_p, 858 - sge->laddr + wqe->processed, bytes); 852 + rv = siw_rx_data(mem_p, srx, &frx->pbl_idx, 853 + sge->laddr + wqe->processed, bytes); 859 854 if (rv != bytes) { 860 855 wqe->wc_status = SIW_WC_GENERAL_ERR; 861 856 rv = -EINVAL; ··· 866 879 siw_init_terminate(qp, TERM_ERROR_LAYER_DDP, DDP_ETYPE_CATASTROPHIC, 867 880 DDP_ECODE_CATASTROPHIC, 0); 868 881 return rv; 882 + } 883 + 884 + static void siw_update_skb_rcvd(struct siw_rx_stream *srx, u16 length) 885 + { 886 + srx->skb_offset += length; 887 + srx->skb_new -= length; 888 + srx->skb_copied += length; 869 889 } 870 890 871 891 int siw_proc_terminate(struct siw_qp *qp) ··· 919 925 goto out; 920 926 921 927 infop += to_copy; 922 - srx->skb_offset += to_copy; 923 - srx->skb_new -= to_copy; 924 - srx->skb_copied += to_copy; 928 + siw_update_skb_rcvd(srx, to_copy); 925 929 srx->fpdu_part_rcvd += to_copy; 926 930 srx->fpdu_part_rem -= to_copy; 927 931 ··· 941 949 term->flag_m ? "valid" : "invalid"); 942 950 } 943 951 out: 944 - srx->skb_new -= to_copy; 945 - srx->skb_offset += to_copy; 946 - srx->skb_copied += to_copy; 952 + siw_update_skb_rcvd(srx, to_copy); 947 953 srx->fpdu_part_rcvd += to_copy; 948 954 srx->fpdu_part_rem -= to_copy; 949 955 ··· 960 970 961 971 skb_copy_bits(skb, srx->skb_offset, tbuf, avail); 962 972 963 - srx->skb_new -= avail; 964 - srx->skb_offset += avail; 965 - srx->skb_copied += avail; 973 + siw_update_skb_rcvd(srx, avail); 966 974 srx->fpdu_part_rem -= avail; 967 975 968 976 if (srx->fpdu_part_rem) ··· 1011 1023 skb_copy_bits(skb, srx->skb_offset, 1012 1024 (char *)c_hdr + srx->fpdu_part_rcvd, bytes); 1013 1025 1026 + siw_update_skb_rcvd(srx, bytes); 1014 1027 srx->fpdu_part_rcvd += bytes; 1015 - 1016 - srx->skb_new -= bytes; 1017 - srx->skb_offset += bytes; 1018 - srx->skb_copied += bytes; 1019 - 1020 1028 if (srx->fpdu_part_rcvd < MIN_DDP_HDR) 1021 1029 return -EAGAIN; 1022 1030 ··· 1075 1091 skb_copy_bits(skb, srx->skb_offset, 1076 1092 (char *)c_hdr + srx->fpdu_part_rcvd, bytes); 1077 1093 1094 + siw_update_skb_rcvd(srx, bytes); 1078 1095 srx->fpdu_part_rcvd += bytes; 1079 - 1080 - srx->skb_new -= bytes; 1081 - srx->skb_offset += bytes; 1082 - srx->skb_copied += bytes; 1083 - 1084 1096 if (srx->fpdu_part_rcvd < hdrlen) 1085 1097 return -EAGAIN; 1086 1098 }
+19 -32
drivers/infiniband/sw/siw/siw_qp_tx.c
··· 34 34 return NULL; 35 35 } 36 36 37 + static struct page *siw_get_page(struct siw_mem *mem, struct siw_sge *sge, 38 + unsigned long offset, int *pbl_idx) 39 + { 40 + if (!mem->is_pbl) 41 + return siw_get_upage(mem->umem, sge->laddr + offset); 42 + else 43 + return siw_get_pblpage(mem, sge->laddr + offset, pbl_idx); 44 + } 45 + 37 46 /* 38 47 * Copy short payload at provided destination payload address 39 48 */ ··· 76 67 char *buffer; 77 68 int pbl_idx = 0; 78 69 79 - if (!mem->is_pbl) 80 - p = siw_get_upage(mem->umem, sge->laddr); 81 - else 82 - p = siw_get_pblpage(mem, sge->laddr, &pbl_idx); 83 - 70 + p = siw_get_page(mem, sge, 0, &pbl_idx); 84 71 if (unlikely(!p)) 85 72 return -EFAULT; 86 73 ··· 90 85 memcpy(paddr, buffer + off, part); 91 86 kunmap_local(buffer); 92 87 93 - if (!mem->is_pbl) 94 - p = siw_get_upage(mem->umem, 95 - sge->laddr + part); 96 - else 97 - p = siw_get_pblpage(mem, 98 - sge->laddr + part, 99 - &pbl_idx); 88 + p = siw_get_page(mem, sge, part, &pbl_idx); 100 89 if (unlikely(!p)) 101 90 return -EFAULT; 102 91 ··· 248 249 /* 249 250 * Do complete CRC if enabled and short packet 250 251 */ 251 - if (c_tx->mpa_crc_hd) { 252 - crypto_shash_init(c_tx->mpa_crc_hd); 253 - if (crypto_shash_update(c_tx->mpa_crc_hd, 254 - (u8 *)&c_tx->pkt, 255 - c_tx->ctrl_len)) 256 - return -EINVAL; 257 - crypto_shash_final(c_tx->mpa_crc_hd, (u8 *)crc); 258 - } 252 + if (c_tx->mpa_crc_hd && 253 + crypto_shash_digest(c_tx->mpa_crc_hd, (u8 *)&c_tx->pkt, 254 + c_tx->ctrl_len, (u8 *)crc) != 0) 255 + return -EINVAL; 259 256 c_tx->ctrl_len += MPA_CRC_SIZE; 260 257 261 258 return PKT_COMPLETE; ··· 292 297 (char *)&c_tx->pkt.ctrl + c_tx->ctrl_sent, 293 298 .iov_len = c_tx->ctrl_len - c_tx->ctrl_sent }; 294 299 295 - int rv = kernel_sendmsg(s, &msg, &iov, 1, 296 - c_tx->ctrl_len - c_tx->ctrl_sent); 300 + int rv = kernel_sendmsg(s, &msg, &iov, 1, iov.iov_len); 297 301 298 302 if (rv >= 0) { 299 303 c_tx->ctrl_sent += rv; ··· 496 502 if (!is_kva) { 497 503 struct page *p; 498 504 499 - if (mem->is_pbl) 500 - p = siw_get_pblpage( 501 - mem, sge->laddr + sge_off, 502 - &pbl_idx); 503 - else 504 - p = siw_get_upage(mem->umem, 505 - sge->laddr + sge_off); 505 + p = siw_get_page(mem, sge, sge_off, &pbl_idx); 506 506 if (unlikely(!p)) { 507 507 siw_unmap_pages(iov, kmap_mask, seg); 508 508 wqe->processed -= c_tx->bytes_unsent; ··· 997 1009 * MPA FPDUs, each containing a DDP segment. 998 1010 * 999 1011 * SQ processing may occur in user context as a result of posting 1000 - * new WQE's or from siw_sq_work_handler() context. Processing in 1012 + * new WQE's or from siw_tx_thread context. Processing in 1001 1013 * user context is limited to non-kernel verbs users. 1002 1014 * 1003 1015 * SQ processing may get paused anytime, possibly in the middle of a WR 1004 1016 * or FPDU, if insufficient send space is available. SQ processing 1005 - * gets resumed from siw_sq_work_handler(), if send space becomes 1006 - * available again. 1017 + * gets resumed from siw_tx_thread, if send space becomes available again. 1007 1018 * 1008 1019 * Must be called with the QP state read-locked. 1009 1020 *
+18 -34
drivers/infiniband/sw/siw/siw_verbs.c
··· 19 19 #include "siw_verbs.h" 20 20 #include "siw_mem.h" 21 21 22 + static int siw_qp_state_to_ib_qp_state[SIW_QP_STATE_COUNT] = { 23 + [SIW_QP_STATE_IDLE] = IB_QPS_INIT, 24 + [SIW_QP_STATE_RTR] = IB_QPS_RTR, 25 + [SIW_QP_STATE_RTS] = IB_QPS_RTS, 26 + [SIW_QP_STATE_CLOSING] = IB_QPS_SQD, 27 + [SIW_QP_STATE_TERMINATE] = IB_QPS_SQE, 28 + [SIW_QP_STATE_ERROR] = IB_QPS_ERR 29 + }; 30 + 22 31 static int ib_qp_state_to_siw_qp_state[IB_QPS_ERR + 1] = { 23 32 [IB_QPS_RESET] = SIW_QP_STATE_IDLE, 24 33 [IB_QPS_INIT] = SIW_QP_STATE_IDLE, ··· 75 66 entry = to_siw_mmap_entry(rdma_entry); 76 67 77 68 rv = remap_vmalloc_range(vma, entry->address, 0); 78 - if (rv) { 69 + if (rv) 79 70 pr_warn("remap_vmalloc_range failed: %lu, %zu\n", vma->vm_pgoff, 80 71 size); 81 - goto out; 82 - } 83 - out: 84 72 rdma_user_mmap_entry_put(rdma_entry); 85 73 86 74 return rv; ··· 342 336 goto err_atomic; 343 337 } 344 338 /* 345 - * NOTE: we allow for zero element SQ and RQ WQE's SGL's 346 - * but not for a QP unable to hold any WQE (SQ + RQ) 339 + * NOTE: we don't allow for a QP unable to hold any SQ WQE 347 340 */ 348 - if (attrs->cap.max_send_wr + attrs->cap.max_recv_wr == 0) { 349 - siw_dbg(base_dev, "QP must have send or receive queue\n"); 341 + if (attrs->cap.max_send_wr == 0) { 342 + siw_dbg(base_dev, "QP must have send queue\n"); 350 343 rv = -EINVAL; 351 344 goto err_atomic; 352 345 } ··· 365 360 if (rv) 366 361 goto err_atomic; 367 362 368 - num_sqe = attrs->cap.max_send_wr; 369 - num_rqe = attrs->cap.max_recv_wr; 370 363 371 364 /* All queue indices are derived from modulo operations 372 365 * on a free running 'get' (consumer) and 'put' (producer) 373 366 * unsigned counter. Having queue sizes at power of two 374 367 * avoids handling counter wrap around. 375 368 */ 376 - if (num_sqe) 377 - num_sqe = roundup_pow_of_two(num_sqe); 378 - else { 379 - /* Zero sized SQ is not supported */ 380 - rv = -EINVAL; 381 - goto err_out_xa; 382 - } 369 + num_sqe = roundup_pow_of_two(attrs->cap.max_send_wr); 370 + num_rqe = attrs->cap.max_recv_wr; 383 371 if (num_rqe) 384 372 num_rqe = roundup_pow_of_two(num_rqe); 385 373 ··· 513 515 } else { 514 516 return -EINVAL; 515 517 } 518 + qp_attr->qp_state = siw_qp_state_to_ib_qp_state[qp->attrs.state]; 516 519 qp_attr->cap.max_inline_data = SIW_MAX_INLINE; 517 520 qp_attr->cap.max_send_wr = qp->attrs.sq_size; 518 521 qp_attr->cap.max_send_sge = qp->attrs.sq_max_sges; ··· 1320 1321 struct siw_umem *umem = NULL; 1321 1322 struct siw_ureq_reg_mr ureq; 1322 1323 struct siw_device *sdev = to_siw_dev(pd->device); 1323 - 1324 - unsigned long mem_limit = rlimit(RLIMIT_MEMLOCK); 1325 1324 int rv; 1326 1325 1327 1326 siw_dbg_pd(pd, "start: 0x%pK, va: 0x%pK, len: %llu\n", ··· 1335 1338 rv = -EINVAL; 1336 1339 goto err_out; 1337 1340 } 1338 - if (mem_limit != RLIM_INFINITY) { 1339 - unsigned long num_pages = 1340 - (PAGE_ALIGN(len + (start & ~PAGE_MASK))) >> PAGE_SHIFT; 1341 - mem_limit >>= PAGE_SHIFT; 1342 - 1343 - if (num_pages > mem_limit - current->mm->locked_vm) { 1344 - siw_dbg_pd(pd, "pages req %lu, max %lu, lock %lu\n", 1345 - num_pages, mem_limit, 1346 - current->mm->locked_vm); 1347 - rv = -ENOMEM; 1348 - goto err_out; 1349 - } 1350 - } 1351 - umem = siw_umem_get(start, len, ib_access_writable(rights)); 1341 + umem = siw_umem_get(pd->device, start, len, rights); 1352 1342 if (IS_ERR(umem)) { 1353 1343 rv = PTR_ERR(umem); 1354 1344 siw_dbg_pd(pd, "getting user memory failed: %d\n", rv); ··· 1388 1404 kfree_rcu(mr, rcu); 1389 1405 } else { 1390 1406 if (umem) 1391 - siw_umem_release(umem, false); 1407 + siw_umem_release(umem); 1392 1408 } 1393 1409 return ERR_PTR(rv); 1394 1410 }
+4
drivers/infiniband/ulp/ipoib/ipoib.h
··· 351 351 struct workqueue_struct *wq; 352 352 struct delayed_work mcast_task; 353 353 struct work_struct carrier_on_task; 354 + struct work_struct reschedule_napi_work; 354 355 struct work_struct flush_light; 355 356 struct work_struct flush_normal; 356 357 struct work_struct flush_heavy; 357 358 struct work_struct restart_task; 359 + struct work_struct tx_timeout_work; 358 360 struct delayed_work ah_reap_task; 359 361 struct delayed_work neigh_reap_task; 360 362 struct ib_device *ca; ··· 501 499 struct ib_ah *address, u32 dqpn); 502 500 void ipoib_reap_ah(struct work_struct *work); 503 501 502 + void ipoib_napi_schedule_work(struct work_struct *work); 504 503 struct ipoib_path *__path_find(struct net_device *dev, void *gid); 505 504 void ipoib_mark_paths_invalid(struct net_device *dev); 506 505 void ipoib_flush_paths(struct net_device *dev); ··· 513 510 void ipoib_ib_dev_flush_light(struct work_struct *work); 514 511 void ipoib_ib_dev_flush_normal(struct work_struct *work); 515 512 void ipoib_ib_dev_flush_heavy(struct work_struct *work); 513 + void ipoib_ib_tx_timeout_work(struct work_struct *work); 516 514 void ipoib_pkey_event(struct work_struct *work); 517 515 void ipoib_ib_dev_cleanup(struct net_device *dev); 518 516
+25 -1
drivers/infiniband/ulp/ipoib/ipoib_ib.c
··· 531 531 napi_schedule(&priv->recv_napi); 532 532 } 533 533 534 + /* The function will force napi_schedule */ 535 + void ipoib_napi_schedule_work(struct work_struct *work) 536 + { 537 + struct ipoib_dev_priv *priv = 538 + container_of(work, struct ipoib_dev_priv, reschedule_napi_work); 539 + bool ret; 540 + 541 + do { 542 + ret = napi_schedule(&priv->send_napi); 543 + if (!ret) 544 + msleep(3); 545 + } while (!ret && netif_queue_stopped(priv->dev) && 546 + test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)); 547 + } 548 + 534 549 void ipoib_ib_tx_completion(struct ib_cq *cq, void *ctx_ptr) 535 550 { 536 551 struct ipoib_dev_priv *priv = ctx_ptr; 552 + bool ret; 537 553 538 - napi_schedule(&priv->send_napi); 554 + ret = napi_schedule(&priv->send_napi); 555 + /* 556 + * if the queue is closed the driver must be able to schedule napi, 557 + * otherwise we can end with closed queue forever, because no new 558 + * packets to send and napi callback might not get new event after 559 + * its re-arm of the napi. 560 + */ 561 + if (!ret && netif_queue_stopped(priv->dev)) 562 + schedule_work(&priv->reschedule_napi_work); 539 563 } 540 564 541 565 static inline int post_send(struct ipoib_dev_priv *priv,
+31 -2
drivers/infiniband/ulp/ipoib/ipoib_main.c
··· 1200 1200 netif_queue_stopped(dev), priv->tx_head, priv->tx_tail, 1201 1201 priv->global_tx_head, priv->global_tx_tail); 1202 1202 1203 - /* XXX reset QP, etc. */ 1203 + 1204 + schedule_work(&priv->tx_timeout_work); 1205 + } 1206 + 1207 + void ipoib_ib_tx_timeout_work(struct work_struct *work) 1208 + { 1209 + struct ipoib_dev_priv *priv = container_of(work, 1210 + struct ipoib_dev_priv, 1211 + tx_timeout_work); 1212 + int err; 1213 + 1214 + rtnl_lock(); 1215 + 1216 + if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) 1217 + goto unlock; 1218 + 1219 + ipoib_stop(priv->dev); 1220 + err = ipoib_open(priv->dev); 1221 + if (err) { 1222 + ipoib_warn(priv, "ipoib_open failed recovering from a tx_timeout, err(%d).\n", 1223 + err); 1224 + goto unlock; 1225 + } 1226 + 1227 + netif_tx_wake_all_queues(priv->dev); 1228 + unlock: 1229 + rtnl_unlock(); 1230 + 1204 1231 } 1205 1232 1206 1233 static int ipoib_hard_header(struct sk_buff *skb, ··· 2139 2112 2140 2113 ipoib_set_ethtool_ops(dev); 2141 2114 2142 - dev->watchdog_timeo = HZ; 2115 + dev->watchdog_timeo = 10 * HZ; 2143 2116 2144 2117 dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 2145 2118 ··· 2177 2150 2178 2151 INIT_DELAYED_WORK(&priv->mcast_task, ipoib_mcast_join_task); 2179 2152 INIT_WORK(&priv->carrier_on_task, ipoib_mcast_carrier_on_task); 2153 + INIT_WORK(&priv->reschedule_napi_work, ipoib_napi_schedule_work); 2180 2154 INIT_WORK(&priv->flush_light, ipoib_ib_dev_flush_light); 2181 2155 INIT_WORK(&priv->flush_normal, ipoib_ib_dev_flush_normal); 2182 2156 INIT_WORK(&priv->flush_heavy, ipoib_ib_dev_flush_heavy); 2183 2157 INIT_WORK(&priv->restart_task, ipoib_mcast_restart_task); 2158 + INIT_WORK(&priv->tx_timeout_work, ipoib_ib_tx_timeout_work); 2184 2159 INIT_DELAYED_WORK(&priv->ah_reap_task, ipoib_reap_ah); 2185 2160 INIT_DELAYED_WORK(&priv->neigh_reap_task, ipoib_reap_neigh); 2186 2161 }
+2 -5
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
··· 531 531 if (test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) 532 532 rec.join_state = SENDONLY_FULLMEMBER_JOIN; 533 533 } 534 - spin_unlock_irq(&priv->lock); 535 534 536 535 multicast = ib_sa_join_multicast(&ipoib_sa_client, priv->ca, priv->port, 537 - &rec, comp_mask, GFP_KERNEL, 536 + &rec, comp_mask, GFP_ATOMIC, 538 537 ipoib_mcast_join_complete, mcast); 539 - spin_lock_irq(&priv->lock); 540 538 if (IS_ERR(multicast)) { 541 539 ret = PTR_ERR(multicast); 542 540 ipoib_warn(priv, "ib_sa_join_multicast failed, status %d\n", ret); 543 541 /* Requeue this join task with a backoff delay */ 544 542 __ipoib_mcast_schedule_join_thread(priv, mcast, 1); 545 543 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); 546 - spin_unlock_irq(&priv->lock); 547 544 complete(&mcast->done); 548 - spin_lock_irq(&priv->lock); 545 + return ret; 549 546 } 550 547 return 0; 551 548 }
+2 -5
drivers/infiniband/ulp/iser/iscsi_iser.h
··· 182 182 * 183 183 * @sg: pointer to the sg list 184 184 * @size: num entries of this sg 185 - * @data_len: total beffer byte len 185 + * @data_len: total buffer byte len 186 186 * @dma_nents: returned by dma_map_sg 187 187 */ 188 188 struct iser_data_buf { ··· 299 299 * 300 300 * @ib_device: RDMA device 301 301 * @pd: Protection Domain for this device 302 - * @mr: Global DMA memory region 303 302 * @event_handler: IB events handle routine 304 303 * @ig_list: entry in devices list 305 304 * @refcount: Reference counter, dominated by open iser connections ··· 316 317 * 317 318 * @mr: memory region 318 319 * @sig_mr: signature memory region 319 - * @mr_valid: is mr valid indicator 320 320 */ 321 321 struct iser_reg_resources { 322 322 struct ib_mr *mr; 323 323 struct ib_mr *sig_mr; 324 - u8 mr_valid:1; 325 324 }; 326 325 327 326 /** ··· 386 389 * to max number of post recvs 387 390 * @max_cmds: maximum cmds allowed for this connection 388 391 * @name: connection peer portal 389 - * @release_work: deffered work for release job 392 + * @release_work: deferred work for release job 390 393 * @state_mutex: protects iser onnection state 391 394 * @stop_completion: conn_stop completion 392 395 * @ib_completion: RDMA cleanup completion
+4 -1
drivers/infiniband/ulp/iser/iser_initiator.c
··· 581 581 return -EINVAL; 582 582 } 583 583 584 - desc->rsc.mr_valid = 0; 584 + if (desc->sig_protected) 585 + desc->rsc.sig_mr->need_inval = false; 586 + else 587 + desc->rsc.mr->need_inval = false; 585 588 586 589 return 0; 587 590 }
+4 -4
drivers/infiniband/ulp/iser/iser_memory.c
··· 264 264 265 265 iser_set_prot_checks(iser_task->sc, &sig_attrs->check_mask); 266 266 267 - if (rsc->mr_valid) 267 + if (rsc->sig_mr->need_inval) 268 268 iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr); 269 269 270 270 ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey)); ··· 288 288 wr->access = IB_ACCESS_LOCAL_WRITE | 289 289 IB_ACCESS_REMOTE_READ | 290 290 IB_ACCESS_REMOTE_WRITE; 291 - rsc->mr_valid = 1; 291 + rsc->sig_mr->need_inval = true; 292 292 293 293 sig_reg->sge.lkey = mr->lkey; 294 294 sig_reg->rkey = mr->rkey; ··· 313 313 struct ib_reg_wr *wr = &tx_desc->reg_wr; 314 314 int n; 315 315 316 - if (rsc->mr_valid) 316 + if (rsc->mr->need_inval) 317 317 iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr); 318 318 319 319 ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey)); ··· 336 336 IB_ACCESS_REMOTE_WRITE | 337 337 IB_ACCESS_REMOTE_READ; 338 338 339 - rsc->mr_valid = 1; 339 + rsc->mr->need_inval = true; 340 340 341 341 reg->sge.lkey = mr->lkey; 342 342 reg->rkey = mr->rkey;
-1
drivers/infiniband/ulp/iser/iser_verbs.c
··· 129 129 goto err_alloc_mr_integrity; 130 130 } 131 131 } 132 - desc->rsc.mr_valid = 0; 133 132 134 133 return desc; 135 134
+6 -6
drivers/infiniband/ulp/rtrs/rtrs-clt.c
··· 1391 1391 clt_path->max_pages_per_mr); 1392 1392 if (IS_ERR(req->mr)) { 1393 1393 err = PTR_ERR(req->mr); 1394 + pr_err("Failed to alloc clt_path->max_pages_per_mr %d: %pe\n", 1395 + clt_path->max_pages_per_mr, req->mr); 1394 1396 req->mr = NULL; 1395 - pr_err("Failed to alloc clt_path->max_pages_per_mr %d\n", 1396 - clt_path->max_pages_per_mr); 1397 1397 goto out; 1398 1398 } 1399 1399 ··· 2025 2025 /* 2026 2026 * Device removal is a special case. Queue close and return 0. 2027 2027 */ 2028 + rtrs_wrn_rl(s, "CM event: %s, status: %d\n", rdma_event_msg(ev->event), 2029 + ev->status); 2028 2030 rtrs_clt_close_conns(clt_path, false); 2029 2031 return 0; 2030 2032 default: ··· 2060 2058 clt_path->s.dst_addr.ss_family == AF_IB ? 2061 2059 RDMA_PS_IB : RDMA_PS_TCP, IB_QPT_RC); 2062 2060 if (IS_ERR(cm_id)) { 2063 - err = PTR_ERR(cm_id); 2064 - rtrs_err(s, "Failed to create CM ID, err: %d\n", err); 2065 - 2066 - return err; 2061 + rtrs_err(s, "Failed to create CM ID, err: %pe\n", cm_id); 2062 + return PTR_ERR(cm_id); 2067 2063 } 2068 2064 con->c.cm_id = cm_id; 2069 2065 con->cm_err = 0;
+2 -2
drivers/infiniband/ulp/rtrs/rtrs.c
··· 242 242 cq = ib_cq_pool_get(cm_id->device, nr_cqe, cq_vector, poll_ctx); 243 243 244 244 if (IS_ERR(cq)) { 245 - rtrs_err(con->path, "Creating completion queue failed, errno: %ld\n", 246 - PTR_ERR(cq)); 245 + rtrs_err(con->path, "Creating completion queue failed, errno: %pe\n", 246 + cq); 247 247 return PTR_ERR(cq); 248 248 } 249 249 con->cq = cq;
-7
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
··· 618 618 return esw && MLX5_ESWITCH_MANAGER(esw->dev); 619 619 } 620 620 621 - /* The returned number is valid only when the dev is eswitch manager. */ 622 - static inline u16 mlx5_eswitch_manager_vport(struct mlx5_core_dev *dev) 623 - { 624 - return mlx5_core_is_ecpf_esw_manager(dev) ? 625 - MLX5_VPORT_ECPF : MLX5_VPORT_PF; 626 - } 627 - 628 621 static inline bool 629 622 mlx5_esw_is_manager_vport(const struct mlx5_eswitch *esw, u16 vport_num) 630 623 {
+37 -1
drivers/net/ethernet/mellanox/mlx5/core/lib/dm.c
··· 13 13 unsigned long *steering_sw_icm_alloc_blocks; 14 14 unsigned long *header_modify_sw_icm_alloc_blocks; 15 15 unsigned long *header_modify_pattern_sw_icm_alloc_blocks; 16 + unsigned long *header_encap_sw_icm_alloc_blocks; 16 17 }; 17 18 18 19 struct mlx5_dm *mlx5_dm_create(struct mlx5_core_dev *dev) 19 20 { 20 21 u64 header_modify_pattern_icm_blocks = 0; 22 + u64 header_sw_encap_icm_blocks = 0; 21 23 u64 header_modify_icm_blocks = 0; 22 24 u64 steering_icm_blocks = 0; 23 25 struct mlx5_dm *dm; ··· 56 54 goto err_modify_hdr; 57 55 } 58 56 57 + if (MLX5_CAP_DEV_MEM(dev, log_indirect_encap_sw_icm_size)) { 58 + header_sw_encap_icm_blocks = 59 + BIT(MLX5_CAP_DEV_MEM(dev, log_indirect_encap_sw_icm_size) - 60 + MLX5_LOG_SW_ICM_BLOCK_SIZE(dev)); 61 + 62 + dm->header_encap_sw_icm_alloc_blocks = 63 + bitmap_zalloc(header_sw_encap_icm_blocks, GFP_KERNEL); 64 + if (!dm->header_encap_sw_icm_alloc_blocks) 65 + goto err_pattern; 66 + } 67 + 59 68 support_v2 = MLX5_CAP_FLOWTABLE_NIC_RX(dev, sw_owner_v2) && 60 69 MLX5_CAP_FLOWTABLE_NIC_TX(dev, sw_owner_v2) && 61 70 MLX5_CAP64_DEV_MEM(dev, header_modify_pattern_sw_icm_start_address); ··· 79 66 dm->header_modify_pattern_sw_icm_alloc_blocks = 80 67 bitmap_zalloc(header_modify_pattern_icm_blocks, GFP_KERNEL); 81 68 if (!dm->header_modify_pattern_sw_icm_alloc_blocks) 82 - goto err_pattern; 69 + goto err_sw_encap; 83 70 } 84 71 85 72 return dm; 73 + 74 + err_sw_encap: 75 + bitmap_free(dm->header_encap_sw_icm_alloc_blocks); 86 76 87 77 err_pattern: 88 78 bitmap_free(dm->header_modify_sw_icm_alloc_blocks); ··· 119 103 log_header_modify_sw_icm_size) - 120 104 MLX5_LOG_SW_ICM_BLOCK_SIZE(dev)))); 121 105 bitmap_free(dm->header_modify_sw_icm_alloc_blocks); 106 + } 107 + 108 + if (dm->header_encap_sw_icm_alloc_blocks) { 109 + WARN_ON(!bitmap_empty(dm->header_encap_sw_icm_alloc_blocks, 110 + BIT(MLX5_CAP_DEV_MEM(dev, 111 + log_indirect_encap_sw_icm_size) - 112 + MLX5_LOG_SW_ICM_BLOCK_SIZE(dev)))); 113 + bitmap_free(dm->header_encap_sw_icm_alloc_blocks); 122 114 } 123 115 124 116 if (dm->header_modify_pattern_sw_icm_alloc_blocks) { ··· 187 163 log_icm_size = MLX5_CAP_DEV_MEM(dev, 188 164 log_header_modify_pattern_sw_icm_size); 189 165 block_map = dm->header_modify_pattern_sw_icm_alloc_blocks; 166 + break; 167 + case MLX5_SW_ICM_TYPE_SW_ENCAP: 168 + icm_start_addr = MLX5_CAP64_DEV_MEM(dev, 169 + indirect_encap_sw_icm_start_address); 170 + log_icm_size = MLX5_CAP_DEV_MEM(dev, 171 + log_indirect_encap_sw_icm_size); 172 + block_map = dm->header_encap_sw_icm_alloc_blocks; 190 173 break; 191 174 default: 192 175 return -EINVAL; ··· 272 241 icm_start_addr = MLX5_CAP64_DEV_MEM(dev, 273 242 header_modify_pattern_sw_icm_start_address); 274 243 block_map = dm->header_modify_pattern_sw_icm_alloc_blocks; 244 + break; 245 + case MLX5_SW_ICM_TYPE_SW_ENCAP: 246 + icm_start_addr = MLX5_CAP64_DEV_MEM(dev, 247 + indirect_encap_sw_icm_start_address); 248 + block_map = dm->header_encap_sw_icm_alloc_blocks; 275 249 break; 276 250 default: 277 251 return -EINVAL;
+5
drivers/net/ethernet/microsoft/mana/gdma_main.c
··· 158 158 if (dev_type == GDMA_DEVICE_MANA) { 159 159 gc->mana.gdma_context = gc; 160 160 gc->mana.dev_id = dev; 161 + } else if (dev_type == GDMA_DEVICE_MANA_IB) { 162 + gc->mana_ib.dev_id = dev; 163 + gc->mana_ib.gdma_context = gc; 161 164 } 162 165 } 163 166 ··· 970 967 971 968 return 0; 972 969 } 970 + EXPORT_SYMBOL_NS(mana_gd_register_device, NET_MANA); 973 971 974 972 int mana_gd_deregister_device(struct gdma_dev *gd) 975 973 { ··· 1001 997 1002 998 return err; 1003 999 } 1000 + EXPORT_SYMBOL_NS(mana_gd_deregister_device, NET_MANA); 1004 1001 1005 1002 u32 mana_gd_wq_avail_space(struct gdma_queue *wq) 1006 1003 {
+1
include/linux/mlx5/driver.h
··· 691 691 MLX5_SW_ICM_TYPE_STEERING, 692 692 MLX5_SW_ICM_TYPE_HEADER_MODIFY, 693 693 MLX5_SW_ICM_TYPE_HEADER_MODIFY_PATTERN, 694 + MLX5_SW_ICM_TYPE_SW_ENCAP, 694 695 }; 695 696 696 697 #define MLX5_MAX_RESERVED_GIDS 8
+8
include/linux/mlx5/eswitch.h
··· 7 7 #define _MLX5_ESWITCH_ 8 8 9 9 #include <linux/mlx5/driver.h> 10 + #include <linux/mlx5/vport.h> 10 11 #include <net/devlink.h> 11 12 12 13 #define MLX5_ESWITCH_MANAGER(mdev) MLX5_CAP_GEN(mdev, eswitch_manager) ··· 209 208 static inline bool is_mdev_switchdev_mode(struct mlx5_core_dev *dev) 210 209 { 211 210 return mlx5_eswitch_mode(dev) == MLX5_ESWITCH_OFFLOADS; 211 + } 212 + 213 + /* The returned number is valid only when the dev is eswitch manager. */ 214 + static inline u16 mlx5_eswitch_manager_vport(struct mlx5_core_dev *dev) 215 + { 216 + return mlx5_core_is_ecpf_esw_manager(dev) ? 217 + MLX5_VPORT_ECPF : MLX5_VPORT_PF; 212 218 } 213 219 214 220 #endif
+7 -2
include/linux/mlx5/mlx5_ifc.h
··· 1193 1193 u8 log_sw_icm_alloc_granularity[0x6]; 1194 1194 u8 log_steering_sw_icm_size[0x8]; 1195 1195 1196 - u8 reserved_at_120[0x18]; 1196 + u8 log_indirect_encap_sw_icm_size[0x8]; 1197 + u8 reserved_at_128[0x10]; 1197 1198 u8 log_header_modify_pattern_sw_icm_size[0x8]; 1198 1199 1199 1200 u8 header_modify_sw_icm_start_address[0x40]; ··· 1205 1204 1206 1205 u8 memic_operations[0x20]; 1207 1206 1208 - u8 reserved_at_220[0x5e0]; 1207 + u8 reserved_at_220[0x20]; 1208 + 1209 + u8 indirect_encap_sw_icm_start_address[0x40]; 1210 + 1211 + u8 reserved_at_280[0x580]; 1209 1212 }; 1210 1213 1211 1214 struct mlx5_ifc_device_event_cap_bits {
+5
include/net/mana/gdma.h
··· 66 66 GDMA_DEVICE_NONE = 0, 67 67 GDMA_DEVICE_HWC = 1, 68 68 GDMA_DEVICE_MANA = 2, 69 + GDMA_DEVICE_MANA_IB = 3, 69 70 }; 70 71 71 72 struct gdma_resource { ··· 150 149 151 150 #define GDMA_MESSAGE_V1 1 152 151 #define GDMA_MESSAGE_V2 2 152 + #define GDMA_MESSAGE_V3 3 153 153 154 154 struct gdma_general_resp { 155 155 struct gdma_resp_hdr hdr; ··· 392 390 393 391 /* Azure network adapter */ 394 392 struct gdma_dev mana; 393 + 394 + /* Azure RDMA adapter */ 395 + struct gdma_dev mana_ib; 395 396 }; 396 397 397 398 #define MAX_NUM_GDMA_DEVICES 4
+41
include/uapi/rdma/bnxt_re-abi.h
··· 54 54 BNXT_RE_UCNTX_CMASK_HAVE_MODE = 0x02ULL, 55 55 BNXT_RE_UCNTX_CMASK_WC_DPI_ENABLED = 0x04ULL, 56 56 BNXT_RE_UCNTX_CMASK_DBR_PACING_ENABLED = 0x08ULL, 57 + BNXT_RE_UCNTX_CMASK_POW2_DISABLED = 0x10ULL, 58 + BNXT_RE_COMP_MASK_UCNTX_HW_RETX_ENABLED = 0x40, 57 59 }; 58 60 59 61 enum bnxt_re_wqe_mode { 60 62 BNXT_QPLIB_WQE_MODE_STATIC = 0x00, 61 63 BNXT_QPLIB_WQE_MODE_VARIABLE = 0x01, 62 64 BNXT_QPLIB_WQE_MODE_INVALID = 0x02, 65 + }; 66 + 67 + enum { 68 + BNXT_RE_COMP_MASK_REQ_UCNTX_POW2_SUPPORT = 0x01, 69 + }; 70 + 71 + struct bnxt_re_uctx_req { 72 + __aligned_u64 comp_mask; 63 73 }; 64 74 65 75 struct bnxt_re_uctx_resp { ··· 102 92 __aligned_u64 cq_handle; 103 93 }; 104 94 95 + enum bnxt_re_cq_mask { 96 + BNXT_RE_CQ_TOGGLE_PAGE_SUPPORT = 0x1, 97 + }; 98 + 105 99 struct bnxt_re_cq_resp { 106 100 __u32 cqid; 107 101 __u32 tail; 108 102 __u32 phase; 109 103 __u32 rsvd; 104 + __aligned_u64 comp_mask; 110 105 }; 111 106 112 107 struct bnxt_re_resize_cq_req { ··· 148 133 enum bnxt_re_objects { 149 134 BNXT_RE_OBJECT_ALLOC_PAGE = (1U << UVERBS_ID_NS_SHIFT), 150 135 BNXT_RE_OBJECT_NOTIFY_DRV, 136 + BNXT_RE_OBJECT_GET_TOGGLE_MEM, 151 137 }; 152 138 153 139 enum bnxt_re_alloc_page_type { ··· 176 160 177 161 enum bnxt_re_notify_drv_methods { 178 162 BNXT_RE_METHOD_NOTIFY_DRV = (1U << UVERBS_ID_NS_SHIFT), 163 + }; 164 + 165 + /* Toggle mem */ 166 + 167 + enum bnxt_re_get_toggle_mem_type { 168 + BNXT_RE_CQ_TOGGLE_MEM = 0, 169 + BNXT_RE_SRQ_TOGGLE_MEM, 170 + }; 171 + 172 + enum bnxt_re_var_toggle_mem_attrs { 173 + BNXT_RE_TOGGLE_MEM_HANDLE = (1U << UVERBS_ID_NS_SHIFT), 174 + BNXT_RE_TOGGLE_MEM_TYPE, 175 + BNXT_RE_TOGGLE_MEM_RES_ID, 176 + BNXT_RE_TOGGLE_MEM_MMAP_PAGE, 177 + BNXT_RE_TOGGLE_MEM_MMAP_OFFSET, 178 + BNXT_RE_TOGGLE_MEM_MMAP_LENGTH, 179 + }; 180 + 181 + enum bnxt_re_toggle_mem_attrs { 182 + BNXT_RE_RELEASE_TOGGLE_MEM_HANDLE = (1U << UVERBS_ID_NS_SHIFT), 183 + }; 184 + 185 + enum bnxt_re_toggle_mem_methods { 186 + BNXT_RE_METHOD_GET_TOGGLE_MEM = (1U << UVERBS_ID_NS_SHIFT), 187 + BNXT_RE_METHOD_RELEASE_TOGGLE_MEM, 179 188 }; 180 189 #endif /* __BNXT_RE_UVERBS_ABI_H__*/
+20 -1
include/uapi/rdma/efa-abi.h
··· 1 1 /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ 2 2 /* 3 - * Copyright 2018-2023 Amazon.com, Inc. or its affiliates. All rights reserved. 3 + * Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved. 4 4 */ 5 5 6 6 #ifndef EFA_ABI_USER_H 7 7 #define EFA_ABI_USER_H 8 8 9 9 #include <linux/types.h> 10 + #include <rdma/ib_user_ioctl_cmds.h> 10 11 11 12 /* 12 13 * Increment this value if any changes that break userspace ABI ··· 133 132 __u16 max_rq_sge; 134 133 __u32 max_rdma_size; 135 134 __u32 device_caps; 135 + }; 136 + 137 + enum { 138 + EFA_QUERY_MR_VALIDITY_RECV_IC_ID = 1 << 0, 139 + EFA_QUERY_MR_VALIDITY_RDMA_READ_IC_ID = 1 << 1, 140 + EFA_QUERY_MR_VALIDITY_RDMA_RECV_IC_ID = 1 << 2, 141 + }; 142 + 143 + enum efa_query_mr_attrs { 144 + EFA_IB_ATTR_QUERY_MR_HANDLE = (1U << UVERBS_ID_NS_SHIFT), 145 + EFA_IB_ATTR_QUERY_MR_RESP_IC_ID_VALIDITY, 146 + EFA_IB_ATTR_QUERY_MR_RESP_RECV_IC_ID, 147 + EFA_IB_ATTR_QUERY_MR_RESP_RDMA_READ_IC_ID, 148 + EFA_IB_ATTR_QUERY_MR_RESP_RDMA_RECV_IC_ID, 149 + }; 150 + 151 + enum efa_mr_methods { 152 + EFA_IB_METHOD_MR_QUERY = (1U << UVERBS_ID_NS_SHIFT), 136 153 }; 137 154 138 155 #endif /* EFA_ABI_USER_H */
+5
include/uapi/rdma/hns-abi.h
··· 125 125 __u32 pdn; 126 126 }; 127 127 128 + struct hns_roce_ib_create_ah_resp { 129 + __u8 dmac[6]; 130 + __u8 reserved[2]; 131 + }; 132 + 128 133 #endif /* HNS_ABI_USER_H */
+2
include/uapi/rdma/mlx5-abi.h
··· 37 37 #include <linux/types.h> 38 38 #include <linux/if_ether.h> /* For ETH_ALEN. */ 39 39 #include <rdma/ib_user_ioctl_verbs.h> 40 + #include <rdma/mlx5_user_ioctl_verbs.h> 40 41 41 42 enum { 42 43 MLX5_QP_FLAG_SIGNATURE = 1 << 0, ··· 276 275 __u32 tunnel_offloads_caps; /* enum mlx5_ib_tunnel_offloads */ 277 276 struct mlx5_ib_dci_streams_caps dci_streams_caps; 278 277 __u16 reserved; 278 + struct mlx5_ib_uapi_reg reg_c0; 279 279 }; 280 280 281 281 enum mlx5_ib_create_cq_flags {
+1
include/uapi/rdma/mlx5_user_ioctl_verbs.h
··· 64 64 MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM, 65 65 MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_SW_ICM, 66 66 MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_PATTERN_SW_ICM, 67 + MLX5_IB_UAPI_DM_TYPE_ENCAP_SW_ICM, 67 68 }; 68 69 69 70 enum mlx5_ib_uapi_devx_create_event_channel_flags {