mempool: avoid division by zero
[dpdk.git] / lib / librte_mempool / rte_mempool.c
index 0ba6c24..b54de43 100644 (file)
@@ -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;
 
@@ -304,11 +307,14 @@ rte_mempool_xmem_usage(__rte_unused void *vaddr, uint32_t elt_num,
 static int
 rte_mempool_ring_create(struct rte_mempool *mp)
 {
-       int rg_flags = 0;
+       int rg_flags = 0, ret;
        char rg_name[RTE_RING_NAMESIZE];
        struct rte_ring *r;
 
-       snprintf(rg_name, sizeof(rg_name), RTE_MEMPOOL_MZ_FORMAT, mp->name);
+       ret = snprintf(rg_name, sizeof(rg_name),
+               RTE_MEMPOOL_MZ_FORMAT, mp->name);
+       if (ret < 0 || ret >= (int)sizeof(rg_name))
+               return -ENAMETOOLONG;
 
        /* ring flags */
        if (mp->flags & MEMPOOL_F_SP_PUT)
@@ -368,7 +374,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)
@@ -410,7 +416,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 +437,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 +450,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 +477,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 +495,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 +542,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 +589,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 +638,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 +679,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;
@@ -685,7 +708,7 @@ rte_mempool_free(struct rte_mempool *mp)
 }
 
 /* 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 +721,7 @@ 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;
+       int ret;
 
        /* compilation-time checks */
        RTE_BUILD_BUG_ON((sizeof(struct rte_mempool) &
@@ -751,7 +775,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)
@@ -760,7 +788,11 @@ 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);
+       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;