X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_mempool%2Frte_mempool.c;h=d78d02b7b8c514cb631d3eee867501c7779ab382;hb=a0fd91cefcc054b770dec6d8fb60db0d3145c45a;hp=0ba6c24008baf369648807e45ed29c8a95a84b2c;hpb=6780f72fb82f0c012e2f87fcbaae082a54b3b4d3;p=dpdk.git diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c index 0ba6c24008..d78d02b7b8 100644 --- a/lib/librte_mempool/rte_mempool.c +++ b/lib/librte_mempool/rte_mempool.c @@ -148,7 +148,7 @@ mempool_add_elem(struct rte_mempool *mp, void *obj, phys_addr_t physaddr) #endif /* enqueue in ring */ - rte_ring_sp_enqueue(mp->ring, obj); + rte_mempool_ops_enqueue_bulk(mp, &obj, 1); } /* call obj_cb() for each mempool element */ @@ -239,6 +239,9 @@ rte_mempool_xmem_size(uint32_t elt_num, size_t total_elt_sz, uint32_t pg_shift) { size_t obj_per_page, pg_num, pg_sz; + if (total_elt_sz == 0) + return 0; + if (pg_shift == 0) return total_elt_sz * elt_num; @@ -300,37 +303,6 @@ rte_mempool_xmem_usage(__rte_unused void *vaddr, uint32_t elt_num, return (size_t)paddr_idx << pg_shift; } -/* create the internal ring */ -static int -rte_mempool_ring_create(struct rte_mempool *mp) -{ - int rg_flags = 0; - char rg_name[RTE_RING_NAMESIZE]; - struct rte_ring *r; - - snprintf(rg_name, sizeof(rg_name), RTE_MEMPOOL_MZ_FORMAT, mp->name); - - /* ring flags */ - if (mp->flags & MEMPOOL_F_SP_PUT) - rg_flags |= RING_F_SP_ENQ; - if (mp->flags & MEMPOOL_F_SC_GET) - rg_flags |= RING_F_SC_DEQ; - - /* Allocate the ring that will be used to store objects. - * Ring functions will return appropriate errors if we are - * running as a secondary process etc., so no checks made - * in this function for that condition. - */ - r = rte_ring_create(rg_name, rte_align32pow2(mp->size + 1), - mp->socket_id, rg_flags); - if (r == NULL) - return -rte_errno; - - mp->ring = r; - mp->flags |= MEMPOOL_F_RING_CREATED; - return 0; -} - /* free a memchunk allocated with rte_memzone_reserve() */ static void rte_mempool_memchunk_mz_free(__rte_unused struct rte_mempool_memhdr *memhdr, @@ -348,7 +320,7 @@ rte_mempool_free_memchunks(struct rte_mempool *mp) void *elt; while (!STAILQ_EMPTY(&mp->elt_list)) { - rte_ring_sc_dequeue(mp->ring, &elt); + rte_mempool_ops_dequeue_bulk(mp, &elt, 1); (void)elt; STAILQ_REMOVE_HEAD(&mp->elt_list, next); mp->populated_size--; @@ -368,7 +340,7 @@ rte_mempool_free_memchunks(struct rte_mempool *mp) * zone. Return the number of objects added, or a negative value * on error. */ -static int +int rte_mempool_populate_phys(struct rte_mempool *mp, char *vaddr, phys_addr_t paddr, size_t len, rte_mempool_memchunk_free_cb_t *free_cb, void *opaque) @@ -380,10 +352,11 @@ rte_mempool_populate_phys(struct rte_mempool *mp, char *vaddr, int ret; /* create the internal ring if not already done */ - if ((mp->flags & MEMPOOL_F_RING_CREATED) == 0) { - ret = rte_mempool_ring_create(mp); - if (ret < 0) + if ((mp->flags & MEMPOOL_F_POOL_CREATED) == 0) { + ret = rte_mempool_ops_alloc(mp); + if (ret != 0) return ret; + mp->flags |= MEMPOOL_F_POOL_CREATED; } /* mempool is already populated */ @@ -410,7 +383,11 @@ rte_mempool_populate_phys(struct rte_mempool *mp, char *vaddr, while (off + total_elt_sz <= len && mp->populated_size < mp->size) { off += mp->header_size; - mempool_add_elem(mp, (char *)vaddr + off, paddr + off); + if (paddr == RTE_BAD_PHYS_ADDR) + mempool_add_elem(mp, (char *)vaddr + off, + RTE_BAD_PHYS_ADDR); + else + mempool_add_elem(mp, (char *)vaddr + off, paddr + off); off += mp->elt_size + mp->trailer_size; i++; } @@ -427,7 +404,7 @@ rte_mempool_populate_phys(struct rte_mempool *mp, char *vaddr, /* Add objects in the pool, using a table of physical pages. Return the * number of objects added, or a negative value on error. */ -static int +int rte_mempool_populate_phys_tab(struct rte_mempool *mp, char *vaddr, const phys_addr_t paddr[], uint32_t pg_num, uint32_t pg_shift, rte_mempool_memchunk_free_cb_t *free_cb, void *opaque) @@ -440,6 +417,10 @@ rte_mempool_populate_phys_tab(struct rte_mempool *mp, char *vaddr, if (mp->nb_mem_chunks != 0) return -EEXIST; + if (mp->flags & MEMPOOL_F_NO_PHYS_CONTIG) + return rte_mempool_populate_phys(mp, vaddr, RTE_BAD_PHYS_ADDR, + pg_num * pg_sz, free_cb, opaque); + for (i = 0; i < pg_num && mp->populated_size < mp->size; i += n) { /* populate with the largest group of contiguous pages */ @@ -463,7 +444,7 @@ rte_mempool_populate_phys_tab(struct rte_mempool *mp, char *vaddr, /* Populate the mempool with a virtual area. Return the number of * objects added, or a negative value on error. */ -static int +int rte_mempool_populate_virt(struct rte_mempool *mp, char *addr, size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb, void *opaque) @@ -481,6 +462,10 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr, if (RTE_ALIGN_CEIL(len, pg_sz) != len) return -EINVAL; + if (mp->flags & MEMPOOL_F_NO_PHYS_CONTIG) + return rte_mempool_populate_phys(mp, addr, RTE_BAD_PHYS_ADDR, + len, free_cb, opaque); + for (off = 0; off + pg_sz <= len && mp->populated_size < mp->size; off += phys_len) { @@ -524,13 +509,14 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr, * and populate them. Return the number of objects added, or a negative * value on error. */ -static int +int rte_mempool_populate_default(struct rte_mempool *mp) { int mz_flags = RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY; char mz_name[RTE_MEMZONE_NAMESIZE]; const struct rte_memzone *mz; size_t size, total_elt_sz, align, pg_sz, pg_shift; + phys_addr_t paddr; unsigned mz_id, n; int ret; @@ -570,10 +556,14 @@ rte_mempool_populate_default(struct rte_mempool *mp) goto fail; } - /* use memzone physical address if it is valid */ + if (mp->flags & MEMPOOL_F_NO_PHYS_CONTIG) + paddr = RTE_BAD_PHYS_ADDR; + else + paddr = mz->phys_addr; + if (rte_eal_has_hugepages() && !rte_xen_dom0_supported()) ret = rte_mempool_populate_phys(mp, mz->addr, - mz->phys_addr, mz->len, + paddr, mz->len, rte_mempool_memchunk_mz_free, (void *)(uintptr_t)mz); else @@ -615,7 +605,7 @@ rte_mempool_memchunk_anon_free(struct rte_mempool_memhdr *memhdr, } /* populate the mempool with an anonymous mapping */ -__rte_unused static int +int rte_mempool_populate_anon(struct rte_mempool *mp) { size_t size; @@ -656,7 +646,7 @@ rte_mempool_populate_anon(struct rte_mempool *mp) } /* free a mempool */ -static void +void rte_mempool_free(struct rte_mempool *mp) { struct rte_mempool_list *mempool_list = NULL; @@ -680,12 +670,59 @@ rte_mempool_free(struct rte_mempool *mp) rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); rte_mempool_free_memchunks(mp); - rte_ring_free(mp->ring); + rte_mempool_ops_free(mp); rte_memzone_free(mp->mz); } +static void +mempool_cache_init(struct rte_mempool_cache *cache, uint32_t size) +{ + cache->size = size; + cache->flushthresh = CALC_CACHE_FLUSHTHRESH(size); + cache->len = 0; +} + +/* + * Create and initialize a cache for objects that are retrieved from and + * returned to an underlying mempool. This structure is identical to the + * local_cache[lcore_id] pointed to by the mempool structure. + */ +struct rte_mempool_cache * +rte_mempool_cache_create(uint32_t size, int socket_id) +{ + struct rte_mempool_cache *cache; + + if (size == 0 || size > RTE_MEMPOOL_CACHE_MAX_SIZE) { + rte_errno = EINVAL; + return NULL; + } + + cache = rte_zmalloc_socket("MEMPOOL_CACHE", sizeof(*cache), + RTE_CACHE_LINE_SIZE, socket_id); + if (cache == NULL) { + RTE_LOG(ERR, MEMPOOL, "Cannot allocate mempool cache.\n"); + rte_errno = ENOMEM; + return NULL; + } + + mempool_cache_init(cache, size); + + return cache; +} + +/* + * Free a cache. It's the responsibility of the user to make sure that any + * remaining objects in the cache are flushed to the corresponding + * mempool. + */ +void +rte_mempool_cache_free(struct rte_mempool_cache *cache) +{ + rte_free(cache); +} + /* create an empty mempool */ -static struct rte_mempool * +struct rte_mempool * rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size, unsigned cache_size, unsigned private_data_size, int socket_id, unsigned flags) @@ -698,6 +735,8 @@ rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size, size_t mempool_size; int mz_flags = RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY; struct rte_mempool_objsz objsz; + unsigned lcore_id; + int ret; /* compilation-time checks */ RTE_BUILD_BUG_ON((sizeof(struct rte_mempool) & @@ -751,7 +790,11 @@ rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size, mempool_size += private_data_size; mempool_size = RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN); - snprintf(mz_name, sizeof(mz_name), RTE_MEMPOOL_MZ_FORMAT, name); + ret = snprintf(mz_name, sizeof(mz_name), RTE_MEMPOOL_MZ_FORMAT, name); + if (ret < 0 || ret >= (int)sizeof(mz_name)) { + rte_errno = ENAMETOOLONG; + goto exit_unlock; + } mz = rte_memzone_reserve(mz_name, mempool_size, socket_id, mz_flags); if (mz == NULL) @@ -759,8 +802,12 @@ rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size, /* init the mempool structure */ mp = mz->addr; - memset(mp, 0, sizeof(*mp)); - snprintf(mp->name, sizeof(mp->name), "%s", name); + memset(mp, 0, MEMPOOL_HEADER_SIZE(mp, cache_size)); + ret = snprintf(mp->name, sizeof(mp->name), "%s", name); + if (ret < 0 || ret >= (int)sizeof(mp->name)) { + rte_errno = ENAMETOOLONG; + goto exit_unlock; + } mp->mz = mz; mp->socket_id = socket_id; mp->size = n; @@ -769,8 +816,8 @@ rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size, mp->elt_size = objsz.elt_size; mp->header_size = objsz.header_size; mp->trailer_size = objsz.trailer_size; + /* Size of default caches, zero means disabled. */ mp->cache_size = cache_size; - mp->cache_flushthresh = CALC_CACHE_FLUSHTHRESH(cache_size); mp->private_data_size = private_data_size; STAILQ_INIT(&mp->elt_list); STAILQ_INIT(&mp->mem_list); @@ -782,7 +829,15 @@ rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size, mp->local_cache = (struct rte_mempool_cache *) RTE_PTR_ADD(mp, MEMPOOL_HEADER_SIZE(mp, 0)); + /* Init all default caches. */ + if (cache_size != 0) { + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) + mempool_cache_init(&mp->local_cache[lcore_id], + cache_size); + } + te->data = mp; + rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK); TAILQ_INSERT_TAIL(mempool_list, te, next); rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); @@ -812,6 +867,19 @@ rte_mempool_create(const char *name, unsigned n, unsigned elt_size, if (mp == NULL) return NULL; + /* + * Since we have 4 combinations of the SP/SC/MP/MC examine the flags to + * set the correct index into the table of ops structs. + */ + if (flags & (MEMPOOL_F_SP_PUT | MEMPOOL_F_SC_GET)) + rte_mempool_set_ops_byname(mp, "ring_sp_sc", NULL); + else if (flags & MEMPOOL_F_SP_PUT) + rte_mempool_set_ops_byname(mp, "ring_sp_mc", NULL); + else if (flags & MEMPOOL_F_SC_GET) + rte_mempool_set_ops_byname(mp, "ring_mp_sc", NULL); + else + rte_mempool_set_ops_byname(mp, "ring_mp_mc", NULL); + /* call the mempool priv initializer */ if (mp_init) mp_init(mp, mp_init_arg); @@ -892,13 +960,13 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size, } /* Return the number of entries in the mempool */ -unsigned -rte_mempool_count(const struct rte_mempool *mp) +unsigned int +rte_mempool_avail_count(const struct rte_mempool *mp) { unsigned count; unsigned lcore_id; - count = rte_ring_count(mp->ring); + count = rte_mempool_ops_get_count(mp); if (mp->cache_size == 0) return count; @@ -915,6 +983,19 @@ rte_mempool_count(const struct rte_mempool *mp) return count; } +/* return the number of entries allocated from the mempool */ +unsigned int +rte_mempool_in_use_count(const struct rte_mempool *mp) +{ + return mp->size - rte_mempool_avail_count(mp); +} + +unsigned int +rte_mempool_count(const struct rte_mempool *mp) +{ + return rte_mempool_avail_count(mp); +} + /* dump the cache status */ static unsigned rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp) @@ -923,7 +1004,7 @@ rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp) unsigned count = 0; unsigned cache_count; - fprintf(f, " cache infos:\n"); + fprintf(f, " internal cache infos:\n"); fprintf(f, " cache_size=%"PRIu32"\n", mp->cache_size); if (mp->cache_size == 0) @@ -931,7 +1012,8 @@ rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp) for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { cache_count = mp->local_cache[lcore_id].len; - fprintf(f, " cache_count[%u]=%u\n", lcore_id, cache_count); + fprintf(f, " cache_count[%u]=%"PRIu32"\n", + lcore_id, cache_count); count += cache_count; } fprintf(f, " total_cache_count=%u\n", count); @@ -971,7 +1053,6 @@ void rte_mempool_check_cookies(const struct rte_mempool *mp, if (free == 0) { if (cookie != RTE_MEMPOOL_HEADER_COOKIE1) { - rte_log_set_history(0); RTE_LOG(CRIT, MEMPOOL, "obj=%p, mempool=%p, cookie=%" PRIx64 "\n", obj, (const void *) mp, cookie); @@ -980,7 +1061,6 @@ void rte_mempool_check_cookies(const struct rte_mempool *mp, hdr->cookie = RTE_MEMPOOL_HEADER_COOKIE2; } else if (free == 1) { if (cookie != RTE_MEMPOOL_HEADER_COOKIE2) { - rte_log_set_history(0); RTE_LOG(CRIT, MEMPOOL, "obj=%p, mempool=%p, cookie=%" PRIx64 "\n", obj, (const void *) mp, cookie); @@ -990,7 +1070,6 @@ void rte_mempool_check_cookies(const struct rte_mempool *mp, } else if (free == 2) { if (cookie != RTE_MEMPOOL_HEADER_COOKIE1 && cookie != RTE_MEMPOOL_HEADER_COOKIE2) { - rte_log_set_history(0); RTE_LOG(CRIT, MEMPOOL, "obj=%p, mempool=%p, cookie=%" PRIx64 "\n", obj, (const void *) mp, cookie); @@ -1000,7 +1079,6 @@ void rte_mempool_check_cookies(const struct rte_mempool *mp, tlr = __mempool_get_trailer(obj); cookie = tlr->cookie; if (cookie != RTE_MEMPOOL_TRAILER_COOKIE) { - rte_log_set_history(0); RTE_LOG(CRIT, MEMPOOL, "obj=%p, mempool=%p, cookie=%" PRIx64 "\n", obj, (const void *) mp, cookie); @@ -1054,7 +1132,9 @@ mempool_audit_cache(const struct rte_mempool *mp) return; for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { - if (mp->local_cache[lcore_id].len > mp->cache_flushthresh) { + const struct rte_mempool_cache *cache; + cache = &mp->local_cache[lcore_id]; + if (cache->len > cache->flushthresh) { RTE_LOG(CRIT, MEMPOOL, "badness on cache[%u]\n", lcore_id); rte_panic("MEMPOOL: invalid cache len\n"); @@ -1091,7 +1171,7 @@ rte_mempool_dump(FILE *f, struct rte_mempool *mp) fprintf(f, "mempool <%s>@%p\n", mp->name, mp); fprintf(f, " flags=%x\n", mp->flags); - fprintf(f, " ring=<%s>@%p\n", mp->ring->name, mp->ring); + fprintf(f, " pool=%p\n", mp->pool_data); fprintf(f, " phys_addr=0x%" PRIx64 "\n", mp->mz->phys_addr); fprintf(f, " nb_mem_chunks=%u\n", mp->nb_mem_chunks); fprintf(f, " size=%"PRIu32"\n", mp->size); @@ -1112,7 +1192,7 @@ rte_mempool_dump(FILE *f, struct rte_mempool *mp) } cache_count = rte_mempool_dump_cache(f, mp); - common_count = rte_ring_count(mp->ring); + common_count = rte_mempool_ops_get_count(mp); if ((cache_count + common_count) > mp->size) common_count = mp->size - cache_count; fprintf(f, " common_pool_count=%u\n", common_count);