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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull rdma fixes from Jason Gunthorpe:
"Many bug fixes in several drivers:

- Fix misuse of the DMA API in rtrs

- Several irdma issues: hung task due to SQ flushing, incorrect
capability reporting to userspace, improper error handling for MW
corners, touching an uninitialized SGL for during invalidation.

- hns was using the wrong page size limits for the HW, an incorrect
calculation of wqe_shift causing WQE corruption, and mis computed a
timer id.

- Fix a crash in SRP triggered by blktests

- Fix compiler errors by calling virt_to_page() with the proper type
in siw

- Userspace triggerable deadlock in ODP

- mlx5 could use the wrong profile due to some driver loading races,
counters were not working in some device configurations, and a
crash on error unwind"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
RDMA/irdma: Report RNR NAK generation in device caps
RDMA/irdma: Use s/g array in post send only when its valid
RDMA/irdma: Return correct WC error for bind operation failure
RDMA/irdma: Return error on MR deregister CQP failure
RDMA/irdma: Report the correct max cqes from query device
MAINTAINERS: Update maintainers of HiSilicon RoCE
RDMA/mlx5: Fix UMR cleanup on error flow of driver init
RDMA/mlx5: Set local port to one when accessing counters
RDMA/mlx5: Rely on RoCE fw cap instead of devlink when setting profile
IB/core: Fix a nested dead lock as part of ODP flow
RDMA/siw: Pass a pointer to virt_to_page()
RDMA/srp: Set scmnd->result only when scmnd is not NULL
RDMA/hns: Remove the num_qpc_timer variable
RDMA/hns: Fix wrong fixed value of qp->rq.wqe_shift
RDMA/hns: Fix supported page size
RDMA/cma: Fix arguments order in net device validation
RDMA/irdma: Fix drain SQ hang with no completion
RDMA/rtrs-srv: Pass the correct number of entries for dma mapped SGL
RDMA/rtrs-clt: Use the right sg_cnt after ib_dma_map_sg

+105 -54
+1 -1
MAINTAINERS
··· 9208 9208 F: drivers/crypto/hisilicon/zip/ 9209 9209 9210 9210 HISILICON ROCE DRIVER 9211 + M: Haoyue Xu <xuhaoyue1@hisilicon.com> 9211 9212 M: Wenpeng Liang <liangwenpeng@huawei.com> 9212 - M: Weihang Li <liweihang@huawei.com> 9213 9213 L: linux-rdma@vger.kernel.org 9214 9214 S: Maintained 9215 9215 F: Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt
+2 -2
drivers/infiniband/core/cma.c
··· 1841 1841 } 1842 1842 1843 1843 if (!validate_net_dev(*net_dev, 1844 - (struct sockaddr *)&req->listen_addr_storage, 1845 - (struct sockaddr *)&req->src_addr_storage)) { 1844 + (struct sockaddr *)&req->src_addr_storage, 1845 + (struct sockaddr *)&req->listen_addr_storage)) { 1846 1846 id_priv = ERR_PTR(-EHOSTUNREACH); 1847 1847 goto err; 1848 1848 }
+1 -1
drivers/infiniband/core/umem_odp.c
··· 462 462 mutex_unlock(&umem_odp->umem_mutex); 463 463 464 464 out_put_mm: 465 - mmput(owning_mm); 465 + mmput_async(owning_mm); 466 466 out_put_task: 467 467 if (owning_process) 468 468 put_task_struct(owning_process);
-1
drivers/infiniband/hw/hns/hns_roce_device.h
··· 730 730 u32 num_qps; 731 731 u32 num_pi_qps; 732 732 u32 reserved_qps; 733 - int num_qpc_timer; 734 733 u32 num_srqs; 735 734 u32 max_wqes; 736 735 u32 max_srq_wrs;
+1 -2
drivers/infiniband/hw/hns/hns_roce_hw_v2.c
··· 1977 1977 1978 1978 caps->num_mtpts = HNS_ROCE_V2_MAX_MTPT_NUM; 1979 1979 caps->num_pds = HNS_ROCE_V2_MAX_PD_NUM; 1980 - caps->num_qpc_timer = HNS_ROCE_V2_MAX_QPC_TIMER_NUM; 1980 + caps->qpc_timer_bt_num = HNS_ROCE_V2_MAX_QPC_TIMER_BT_NUM; 1981 1981 caps->cqc_timer_bt_num = HNS_ROCE_V2_MAX_CQC_TIMER_BT_NUM; 1982 1982 1983 1983 caps->max_qp_init_rdma = HNS_ROCE_V2_MAX_QP_INIT_RDMA; ··· 2273 2273 caps->max_rq_sg = le16_to_cpu(resp_a->max_rq_sg); 2274 2274 caps->max_rq_sg = roundup_pow_of_two(caps->max_rq_sg); 2275 2275 caps->max_extend_sg = le32_to_cpu(resp_a->max_extend_sg); 2276 - caps->num_qpc_timer = le16_to_cpu(resp_a->num_qpc_timer); 2277 2276 caps->max_srq_sges = le16_to_cpu(resp_a->max_srq_sges); 2278 2277 caps->max_srq_sges = roundup_pow_of_two(caps->max_srq_sges); 2279 2278 caps->num_aeq_vectors = resp_a->num_aeq_vectors;
+2 -2
drivers/infiniband/hw/hns/hns_roce_hw_v2.h
··· 36 36 #include <linux/bitops.h> 37 37 38 38 #define HNS_ROCE_V2_MAX_QP_NUM 0x1000 39 - #define HNS_ROCE_V2_MAX_QPC_TIMER_NUM 0x200 40 39 #define HNS_ROCE_V2_MAX_WQE_NUM 0x8000 41 40 #define HNS_ROCE_V2_MAX_SRQ_WR 0x8000 42 41 #define HNS_ROCE_V2_MAX_SRQ_SGE 64 43 42 #define HNS_ROCE_V2_MAX_CQ_NUM 0x100000 43 + #define HNS_ROCE_V2_MAX_QPC_TIMER_BT_NUM 0x100 44 44 #define HNS_ROCE_V2_MAX_CQC_TIMER_BT_NUM 0x100 45 45 #define HNS_ROCE_V2_MAX_SRQ_NUM 0x100000 46 46 #define HNS_ROCE_V2_MAX_CQE_NUM 0x400000 ··· 83 83 84 84 #define HNS_ROCE_V2_QPC_TIMER_ENTRY_SZ PAGE_SIZE 85 85 #define HNS_ROCE_V2_CQC_TIMER_ENTRY_SZ PAGE_SIZE 86 - #define HNS_ROCE_V2_PAGE_SIZE_SUPPORTED 0xFFFFF000 86 + #define HNS_ROCE_V2_PAGE_SIZE_SUPPORTED 0xFFFF000 87 87 #define HNS_ROCE_V2_MAX_INNER_MTPT_NUM 2 88 88 #define HNS_ROCE_INVALID_LKEY 0x0 89 89 #define HNS_ROCE_INVALID_SGE_LENGTH 0x80000000
+1 -1
drivers/infiniband/hw/hns/hns_roce_main.c
··· 725 725 ret = hns_roce_init_hem_table(hr_dev, &hr_dev->qpc_timer_table, 726 726 HEM_TYPE_QPC_TIMER, 727 727 hr_dev->caps.qpc_timer_entry_sz, 728 - hr_dev->caps.num_qpc_timer, 1); 728 + hr_dev->caps.qpc_timer_bt_num, 1); 729 729 if (ret) { 730 730 dev_err(dev, 731 731 "Failed to init QPC timer memory, aborting.\n");
+2 -5
drivers/infiniband/hw/hns/hns_roce_qp.c
··· 462 462 hr_qp->rq.max_gs = roundup_pow_of_two(max(1U, cap->max_recv_sge) + 463 463 hr_qp->rq.rsv_sge); 464 464 465 - if (hr_dev->caps.max_rq_sg <= HNS_ROCE_SGE_IN_WQE) 466 - hr_qp->rq.wqe_shift = ilog2(hr_dev->caps.max_rq_desc_sz); 467 - else 468 - hr_qp->rq.wqe_shift = ilog2(hr_dev->caps.max_rq_desc_sz * 469 - hr_qp->rq.max_gs); 465 + hr_qp->rq.wqe_shift = ilog2(hr_dev->caps.max_rq_desc_sz * 466 + hr_qp->rq.max_gs); 470 467 471 468 hr_qp->rq.wqe_cnt = cnt; 472 469 if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE &&
+5 -2
drivers/infiniband/hw/irdma/uk.c
··· 497 497 FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data)); 498 498 i = 0; 499 499 } else { 500 - qp->wqe_ops.iw_set_fragment(wqe, 0, op_info->sg_list, 500 + qp->wqe_ops.iw_set_fragment(wqe, 0, 501 + frag_cnt ? op_info->sg_list : NULL, 501 502 qp->swqe_polarity); 502 503 i = 1; 503 504 } ··· 1006 1005 int ret_code; 1007 1006 bool move_cq_head = true; 1008 1007 u8 polarity; 1008 + u8 op_type; 1009 1009 bool ext_valid; 1010 1010 __le64 *ext_cqe; 1011 1011 ··· 1189 1187 do { 1190 1188 __le64 *sw_wqe; 1191 1189 u64 wqe_qword; 1192 - u8 op_type; 1193 1190 u32 tail; 1194 1191 1195 1192 tail = qp->sq_ring.tail; ··· 1205 1204 break; 1206 1205 } 1207 1206 } while (1); 1207 + if (op_type == IRDMA_OP_TYPE_BIND_MW && info->minor_err == FLUSH_PROT_ERR) 1208 + info->minor_err = FLUSH_MW_BIND_ERR; 1208 1209 qp->sq_flush_seen = true; 1209 1210 if (!IRDMA_RING_MORE_WORK(qp->sq_ring)) 1210 1211 qp->sq_flush_complete = true;
+9 -6
drivers/infiniband/hw/irdma/utils.c
··· 590 590 cqp_error = cqp_request->compl_info.error; 591 591 if (cqp_error) { 592 592 err_code = -EIO; 593 - if (cqp_request->compl_info.maj_err_code == 0xFFFF && 594 - cqp_request->compl_info.min_err_code == 0x8029) { 595 - if (!rf->reset) { 596 - rf->reset = true; 597 - rf->gen_ops.request_reset(rf); 593 + if (cqp_request->compl_info.maj_err_code == 0xFFFF) { 594 + if (cqp_request->compl_info.min_err_code == 0x8002) 595 + err_code = -EBUSY; 596 + else if (cqp_request->compl_info.min_err_code == 0x8029) { 597 + if (!rf->reset) { 598 + rf->reset = true; 599 + rf->gen_ops.request_reset(rf); 600 + } 598 601 } 599 602 } 600 603 } ··· 2601 2598 spin_unlock_irqrestore(&iwqp->lock, flags2); 2602 2599 spin_unlock_irqrestore(&iwqp->iwscq->lock, flags1); 2603 2600 if (compl_generated) 2604 - irdma_comp_handler(iwqp->iwrcq); 2601 + irdma_comp_handler(iwqp->iwscq); 2605 2602 } else { 2606 2603 spin_unlock_irqrestore(&iwqp->iwscq->lock, flags1); 2607 2604 mod_delayed_work(iwqp->iwdev->cleanup_wq, &iwqp->dwork_flush,
+10 -3
drivers/infiniband/hw/irdma/verbs.c
··· 39 39 props->max_send_sge = hw_attrs->uk_attrs.max_hw_wq_frags; 40 40 props->max_recv_sge = hw_attrs->uk_attrs.max_hw_wq_frags; 41 41 props->max_cq = rf->max_cq - rf->used_cqs; 42 - props->max_cqe = rf->max_cqe; 42 + props->max_cqe = rf->max_cqe - 1; 43 43 props->max_mr = rf->max_mr - rf->used_mrs; 44 44 props->max_mw = props->max_mr; 45 45 props->max_pd = rf->max_pd - rf->used_pds; 46 46 props->max_sge_rd = hw_attrs->uk_attrs.max_hw_read_sges; 47 47 props->max_qp_rd_atom = hw_attrs->max_hw_ird; 48 48 props->max_qp_init_rd_atom = hw_attrs->max_hw_ord; 49 - if (rdma_protocol_roce(ibdev, 1)) 49 + if (rdma_protocol_roce(ibdev, 1)) { 50 + props->device_cap_flags |= IB_DEVICE_RC_RNR_NAK_GEN; 50 51 props->max_pkeys = IRDMA_PKEY_TBL_SZ; 52 + } 53 + 51 54 props->max_ah = rf->max_ah; 52 55 props->max_mcast_grp = rf->max_mcg; 53 56 props->max_mcast_qp_attach = IRDMA_MAX_MGS_PER_CTX; ··· 3012 3009 struct irdma_pble_alloc *palloc = &iwpbl->pble_alloc; 3013 3010 struct irdma_cqp_request *cqp_request; 3014 3011 struct cqp_cmds_info *cqp_info; 3012 + int status; 3015 3013 3016 3014 if (iwmr->type != IRDMA_MEMREG_TYPE_MEM) { 3017 3015 if (iwmr->region) { ··· 3043 3039 cqp_info->post_sq = 1; 3044 3040 cqp_info->in.u.dealloc_stag.dev = &iwdev->rf->sc_dev; 3045 3041 cqp_info->in.u.dealloc_stag.scratch = (uintptr_t)cqp_request; 3046 - irdma_handle_cqp_op(iwdev->rf, cqp_request); 3042 + status = irdma_handle_cqp_op(iwdev->rf, cqp_request); 3047 3043 irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); 3044 + if (status) 3045 + return status; 3046 + 3048 3047 irdma_free_stag(iwdev, iwmr->stag); 3049 3048 done: 3050 3049 if (iwpbl->pbl_allocated)
+6
drivers/infiniband/hw/mlx5/mad.c
··· 166 166 mdev = dev->mdev; 167 167 mdev_port_num = 1; 168 168 } 169 + if (MLX5_CAP_GEN(dev->mdev, num_ports) == 1) { 170 + /* set local port to one for Function-Per-Port HCA. */ 171 + mdev = dev->mdev; 172 + mdev_port_num = 1; 173 + } 174 + 169 175 /* Declaring support of extended counters */ 170 176 if (in_mad->mad_hdr.attr_id == IB_PMA_CLASS_PORT_INFO) { 171 177 struct ib_class_port_info cpi = {};
+1 -1
drivers/infiniband/hw/mlx5/main.c
··· 4336 4336 dev->mdev = mdev; 4337 4337 dev->num_ports = num_ports; 4338 4338 4339 - if (ll == IB_LINK_LAYER_ETHERNET && !mlx5_is_roce_init_enabled(mdev)) 4339 + if (ll == IB_LINK_LAYER_ETHERNET && !mlx5_get_roce_state(mdev)) 4340 4340 profile = &raw_eth_profile; 4341 4341 else 4342 4342 profile = &pf_profile;
+1
drivers/infiniband/hw/mlx5/mlx5_ib.h
··· 708 708 }; 709 709 710 710 enum { 711 + MLX5_UMR_STATE_UNINIT, 711 712 MLX5_UMR_STATE_ACTIVE, 712 713 MLX5_UMR_STATE_RECOVER, 713 714 MLX5_UMR_STATE_ERR,
+3
drivers/infiniband/hw/mlx5/umr.c
··· 177 177 178 178 sema_init(&dev->umrc.sem, MAX_UMR_WR); 179 179 mutex_init(&dev->umrc.lock); 180 + dev->umrc.state = MLX5_UMR_STATE_ACTIVE; 180 181 181 182 return 0; 182 183 ··· 192 191 193 192 void mlx5r_umr_resource_cleanup(struct mlx5_ib_dev *dev) 194 193 { 194 + if (dev->umrc.state == MLX5_UMR_STATE_UNINIT) 195 + return; 195 196 ib_destroy_qp(dev->umrc.qp); 196 197 ib_free_cq(dev->umrc.cq); 197 198 ib_dealloc_pd(dev->umrc.pd);
+14 -4
drivers/infiniband/sw/siw/siw_qp_tx.c
··· 29 29 dma_addr_t paddr = siw_pbl_get_buffer(pbl, offset, NULL, idx); 30 30 31 31 if (paddr) 32 - return virt_to_page(paddr); 32 + return virt_to_page((void *)paddr); 33 33 34 34 return NULL; 35 35 } ··· 533 533 kunmap_local(kaddr); 534 534 } 535 535 } else { 536 - u64 va = sge->laddr + sge_off; 536 + /* 537 + * Cast to an uintptr_t to preserve all 64 bits 538 + * in sge->laddr. 539 + */ 540 + uintptr_t va = (uintptr_t)(sge->laddr + sge_off); 537 541 538 - page_array[seg] = virt_to_page(va & PAGE_MASK); 542 + /* 543 + * virt_to_page() takes a (void *) pointer 544 + * so cast to a (void *) meaning it will be 64 545 + * bits on a 64 bit platform and 32 bits on a 546 + * 32 bit platform. 547 + */ 548 + page_array[seg] = virt_to_page((void *)(va & PAGE_MASK)); 539 549 if (do_crc) 540 550 crypto_shash_update( 541 551 c_tx->mpa_crc_hd, 542 - (void *)(uintptr_t)va, 552 + (void *)va, 543 553 plen); 544 554 } 545 555
+5 -4
drivers/infiniband/ulp/rtrs/rtrs-clt.c
··· 1004 1004 static int rtrs_post_rdma_write_sg(struct rtrs_clt_con *con, 1005 1005 struct rtrs_clt_io_req *req, 1006 1006 struct rtrs_rbuf *rbuf, bool fr_en, 1007 - u32 size, u32 imm, struct ib_send_wr *wr, 1007 + u32 count, u32 size, u32 imm, 1008 + struct ib_send_wr *wr, 1008 1009 struct ib_send_wr *tail) 1009 1010 { 1010 1011 struct rtrs_clt_path *clt_path = to_clt_path(con->c.path); ··· 1025 1024 num_sge = 2; 1026 1025 ptail = tail; 1027 1026 } else { 1028 - for_each_sg(req->sglist, sg, req->sg_cnt, i) { 1027 + for_each_sg(req->sglist, sg, count, i) { 1029 1028 sge[i].addr = sg_dma_address(sg); 1030 1029 sge[i].length = sg_dma_len(sg); 1031 1030 sge[i].lkey = clt_path->s.dev->ib_pd->local_dma_lkey; 1032 1031 } 1033 - num_sge = 1 + req->sg_cnt; 1032 + num_sge = 1 + count; 1034 1033 } 1035 1034 sge[i].addr = req->iu->dma_addr; 1036 1035 sge[i].length = size; ··· 1143 1142 */ 1144 1143 rtrs_clt_update_all_stats(req, WRITE); 1145 1144 1146 - ret = rtrs_post_rdma_write_sg(req->con, req, rbuf, fr_en, 1145 + ret = rtrs_post_rdma_write_sg(req->con, req, rbuf, fr_en, count, 1147 1146 req->usr_len + sizeof(*msg), 1148 1147 imm, wr, &inv_wr); 1149 1148 if (ret) {
+7 -7
drivers/infiniband/ulp/rtrs/rtrs-srv.c
··· 595 595 struct sg_table *sgt = &srv_mr->sgt; 596 596 struct scatterlist *s; 597 597 struct ib_mr *mr; 598 - int nr, chunks; 598 + int nr, nr_sgt, chunks; 599 599 600 600 chunks = chunks_per_mr * mri; 601 601 if (!always_invalidate) ··· 610 610 sg_set_page(s, srv->chunks[chunks + i], 611 611 max_chunk_size, 0); 612 612 613 - nr = ib_dma_map_sg(srv_path->s.dev->ib_dev, sgt->sgl, 613 + nr_sgt = ib_dma_map_sg(srv_path->s.dev->ib_dev, sgt->sgl, 614 614 sgt->nents, DMA_BIDIRECTIONAL); 615 - if (nr < sgt->nents) { 616 - err = nr < 0 ? nr : -EINVAL; 615 + if (!nr_sgt) { 616 + err = -EINVAL; 617 617 goto free_sg; 618 618 } 619 619 mr = ib_alloc_mr(srv_path->s.dev->ib_pd, IB_MR_TYPE_MEM_REG, 620 - sgt->nents); 620 + nr_sgt); 621 621 if (IS_ERR(mr)) { 622 622 err = PTR_ERR(mr); 623 623 goto unmap_sg; 624 624 } 625 - nr = ib_map_mr_sg(mr, sgt->sgl, sgt->nents, 625 + nr = ib_map_mr_sg(mr, sgt->sgl, nr_sgt, 626 626 NULL, max_chunk_size); 627 627 if (nr < 0 || nr < sgt->nents) { 628 628 err = nr < 0 ? nr : -EINVAL; ··· 641 641 } 642 642 } 643 643 /* Eventually dma addr for each chunk can be cached */ 644 - for_each_sg(sgt->sgl, s, sgt->orig_nents, i) 644 + for_each_sg(sgt->sgl, s, nr_sgt, i) 645 645 srv_path->dma_addr[chunks + i] = sg_dma_address(s); 646 646 647 647 ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey));
+2 -1
drivers/infiniband/ulp/srp/ib_srp.c
··· 1961 1961 if (scmnd) { 1962 1962 req = scsi_cmd_priv(scmnd); 1963 1963 scmnd = srp_claim_req(ch, req, NULL, scmnd); 1964 - } else { 1964 + } 1965 + if (!scmnd) { 1965 1966 shost_printk(KERN_ERR, target->scsi_host, 1966 1967 "Null scmnd for RSP w/tag %#016llx received on ch %td / QP %#x\n", 1967 1968 rsp->tag, ch - target->ch, ch->qp->qp_num);
+21 -2
drivers/net/ethernet/mellanox/mlx5/core/main.c
··· 494 494 return err; 495 495 } 496 496 497 + bool mlx5_is_roce_on(struct mlx5_core_dev *dev) 498 + { 499 + struct devlink *devlink = priv_to_devlink(dev); 500 + union devlink_param_value val; 501 + int err; 502 + 503 + err = devlink_param_driverinit_value_get(devlink, 504 + DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE, 505 + &val); 506 + 507 + if (!err) 508 + return val.vbool; 509 + 510 + mlx5_core_dbg(dev, "Failed to get param. err = %d\n", err); 511 + return MLX5_CAP_GEN(dev, roce); 512 + } 513 + EXPORT_SYMBOL(mlx5_is_roce_on); 514 + 497 515 static int handle_hca_cap_2(struct mlx5_core_dev *dev, void *set_ctx) 498 516 { 499 517 void *set_hca_cap; ··· 615 597 MLX5_CAP_GEN_MAX(dev, num_total_dynamic_vf_msix)); 616 598 617 599 if (MLX5_CAP_GEN(dev, roce_rw_supported)) 618 - MLX5_SET(cmd_hca_cap, set_hca_cap, roce, mlx5_is_roce_init_enabled(dev)); 600 + MLX5_SET(cmd_hca_cap, set_hca_cap, roce, 601 + mlx5_is_roce_on(dev)); 619 602 620 603 max_uc_list = max_uc_list_get_devlink_param(dev); 621 604 if (max_uc_list > 0) ··· 642 623 */ 643 624 static bool is_roce_fw_disabled(struct mlx5_core_dev *dev) 644 625 { 645 - return (MLX5_CAP_GEN(dev, roce_rw_supported) && !mlx5_is_roce_init_enabled(dev)) || 626 + return (MLX5_CAP_GEN(dev, roce_rw_supported) && !mlx5_is_roce_on(dev)) || 646 627 (!MLX5_CAP_GEN(dev, roce_rw_supported) && !MLX5_CAP_GEN(dev, roce)); 647 628 } 648 629
+10 -9
include/linux/mlx5/driver.h
··· 1280 1280 MLX5_TRIGGERED_CMD_COMP = (u64)1 << 32, 1281 1281 }; 1282 1282 1283 - static inline bool mlx5_is_roce_init_enabled(struct mlx5_core_dev *dev) 1284 - { 1285 - struct devlink *devlink = priv_to_devlink(dev); 1286 - union devlink_param_value val; 1287 - int err; 1283 + bool mlx5_is_roce_on(struct mlx5_core_dev *dev); 1288 1284 1289 - err = devlink_param_driverinit_value_get(devlink, 1290 - DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE, 1291 - &val); 1292 - return err ? MLX5_CAP_GEN(dev, roce) : val.vbool; 1285 + static inline bool mlx5_get_roce_state(struct mlx5_core_dev *dev) 1286 + { 1287 + if (MLX5_CAP_GEN(dev, roce_rw_supported)) 1288 + return MLX5_CAP_GEN(dev, roce); 1289 + 1290 + /* If RoCE cap is read-only in FW, get RoCE state from devlink 1291 + * in order to support RoCE enable/disable feature 1292 + */ 1293 + return mlx5_is_roce_on(dev); 1293 1294 } 1294 1295 1295 1296 #endif /* MLX5_DRIVER_H */
+1
kernel/fork.c
··· 1225 1225 schedule_work(&mm->async_put_work); 1226 1226 } 1227 1227 } 1228 + EXPORT_SYMBOL_GPL(mmput_async); 1228 1229 #endif 1229 1230 1230 1231 /**