1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "spdk/env.h" 37 38 #include <rte_config.h> 39 #include <rte_cycles.h> 40 #include <rte_malloc.h> 41 #include <rte_mempool.h> 42 #include <rte_memzone.h> 43 #include <rte_version.h> 44 45 void * 46 spdk_malloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id) 47 { 48 void *buf = rte_malloc_socket(NULL, size, align, socket_id); 49 if (buf && phys_addr) { 50 *phys_addr = rte_malloc_virt2phy(buf); 51 } 52 return buf; 53 } 54 55 void * 56 spdk_zmalloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id) 57 { 58 void *buf = spdk_malloc_socket(size, align, phys_addr, socket_id); 59 if (buf) { 60 memset(buf, 0, size); 61 } 62 return buf; 63 } 64 65 void * 66 spdk_malloc(size_t size, size_t align, uint64_t *phys_addr) 67 { 68 return spdk_malloc_socket(size, align, phys_addr, SPDK_ENV_SOCKET_ID_ANY); 69 } 70 71 void * 72 spdk_zmalloc(size_t size, size_t align, uint64_t *phys_addr) 73 { 74 return spdk_zmalloc_socket(size, align, phys_addr, SPDK_ENV_SOCKET_ID_ANY); 75 } 76 77 void * 78 spdk_realloc(void *buf, size_t size, size_t align, uint64_t *phys_addr) 79 { 80 void *new_buf = rte_realloc(buf, size, align); 81 if (new_buf && phys_addr) { 82 *phys_addr = rte_malloc_virt2phy(new_buf); 83 } 84 return new_buf; 85 } 86 87 void 88 spdk_free(void *buf) 89 { 90 rte_free(buf); 91 } 92 93 void * 94 spdk_memzone_reserve(const char *name, size_t len, int socket_id, unsigned flags) 95 { 96 const struct rte_memzone *mz; 97 98 if (socket_id == SPDK_ENV_SOCKET_ID_ANY) { 99 socket_id = SOCKET_ID_ANY; 100 } 101 102 mz = rte_memzone_reserve(name, len, socket_id, flags); 103 104 if (mz != NULL) { 105 memset(mz->addr, 0, len); 106 return mz->addr; 107 } else { 108 return NULL; 109 } 110 } 111 112 void * 113 spdk_memzone_lookup(const char *name) 114 { 115 const struct rte_memzone *mz = rte_memzone_lookup(name); 116 117 if (mz != NULL) { 118 return mz->addr; 119 } else { 120 return NULL; 121 } 122 } 123 124 int 125 spdk_memzone_free(const char *name) 126 { 127 const struct rte_memzone *mz = rte_memzone_lookup(name); 128 129 if (mz != NULL) { 130 return rte_memzone_free(mz); 131 } 132 133 return -1; 134 } 135 136 void 137 spdk_memzone_dump(FILE *f) 138 { 139 rte_memzone_dump(f); 140 } 141 142 struct spdk_mempool * 143 spdk_mempool_create(const char *name, size_t count, 144 size_t ele_size, size_t cache_size, int socket_id) 145 { 146 struct rte_mempool *mp; 147 size_t tmp; 148 149 if (socket_id == SPDK_ENV_SOCKET_ID_ANY) { 150 socket_id = SOCKET_ID_ANY; 151 } 152 153 /* No more than half of all elements can be in cache */ 154 tmp = (count / 2) / rte_lcore_count(); 155 if (cache_size > tmp) { 156 cache_size = tmp; 157 } 158 159 if (cache_size > RTE_MEMPOOL_CACHE_MAX_SIZE) { 160 cache_size = RTE_MEMPOOL_CACHE_MAX_SIZE; 161 } 162 163 mp = rte_mempool_create(name, count, ele_size, cache_size, 164 0, NULL, NULL, NULL, NULL, 165 socket_id, 0); 166 167 return (struct spdk_mempool *)mp; 168 } 169 170 void 171 spdk_mempool_free(struct spdk_mempool *mp) 172 { 173 #if RTE_VERSION >= RTE_VERSION_NUM(16, 7, 0, 1) 174 rte_mempool_free((struct rte_mempool *)mp); 175 #endif 176 } 177 178 void * 179 spdk_mempool_get(struct spdk_mempool *mp) 180 { 181 void *ele = NULL; 182 183 rte_mempool_get((struct rte_mempool *)mp, &ele); 184 185 return ele; 186 } 187 188 void 189 spdk_mempool_put(struct spdk_mempool *mp, void *ele) 190 { 191 rte_mempool_put((struct rte_mempool *)mp, ele); 192 } 193 194 void 195 spdk_mempool_put_bulk(struct spdk_mempool *mp, void *const *ele_arr, size_t count) 196 { 197 rte_mempool_put_bulk((struct rte_mempool *)mp, ele_arr, count); 198 } 199 200 size_t 201 spdk_mempool_count(const struct spdk_mempool *pool) 202 { 203 #if RTE_VERSION < RTE_VERSION_NUM(16, 7, 0, 1) 204 return rte_mempool_count((struct rte_mempool *)pool); 205 #else 206 return rte_mempool_avail_count((struct rte_mempool *)pool); 207 #endif 208 } 209 210 bool 211 spdk_process_is_primary(void) 212 { 213 return (rte_eal_process_type() == RTE_PROC_PRIMARY); 214 } 215 216 uint64_t spdk_get_ticks(void) 217 { 218 return rte_get_timer_cycles(); 219 } 220 221 uint64_t spdk_get_ticks_hz(void) 222 { 223 return rte_get_timer_hz(); 224 } 225 226 void spdk_delay_us(unsigned int us) 227 { 228 rte_delay_us(us); 229 } 230 231 void * 232 spdk_call_unaffinitized(void *cb(void *arg), void *arg) 233 { 234 rte_cpuset_t orig_cpuset, new_cpuset; 235 void *ret; 236 long num_cores, i; 237 238 if (cb == NULL) { 239 return NULL; 240 } 241 242 rte_thread_get_affinity(&orig_cpuset); 243 244 CPU_ZERO(&new_cpuset); 245 246 num_cores = sysconf(_SC_NPROCESSORS_CONF); 247 248 /* Create a mask containing all CPUs */ 249 for (i = 0; i < num_cores; i++) { 250 CPU_SET(i, &new_cpuset); 251 } 252 253 rte_thread_set_affinity(&new_cpuset); 254 255 ret = cb(arg); 256 257 rte_thread_set_affinity(&orig_cpuset); 258 259 return ret; 260 } 261