LCOV - code coverage report
Current view: top level - lib/rdma_provider - rdma_provider_verbs.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 0 77 0.0 %
Date: 2024-07-14 21:06:34 Functions: 0 7 0.0 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright (C) 2020 Intel Corporation. All rights reserved.
       3             :  *   Copyright (c) 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/stdinc.h"
      10             : #include "spdk/string.h"
      11             : #include "spdk/likely.h"
      12             : 
      13             : #include "spdk_internal/rdma_provider.h"
      14             : #include "spdk/log.h"
      15             : 
      16             : struct spdk_rdma_provider_qp *
      17           0 : spdk_rdma_provider_qp_create(struct rdma_cm_id *cm_id,
      18             :                              struct spdk_rdma_provider_qp_init_attr *qp_attr)
      19             : {
      20             :         struct spdk_rdma_provider_qp *spdk_rdma_qp;
      21             :         int rc;
      22           0 :         struct ibv_qp_init_attr attr = {
      23           0 :                 .qp_context = qp_attr->qp_context,
      24           0 :                 .send_cq = qp_attr->send_cq,
      25           0 :                 .recv_cq = qp_attr->recv_cq,
      26           0 :                 .srq = qp_attr->srq,
      27             :                 .cap = qp_attr->cap,
      28             :                 .qp_type = IBV_QPT_RC
      29             :         };
      30             : 
      31           0 :         spdk_rdma_qp = calloc(1, sizeof(*spdk_rdma_qp));
      32           0 :         if (!spdk_rdma_qp) {
      33           0 :                 SPDK_ERRLOG("qp memory allocation failed\n");
      34           0 :                 return NULL;
      35             :         }
      36             : 
      37           0 :         if (qp_attr->stats) {
      38           0 :                 spdk_rdma_qp->stats = qp_attr->stats;
      39           0 :                 spdk_rdma_qp->shared_stats = true;
      40             :         } else {
      41           0 :                 spdk_rdma_qp->stats = calloc(1, sizeof(*spdk_rdma_qp->stats));
      42           0 :                 if (!spdk_rdma_qp->stats) {
      43           0 :                         SPDK_ERRLOG("qp statistics memory allocation failed\n");
      44           0 :                         free(spdk_rdma_qp);
      45           0 :                         return NULL;
      46             :                 }
      47             :         }
      48             : 
      49           0 :         rc = rdma_create_qp(cm_id, qp_attr->pd, &attr);
      50           0 :         if (rc) {
      51           0 :                 SPDK_ERRLOG("Failed to create qp, rc %d, errno %s (%d)\n", rc, spdk_strerror(errno), errno);
      52           0 :                 free(spdk_rdma_qp);
      53           0 :                 return NULL;
      54             :         }
      55             : 
      56           0 :         qp_attr->cap = attr.cap;
      57           0 :         spdk_rdma_qp->qp = cm_id->qp;
      58           0 :         spdk_rdma_qp->cm_id = cm_id;
      59             : 
      60           0 :         return spdk_rdma_qp;
      61             : }
      62             : 
      63             : int
      64           0 : spdk_rdma_provider_qp_accept(struct spdk_rdma_provider_qp *spdk_rdma_qp,
      65             :                              struct rdma_conn_param *conn_param)
      66             : {
      67           0 :         assert(spdk_rdma_qp != NULL);
      68           0 :         assert(spdk_rdma_qp->cm_id != NULL);
      69             : 
      70           0 :         return rdma_accept(spdk_rdma_qp->cm_id, conn_param);
      71             : }
      72             : 
      73             : int
      74           0 : spdk_rdma_provider_qp_complete_connect(struct spdk_rdma_provider_qp *spdk_rdma_qp)
      75             : {
      76             :         /* Nothing to be done for Verbs */
      77           0 :         return 0;
      78             : }
      79             : 
      80             : void
      81           0 : spdk_rdma_provider_qp_destroy(struct spdk_rdma_provider_qp *spdk_rdma_qp)
      82             : {
      83           0 :         assert(spdk_rdma_qp != NULL);
      84             : 
      85           0 :         if (spdk_rdma_qp->send_wrs.first != NULL) {
      86           0 :                 SPDK_WARNLOG("Destroying qpair with queued Work Requests\n");
      87             :         }
      88             : 
      89           0 :         if (spdk_rdma_qp->qp) {
      90           0 :                 rdma_destroy_qp(spdk_rdma_qp->cm_id);
      91             :         }
      92             : 
      93           0 :         if (!spdk_rdma_qp->shared_stats) {
      94           0 :                 free(spdk_rdma_qp->stats);
      95             :         }
      96             : 
      97           0 :         free(spdk_rdma_qp);
      98           0 : }
      99             : 
     100             : int
     101           0 : spdk_rdma_provider_qp_disconnect(struct spdk_rdma_provider_qp *spdk_rdma_qp)
     102             : {
     103           0 :         int rc = 0;
     104             : 
     105           0 :         assert(spdk_rdma_qp != NULL);
     106             : 
     107           0 :         if (spdk_rdma_qp->cm_id) {
     108           0 :                 rc = rdma_disconnect(spdk_rdma_qp->cm_id);
     109           0 :                 if (rc) {
     110           0 :                         if (errno == EINVAL && spdk_rdma_qp->qp->context->device->transport_type == IBV_TRANSPORT_IWARP) {
     111             :                                 /* rdma_disconnect may return an error and set errno to EINVAL in case of iWARP.
     112             :                                  * This behaviour is expected since iWARP handles disconnect event other than IB and
     113             :                                  * qpair is already in error state when we call rdma_disconnect */
     114           0 :                                 return 0;
     115             :                         }
     116           0 :                         SPDK_ERRLOG("rdma_disconnect failed, errno %s (%d)\n", spdk_strerror(errno), errno);
     117             :                 }
     118             :         }
     119             : 
     120           0 :         return rc;
     121             : }
     122             : 
     123             : bool
     124           0 : spdk_rdma_provider_qp_queue_send_wrs(struct spdk_rdma_provider_qp *spdk_rdma_qp,
     125             :                                      struct ibv_send_wr *first)
     126             : {
     127             :         struct ibv_send_wr *last;
     128             : 
     129           0 :         assert(spdk_rdma_qp);
     130           0 :         assert(first);
     131             : 
     132           0 :         spdk_rdma_qp->stats->send.num_submitted_wrs++;
     133           0 :         last = first;
     134           0 :         while (last->next != NULL) {
     135           0 :                 last = last->next;
     136           0 :                 spdk_rdma_qp->stats->send.num_submitted_wrs++;
     137             :         }
     138             : 
     139           0 :         if (spdk_rdma_qp->send_wrs.first == NULL) {
     140           0 :                 spdk_rdma_qp->send_wrs.first = first;
     141           0 :                 spdk_rdma_qp->send_wrs.last = last;
     142           0 :                 return true;
     143             :         } else {
     144           0 :                 spdk_rdma_qp->send_wrs.last->next = first;
     145           0 :                 spdk_rdma_qp->send_wrs.last = last;
     146           0 :                 return false;
     147             :         }
     148             : }
     149             : 
     150             : int
     151           0 : spdk_rdma_provider_qp_flush_send_wrs(struct spdk_rdma_provider_qp *spdk_rdma_qp,
     152             :                                      struct ibv_send_wr **bad_wr)
     153             : {
     154             :         int rc;
     155             : 
     156           0 :         assert(spdk_rdma_qp);
     157           0 :         assert(bad_wr);
     158             : 
     159           0 :         if (spdk_unlikely(!spdk_rdma_qp->send_wrs.first)) {
     160           0 :                 return 0;
     161             :         }
     162             : 
     163           0 :         rc = ibv_post_send(spdk_rdma_qp->qp, spdk_rdma_qp->send_wrs.first, bad_wr);
     164             : 
     165           0 :         spdk_rdma_qp->send_wrs.first = NULL;
     166           0 :         spdk_rdma_qp->stats->send.doorbell_updates++;
     167             : 
     168           0 :         return rc;
     169             : }

Generated by: LCOV version 1.15