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