18a01b4d6SAlexey Marchuk /* SPDX-License-Identifier: BSD-3-Clause 28a01b4d6SAlexey Marchuk * Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 38a01b4d6SAlexey Marchuk */ 48a01b4d6SAlexey Marchuk 58a01b4d6SAlexey Marchuk #ifndef SPDK_UTILS_RDMA_H 68a01b4d6SAlexey Marchuk #define SPDK_UTILS_RDMA_H 78a01b4d6SAlexey Marchuk 88a01b4d6SAlexey Marchuk #ifdef __cplusplus 98a01b4d6SAlexey Marchuk extern "C" { 108a01b4d6SAlexey Marchuk #endif 118a01b4d6SAlexey Marchuk 128a01b4d6SAlexey Marchuk /* Contains hooks definition */ 138a01b4d6SAlexey Marchuk #include "spdk/nvme.h" 148a01b4d6SAlexey Marchuk 158a01b4d6SAlexey Marchuk #include <infiniband/verbs.h> 168a01b4d6SAlexey Marchuk 178a01b4d6SAlexey Marchuk union spdk_rdma_utils_mr { 188a01b4d6SAlexey Marchuk struct ibv_mr *mr; 198a01b4d6SAlexey Marchuk uint64_t key; 208a01b4d6SAlexey Marchuk }; 218a01b4d6SAlexey Marchuk 228a01b4d6SAlexey Marchuk enum SPDK_RDMA_UTILS_TRANSLATION_TYPE { 238a01b4d6SAlexey Marchuk SPDK_RDMA_UTILS_TRANSLATION_MR = 0, 248a01b4d6SAlexey Marchuk SPDK_RDMA_UTILS_TRANSLATION_KEY 258a01b4d6SAlexey Marchuk }; 268a01b4d6SAlexey Marchuk 278a01b4d6SAlexey Marchuk struct spdk_rdma_utils_memory_translation { 288a01b4d6SAlexey Marchuk union spdk_rdma_utils_mr mr_or_key; 298a01b4d6SAlexey Marchuk uint8_t translation_type; 308a01b4d6SAlexey Marchuk }; 318a01b4d6SAlexey Marchuk 328a01b4d6SAlexey Marchuk struct spdk_rdma_utils_mem_map; 338a01b4d6SAlexey Marchuk 348a01b4d6SAlexey Marchuk /** 358a01b4d6SAlexey Marchuk * Create a memory map which is used to register Memory Regions and perform address -> memory 368a01b4d6SAlexey Marchuk * key translations 378a01b4d6SAlexey Marchuk * 388a01b4d6SAlexey Marchuk * \param pd Protection Domain which will be used to create Memory Regions 398a01b4d6SAlexey Marchuk * \param hooks Optional hooks which are used to create Protection Domain or ger RKey 408ffb2c09SAlexey Marchuk * \param access_flags Memory access permissions, bitwise combination of values from \b enum ibv_access_flags 418a01b4d6SAlexey Marchuk * \return Pointer to memory map or NULL on failure 428a01b4d6SAlexey Marchuk */ 438a01b4d6SAlexey Marchuk struct spdk_rdma_utils_mem_map * 448a01b4d6SAlexey Marchuk spdk_rdma_utils_create_mem_map(struct ibv_pd *pd, struct spdk_nvme_rdma_hooks *hooks, 458ffb2c09SAlexey Marchuk uint32_t access_flags); 468a01b4d6SAlexey Marchuk 478a01b4d6SAlexey Marchuk /** 488a01b4d6SAlexey Marchuk * Free previously allocated memory map 498a01b4d6SAlexey Marchuk * 508a01b4d6SAlexey Marchuk * \param map Pointer to memory map to free 518a01b4d6SAlexey Marchuk */ 528a01b4d6SAlexey Marchuk void spdk_rdma_utils_free_mem_map(struct spdk_rdma_utils_mem_map **map); 538a01b4d6SAlexey Marchuk 548a01b4d6SAlexey Marchuk /** 558a01b4d6SAlexey Marchuk * Get a translation for the given address and length. 568a01b4d6SAlexey Marchuk * 578a01b4d6SAlexey Marchuk * Note: the user of this function should use address returned in \b translation structure 588a01b4d6SAlexey Marchuk * 598a01b4d6SAlexey Marchuk * \param map Pointer to translation map 608a01b4d6SAlexey Marchuk * \param address Memory address for translation 618a01b4d6SAlexey Marchuk * \param length Length of the memory address 628a01b4d6SAlexey Marchuk * \param[in,out] translation Pointer to translation result to be filled by this function 638a01b4d6SAlexey Marchuk * \retval -EINVAL if translation is not found 648a01b4d6SAlexey Marchuk * \retval 0 translation succeed 658a01b4d6SAlexey Marchuk */ 668a01b4d6SAlexey Marchuk int spdk_rdma_utils_get_translation(struct spdk_rdma_utils_mem_map *map, void *address, 678a01b4d6SAlexey Marchuk size_t length, struct spdk_rdma_utils_memory_translation *translation); 688a01b4d6SAlexey Marchuk 698a01b4d6SAlexey Marchuk /** 708a01b4d6SAlexey Marchuk * Helper function for retrieving Local Memory Key. Should be applied to a translation 718a01b4d6SAlexey Marchuk * returned by \b spdk_rdma_utils_get_translation 728a01b4d6SAlexey Marchuk * 738a01b4d6SAlexey Marchuk * \param translation Memory translation 748a01b4d6SAlexey Marchuk * \return Local Memory Key 758a01b4d6SAlexey Marchuk */ 768a01b4d6SAlexey Marchuk static inline uint32_t 778a01b4d6SAlexey Marchuk spdk_rdma_utils_memory_translation_get_lkey( 788a01b4d6SAlexey Marchuk struct spdk_rdma_utils_memory_translation *translation) 798a01b4d6SAlexey Marchuk { 808a01b4d6SAlexey Marchuk return translation->translation_type == SPDK_RDMA_UTILS_TRANSLATION_MR ? 818a01b4d6SAlexey Marchuk translation->mr_or_key.mr->lkey : (uint32_t)translation->mr_or_key.key; 828a01b4d6SAlexey Marchuk } 838a01b4d6SAlexey Marchuk 848a01b4d6SAlexey Marchuk /** 858a01b4d6SAlexey Marchuk * Helper function for retrieving Remote Memory Key. Should be applied to a translation 868a01b4d6SAlexey Marchuk * returned by \b spdk_rdma_utils_get_translation 878a01b4d6SAlexey Marchuk * 888a01b4d6SAlexey Marchuk * \param translation Memory translation 898a01b4d6SAlexey Marchuk * \return Remote Memory Key 908a01b4d6SAlexey Marchuk */ 918a01b4d6SAlexey Marchuk static inline uint32_t 928a01b4d6SAlexey Marchuk spdk_rdma_utils_memory_translation_get_rkey( 938a01b4d6SAlexey Marchuk struct spdk_rdma_utils_memory_translation *translation) 948a01b4d6SAlexey Marchuk { 958a01b4d6SAlexey Marchuk return translation->translation_type == SPDK_RDMA_UTILS_TRANSLATION_MR ? 968a01b4d6SAlexey Marchuk translation->mr_or_key.mr->rkey : (uint32_t)translation->mr_or_key.key; 978a01b4d6SAlexey Marchuk } 988a01b4d6SAlexey Marchuk 998a01b4d6SAlexey Marchuk /** 1008a01b4d6SAlexey Marchuk * Get a Protection Domain for an RDMA device context. 1018a01b4d6SAlexey Marchuk * 1028a01b4d6SAlexey Marchuk * \param context RDMA device context 1038a01b4d6SAlexey Marchuk * \return Pointer to the allocated Protection Domain 1048a01b4d6SAlexey Marchuk */ 1058a01b4d6SAlexey Marchuk struct ibv_pd * 1068a01b4d6SAlexey Marchuk spdk_rdma_utils_get_pd(struct ibv_context *context); 1078a01b4d6SAlexey Marchuk 1088a01b4d6SAlexey Marchuk /** 1098a01b4d6SAlexey Marchuk * Return a Protection Domain. 1108a01b4d6SAlexey Marchuk * 1118a01b4d6SAlexey Marchuk * \param pd Pointer to the Protection Domain 1128a01b4d6SAlexey Marchuk */ 1138a01b4d6SAlexey Marchuk void spdk_rdma_utils_put_pd(struct ibv_pd *pd); 1148a01b4d6SAlexey Marchuk 1150a9c0239SAlexey Marchuk /** 1160a9c0239SAlexey Marchuk * Get memory domain for the specified protection domain. 1170a9c0239SAlexey Marchuk * 1180a9c0239SAlexey Marchuk * If memory domain does not exist for the specified protection domain, it will be allocated. 1190a9c0239SAlexey Marchuk * If memory domain already exists, reference will be increased. 1200a9c0239SAlexey Marchuk * 1210a9c0239SAlexey Marchuk * \param pd Protection domain of memory domain 1220a9c0239SAlexey Marchuk * \return Pointer to memory domain or NULL; 1230a9c0239SAlexey Marchuk */ 1240a9c0239SAlexey Marchuk struct spdk_memory_domain *spdk_rdma_utils_get_memory_domain(struct ibv_pd *pd); 1250a9c0239SAlexey Marchuk 1260a9c0239SAlexey Marchuk /** 1270a9c0239SAlexey Marchuk * Release a reference to a memory domain, which will be destroyed when reference becomes 0. 1280a9c0239SAlexey Marchuk * 1290a9c0239SAlexey Marchuk * \param _domain Pointer to memory domain 1300a9c0239SAlexey Marchuk * \return 0 on success, negated errno on failure 1310a9c0239SAlexey Marchuk */ 1320a9c0239SAlexey Marchuk int spdk_rdma_utils_put_memory_domain(struct spdk_memory_domain *_domain); 1330a9c0239SAlexey Marchuk 134*20b14cdcSJim Harris struct rdma_cm_id; 135*20b14cdcSJim Harris /** 136*20b14cdcSJim Harris * Get the NUMA ID for the local interface associated with the given cm_id. 137*20b14cdcSJim Harris * 138*20b14cdcSJim Harris * \param cm_id cm_id 139*20b14cdcSJim Harris * \return NUMA ID 140*20b14cdcSJim Harris */ 141*20b14cdcSJim Harris int32_t spdk_rdma_cm_id_get_numa_id(struct rdma_cm_id *cm_id); 142*20b14cdcSJim Harris 1438a01b4d6SAlexey Marchuk #ifdef __cplusplus 1448a01b4d6SAlexey Marchuk } 1458a01b4d6SAlexey Marchuk #endif 1468a01b4d6SAlexey Marchuk 1478a01b4d6SAlexey Marchuk #endif /* SPDK_RDMA_UTILS_H */ 148