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 enum spdk_rdma_utils_memory_map_role { 33 SPDK_RDMA_UTILS_MEMORY_MAP_ROLE_TARGET, 34 SPDK_RDMA_UTILS_MEMORY_MAP_ROLE_INITIATOR 35 }; 36 37 struct spdk_rdma_utils_mem_map; 38 39 /** 40 * Create a memory map which is used to register Memory Regions and perform address -> memory 41 * key translations 42 * 43 * \param pd Protection Domain which will be used to create Memory Regions 44 * \param hooks Optional hooks which are used to create Protection Domain or ger RKey 45 * \param role Specifies whether this map is used by RDMA target or initiator, determines access flags of registered MRs 46 * \return Pointer to memory map or NULL on failure 47 */ 48 struct spdk_rdma_utils_mem_map * 49 spdk_rdma_utils_create_mem_map(struct ibv_pd *pd, struct spdk_nvme_rdma_hooks *hooks, 50 enum spdk_rdma_utils_memory_map_role role); 51 52 /** 53 * Free previously allocated memory map 54 * 55 * \param map Pointer to memory map to free 56 */ 57 void spdk_rdma_utils_free_mem_map(struct spdk_rdma_utils_mem_map **map); 58 59 /** 60 * Get a translation for the given address and length. 61 * 62 * Note: the user of this function should use address returned in \b translation structure 63 * 64 * \param map Pointer to translation map 65 * \param address Memory address for translation 66 * \param length Length of the memory address 67 * \param[in,out] translation Pointer to translation result to be filled by this function 68 * \retval -EINVAL if translation is not found 69 * \retval 0 translation succeed 70 */ 71 int spdk_rdma_utils_get_translation(struct spdk_rdma_utils_mem_map *map, void *address, 72 size_t length, struct spdk_rdma_utils_memory_translation *translation); 73 74 /** 75 * Helper function for retrieving Local Memory Key. Should be applied to a translation 76 * returned by \b spdk_rdma_utils_get_translation 77 * 78 * \param translation Memory translation 79 * \return Local Memory Key 80 */ 81 static inline uint32_t 82 spdk_rdma_utils_memory_translation_get_lkey( 83 struct spdk_rdma_utils_memory_translation *translation) 84 { 85 return translation->translation_type == SPDK_RDMA_UTILS_TRANSLATION_MR ? 86 translation->mr_or_key.mr->lkey : (uint32_t)translation->mr_or_key.key; 87 } 88 89 /** 90 * Helper function for retrieving Remote Memory Key. Should be applied to a translation 91 * returned by \b spdk_rdma_utils_get_translation 92 * 93 * \param translation Memory translation 94 * \return Remote Memory Key 95 */ 96 static inline uint32_t 97 spdk_rdma_utils_memory_translation_get_rkey( 98 struct spdk_rdma_utils_memory_translation *translation) 99 { 100 return translation->translation_type == SPDK_RDMA_UTILS_TRANSLATION_MR ? 101 translation->mr_or_key.mr->rkey : (uint32_t)translation->mr_or_key.key; 102 } 103 104 /** 105 * Get a Protection Domain for an RDMA device context. 106 * 107 * \param context RDMA device context 108 * \return Pointer to the allocated Protection Domain 109 */ 110 struct ibv_pd * 111 spdk_rdma_utils_get_pd(struct ibv_context *context); 112 113 /** 114 * Return a Protection Domain. 115 * 116 * \param pd Pointer to the Protection Domain 117 */ 118 void spdk_rdma_utils_put_pd(struct ibv_pd *pd); 119 120 #ifdef __cplusplus 121 } 122 #endif 123 124 #endif /* SPDK_RDMA_UTILS_H */ 125