1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 */ 4 5 #ifndef SPDK_UTILS_RDMA_H 6 #define SPDK_UTILS_RDMA_H 7 8 #ifdef __cplusplus 9 extern "C" { 10 #endif 11 12 /* Contains hooks definition */ 13 #include "spdk/nvme.h" 14 15 #include <infiniband/verbs.h> 16 17 union spdk_rdma_utils_mr { 18 struct ibv_mr *mr; 19 uint64_t key; 20 }; 21 22 enum SPDK_RDMA_UTILS_TRANSLATION_TYPE { 23 SPDK_RDMA_UTILS_TRANSLATION_MR = 0, 24 SPDK_RDMA_UTILS_TRANSLATION_KEY 25 }; 26 27 struct spdk_rdma_utils_memory_translation { 28 union spdk_rdma_utils_mr mr_or_key; 29 uint8_t translation_type; 30 }; 31 32 struct spdk_rdma_utils_mem_map; 33 34 /** 35 * Create a memory map which is used to register Memory Regions and perform address -> memory 36 * key translations 37 * 38 * \param pd Protection Domain which will be used to create Memory Regions 39 * \param hooks Optional hooks which are used to create Protection Domain or ger RKey 40 * \param access_flags Memory access permissions, bitwise combination of values from \b enum ibv_access_flags 41 * \return Pointer to memory map or NULL on failure 42 */ 43 struct spdk_rdma_utils_mem_map * 44 spdk_rdma_utils_create_mem_map(struct ibv_pd *pd, struct spdk_nvme_rdma_hooks *hooks, 45 uint32_t access_flags); 46 47 /** 48 * Free previously allocated memory map 49 * 50 * \param map Pointer to memory map to free 51 */ 52 void spdk_rdma_utils_free_mem_map(struct spdk_rdma_utils_mem_map **map); 53 54 /** 55 * Get a translation for the given address and length. 56 * 57 * Note: the user of this function should use address returned in \b translation structure 58 * 59 * \param map Pointer to translation map 60 * \param address Memory address for translation 61 * \param length Length of the memory address 62 * \param[in,out] translation Pointer to translation result to be filled by this function 63 * \retval -EINVAL if translation is not found 64 * \retval 0 translation succeed 65 */ 66 int spdk_rdma_utils_get_translation(struct spdk_rdma_utils_mem_map *map, void *address, 67 size_t length, struct spdk_rdma_utils_memory_translation *translation); 68 69 /** 70 * Helper function for retrieving Local Memory Key. Should be applied to a translation 71 * returned by \b spdk_rdma_utils_get_translation 72 * 73 * \param translation Memory translation 74 * \return Local Memory Key 75 */ 76 static inline uint32_t 77 spdk_rdma_utils_memory_translation_get_lkey( 78 struct spdk_rdma_utils_memory_translation *translation) 79 { 80 return translation->translation_type == SPDK_RDMA_UTILS_TRANSLATION_MR ? 81 translation->mr_or_key.mr->lkey : (uint32_t)translation->mr_or_key.key; 82 } 83 84 /** 85 * Helper function for retrieving Remote Memory Key. Should be applied to a translation 86 * returned by \b spdk_rdma_utils_get_translation 87 * 88 * \param translation Memory translation 89 * \return Remote Memory Key 90 */ 91 static inline uint32_t 92 spdk_rdma_utils_memory_translation_get_rkey( 93 struct spdk_rdma_utils_memory_translation *translation) 94 { 95 return translation->translation_type == SPDK_RDMA_UTILS_TRANSLATION_MR ? 96 translation->mr_or_key.mr->rkey : (uint32_t)translation->mr_or_key.key; 97 } 98 99 /** 100 * Get a Protection Domain for an RDMA device context. 101 * 102 * \param context RDMA device context 103 * \return Pointer to the allocated Protection Domain 104 */ 105 struct ibv_pd * 106 spdk_rdma_utils_get_pd(struct ibv_context *context); 107 108 /** 109 * Return a Protection Domain. 110 * 111 * \param pd Pointer to the Protection Domain 112 */ 113 void spdk_rdma_utils_put_pd(struct ibv_pd *pd); 114 115 /** 116 * Get memory domain for the specified protection domain. 117 * 118 * If memory domain does not exist for the specified protection domain, it will be allocated. 119 * If memory domain already exists, reference will be increased. 120 * 121 * \param pd Protection domain of memory domain 122 * \return Pointer to memory domain or NULL; 123 */ 124 struct spdk_memory_domain *spdk_rdma_utils_get_memory_domain(struct ibv_pd *pd); 125 126 /** 127 * Release a reference to a memory domain, which will be destroyed when reference becomes 0. 128 * 129 * \param _domain Pointer to memory domain 130 * \return 0 on success, negated errno on failure 131 */ 132 int spdk_rdma_utils_put_memory_domain(struct spdk_memory_domain *_domain); 133 134 #ifdef __cplusplus 135 } 136 #endif 137 138 #endif /* SPDK_RDMA_UTILS_H */ 139