From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from wes1-so2.wedos.net (wes1-so2.wedos.net [46.28.106.16]) by dpdk.org (Postfix) with ESMTP id DA6465A35 for ; Mon, 23 May 2016 14:47:10 +0200 (CEST) Received: from pcviktorin.fit.vutbr.cz (pcviktorin.fit.vutbr.cz [147.229.13.147]) by wes1-so2.wedos.net (Postfix) with ESMTPSA id 3rCywt47TGz37S; Mon, 23 May 2016 14:47:10 +0200 (CEST) Date: Mon, 23 May 2016 14:45:30 +0200 From: Jan Viktorin To: David Hunt Cc: dev@dpdk.org, olivier.matz@6wind.com, yuanhan.liu@linux.intel.com, pmatilai@redhat.com Message-ID: <20160523144530.290b8e97@pcviktorin.fit.vutbr.cz> In-Reply-To: <1463665501-18325-3-git-send-email-david.hunt@intel.com> References: <1463665501-18325-3-git-send-email-david.hunt@intel.com> Organization: RehiveTech MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Subject: Re: [dpdk-dev] [dpdk-dev, v5, 2/3] app/test: test external mempool handler X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 May 2016 12:47:11 -0000 On Thu, 19 May 2016 14:45:00 +0100 David Hunt wrote: > Use a minimal custom mempool external handler and check that it also > passes basic mempool autotests. > > Signed-off-by: Olivier Matz > Signed-off-by: David Hunt > > --- > app/test/test_mempool.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 113 insertions(+) > > diff --git a/app/test/test_mempool.c b/app/test/test_mempool.c > index 9f02758..f55d126 100644 > --- a/app/test/test_mempool.c > +++ b/app/test/test_mempool.c > @@ -85,6 +85,96 @@ > static rte_atomic32_t synchro; > > /* > + * Simple example of custom mempool structure. Holds pointers to all the > + * elements which are simply malloc'd in this example. > + */ > +struct custom_mempool { > + rte_spinlock_t lock; > + unsigned count; > + unsigned size; > + void *elts[]; > +}; > + > +/* > + * Loop though all the element pointers and allocate a chunk of memory, then s/though/through/ > + * insert that memory into the ring. > + */ > +static void * > +custom_mempool_alloc(struct rte_mempool *mp) > +{ > + struct custom_mempool *cm; > + > + cm = rte_zmalloc("custom_mempool", > + sizeof(struct custom_mempool) + mp->size * sizeof(void *), 0); > + if (cm == NULL) > + return NULL; > + > + rte_spinlock_init(&cm->lock); > + cm->count = 0; > + cm->size = mp->size; > + return cm; > +} > + > +static void > +custom_mempool_free(void *p) > +{ > + rte_free(p); > +} > + > +static int > +custom_mempool_put(void *p, void * const *obj_table, unsigned n) > +{ > + struct custom_mempool *cm = (struct custom_mempool *)p; > + int ret = 0; > + > + rte_spinlock_lock(&cm->lock); > + if (cm->count + n > cm->size) { > + ret = -ENOBUFS; > + } else { > + memcpy(&cm->elts[cm->count], obj_table, sizeof(void *) * n); > + cm->count += n; > + } > + rte_spinlock_unlock(&cm->lock); > + return ret; > +} > + > + > +static int > +custom_mempool_get(void *p, void **obj_table, unsigned n) > +{ > + struct custom_mempool *cm = (struct custom_mempool *)p; > + int ret = 0; > + > + rte_spinlock_lock(&cm->lock); > + if (n > cm->count) { > + ret = -ENOENT; > + } else { > + cm->count -= n; > + memcpy(obj_table, &cm->elts[cm->count], sizeof(void *) * n); > + } > + rte_spinlock_unlock(&cm->lock); > + return ret; > +} > + > +static unsigned > +custom_mempool_get_count(void *p) > +{ > + struct custom_mempool *cm = (struct custom_mempool *)p; > + return cm->count; > +} > + > +static struct rte_mempool_handler mempool_handler_custom = { > + .name = "custom_handler", > + .alloc = custom_mempool_alloc, > + .free = custom_mempool_free, > + .put = custom_mempool_put, > + .get = custom_mempool_get, > + .get_count = custom_mempool_get_count, > +}; > + > +MEMPOOL_REGISTER_HANDLER(mempool_handler_custom); What about to drop the rte_mempool_handler.name field and derive the name from the variable name given to the MEMPOOL_REGISTER_HANDLER. The MEMPOOL_REGISTER_HANDLER sould do some macro magic inside and call rte_mempool_handler_register(name, handler); Just an idea... > + > +/* > * save the object number in the first 4 bytes of object data. All > * other bytes are set to 0. > */ > @@ -479,6 +569,7 @@ test_mempool(void) > { > struct rte_mempool *mp_cache = NULL; > struct rte_mempool *mp_nocache = NULL; > + struct rte_mempool *mp_ext = NULL; > > rte_atomic32_init(&synchro); > > @@ -507,6 +598,27 @@ test_mempool(void) > goto err; > } > > + /* create a mempool with an external handler */ > + mp_ext = rte_mempool_create_empty("test_ext", > + MEMPOOL_SIZE, > + MEMPOOL_ELT_SIZE, > + RTE_MEMPOOL_CACHE_MAX_SIZE, 0, > + SOCKET_ID_ANY, 0); > + > + if (mp_ext == NULL) { > + printf("cannot allocate mp_ext mempool\n"); > + goto err; > + } > + if (rte_mempool_set_handler(mp_ext, "custom_handler") < 0) { > + printf("cannot set custom handler\n"); > + goto err; > + } > + if (rte_mempool_populate_default(mp_ext) < 0) { > + printf("cannot populate mp_ext mempool\n"); > + goto err; > + } > + rte_mempool_obj_iter(mp_ext, my_obj_init, NULL); > + The test becomes quite complex. What about having several smaller tests with a clear setup and cleanup steps? > /* retrieve the mempool from its name */ > if (rte_mempool_lookup("test_nocache") != mp_nocache) { > printf("Cannot lookup mempool from its name\n"); > @@ -547,6 +659,7 @@ test_mempool(void) > err: > rte_mempool_free(mp_nocache); > rte_mempool_free(mp_cache); > + rte_mempool_free(mp_ext); > return -1; > } >