Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2016 Intel Corporation.
3 : : * Copyright(c) 2016 6WIND S.A.
4 : : */
5 : :
6 : : #include <stdio.h>
7 : : #include <string.h>
8 : :
9 : : #include <rte_string_fns.h>
10 : : #include <rte_mempool.h>
11 : : #include <rte_errno.h>
12 : : #include <dev_driver.h>
13 : :
14 : : #include "mempool_trace.h"
15 : :
16 : : /* indirect jump table to support external memory pools. */
17 : : struct rte_mempool_ops_table rte_mempool_ops_table = {
18 : : .sl = RTE_SPINLOCK_INITIALIZER,
19 : : .num_ops = 0
20 : : };
21 : :
22 : : /* add a new ops struct in rte_mempool_ops_table, return its index. */
23 : : int
24 : 3780 : rte_mempool_register_ops(const struct rte_mempool_ops *h)
25 : : {
26 : : struct rte_mempool_ops *ops;
27 : : int16_t ops_index;
28 : :
29 : : rte_spinlock_lock(&rte_mempool_ops_table.sl);
30 : :
31 [ - + ]: 3780 : if (rte_mempool_ops_table.num_ops >=
32 : : RTE_MEMPOOL_MAX_OPS_IDX) {
33 : : rte_spinlock_unlock(&rte_mempool_ops_table.sl);
34 : 0 : RTE_MEMPOOL_LOG(ERR,
35 : : "Maximum number of mempool ops structs exceeded");
36 : 0 : return -ENOSPC;
37 : : }
38 : :
39 [ + - + - ]: 3780 : if (h->alloc == NULL || h->enqueue == NULL ||
40 [ + - - + ]: 3780 : h->dequeue == NULL || h->get_count == NULL) {
41 : : rte_spinlock_unlock(&rte_mempool_ops_table.sl);
42 : 0 : RTE_MEMPOOL_LOG(ERR,
43 : : "Missing callback while registering mempool ops");
44 : 0 : return -EINVAL;
45 : : }
46 : :
47 [ - + ]: 3780 : if (strlen(h->name) >= sizeof(ops->name) - 1) {
48 : : rte_spinlock_unlock(&rte_mempool_ops_table.sl);
49 : 0 : RTE_MEMPOOL_LOG(DEBUG, "%s(): mempool_ops <%s>: name too long",
50 : : __func__, h->name);
51 : 0 : rte_errno = EEXIST;
52 : 0 : return -EEXIST;
53 : : }
54 : :
55 : 3780 : ops_index = rte_mempool_ops_table.num_ops++;
56 : 3780 : ops = &rte_mempool_ops_table.ops[ops_index];
57 : 3780 : strlcpy(ops->name, h->name, sizeof(ops->name));
58 : 3780 : ops->alloc = h->alloc;
59 : 3780 : ops->free = h->free;
60 : 3780 : ops->enqueue = h->enqueue;
61 : 3780 : ops->dequeue = h->dequeue;
62 : 3780 : ops->get_count = h->get_count;
63 : 3780 : ops->calc_mem_size = h->calc_mem_size;
64 : 3780 : ops->populate = h->populate;
65 : 3780 : ops->get_info = h->get_info;
66 : 3780 : ops->dequeue_contig_blocks = h->dequeue_contig_blocks;
67 : :
68 : : rte_spinlock_unlock(&rte_mempool_ops_table.sl);
69 : :
70 : 3780 : return ops_index;
71 : : }
72 : :
73 : : /* wrapper to allocate an external mempool's private (pool) data. */
74 : : int
75 [ - + ]: 110 : rte_mempool_ops_alloc(struct rte_mempool *mp)
76 : : {
77 : : struct rte_mempool_ops *ops;
78 : :
79 : 110 : rte_mempool_trace_ops_alloc(mp);
80 [ - + ]: 110 : ops = rte_mempool_get_ops(mp->ops_index);
81 : 110 : return ops->alloc(mp);
82 : : }
83 : :
84 : : /* wrapper to free an external pool ops. */
85 : : void
86 [ - + ]: 105 : rte_mempool_ops_free(struct rte_mempool *mp)
87 : : {
88 : : struct rte_mempool_ops *ops;
89 : :
90 : 105 : rte_mempool_trace_ops_free(mp);
91 [ - + ]: 105 : ops = rte_mempool_get_ops(mp->ops_index);
92 [ + - ]: 105 : if (ops->free == NULL)
93 : : return;
94 : 105 : ops->free(mp);
95 : : }
96 : :
97 : : /* wrapper to get available objects in an external mempool. */
98 : : unsigned int
99 : 650 : rte_mempool_ops_get_count(const struct rte_mempool *mp)
100 : : {
101 : : struct rte_mempool_ops *ops;
102 : :
103 [ - + ]: 650 : ops = rte_mempool_get_ops(mp->ops_index);
104 : 650 : return ops->get_count(mp);
105 : : }
106 : :
107 : : /* wrapper to calculate the memory size required to store given number
108 : : * of objects
109 : : */
110 : : ssize_t
111 : 111 : rte_mempool_ops_calc_mem_size(const struct rte_mempool *mp,
112 : : uint32_t obj_num, uint32_t pg_shift,
113 : : size_t *min_chunk_size, size_t *align)
114 : : {
115 : : struct rte_mempool_ops *ops;
116 : :
117 [ - + ]: 111 : ops = rte_mempool_get_ops(mp->ops_index);
118 : :
119 [ + - ]: 111 : if (ops->calc_mem_size == NULL)
120 : 111 : return rte_mempool_op_calc_mem_size_default(mp, obj_num,
121 : : pg_shift, min_chunk_size, align);
122 : :
123 : 0 : return ops->calc_mem_size(mp, obj_num, pg_shift, min_chunk_size, align);
124 : : }
125 : :
126 : : /* wrapper to populate memory pool objects using provided memory chunk */
127 : : int
128 : 1197 : rte_mempool_ops_populate(struct rte_mempool *mp, unsigned int max_objs,
129 : : void *vaddr, rte_iova_t iova, size_t len,
130 : : rte_mempool_populate_obj_cb_t *obj_cb,
131 : : void *obj_cb_arg)
132 : : {
133 : : struct rte_mempool_ops *ops;
134 : :
135 [ - + ]: 1197 : ops = rte_mempool_get_ops(mp->ops_index);
136 : :
137 : 1197 : rte_mempool_trace_ops_populate(mp, max_objs, vaddr, iova, len, obj_cb,
138 : : obj_cb_arg);
139 [ + - ]: 1197 : if (ops->populate == NULL)
140 : 1197 : return rte_mempool_op_populate_default(mp, max_objs, vaddr,
141 : : iova, len, obj_cb,
142 : : obj_cb_arg);
143 : :
144 : 0 : return ops->populate(mp, max_objs, vaddr, iova, len, obj_cb,
145 : : obj_cb_arg);
146 : : }
147 : :
148 : : /* wrapper to get additional mempool info */
149 : : int
150 : 0 : rte_mempool_ops_get_info(const struct rte_mempool *mp,
151 : : struct rte_mempool_info *info)
152 : : {
153 : : struct rte_mempool_ops *ops;
154 : :
155 [ # # ]: 0 : ops = rte_mempool_get_ops(mp->ops_index);
156 : :
157 [ # # ]: 0 : if (ops->get_info == NULL)
158 : : return -ENOTSUP;
159 : 0 : return ops->get_info(mp, info);
160 : : }
161 : :
162 : :
163 : : /* sets mempool ops previously registered by rte_mempool_register_ops. */
164 : : int
165 : 141 : rte_mempool_set_ops_byname(struct rte_mempool *mp, const char *name,
166 : : void *pool_config)
167 : : {
168 : : struct rte_mempool_ops *ops = NULL;
169 : : unsigned i;
170 : :
171 : : /* too late, the mempool is already populated. */
172 [ + - ]: 141 : if (mp->flags & RTE_MEMPOOL_F_POOL_CREATED)
173 : : return -EEXIST;
174 : :
175 [ + - ]: 1140 : for (i = 0; i < rte_mempool_ops_table.num_ops; i++) {
176 : 1140 : if (!strcmp(name,
177 [ + + ]: 1140 : rte_mempool_ops_table.ops[i].name)) {
178 : 141 : ops = &rte_mempool_ops_table.ops[i];
179 : 141 : break;
180 : : }
181 : : }
182 : :
183 [ + - ]: 141 : if (ops == NULL)
184 : : return -EINVAL;
185 : :
186 : 141 : mp->ops_index = i;
187 [ - + ]: 141 : mp->pool_config = pool_config;
188 : 141 : rte_mempool_trace_set_ops_byname(mp, name, pool_config);
189 : 141 : return 0;
190 : : }
|