Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2020 Mellanox Technologies, Ltd
3 : : */
4 : :
5 : : #include <stddef.h>
6 : : #include <errno.h>
7 : : #include <string.h>
8 : : #include <stdint.h>
9 : : #include <unistd.h>
10 : : #include <sys/mman.h>
11 : : #include <inttypes.h>
12 : :
13 : : #include <rte_errno.h>
14 : : #include <rte_eal_paging.h>
15 : :
16 : : #include "mlx5_common_utils.h"
17 : : #include "mlx5_common_log.h"
18 : : #include "mlx5_autoconf.h"
19 : : #include <mlx5_glue.h>
20 : : #include <mlx5_malloc.h>
21 : : #include <mlx5_common.h>
22 : : #include <mlx5_common_mr.h>
23 : :
24 : : /**
25 : : * Verbs callback to allocate a memory. This function should allocate the space
26 : : * according to the size provided residing inside a huge page.
27 : : * Please note that all allocation must respect the alignment from libmlx5
28 : : * (i.e. currently rte_mem_page_size()).
29 : : *
30 : : * @param[in] size
31 : : * The size in bytes of the memory to allocate.
32 : : * @param[in] data
33 : : * A pointer to the callback data.
34 : : *
35 : : * @return
36 : : * Allocated buffer, NULL otherwise and rte_errno is set.
37 : : */
38 : : static void *
39 : 0 : mlx5_alloc_verbs_buf(size_t size, void *data)
40 : : {
41 : : struct rte_device *dev = data;
42 : : void *ret;
43 : 0 : size_t alignment = rte_mem_page_size();
44 [ # # ]: 0 : if (alignment == (size_t)-1) {
45 : 0 : DRV_LOG(ERR, "Failed to get mem page size");
46 : 0 : rte_errno = ENOMEM;
47 : 0 : return NULL;
48 : : }
49 : :
50 : : MLX5_ASSERT(data != NULL);
51 : 0 : ret = mlx5_malloc(0, size, alignment, dev->numa_node);
52 [ # # ]: 0 : if (!ret && size)
53 : 0 : rte_errno = ENOMEM;
54 : : return ret;
55 : : }
56 : :
57 : : /**
58 : : * Verbs callback to free a memory.
59 : : *
60 : : * @param[in] ptr
61 : : * A pointer to the memory to free.
62 : : * @param[in] data
63 : : * A pointer to the callback data.
64 : : */
65 : : static void
66 : 0 : mlx5_free_verbs_buf(void *ptr, void *data __rte_unused)
67 : : {
68 : : MLX5_ASSERT(data != NULL);
69 : 0 : mlx5_free(ptr);
70 : 0 : }
71 : :
72 : : /**
73 : : * Hint libmlx5 to use PMD allocator for data plane resources.
74 : : *
75 : : * @param dev
76 : : * Pointer to the generic device.
77 : : */
78 : : void
79 : 0 : mlx5_set_context_attr(struct rte_device *dev, struct ibv_context *ctx)
80 : : {
81 : 0 : struct mlx5dv_ctx_allocators allocator = {
82 : : .alloc = &mlx5_alloc_verbs_buf,
83 : : .free = &mlx5_free_verbs_buf,
84 : : .data = dev,
85 : : };
86 : :
87 : : /* Hint libmlx5 to use PMD allocator for data plane resources */
88 : 0 : mlx5_glue->dv_set_context_attr(ctx, MLX5DV_CTX_ATTR_BUF_ALLOCATORS,
89 : : (void *)((uintptr_t)&allocator));
90 : 0 : }
91 : :
92 : : /**
93 : : * Register mr. Given protection domain pointer, pointer to addr and length
94 : : * register the memory region.
95 : : *
96 : : * @param[in] pd
97 : : * Pointer to protection domain context.
98 : : * @param[in] addr
99 : : * Pointer to memory start address.
100 : : * @param[in] length
101 : : * Length of the memory to register.
102 : : * @param[out] pmd_mr
103 : : * pmd_mr struct set with lkey, address, length and pointer to mr object
104 : : *
105 : : * @return
106 : : * 0 on successful registration, -1 otherwise
107 : : */
108 : : int
109 : 0 : mlx5_common_verbs_reg_mr(void *pd, void *addr, size_t length,
110 : : struct mlx5_pmd_mr *pmd_mr)
111 : : {
112 : : struct ibv_mr *ibv_mr;
113 : :
114 : 0 : ibv_mr = mlx5_glue->reg_mr(pd, addr, length,
115 : : IBV_ACCESS_LOCAL_WRITE |
116 [ # # ]: 0 : (haswell_broadwell_cpu ? 0 :
117 : : IBV_ACCESS_RELAXED_ORDERING));
118 [ # # ]: 0 : if (!ibv_mr)
119 : : return -1;
120 : :
121 : 0 : *pmd_mr = (struct mlx5_pmd_mr){
122 : 0 : .lkey = ibv_mr->lkey,
123 : 0 : .addr = ibv_mr->addr,
124 : 0 : .len = ibv_mr->length,
125 : : .obj = (void *)ibv_mr,
126 : : };
127 : 0 : return 0;
128 : : }
129 : :
130 : : /**
131 : : * Deregister mr. Given the mlx5 pmd MR - deregister the MR
132 : : *
133 : : * @param[in] pmd_mr
134 : : * pmd_mr struct set with lkey, address, length and pointer to mr object
135 : : *
136 : : */
137 : : void
138 : 0 : mlx5_common_verbs_dereg_mr(struct mlx5_pmd_mr *pmd_mr)
139 : : {
140 [ # # # # ]: 0 : if (pmd_mr && pmd_mr->obj != NULL) {
141 : 0 : claim_zero(mlx5_glue->dereg_mr(pmd_mr->obj));
142 : : memset(pmd_mr, 0, sizeof(*pmd_mr));
143 : : }
144 : 0 : }
145 : :
146 : : /**
147 : : * Set the reg_mr and dereg_mr callbacks.
148 : : *
149 : : * @param[out] reg_mr_cb
150 : : * Pointer to reg_mr func
151 : : * @param[out] dereg_mr_cb
152 : : * Pointer to dereg_mr func
153 : : */
154 : : void
155 : 0 : mlx5_os_set_reg_mr_cb(mlx5_reg_mr_t *reg_mr_cb, mlx5_dereg_mr_t *dereg_mr_cb)
156 : : {
157 : 0 : *reg_mr_cb = mlx5_common_verbs_reg_mr;
158 : 0 : *dereg_mr_cb = mlx5_common_verbs_dereg_mr;
159 : 0 : }
|