Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright (C) 2021 Intel Corporation. All rights reserved. 3 : : * Copyright (c) 2020, 2021 Mellanox Technologies LTD. All rights reserved. 4 : : * Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5 : : */ 6 : : 7 : : #include <rdma/rdma_cma.h> 8 : : 9 : : #include "spdk/log.h" 10 : : #include "spdk/string.h" 11 : : #include "spdk/likely.h" 12 : : 13 : : #include "spdk_internal/rdma_provider.h" 14 : : 15 : : struct spdk_rdma_provider_srq * 16 : 252 : spdk_rdma_provider_srq_create(struct spdk_rdma_provider_srq_init_attr *init_attr) 17 : : { 18 [ - + ]: 252 : assert(init_attr); 19 [ - + ]: 252 : assert(init_attr->pd); 20 : : 21 : 252 : struct spdk_rdma_provider_srq *rdma_srq = calloc(1, sizeof(*rdma_srq)); 22 : : 23 [ - + ]: 252 : if (!rdma_srq) { 24 : 0 : SPDK_ERRLOG("Can't allocate memory for SRQ handle\n"); 25 : 0 : return NULL; 26 : : } 27 : : 28 [ + - ]: 252 : if (init_attr->stats) { 29 : 252 : rdma_srq->stats = init_attr->stats; 30 : 252 : rdma_srq->shared_stats = true; 31 : : } else { 32 : 0 : rdma_srq->stats = calloc(1, sizeof(*rdma_srq->stats)); 33 [ # # ]: 0 : if (!rdma_srq->stats) { 34 : 0 : SPDK_ERRLOG("SRQ statistics memory allocation failed"); 35 : 0 : free(rdma_srq); 36 : 0 : return NULL; 37 : : } 38 : : } 39 : : 40 : 252 : rdma_srq->srq = ibv_create_srq(init_attr->pd, &init_attr->srq_init_attr); 41 [ - + ]: 252 : if (!rdma_srq->srq) { 42 [ # # ]: 0 : if (!init_attr->stats) { 43 : 0 : free(rdma_srq->stats); 44 : : } 45 : 0 : SPDK_ERRLOG("Unable to create SRQ, errno %d (%s)\n", errno, spdk_strerror(errno)); 46 : 0 : free(rdma_srq); 47 : 0 : return NULL; 48 : : } 49 : : 50 : 252 : return rdma_srq; 51 : : } 52 : : 53 : : int 54 : 252 : spdk_rdma_provider_srq_destroy(struct spdk_rdma_provider_srq *rdma_srq) 55 : : { 56 : : int rc; 57 : : 58 [ - + ]: 252 : if (!rdma_srq) { 59 : 0 : return 0; 60 : : } 61 : : 62 [ - + ]: 252 : assert(rdma_srq->srq); 63 : : 64 [ - + ]: 252 : if (rdma_srq->recv_wrs.first != NULL) { 65 : 0 : SPDK_WARNLOG("Destroying RDMA SRQ with queued recv WRs\n"); 66 : : } 67 : : 68 : 252 : rc = ibv_destroy_srq(rdma_srq->srq); 69 [ - + ]: 252 : if (rc) { 70 : 0 : SPDK_ERRLOG("SRQ destroy failed with %d\n", rc); 71 : : } 72 : : 73 [ - + - + ]: 252 : if (!rdma_srq->shared_stats) { 74 : 0 : free(rdma_srq->stats); 75 : : } 76 : : 77 : 252 : free(rdma_srq); 78 : : 79 : 252 : return rc; 80 : : } 81 : : 82 : : static inline bool 83 : 11710738 : rdma_queue_recv_wrs(struct spdk_rdma_provider_recv_wr_list *recv_wrs, struct ibv_recv_wr *first, 84 : : struct spdk_rdma_provider_wr_stats *recv_stats) 85 : : { 86 : : struct ibv_recv_wr *last; 87 : : 88 : 11710738 : recv_stats->num_submitted_wrs++; 89 : 11710738 : last = first; 90 [ - + ]: 11710738 : while (last->next != NULL) { 91 : 0 : last = last->next; 92 : 0 : recv_stats->num_submitted_wrs++; 93 : : } 94 : : 95 [ + + ]: 11710738 : if (recv_wrs->first == NULL) { 96 : 1308389 : recv_wrs->first = first; 97 : 1308389 : recv_wrs->last = last; 98 : 1308389 : return true; 99 : : } else { 100 : 10402349 : recv_wrs->last->next = first; 101 : 10402349 : recv_wrs->last = last; 102 : 10402349 : return false; 103 : : } 104 : : } 105 : : 106 : : bool 107 : 6047866 : spdk_rdma_provider_srq_queue_recv_wrs(struct spdk_rdma_provider_srq *rdma_srq, 108 : : struct ibv_recv_wr *first) 109 : : { 110 [ - + ]: 6047866 : assert(rdma_srq); 111 [ - + ]: 6047866 : assert(first); 112 : : 113 : 6047866 : return rdma_queue_recv_wrs(&rdma_srq->recv_wrs, first, rdma_srq->stats); 114 : : } 115 : : 116 : : int 117 : 496950087 : spdk_rdma_provider_srq_flush_recv_wrs(struct spdk_rdma_provider_srq *rdma_srq, 118 : : struct ibv_recv_wr **bad_wr) 119 : : { 120 : : int rc; 121 : : 122 [ + + ]: 496950087 : if (spdk_unlikely(rdma_srq->recv_wrs.first == NULL)) { 123 : 496364522 : return 0; 124 : : } 125 : : 126 : 585565 : rc = ibv_post_srq_recv(rdma_srq->srq, rdma_srq->recv_wrs.first, bad_wr); 127 : : 128 : 585565 : rdma_srq->recv_wrs.first = NULL; 129 : 585565 : rdma_srq->stats->doorbell_updates++; 130 : : 131 : 585565 : return rc; 132 : : } 133 : : 134 : : bool 135 : 5662872 : spdk_rdma_provider_qp_queue_recv_wrs(struct spdk_rdma_provider_qp *spdk_rdma_qp, 136 : : struct ibv_recv_wr *first) 137 : : { 138 [ - + ]: 5662872 : assert(spdk_rdma_qp); 139 [ - + ]: 5662872 : assert(first); 140 : : 141 : 5662872 : return rdma_queue_recv_wrs(&spdk_rdma_qp->recv_wrs, first, &spdk_rdma_qp->stats->recv); 142 : : } 143 : : 144 : : int 145 : 68820315 : spdk_rdma_provider_qp_flush_recv_wrs(struct spdk_rdma_provider_qp *spdk_rdma_qp, 146 : : struct ibv_recv_wr **bad_wr) 147 : : { 148 : : int rc; 149 : : 150 [ + + ]: 68820315 : if (spdk_unlikely(spdk_rdma_qp->recv_wrs.first == NULL)) { 151 : 68097491 : return 0; 152 : : } 153 : : 154 : 722824 : rc = ibv_post_recv(spdk_rdma_qp->qp, spdk_rdma_qp->recv_wrs.first, bad_wr); 155 : : 156 : 722824 : spdk_rdma_qp->recv_wrs.first = NULL; 157 : 722824 : spdk_rdma_qp->stats->recv.doorbell_updates++; 158 : : 159 : 722824 : return rc; 160 : : }