xref: /dpdk/drivers/common/mlx5/linux/mlx5_common_verbs.c (revision 5fbc75ace1f83b3616a3614fdcb27ca70db063c0)
158a17853SOphir Munk /* SPDX-License-Identifier: BSD-3-Clause
258a17853SOphir Munk  * Copyright 2020 Mellanox Technologies, Ltd
358a17853SOphir Munk  */
458a17853SOphir Munk 
558a17853SOphir Munk #include <stddef.h>
658a17853SOphir Munk #include <errno.h>
758a17853SOphir Munk #include <string.h>
858a17853SOphir Munk #include <stdint.h>
958a17853SOphir Munk #include <unistd.h>
1058a17853SOphir Munk #include <sys/mman.h>
1158a17853SOphir Munk #include <inttypes.h>
1258a17853SOphir Munk 
13ad435d32SXueming Li #include <rte_errno.h>
14887183efSMichael Baum #include <rte_eal_paging.h>
15ad435d32SXueming Li 
16ad435d32SXueming Li #include "mlx5_common_utils.h"
17ad435d32SXueming Li #include "mlx5_common_log.h"
1858a17853SOphir Munk #include "mlx5_autoconf.h"
1958a17853SOphir Munk #include <mlx5_glue.h>
20887183efSMichael Baum #include <mlx5_malloc.h>
2158a17853SOphir Munk #include <mlx5_common.h>
2258a17853SOphir Munk #include <mlx5_common_mr.h>
2358a17853SOphir Munk 
2458a17853SOphir Munk /**
25887183efSMichael Baum  * Verbs callback to allocate a memory. This function should allocate the space
26887183efSMichael Baum  * according to the size provided residing inside a huge page.
27887183efSMichael Baum  * Please note that all allocation must respect the alignment from libmlx5
28887183efSMichael Baum  * (i.e. currently rte_mem_page_size()).
29887183efSMichael Baum  *
30887183efSMichael Baum  * @param[in] size
31887183efSMichael Baum  *   The size in bytes of the memory to allocate.
32887183efSMichael Baum  * @param[in] data
33887183efSMichael Baum  *   A pointer to the callback data.
34887183efSMichael Baum  *
35887183efSMichael Baum  * @return
36887183efSMichael Baum  *   Allocated buffer, NULL otherwise and rte_errno is set.
37887183efSMichael Baum  */
38887183efSMichael Baum static void *
mlx5_alloc_verbs_buf(size_t size,void * data)39887183efSMichael Baum mlx5_alloc_verbs_buf(size_t size, void *data)
40887183efSMichael Baum {
41887183efSMichael Baum 	struct rte_device *dev = data;
42887183efSMichael Baum 	void *ret;
43887183efSMichael Baum 	size_t alignment = rte_mem_page_size();
44887183efSMichael Baum 	if (alignment == (size_t)-1) {
45887183efSMichael Baum 		DRV_LOG(ERR, "Failed to get mem page size");
46887183efSMichael Baum 		rte_errno = ENOMEM;
47887183efSMichael Baum 		return NULL;
48887183efSMichael Baum 	}
49887183efSMichael Baum 
50887183efSMichael Baum 	MLX5_ASSERT(data != NULL);
51887183efSMichael Baum 	ret = mlx5_malloc(0, size, alignment, dev->numa_node);
52887183efSMichael Baum 	if (!ret && size)
53887183efSMichael Baum 		rte_errno = ENOMEM;
54887183efSMichael Baum 	return ret;
55887183efSMichael Baum }
56887183efSMichael Baum 
57887183efSMichael Baum /**
58887183efSMichael Baum  * Verbs callback to free a memory.
59887183efSMichael Baum  *
60887183efSMichael Baum  * @param[in] ptr
61887183efSMichael Baum  *   A pointer to the memory to free.
62887183efSMichael Baum  * @param[in] data
63887183efSMichael Baum  *   A pointer to the callback data.
64887183efSMichael Baum  */
65887183efSMichael Baum static void
mlx5_free_verbs_buf(void * ptr,void * data __rte_unused)66887183efSMichael Baum mlx5_free_verbs_buf(void *ptr, void *data __rte_unused)
67887183efSMichael Baum {
68887183efSMichael Baum 	MLX5_ASSERT(data != NULL);
69887183efSMichael Baum 	mlx5_free(ptr);
70887183efSMichael Baum }
71887183efSMichael Baum 
72887183efSMichael Baum /**
73887183efSMichael Baum  * Hint libmlx5 to use PMD allocator for data plane resources.
74887183efSMichael Baum  *
75887183efSMichael Baum  * @param dev
76887183efSMichael Baum  *   Pointer to the generic device.
77887183efSMichael Baum  */
78887183efSMichael Baum void
mlx5_set_context_attr(struct rte_device * dev,struct ibv_context * ctx)79887183efSMichael Baum mlx5_set_context_attr(struct rte_device *dev, struct ibv_context *ctx)
80887183efSMichael Baum {
81887183efSMichael Baum 	struct mlx5dv_ctx_allocators allocator = {
82887183efSMichael Baum 		.alloc = &mlx5_alloc_verbs_buf,
83887183efSMichael Baum 		.free = &mlx5_free_verbs_buf,
84887183efSMichael Baum 		.data = dev,
85887183efSMichael Baum 	};
86887183efSMichael Baum 
87887183efSMichael Baum 	/* Hint libmlx5 to use PMD allocator for data plane resources */
88887183efSMichael Baum 	mlx5_glue->dv_set_context_attr(ctx, MLX5DV_CTX_ATTR_BUF_ALLOCATORS,
89887183efSMichael Baum 				       (void *)((uintptr_t)&allocator));
90887183efSMichael Baum }
91887183efSMichael Baum 
92887183efSMichael Baum /**
9358a17853SOphir Munk  * Register mr. Given protection domain pointer, pointer to addr and length
9458a17853SOphir Munk  * register the memory region.
9558a17853SOphir Munk  *
9658a17853SOphir Munk  * @param[in] pd
9758a17853SOphir Munk  *   Pointer to protection domain context.
9858a17853SOphir Munk  * @param[in] addr
9958a17853SOphir Munk  *   Pointer to memory start address.
10058a17853SOphir Munk  * @param[in] length
10158a17853SOphir Munk  *   Length of the memory to register.
10258a17853SOphir Munk  * @param[out] pmd_mr
10358a17853SOphir Munk  *   pmd_mr struct set with lkey, address, length and pointer to mr object
10458a17853SOphir Munk  *
10558a17853SOphir Munk  * @return
10658a17853SOphir Munk  *   0 on successful registration, -1 otherwise
10758a17853SOphir Munk  */
10858a17853SOphir Munk int
mlx5_common_verbs_reg_mr(void * pd,void * addr,size_t length,struct mlx5_pmd_mr * pmd_mr)10958a17853SOphir Munk mlx5_common_verbs_reg_mr(void *pd, void *addr, size_t length,
11058a17853SOphir Munk 			 struct mlx5_pmd_mr *pmd_mr)
11158a17853SOphir Munk {
11258a17853SOphir Munk 	struct ibv_mr *ibv_mr;
11358a17853SOphir Munk 
11458a17853SOphir Munk 	ibv_mr = mlx5_glue->reg_mr(pd, addr, length,
11558a17853SOphir Munk 				   IBV_ACCESS_LOCAL_WRITE |
11658a17853SOphir Munk 				   (haswell_broadwell_cpu ? 0 :
11758a17853SOphir Munk 				   IBV_ACCESS_RELAXED_ORDERING));
11858a17853SOphir Munk 	if (!ibv_mr)
11958a17853SOphir Munk 		return -1;
12058a17853SOphir Munk 
12158a17853SOphir Munk 	*pmd_mr = (struct mlx5_pmd_mr){
12258a17853SOphir Munk 		.lkey = ibv_mr->lkey,
12358a17853SOphir Munk 		.addr = ibv_mr->addr,
12458a17853SOphir Munk 		.len = ibv_mr->length,
12558a17853SOphir Munk 		.obj = (void *)ibv_mr,
12658a17853SOphir Munk 	};
12758a17853SOphir Munk 	return 0;
12858a17853SOphir Munk }
12958a17853SOphir Munk 
13058a17853SOphir Munk /**
13158a17853SOphir Munk  * Deregister mr. Given the mlx5 pmd MR - deregister the MR
13258a17853SOphir Munk  *
13358a17853SOphir Munk  * @param[in] pmd_mr
13458a17853SOphir Munk  *   pmd_mr struct set with lkey, address, length and pointer to mr object
13558a17853SOphir Munk  *
13658a17853SOphir Munk  */
13758a17853SOphir Munk void
mlx5_common_verbs_dereg_mr(struct mlx5_pmd_mr * pmd_mr)13858a17853SOphir Munk mlx5_common_verbs_dereg_mr(struct mlx5_pmd_mr *pmd_mr)
13958a17853SOphir Munk {
14058a17853SOphir Munk 	if (pmd_mr && pmd_mr->obj != NULL) {
14158a17853SOphir Munk 		claim_zero(mlx5_glue->dereg_mr(pmd_mr->obj));
14258a17853SOphir Munk 		memset(pmd_mr, 0, sizeof(*pmd_mr));
14358a17853SOphir Munk 	}
14458a17853SOphir Munk }
145*5fbc75acSMichael Baum 
146*5fbc75acSMichael Baum /**
147*5fbc75acSMichael Baum  * Set the reg_mr and dereg_mr callbacks.
148*5fbc75acSMichael Baum  *
149*5fbc75acSMichael Baum  * @param[out] reg_mr_cb
150*5fbc75acSMichael Baum  *   Pointer to reg_mr func
151*5fbc75acSMichael Baum  * @param[out] dereg_mr_cb
152*5fbc75acSMichael Baum  *   Pointer to dereg_mr func
153*5fbc75acSMichael Baum  */
154*5fbc75acSMichael Baum void
mlx5_os_set_reg_mr_cb(mlx5_reg_mr_t * reg_mr_cb,mlx5_dereg_mr_t * dereg_mr_cb)155*5fbc75acSMichael Baum mlx5_os_set_reg_mr_cb(mlx5_reg_mr_t *reg_mr_cb, mlx5_dereg_mr_t *dereg_mr_cb)
156*5fbc75acSMichael Baum {
157*5fbc75acSMichael Baum 	*reg_mr_cb = mlx5_common_verbs_reg_mr;
158*5fbc75acSMichael Baum 	*dereg_mr_cb = mlx5_common_verbs_dereg_mr;
159*5fbc75acSMichael Baum }
160