1*5566a3e3SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 2*5566a3e3SBruce Richardson * Copyright(c) 2016 Intel Corporation 31263b426SShreyansh Jain */ 41263b426SShreyansh Jain 51263b426SShreyansh Jain #include <stdio.h> 61263b426SShreyansh Jain #include <rte_mempool.h> 71263b426SShreyansh Jain #include <rte_malloc.h> 81263b426SShreyansh Jain 91263b426SShreyansh Jain struct rte_mempool_stack { 101263b426SShreyansh Jain rte_spinlock_t sl; 111263b426SShreyansh Jain 121263b426SShreyansh Jain uint32_t size; 131263b426SShreyansh Jain uint32_t len; 141263b426SShreyansh Jain void *objs[]; 151263b426SShreyansh Jain }; 161263b426SShreyansh Jain 171263b426SShreyansh Jain static int 181263b426SShreyansh Jain stack_alloc(struct rte_mempool *mp) 191263b426SShreyansh Jain { 201263b426SShreyansh Jain struct rte_mempool_stack *s; 211263b426SShreyansh Jain unsigned n = mp->size; 221263b426SShreyansh Jain int size = sizeof(*s) + (n+16)*sizeof(void *); 231263b426SShreyansh Jain 241263b426SShreyansh Jain /* Allocate our local memory structure */ 251263b426SShreyansh Jain s = rte_zmalloc_socket("mempool-stack", 261263b426SShreyansh Jain size, 271263b426SShreyansh Jain RTE_CACHE_LINE_SIZE, 281263b426SShreyansh Jain mp->socket_id); 291263b426SShreyansh Jain if (s == NULL) { 301263b426SShreyansh Jain RTE_LOG(ERR, MEMPOOL, "Cannot allocate stack!\n"); 311263b426SShreyansh Jain return -ENOMEM; 321263b426SShreyansh Jain } 331263b426SShreyansh Jain 341263b426SShreyansh Jain rte_spinlock_init(&s->sl); 351263b426SShreyansh Jain 361263b426SShreyansh Jain s->size = n; 371263b426SShreyansh Jain mp->pool_data = s; 381263b426SShreyansh Jain 391263b426SShreyansh Jain return 0; 401263b426SShreyansh Jain } 411263b426SShreyansh Jain 421263b426SShreyansh Jain static int 431263b426SShreyansh Jain stack_enqueue(struct rte_mempool *mp, void * const *obj_table, 441263b426SShreyansh Jain unsigned n) 451263b426SShreyansh Jain { 461263b426SShreyansh Jain struct rte_mempool_stack *s = mp->pool_data; 471263b426SShreyansh Jain void **cache_objs; 481263b426SShreyansh Jain unsigned index; 491263b426SShreyansh Jain 501263b426SShreyansh Jain rte_spinlock_lock(&s->sl); 511263b426SShreyansh Jain cache_objs = &s->objs[s->len]; 521263b426SShreyansh Jain 531263b426SShreyansh Jain /* Is there sufficient space in the stack ? */ 541263b426SShreyansh Jain if ((s->len + n) > s->size) { 551263b426SShreyansh Jain rte_spinlock_unlock(&s->sl); 561263b426SShreyansh Jain return -ENOBUFS; 571263b426SShreyansh Jain } 581263b426SShreyansh Jain 591263b426SShreyansh Jain /* Add elements back into the cache */ 601263b426SShreyansh Jain for (index = 0; index < n; ++index, obj_table++) 611263b426SShreyansh Jain cache_objs[index] = *obj_table; 621263b426SShreyansh Jain 631263b426SShreyansh Jain s->len += n; 641263b426SShreyansh Jain 651263b426SShreyansh Jain rte_spinlock_unlock(&s->sl); 661263b426SShreyansh Jain return 0; 671263b426SShreyansh Jain } 681263b426SShreyansh Jain 691263b426SShreyansh Jain static int 701263b426SShreyansh Jain stack_dequeue(struct rte_mempool *mp, void **obj_table, 711263b426SShreyansh Jain unsigned n) 721263b426SShreyansh Jain { 731263b426SShreyansh Jain struct rte_mempool_stack *s = mp->pool_data; 741263b426SShreyansh Jain void **cache_objs; 751263b426SShreyansh Jain unsigned index, len; 761263b426SShreyansh Jain 771263b426SShreyansh Jain rte_spinlock_lock(&s->sl); 781263b426SShreyansh Jain 791263b426SShreyansh Jain if (unlikely(n > s->len)) { 801263b426SShreyansh Jain rte_spinlock_unlock(&s->sl); 811263b426SShreyansh Jain return -ENOENT; 821263b426SShreyansh Jain } 831263b426SShreyansh Jain 841263b426SShreyansh Jain cache_objs = s->objs; 851263b426SShreyansh Jain 861263b426SShreyansh Jain for (index = 0, len = s->len - 1; index < n; 871263b426SShreyansh Jain ++index, len--, obj_table++) 881263b426SShreyansh Jain *obj_table = cache_objs[len]; 891263b426SShreyansh Jain 901263b426SShreyansh Jain s->len -= n; 911263b426SShreyansh Jain rte_spinlock_unlock(&s->sl); 921263b426SShreyansh Jain return 0; 931263b426SShreyansh Jain } 941263b426SShreyansh Jain 951263b426SShreyansh Jain static unsigned 961263b426SShreyansh Jain stack_get_count(const struct rte_mempool *mp) 971263b426SShreyansh Jain { 981263b426SShreyansh Jain struct rte_mempool_stack *s = mp->pool_data; 991263b426SShreyansh Jain 1001263b426SShreyansh Jain return s->len; 1011263b426SShreyansh Jain } 1021263b426SShreyansh Jain 1031263b426SShreyansh Jain static void 1041263b426SShreyansh Jain stack_free(struct rte_mempool *mp) 1051263b426SShreyansh Jain { 1061263b426SShreyansh Jain rte_free((void *)(mp->pool_data)); 1071263b426SShreyansh Jain } 1081263b426SShreyansh Jain 1091263b426SShreyansh Jain static struct rte_mempool_ops ops_stack = { 1101263b426SShreyansh Jain .name = "stack", 1111263b426SShreyansh Jain .alloc = stack_alloc, 1121263b426SShreyansh Jain .free = stack_free, 1131263b426SShreyansh Jain .enqueue = stack_enqueue, 1141263b426SShreyansh Jain .dequeue = stack_dequeue, 1151263b426SShreyansh Jain .get_count = stack_get_count 1161263b426SShreyansh Jain }; 1171263b426SShreyansh Jain 1181263b426SShreyansh Jain MEMPOOL_REGISTER_OPS(ops_stack); 119