common/sfc_efx/base: add flag to use Rx prefix user flag
[dpdk.git] / drivers / mempool / bucket / rte_mempool_bucket.c
index 24be24e..c0b480b 100644 (file)
@@ -42,6 +42,7 @@ struct bucket_data {
        unsigned int header_size;
        unsigned int total_elt_size;
        unsigned int obj_per_bucket;
+       unsigned int bucket_stack_thresh;
        uintptr_t bucket_page_mask;
        struct rte_ring *shared_bucket_ring;
        struct bucket_stack *buckets[RTE_MAX_LCORE];
@@ -54,6 +55,7 @@ struct bucket_data {
        struct rte_ring *shared_orphan_ring;
        struct rte_mempool *pool;
        unsigned int bucket_mem_size;
+       void *lcore_callback_handle;
 };
 
 static struct bucket_stack *
@@ -139,6 +141,7 @@ bucket_enqueue(struct rte_mempool *mp, void * const *obj_table,
               unsigned int n)
 {
        struct bucket_data *bd = mp->pool_data;
+       struct bucket_stack *local_stack = bd->buckets[rte_lcore_id()];
        unsigned int i;
        int rc = 0;
 
@@ -146,6 +149,15 @@ bucket_enqueue(struct rte_mempool *mp, void * const *obj_table,
                rc = bucket_enqueue_single(bd, obj_table[i]);
                RTE_ASSERT(rc == 0);
        }
+       if (local_stack->top > bd->bucket_stack_thresh) {
+               rte_ring_enqueue_bulk(bd->shared_bucket_ring,
+                                     &local_stack->objects
+                                     [bd->bucket_stack_thresh],
+                                     local_stack->top -
+                                     bd->bucket_stack_thresh,
+                                     NULL);
+           local_stack->top = bd->bucket_stack_thresh;
+       }
        return rc;
 }
 
@@ -334,6 +346,23 @@ bucket_dequeue_contig_blocks(struct rte_mempool *mp, void **first_obj_table,
        return 0;
 }
 
+struct bucket_count_per_lcore_ctx {
+       const struct bucket_data *bd;
+       unsigned int count;
+};
+
+static int
+bucket_count_per_lcore(unsigned int lcore_id, void *arg)
+{
+       struct bucket_count_per_lcore_ctx *bplc = arg;
+
+       bplc->count += bplc->bd->obj_per_bucket *
+               bplc->bd->buckets[lcore_id]->top;
+       bplc->count +=
+               rte_ring_count(bplc->bd->adoption_buffer_rings[lcore_id]);
+       return 0;
+}
+
 static void
 count_underfilled_buckets(struct rte_mempool *mp,
                          void *opaque,
@@ -362,23 +391,64 @@ count_underfilled_buckets(struct rte_mempool *mp,
 static unsigned int
 bucket_get_count(const struct rte_mempool *mp)
 {
-       const struct bucket_data *bd = mp->pool_data;
-       unsigned int count =
-               bd->obj_per_bucket * rte_ring_count(bd->shared_bucket_ring) +
-               rte_ring_count(bd->shared_orphan_ring);
-       unsigned int i;
+       struct bucket_count_per_lcore_ctx bplc;
 
-       for (i = 0; i < RTE_MAX_LCORE; i++) {
-               if (!rte_lcore_is_enabled(i))
-                       continue;
-               count += bd->obj_per_bucket * bd->buckets[i]->top +
-                       rte_ring_count(bd->adoption_buffer_rings[i]);
-       }
+       bplc.bd = mp->pool_data;
+       bplc.count = bplc.bd->obj_per_bucket *
+               rte_ring_count(bplc.bd->shared_bucket_ring);
+       bplc.count += rte_ring_count(bplc.bd->shared_orphan_ring);
 
+       rte_lcore_iterate(bucket_count_per_lcore, &bplc);
        rte_mempool_mem_iter((struct rte_mempool *)(uintptr_t)mp,
-                            count_underfilled_buckets, &count);
+                            count_underfilled_buckets, &bplc.count);
 
-       return count;
+       return bplc.count;
+}
+
+static int
+bucket_init_per_lcore(unsigned int lcore_id, void *arg)
+{
+       char rg_name[RTE_RING_NAMESIZE];
+       struct bucket_data *bd = arg;
+       struct rte_mempool *mp;
+       int rg_flags;
+       int rc;
+
+       mp = bd->pool;
+       bd->buckets[lcore_id] = bucket_stack_create(mp,
+               mp->size / bd->obj_per_bucket);
+       if (bd->buckets[lcore_id] == NULL)
+               goto error;
+
+       rc = snprintf(rg_name, sizeof(rg_name), RTE_MEMPOOL_MZ_FORMAT ".a%u",
+               mp->name, lcore_id);
+       if (rc < 0 || rc >= (int)sizeof(rg_name))
+               goto error;
+
+       rg_flags = RING_F_SC_DEQ;
+       if (mp->flags & RTE_MEMPOOL_F_SP_PUT)
+               rg_flags |= RING_F_SP_ENQ;
+       bd->adoption_buffer_rings[lcore_id] = rte_ring_create(rg_name,
+               rte_align32pow2(mp->size + 1), mp->socket_id, rg_flags);
+       if (bd->adoption_buffer_rings[lcore_id] == NULL)
+               goto error;
+
+       return 0;
+error:
+       rte_free(bd->buckets[lcore_id]);
+       bd->buckets[lcore_id] = NULL;
+       return -1;
+}
+
+static void
+bucket_uninit_per_lcore(unsigned int lcore_id, void *arg)
+{
+       struct bucket_data *bd = arg;
+
+       rte_ring_free(bd->adoption_buffer_rings[lcore_id]);
+       bd->adoption_buffer_rings[lcore_id] = NULL;
+       rte_free(bd->buckets[lcore_id]);
+       bd->buckets[lcore_id] = NULL;
 }
 
 static int
@@ -388,8 +458,12 @@ bucket_alloc(struct rte_mempool *mp)
        int rc = 0;
        char rg_name[RTE_RING_NAMESIZE];
        struct bucket_data *bd;
-       unsigned int i;
        unsigned int bucket_header_size;
+       size_t pg_sz;
+
+       rc = rte_mempool_get_page_size(mp, &pg_sz);
+       if (rc < 0)
+               return rc;
 
        bd = rte_zmalloc_socket("bucket_pool", sizeof(*bd),
                                RTE_CACHE_LINE_SIZE, mp->socket_id);
@@ -398,48 +472,32 @@ bucket_alloc(struct rte_mempool *mp)
                goto no_mem_for_data;
        }
        bd->pool = mp;
-       if (mp->flags & MEMPOOL_F_NO_CACHE_ALIGN)
+       if (mp->flags & RTE_MEMPOOL_F_NO_CACHE_ALIGN)
                bucket_header_size = sizeof(struct bucket_header);
        else
                bucket_header_size = RTE_CACHE_LINE_SIZE;
        RTE_BUILD_BUG_ON(sizeof(struct bucket_header) > RTE_CACHE_LINE_SIZE);
        bd->header_size = mp->header_size + bucket_header_size;
        bd->total_elt_size = mp->header_size + mp->elt_size + mp->trailer_size;
-       bd->bucket_mem_size = RTE_DRIVER_MEMPOOL_BUCKET_SIZE_KB * 1024;
+       bd->bucket_mem_size = RTE_MIN(pg_sz,
+                       (size_t)(RTE_DRIVER_MEMPOOL_BUCKET_SIZE_KB * 1024));
        bd->obj_per_bucket = (bd->bucket_mem_size - bucket_header_size) /
                bd->total_elt_size;
        bd->bucket_page_mask = ~(rte_align64pow2(bd->bucket_mem_size) - 1);
+       /* eventually this should be a tunable parameter */
+       bd->bucket_stack_thresh = (mp->size / bd->obj_per_bucket) * 4 / 3;
 
-       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;
-
-       for (i = 0; i < RTE_MAX_LCORE; i++) {
-               if (!rte_lcore_is_enabled(i))
-                       continue;
-               bd->buckets[i] =
-                       bucket_stack_create(mp, mp->size / bd->obj_per_bucket);
-               if (bd->buckets[i] == NULL) {
-                       rc = -ENOMEM;
-                       goto no_mem_for_stacks;
-               }
-               rc = snprintf(rg_name, sizeof(rg_name),
-                             RTE_MEMPOOL_MZ_FORMAT ".a%u", mp->name, i);
-               if (rc < 0 || rc >= (int)sizeof(rg_name)) {
-                       rc = -ENAMETOOLONG;
-                       goto no_mem_for_stacks;
-               }
-               bd->adoption_buffer_rings[i] =
-                       rte_ring_create(rg_name, rte_align32pow2(mp->size + 1),
-                                       mp->socket_id,
-                                       rg_flags | RING_F_SC_DEQ);
-               if (bd->adoption_buffer_rings[i] == NULL) {
-                       rc = -rte_errno;
-                       goto no_mem_for_stacks;
-               }
+       bd->lcore_callback_handle = rte_lcore_callback_register("bucket",
+               bucket_init_per_lcore, bucket_uninit_per_lcore, bd);
+       if (bd->lcore_callback_handle == NULL) {
+               rc = -ENOMEM;
+               goto no_mem_for_stacks;
        }
 
+       if (mp->flags & RTE_MEMPOOL_F_SP_PUT)
+               rg_flags |= RING_F_SP_ENQ;
+       if (mp->flags & RTE_MEMPOOL_F_SC_GET)
+               rg_flags |= RING_F_SC_DEQ;
        rc = snprintf(rg_name, sizeof(rg_name),
                      RTE_MEMPOOL_MZ_FORMAT ".0", mp->name);
        if (rc < 0 || rc >= (int)sizeof(rg_name)) {
@@ -479,11 +537,8 @@ invalid_shared_bucket_ring:
        rte_ring_free(bd->shared_orphan_ring);
 cannot_create_shared_orphan_ring:
 invalid_shared_orphan_ring:
+       rte_lcore_callback_unregister(bd->lcore_callback_handle);
 no_mem_for_stacks:
-       for (i = 0; i < RTE_MAX_LCORE; i++) {
-               rte_free(bd->buckets[i]);
-               rte_ring_free(bd->adoption_buffer_rings[i]);
-       }
        rte_free(bd);
 no_mem_for_data:
        rte_errno = -rc;
@@ -493,16 +548,12 @@ no_mem_for_data:
 static void
 bucket_free(struct rte_mempool *mp)
 {
-       unsigned int i;
        struct bucket_data *bd = mp->pool_data;
 
        if (bd == NULL)
                return;
 
-       for (i = 0; i < RTE_MAX_LCORE; i++) {
-               rte_free(bd->buckets[i]);
-               rte_ring_free(bd->adoption_buffer_rings[i]);
-       }
+       rte_lcore_callback_unregister(bd->lcore_callback_handle);
 
        rte_ring_free(bd->shared_orphan_ring);
        rte_ring_free(bd->shared_bucket_ring);
@@ -572,7 +623,7 @@ bucket_populate(struct rte_mempool *mp, unsigned int max_objs,
 
                hdr->fill_cnt = 0;
                hdr->lcore_id = LCORE_ID_ANY;
-               rc = rte_mempool_op_populate_default(mp,
+               rc = rte_mempool_op_populate_helper(mp, 0,
                                                     RTE_MIN(bd->obj_per_bucket,
                                                             max_objs - n_objs),
                                                     iter + bucket_header_sz,
@@ -612,4 +663,4 @@ static const struct rte_mempool_ops ops_bucket = {
 };
 
 
-MEMPOOL_REGISTER_OPS(ops_bucket);
+RTE_MEMPOOL_REGISTER_OPS(ops_bucket);