xref: /spdk/include/spdk_internal/rdma_utils.h (revision 8afdeef3becfe9409cc9e7372bd0bc10e8b7d46d)
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