DPDK patches and discussions
 help / color / mirror / Atom feed
From: Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>
To: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>,
	"stephen@networkplumber.org" <stephen@networkplumber.org>,
	"paulmck@linux.ibm.com" <paulmck@linux.ibm.com>
Cc: "Wang, Yipeng1" <yipeng1.wang@intel.com>,
	"Medvedkin, Vladimir" <vladimir.medvedkin@intel.com>,
	"Ruifeng Wang (Arm Technology China)" <Ruifeng.Wang@arm.com>,
	Dharmik Thakkar <Dharmik.Thakkar@arm.com>,
	Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>,
	"dev@dpdk.org" <dev@dpdk.org>, nd <nd@arm.com>, nd <nd@arm.com>
Subject: Re: [dpdk-dev] [PATCH v3 2/3] lib/rcu: add resource reclamation APIs
Date: Thu, 3 Oct 2019 06:29:28 +0000	[thread overview]
Message-ID: <VE1PR08MB514912CDFC19476AF82B197F989F0@VE1PR08MB5149.eurprd08.prod.outlook.com> (raw)
In-Reply-To: <2601191342CEEE43887BDE71AB977258019196FF8E@irsmsx105.ger.corp.intel.com>

> 
> Hi Honnappa,
Thanks Konstantin for the feedback.

> 
> 
> > Add resource reclamation APIs to make it simple for applications and
> > libraries to integrate rte_rcu library.
> >
> > Signed-off-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > Reviewed-by: Ola Liljedhal <ola.liljedhal@arm.com>
> > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > ---
> >  app/test/test_rcu_qsbr.c           | 291 ++++++++++++++++++++++++++++-
> >  lib/librte_rcu/meson.build         |   2 +
> >  lib/librte_rcu/rte_rcu_qsbr.c      | 185 ++++++++++++++++++
> >  lib/librte_rcu/rte_rcu_qsbr.h      | 169 +++++++++++++++++
> >  lib/librte_rcu/rte_rcu_qsbr_pvt.h  |  46 +++++
> >  lib/librte_rcu/rte_rcu_version.map |   4 +
> >  lib/meson.build                    |   6 +-
> >  7 files changed, 700 insertions(+), 3 deletions(-)  create mode
> > 100644 lib/librte_rcu/rte_rcu_qsbr_pvt.h
> >
> > diff --git a/lib/librte_rcu/rte_rcu_qsbr.c
> > b/lib/librte_rcu/rte_rcu_qsbr.c index ce7f93dd3..76814f50b 100644
> > --- a/lib/librte_rcu/rte_rcu_qsbr.c
> > +++ b/lib/librte_rcu/rte_rcu_qsbr.c
> > @@ -21,6 +21,7 @@
> >  #include <rte_errno.h>
> >
> >  #include "rte_rcu_qsbr.h"
> > +#include "rte_rcu_qsbr_pvt.h"
> >
> >  /* Get the memory size of QSBR variable */  size_t @@ -267,6 +268,190
> > @@ rte_rcu_qsbr_dump(FILE *f, struct rte_rcu_qsbr *v)
> >  	return 0;
> >  }
> >
> > +/* Create a queue used to store the data structure elements that can
> > + * be freed later. This queue is referred to as 'defer queue'.
> > + */
> > +struct rte_rcu_qsbr_dq *
> > +rte_rcu_qsbr_dq_create(const struct rte_rcu_qsbr_dq_parameters
> > +*params) {
> > +	struct rte_rcu_qsbr_dq *dq;
> > +	uint32_t qs_fifo_size;
> > +
> > +	if (params == NULL || params->f == NULL ||
> > +		params->v == NULL || params->name == NULL ||
> > +		params->size == 0 || params->esize == 0 ||
> > +		(params->esize % 8 != 0)) {
> > +		rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > +			"%s(): Invalid input parameter\n", __func__);
> > +		rte_errno = EINVAL;
> > +
> > +		return NULL;
> > +	}
> > +
> > +	dq = rte_zmalloc(NULL,
> > +		(sizeof(struct rte_rcu_qsbr_dq) + params->esize),
> > +		RTE_CACHE_LINE_SIZE);
> > +	if (dq == NULL) {
> > +		rte_errno = ENOMEM;
> > +
> > +		return NULL;
> > +	}
> > +
> > +	/* round up qs_fifo_size to next power of two that is not less than
> > +	 * max_size.
> > +	 */
> > +	qs_fifo_size = rte_align32pow2((((params->esize/8) + 1)
> > +					* params->size) + 1);
> > +	dq->r = rte_ring_create(params->name, qs_fifo_size,
> > +					SOCKET_ID_ANY, 0);
> 
> If it is going to be not MT safe, then why not to create the ring with
> (RING_F_SP_ENQ | RING_F_SC_DEQ) flags set?
Agree.

> Though I think it could be changed to allow MT safe multiple enqeue/single
> dequeue, see below.
The MT safe issue is due to reclaim code. The reclaim code has the following sequence:

rte_ring_peek
rte_rcu_qsbr_check
rte_ring_dequeue

This entire sequence needs to be atomic as the entry cannot be dequeued without knowing that the grace period for that entry is over. Note that due to optimizations in rte_rcu_qsbr_check API, this sequence should not be large in most cases. I do not have ideas on how to make this sequence lock-free.

If the writer is on the control plane, most use cases will use mutex locks for synchronization if they are multi-threaded. That lock should be enough to provide the thread safety for these APIs.

If the writer is multi-threaded and lock-free, then one should use per thread defer queue.

> 
> > +	if (dq->r == NULL) {
> > +		rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > +			"%s(): defer queue create failed\n", __func__);
> > +		rte_free(dq);
> > +		return NULL;
> > +	}
> > +
> > +	dq->v = params->v;
> > +	dq->size = params->size;
> > +	dq->esize = params->esize;
> > +	dq->f = params->f;
> > +	dq->p = params->p;
> > +
> > +	return dq;
> > +}
> > +
> > +/* Enqueue one resource to the defer queue to free after the grace
> > + * period is over.
> > + */
> > +int rte_rcu_qsbr_dq_enqueue(struct rte_rcu_qsbr_dq *dq, void *e) {
> > +	uint64_t token;
> > +	uint64_t *tmp;
> > +	uint32_t i;
> > +	uint32_t cur_size, free_size;
> > +
> > +	if (dq == NULL || e == NULL) {
> > +		rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > +			"%s(): Invalid input parameter\n", __func__);
> > +		rte_errno = EINVAL;
> > +
> > +		return 1;
> 
> Why just not to return -EINVAL straightway?
> I think there is no much point to set rte_errno in that function at all, just
> return value should do.
I am trying to keep these consistent with the existing APIs. They return 0 or 1 and set the rte_errno.

> 
> > +	}
> > +
> > +	/* Start the grace period */
> > +	token = rte_rcu_qsbr_start(dq->v);
> > +
> > +	/* Reclaim resources if the queue is 1/8th full. This helps
> > +	 * the queue from growing too large and allows time for reader
> > +	 * threads to report their quiescent state.
> > +	 */
> > +	cur_size = rte_ring_count(dq->r) / (dq->esize/8 + 1);
> 
> Probably would be a bit easier if you just store in dq->esize (elt size + token
> size) / 8.
Agree

> 
> > +	if (cur_size > (dq->size >> RTE_RCU_QSBR_AUTO_RECLAIM_LIMIT)) {
> 
> Why to make this threshold value hard-coded?
> Why either not to put it into create parameter, or just return a special return
> value, to indicate that threshold is reached?
My thinking was to keep the programming interface easy to use. The more the parameters, the more painful it is for the user. IMO, the constants chosen should be good enough for most cases. More advanced users could modify the constants. However, we could make these as part of the parameters, but make them optional for the user. For ex: if they set them to 0, default values can be used.

> Or even return number of filled/free entroes on success, so caller can decide
> to reclaim or not based on that information on his own?
This means more code on the user side. I think adding these to parameters seems like a better option.

> 
> > +		rte_log(RTE_LOG_INFO, rte_rcu_log_type,
> > +			"%s(): Triggering reclamation\n", __func__);
> > +		rte_rcu_qsbr_dq_reclaim(dq);
> > +	}
> > +
> > +	/* Check if there is space for atleast for 1 resource */
> > +	free_size = rte_ring_free_count(dq->r) / (dq->esize/8 + 1);
> > +	if (!free_size) {
> > +		rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > +			"%s(): Defer queue is full\n", __func__);
> > +		rte_errno = ENOSPC;
> > +		return 1;
> > +	}
> > +
> > +	/* Enqueue the resource */
> > +	rte_ring_sp_enqueue(dq->r, (void *)(uintptr_t)token);
> > +
> > +	/* The resource to enqueue needs to be a multiple of 64b
> > +	 * due to the limitation of the rte_ring implementation.
> > +	 */
> > +	for (i = 0, tmp = (uint64_t *)e; i < dq->esize/8; i++, tmp++)
> > +		rte_ring_sp_enqueue(dq->r, (void *)(uintptr_t)*tmp);
> 
> 
> That whole construction above looks a bit clumsy and error prone...
> I suppose just:
> 
> const uint32_t nb_elt =  dq->elt_size/8 + 1; uint32_t free, n; ...
> n = rte_ring_enqueue_bulk(dq->r, e, nb_elt, &free); if (n == 0)
Yes, bulk enqueue can be used. But note that once the flexible element size ring patch is done, this code will use that.

>   return -ENOSPC;
> return free;
> 
> That way I think you can have MT-safe version of that function.
Please see the description of MT safe issue above.

> 
> > +
> > +	return 0;
> > +}
> > +
> > +/* Reclaim resources from the defer queue. */ int
> > +rte_rcu_qsbr_dq_reclaim(struct rte_rcu_qsbr_dq *dq) {
> > +	uint32_t max_cnt;
> > +	uint32_t cnt;
> > +	void *token;
> > +	uint64_t *tmp;
> > +	uint32_t i;
> > +
> > +	if (dq == NULL) {
> > +		rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > +			"%s(): Invalid input parameter\n", __func__);
> > +		rte_errno = EINVAL;
> > +
> > +		return 1;
> 
> Same story as above - I think rte_errno is excessive in this function.
> Just return value should be enough.
> 
> 
> > +	}
> > +
> > +	/* Anything to reclaim? */
> > +	if (rte_ring_count(dq->r) == 0)
> > +		return 0;
> 
> Not sure you need that, see below.
> 
> > +
> > +	/* Reclaim at the max 1/16th the total number of entries. */
> > +	max_cnt = dq->size >> RTE_RCU_QSBR_MAX_RECLAIM_LIMIT;
> > +	max_cnt = (max_cnt == 0) ? dq->size : max_cnt;
> 
> Again why not to make max_cnt a configurable at create() parameter?
I think making this as an optional parameter for creating defer queue is a better option.

> Or even a parameter for that function?
> 
> > +	cnt = 0;
> > +
> > +	/* Check reader threads quiescent state and reclaim resources */
> > +	while ((cnt < max_cnt) && (rte_ring_peek(dq->r, &token) == 0) &&
> > +		(rte_rcu_qsbr_check(dq->v, (uint64_t)((uintptr_t)token), false)
> > +			== 1)) {
> 
> 
> > +		(void)rte_ring_sc_dequeue(dq->r, &token);
> > +		/* The resource to dequeue needs to be a multiple of 64b
> > +		 * due to the limitation of the rte_ring implementation.
> > +		 */
> > +		for (i = 0, tmp = (uint64_t *)dq->e; i < dq->esize/8;
> > +			i++, tmp++)
> > +			(void)rte_ring_sc_dequeue(dq->r,
> > +					(void *)(uintptr_t)tmp);
> 
> Again, no need for such constructs with multiple dequeuer I believe.
> Just:
> 
> const uint32_t nb_elt =  dq->elt_size/8 + 1; uint32_t n; uintptr_t
> elt[nb_elt]; ...
> n = rte_ring_dequeue_bulk(dq->r, elt, nb_elt, NULL); if (n != 0) {dq->f(dq->p,
> elt);}
Agree on bulk API use.

> 
> Seems enough.
> Again in that case you can have enqueue/reclaim running in different threads
> simultaneously, plus you don't need dq->e at all.
Will check on dq->e

> 
> > +		dq->f(dq->p, dq->e);
> > +
> > +		cnt++;
> > +	}
> > +
> > +	rte_log(RTE_LOG_INFO, rte_rcu_log_type,
> > +		"%s(): Reclaimed %u resources\n", __func__, cnt);
> > +
> > +	if (cnt == 0) {
> > +		/* No resources were reclaimed */
> > +		rte_errno = EAGAIN;
> > +		return 1;
> > +	}
> > +
> > +	return 0;
> 
> I'd suggest to return cnt on success.
I am trying to keep the APIs simple. I do not see much use for 'cnt' as return value to the user. It exposes more details which I think are internal to the library.

> 
> > +}
> > +
> > +/* Delete a defer queue. */
> > +int
> > +rte_rcu_qsbr_dq_delete(struct rte_rcu_qsbr_dq *dq) {
> > +	if (dq == NULL) {
> > +		rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > +			"%s(): Invalid input parameter\n", __func__);
> > +		rte_errno = EINVAL;
> > +
> > +		return 1;
> > +	}
> > +
> > +	/* Reclaim all the resources */
> > +	if (rte_rcu_qsbr_dq_reclaim(dq) != 0)
> > +		/* Error number is already set by the reclaim API */
> > +		return 1;
> 
> How do you know that you have reclaimed everything?
Good point, will come back with a different solution.

> 
> > +
> > +	rte_ring_free(dq->r);
> > +	rte_free(dq);
> > +
> > +	return 0;
> > +}
> > +
> >  int rte_rcu_log_type;
> >
> >  RTE_INIT(rte_rcu_register)
> > diff --git a/lib/librte_rcu/rte_rcu_qsbr.h
> > b/lib/librte_rcu/rte_rcu_qsbr.h index c80f15c00..185d4b50a 100644
> > --- a/lib/librte_rcu/rte_rcu_qsbr.h
> > +++ b/lib/librte_rcu/rte_rcu_qsbr.h
> > @@ -34,6 +34,7 @@ extern "C" {
> >  #include <rte_lcore.h>
> >  #include <rte_debug.h>
> >  #include <rte_atomic.h>
> > +#include <rte_ring.h>
> >
> >  extern int rte_rcu_log_type;
> >
> > @@ -109,6 +110,67 @@ struct rte_rcu_qsbr {
> >  	 */
> >  } __rte_cache_aligned;
> >
> > +/**
> > + * Call back function called to free the resources.
> > + *
> > + * @param p
> > + *   Pointer provided while creating the defer queue
> > + * @param e
> > + *   Pointer to the resource data stored on the defer queue
> > + *
> > + * @return
> > + *   None
> > + */
> > +typedef void (*rte_rcu_qsbr_free_resource)(void *p, void *e);
> 
> Stylish thing - usually in DPDK we have typedf newtype_t ...
> Though I am not sure you need a new typedef at all - just a function pointer
> inside the struct seems enough.
Other libraries (for ex: rte_hash) use this approach. I think it is better to keep it out of the structure to allow for better commenting.

> 
> > +
> > +#define RTE_RCU_QSBR_DQ_NAMESIZE RTE_RING_NAMESIZE
> > +
> > +/**
> > + *  Trigger automatic reclamation after 1/8th the defer queue is full.
> > + */
> > +#define RTE_RCU_QSBR_AUTO_RECLAIM_LIMIT 3
> > +
> > +/**
> > + *  Reclaim at the max 1/16th the total number of resources.
> > + */
> > +#define RTE_RCU_QSBR_MAX_RECLAIM_LIMIT 4
> 
> 
> As I said above, I don't think these thresholds need to be hardcoded.
> In any case, there seems not much point to put them in the public header file.
> 
> > +
> > +/**
> > + * Parameters used when creating the defer queue.
> > + */
> > +struct rte_rcu_qsbr_dq_parameters {
> > +	const char *name;
> > +	/**< Name of the queue. */
> > +	uint32_t size;
> > +	/**< Number of entries in queue. Typically, this will be
> > +	 *   the same as the maximum number of entries supported in the
> > +	 *   lock free data structure.
> > +	 *   Data structures with unbounded number of entries is not
> > +	 *   supported currently.
> > +	 */
> > +	uint32_t esize;
> > +	/**< Size (in bytes) of each element in the defer queue.
> > +	 *   This has to be multiple of 8B as the rte_ring APIs
> > +	 *   support 8B element sizes only.
> > +	 */
> > +	rte_rcu_qsbr_free_resource f;
> > +	/**< Function to call to free the resource. */
> > +	void *p;
> 
> Style nit again - I like short names myself, but that seems a bit extreme... :)
> Might be at least:
> void (*reclaim)(void *, void *);
May be 'free_fn'?

> void * reclaim_data;
> ?
This is the pointer to the data structure to free the resource into. For ex: In LPM data structure, it will be pointer to LPM. 'reclaim_data' does not convey the meaning correctly.

> 
> > +	/**< Pointer passed to the free function. Typically, this is the
> > +	 *   pointer to the data structure to which the resource to free
> > +	 *   belongs. This can be NULL.
> > +	 */
> > +	struct rte_rcu_qsbr *v;
> 
> Does it need to be inside that struct?
> Might be better:
> rte_rcu_qsbr_dq_create(struct rte_rcu_qsbr *v, const struct
> rte_rcu_qsbr_dq_parameters *params);
The API takes a parameter structure as input anyway, why to add another argument to the function? QSBR variable is also another parameter.

> 
> Another alternative: make both reclaim() and enqueue() to take v as a
> parameter.
But both of them need access to some of the parameters provided in rte_rcu_qsbr_dq_create API. We would end up passing 2 arguments to the functions.

> 
> > +	/**< RCU QSBR variable to use for this defer queue */ };
> > +
> > +/* RTE defer queue structure.
> > + * This structure holds the defer queue. The defer queue is used to
> > + * hold the deleted entries from the data structure that are not
> > + * yet freed.
> > + */
> > +struct rte_rcu_qsbr_dq;
> > +
> >  /**
> >   * @warning
> >   * @b EXPERIMENTAL: this API may change without prior notice @@
> > -648,6 +710,113 @@ __rte_experimental  int  rte_rcu_qsbr_dump(FILE *f,
> > struct rte_rcu_qsbr *v);
> >
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + *
> > + * Create a queue used to store the data structure elements that can
> > + * be freed later. This queue is referred to as 'defer queue'.
> > + *
> > + * @param params
> > + *   Parameters to create a defer queue.
> > + * @return
> > + *   On success - Valid pointer to defer queue
> > + *   On error - NULL
> > + *   Possible rte_errno codes are:
> > + *   - EINVAL - NULL parameters are passed
> > + *   - ENOMEM - Not enough memory
> > + */
> > +__rte_experimental
> > +struct rte_rcu_qsbr_dq *
> > +rte_rcu_qsbr_dq_create(const struct rte_rcu_qsbr_dq_parameters
> > +*params);
> > +
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + *
> > + * Enqueue one resource to the defer queue and start the grace period.
> > + * The resource will be freed later after at least one grace period
> > + * is over.
> > + *
> > + * If the defer queue is full, it will attempt to reclaim resources.
> > + * It will also reclaim resources at regular intervals to avoid
> > + * the defer queue from growing too big.
> > + *
> > + * This API is not multi-thread safe. It is expected that the caller
> > + * provides multi-thread safety by locking a mutex or some other means.
> > + *
> > + * A lock free multi-thread writer algorithm could achieve
> > +multi-thread
> > + * safety by creating and using one defer queue per thread.
> > + *
> > + * @param dq
> > + *   Defer queue to allocate an entry from.
> > + * @param e
> > + *   Pointer to resource data to copy to the defer queue. The size of
> > + *   the data to copy is equal to the element size provided when the
> > + *   defer queue was created.
> > + * @return
> > + *   On success - 0
> > + *   On error - 1 with rte_errno set to
> > + *   - EINVAL - NULL parameters are passed
> > + *   - ENOSPC - Defer queue is full. This condition can not happen
> > + *		if the defer queue size is equal (or larger) than the
> > + *		number of elements in the data structure.
> > + */
> > +__rte_experimental
> > +int
> > +rte_rcu_qsbr_dq_enqueue(struct rte_rcu_qsbr_dq *dq, void *e);
> > +
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + *
> > + * Reclaim resources from the defer queue.
> > + *
> > + * This API is not multi-thread safe. It is expected that the caller
> > + * provides multi-thread safety by locking a mutex or some other means.
> > + *
> > + * A lock free multi-thread writer algorithm could achieve
> > +multi-thread
> > + * safety by creating and using one defer queue per thread.
> > + *
> > + * @param dq
> > + *   Defer queue to reclaim an entry from.
> > + * @return
> > + *   On successful reclamation of at least 1 resource - 0
> > + *   On error - 1 with rte_errno set to
> > + *   - EINVAL - NULL parameters are passed
> > + *   - EAGAIN - None of the resources have completed at least 1 grace
> period,
> > + *		try again.
> > + */
> > +__rte_experimental
> > +int
> > +rte_rcu_qsbr_dq_reclaim(struct rte_rcu_qsbr_dq *dq);
> > +
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + *
> > + * Delete a defer queue.
> > + *
> > + * It tries to reclaim all the resources on the defer queue.
> > + * If any of the resources have not completed the grace period
> > + * the reclamation stops and returns immediately. The rest of
> > + * the resources are not reclaimed and the defer queue is not
> > + * freed.
> > + *
> > + * @param dq
> > + *   Defer queue to delete.
> > + * @return
> > + *   On success - 0
> > + *   On error - 1
> > + *   Possible rte_errno codes are:
> > + *   - EINVAL - NULL parameters are passed
> > + *   - EAGAIN - Some of the resources have not completed at least 1 grace
> > + *		period, try again.
> > + */
> > +__rte_experimental
> > +int
> > +rte_rcu_qsbr_dq_delete(struct rte_rcu_qsbr_dq *dq);
> > +
> >  #ifdef __cplusplus
> >  }
> >  #endif
> > diff --git a/lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > b/lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > new file mode 100644
> > index 000000000..2122bc36a
> > --- /dev/null
> > +++ b/lib/librte_rcu/rte_rcu_qsbr_pvt.h
> 
> Again style suggestion: as it is not public header - don't use rte_ prefix for
> naming.
> From my perspective - easier to relalize for reader what is public header,
> what is not.
Looks like the guidelines are not defined very well. I see one private file with rte_ prefix. I see Stephen not using rte_ prefix. I do not have any preference. But, a consistent approach is required.

> 
> > @@ -0,0 +1,46 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright (c) 2019 Arm Limited
> > + */
> > +
> > +#ifndef _RTE_RCU_QSBR_PVT_H_
> > +#define _RTE_RCU_QSBR_PVT_H_
> > +
> > +/**
> > + * This file is private to the RCU library. It should not be included
> > + * by the user of this library.
> > + */
> > +
> > +#ifdef __cplusplus
> > +extern "C" {
> > +#endif
> > +
> > +#include "rte_rcu_qsbr.h"
> > +
> > +/* RTE defer queue structure.
> > + * This structure holds the defer queue. The defer queue is used to
> > + * hold the deleted entries from the data structure that are not
> > + * yet freed.
> > + */
> > +struct rte_rcu_qsbr_dq {
> > +	struct rte_rcu_qsbr *v; /**< RCU QSBR variable used by this queue.*/
> > +	struct rte_ring *r;     /**< RCU QSBR defer queue. */
> > +	uint32_t size;
> > +	/**< Number of elements in the defer queue */
> > +	uint32_t esize;
> > +	/**< Size (in bytes) of data stored on the defer queue */
> > +	rte_rcu_qsbr_free_resource f;
> > +	/**< Function to call to free the resource. */
> > +	void *p;
> > +	/**< Pointer passed to the free function. Typically, this is the
> > +	 *   pointer to the data structure to which the resource to free
> > +	 *   belongs.
> > +	 */
> > +	char e[0];
> > +	/**< Temporary storage to copy the defer queue element. */
> 
> Do you really need 'e' at all?
> Can't it be just temporary stack variable?
Ok, will check.

> 
> > +};
> > +
> > +#ifdef __cplusplus
> > +}
> > +#endif
> > +
> > +#endif /* _RTE_RCU_QSBR_PVT_H_ */
> > diff --git a/lib/librte_rcu/rte_rcu_version.map
> > b/lib/librte_rcu/rte_rcu_version.map
> > index f8b9ef2ab..dfac88a37 100644
> > --- a/lib/librte_rcu/rte_rcu_version.map
> > +++ b/lib/librte_rcu/rte_rcu_version.map
> > @@ -8,6 +8,10 @@ EXPERIMENTAL {
> >  	rte_rcu_qsbr_synchronize;
> >  	rte_rcu_qsbr_thread_register;
> >  	rte_rcu_qsbr_thread_unregister;
> > +	rte_rcu_qsbr_dq_create;
> > +	rte_rcu_qsbr_dq_enqueue;
> > +	rte_rcu_qsbr_dq_reclaim;
> > +	rte_rcu_qsbr_dq_delete;
> >
> >  	local: *;
> >  };
> > diff --git a/lib/meson.build b/lib/meson.build index
> > e5ff83893..0e1be8407 100644
> > --- a/lib/meson.build
> > +++ b/lib/meson.build
> > @@ -11,7 +11,9 @@
> >  libraries = [
> >  	'kvargs', # eal depends on kvargs
> >  	'eal', # everything depends on eal
> > -	'ring', 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
> > +	'ring',
> > +	'rcu', # rcu depends on ring
> > +	'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
> >  	'cmdline',
> >  	'metrics', # bitrate/latency stats depends on this
> >  	'hash',    # efd depends on this
> > @@ -22,7 +24,7 @@ libraries = [
> >  	'gro', 'gso', 'ip_frag', 'jobstats',
> >  	'kni', 'latencystats', 'lpm', 'member',
> >  	'power', 'pdump', 'rawdev',
> > -	'rcu', 'reorder', 'sched', 'security', 'stack', 'vhost',
> > +	'reorder', 'sched', 'security', 'stack', 'vhost',
> >  	# ipsec lib depends on net, crypto and security
> >  	'ipsec',
> >  	# add pkt framework libs which use other libs from above
> > --
> > 2.17.1


  reply	other threads:[~2019-10-03  6:29 UTC|newest]

Thread overview: 137+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-22  6:34 [dpdk-dev] [RFC PATCH 0/3] RCU integration with LPM library Ruifeng Wang
2019-08-22  6:34 ` [dpdk-dev] [RFC PATCH 1/3] doc/rcu: add RCU integration design details Ruifeng Wang
2019-08-22  6:34 ` [dpdk-dev] [RFC PATCH 2/3] lib/ring: add peek API Ruifeng Wang
2019-08-22  6:34 ` [dpdk-dev] [RFC PATCH 3/3] lib/lpm: integrate RCU QSBR Ruifeng Wang
2019-08-23  1:23   ` Stephen Hemminger
2019-08-26  3:11     ` Ruifeng Wang (Arm Technology China)
2019-08-26  5:32       ` Honnappa Nagarahalli
2019-08-22 15:52 ` [dpdk-dev] [RFC PATCH 0/3] RCU integration with LPM library Honnappa Nagarahalli
2019-09-06  9:45 ` [dpdk-dev] [PATCH v2 0/6] " Ruifeng Wang
2019-09-06  9:45   ` [dpdk-dev] [PATCH v2 1/6] doc/rcu: add RCU integration design details Ruifeng Wang
2019-09-06 19:44     ` Honnappa Nagarahalli
2019-09-06  9:45   ` [dpdk-dev] [PATCH v2 2/6] lib/ring: add peek API Ruifeng Wang
2019-09-06  9:45   ` [dpdk-dev] [PATCH v2 3/6] lib/lpm: integrate RCU QSBR Ruifeng Wang
2019-09-06 19:44     ` Honnappa Nagarahalli
2019-09-18 16:15     ` Medvedkin, Vladimir
2019-09-19  6:17       ` Ruifeng Wang (Arm Technology China)
2019-09-06  9:45   ` [dpdk-dev] [PATCH v2 4/6] app/test: add test case for LPM RCU integration Ruifeng Wang
2019-09-06 19:45     ` Honnappa Nagarahalli
2019-09-06  9:45   ` [dpdk-dev] [PATCH v2 5/6] test/lpm: reset total time Ruifeng Wang
2019-09-18 16:17     ` Medvedkin, Vladimir
2019-09-19  6:22       ` Ruifeng Wang (Arm Technology China)
2019-09-06  9:45   ` [dpdk-dev] [PATCH v2 6/6] test/lpm: add RCU integration performance tests Ruifeng Wang
2019-09-06 19:46     ` Honnappa Nagarahalli
2019-10-01  6:29   ` [dpdk-dev] [PATCH v3 0/3] Add RCU reclamation APIs Honnappa Nagarahalli
2019-10-01  6:29     ` [dpdk-dev] [PATCH v3 1/3] lib/ring: add peek API Honnappa Nagarahalli
2019-10-02 18:42       ` Ananyev, Konstantin
2019-10-03 19:49         ` Honnappa Nagarahalli
2019-10-07  9:01           ` Ananyev, Konstantin
2019-10-09  4:25             ` Honnappa Nagarahalli
2019-10-10 15:09               ` Ananyev, Konstantin
2019-10-11  5:03                 ` Honnappa Nagarahalli
2019-10-11 14:41                   ` Ananyev, Konstantin
2019-10-11 18:28                     ` Honnappa Nagarahalli
2019-10-13 20:09                       ` Ananyev, Konstantin
2019-10-14  4:11                         ` Honnappa Nagarahalli
2019-10-01  6:29     ` [dpdk-dev] [PATCH v3 2/3] lib/rcu: add resource reclamation APIs Honnappa Nagarahalli
2019-10-02 17:39       ` Ananyev, Konstantin
2019-10-03  6:29         ` Honnappa Nagarahalli [this message]
2019-10-03 12:26           ` Ananyev, Konstantin
2019-10-04  6:07             ` Honnappa Nagarahalli
2019-10-07 10:46               ` Ananyev, Konstantin
2019-10-13  4:35                 ` Honnappa Nagarahalli
2019-10-02 18:50       ` Ananyev, Konstantin
2019-10-03  6:42         ` Honnappa Nagarahalli
2019-10-03 11:52           ` Ananyev, Konstantin
2019-10-04 19:01       ` Medvedkin, Vladimir
2019-10-07 13:11       ` Medvedkin, Vladimir
2019-10-13  3:02         ` Honnappa Nagarahalli
2019-10-15 16:48           ` Medvedkin, Vladimir
2019-10-18  3:47             ` Honnappa Nagarahalli
2019-10-01  6:29     ` [dpdk-dev] [PATCH v3 3/3] doc/rcu: add RCU integration design details Honnappa Nagarahalli
2020-03-29 20:57     ` [dpdk-dev] [PATCH v3 0/3] Add RCU reclamation APIs Thomas Monjalon
2020-03-30 17:37       ` Honnappa Nagarahalli
2020-04-03 18:41     ` [dpdk-dev] [PATCH v4 0/4] " Honnappa Nagarahalli
2020-04-03 18:41       ` [dpdk-dev] [PATCH v4 1/4] lib/rcu: add resource " Honnappa Nagarahalli
2020-04-07 17:39         ` Ananyev, Konstantin
2020-04-19 23:22           ` Honnappa Nagarahalli
2020-04-20  8:19             ` Ananyev, Konstantin
2020-04-03 18:41       ` [dpdk-dev] [PATCH v4 2/4] test/rcu: test cases for RCU defer queue APIs Honnappa Nagarahalli
2020-04-03 18:41       ` [dpdk-dev] [PATCH v4 3/4] doc/rcu: add RCU integration design details Honnappa Nagarahalli
2020-04-03 18:41       ` [dpdk-dev] [PATCH v4 4/4] lib/rcu: add additional debug logs Honnappa Nagarahalli
2020-04-22  3:30     ` [dpdk-dev] [PATCH v5 0/4] Add RCU reclamation APIs Honnappa Nagarahalli
2020-04-22  3:30       ` [dpdk-dev] [PATCH v5 1/4] lib/rcu: add resource " Honnappa Nagarahalli
2020-04-22  8:36         ` Ananyev, Konstantin
2020-04-22  8:42           ` David Marchand
2020-04-22  8:51             ` David Marchand
2020-04-22  9:26               ` Ananyev, Konstantin
2020-04-22  3:30       ` [dpdk-dev] [PATCH v5 2/4] test/rcu: test cases for RCU defer queue APIs Honnappa Nagarahalli
2020-04-22  8:27         ` Ananyev, Konstantin
2020-04-22  3:30       ` [dpdk-dev] [PATCH v5 3/4] doc/rcu: add RCU integration design details Honnappa Nagarahalli
2020-04-22  3:30       ` [dpdk-dev] [PATCH v5 4/4] lib/rcu: add additional debug logs Honnappa Nagarahalli
2020-04-22  8:25         ` Ananyev, Konstantin
2020-04-22 18:46       ` [dpdk-dev] [PATCH v5 0/4] Add RCU reclamation APIs David Marchand
2019-10-01 18:28   ` [dpdk-dev] [PATCH v3 0/3] RCU integration with LPM library Honnappa Nagarahalli
2019-10-01 18:28     ` [dpdk-dev] [PATCH v3 1/3] lib/lpm: integrate RCU QSBR Honnappa Nagarahalli
2019-10-04 16:05       ` Medvedkin, Vladimir
2019-10-09  3:48         ` Honnappa Nagarahalli
2019-10-07  9:21       ` Ananyev, Konstantin
2019-10-13  4:36         ` Honnappa Nagarahalli
2019-10-15 11:15           ` Ananyev, Konstantin
2019-10-18  3:32             ` Honnappa Nagarahalli
2019-10-01 18:28     ` [dpdk-dev] [PATCH v3 2/3] app/test: add test case for LPM RCU integration Honnappa Nagarahalli
2019-10-01 18:28     ` [dpdk-dev] [PATCH v3 3/3] test/lpm: add RCU integration performance tests Honnappa Nagarahalli
2019-10-02 13:02       ` Aaron Conole
2019-10-03  9:09         ` Bruce Richardson
2020-06-08  5:16   ` [dpdk-dev] [PATCH v4 0/3] RCU integration with LPM library Ruifeng Wang
2020-06-08  5:16     ` [dpdk-dev] [PATCH v4 1/3] lib/lpm: integrate RCU QSBR Ruifeng Wang
2020-06-08 18:46       ` Honnappa Nagarahalli
2020-06-18 17:36         ` Medvedkin, Vladimir
2020-06-18 17:21       ` Medvedkin, Vladimir
2020-06-22  5:46         ` Ruifeng Wang
2020-06-23  4:34           ` Honnappa Nagarahalli
2020-06-08  5:16     ` [dpdk-dev] [PATCH v4 2/3] test/lpm: add LPM RCU integration functional tests Ruifeng Wang
2020-06-08  5:16     ` [dpdk-dev] [PATCH v4 3/3] test/lpm: add RCU integration performance tests Ruifeng Wang
2020-06-29  8:02   ` [dpdk-dev] [PATCH v5 0/3] RCU integration with LPM library Ruifeng Wang
2020-06-29  8:02     ` [dpdk-dev] [PATCH v5 1/3] lib/lpm: integrate RCU QSBR Ruifeng Wang
2020-06-29 11:56       ` David Marchand
2020-06-29 12:55         ` Bruce Richardson
2020-06-30 10:35           ` Kinsella, Ray
2020-07-03  7:43         ` David Marchand
2020-07-04 17:00         ` Ruifeng Wang
2020-06-30 10:33       ` Kinsella, Ray
2020-06-29  8:02     ` [dpdk-dev] [PATCH v5 2/3] test/lpm: add LPM RCU integration functional tests Ruifeng Wang
2020-06-29  8:03     ` [dpdk-dev] [PATCH v5 3/3] test/lpm: add RCU integration performance tests Ruifeng Wang
2020-07-07 14:40   ` [dpdk-dev] [PATCH v6 0/3] RCU integration with LPM library Ruifeng Wang
2020-07-07 14:40     ` [dpdk-dev] [PATCH v6 1/3] lib/lpm: integrate RCU QSBR Ruifeng Wang
2020-07-07 14:40     ` [dpdk-dev] [PATCH v6 2/3] test/lpm: add LPM RCU integration functional tests Ruifeng Wang
2020-07-07 14:40     ` [dpdk-dev] [PATCH v6 3/3] test/lpm: add RCU integration performance tests Ruifeng Wang
2020-07-07 15:15   ` [dpdk-dev] [PATCH v7 0/3] RCU integration with LPM library Ruifeng Wang
2020-07-07 15:15     ` [dpdk-dev] [PATCH v7 1/3] lib/lpm: integrate RCU QSBR Ruifeng Wang
2020-07-08 12:36       ` Medvedkin, Vladimir
2020-07-08 14:30       ` David Marchand
2020-07-08 15:34         ` Ruifeng Wang
2020-07-07 15:15     ` [dpdk-dev] [PATCH v7 2/3] test/lpm: add LPM RCU integration functional tests Ruifeng Wang
2020-07-08 12:37       ` Medvedkin, Vladimir
2020-07-08 14:00         ` Ruifeng Wang
2020-07-07 15:15     ` [dpdk-dev] [PATCH v7 3/3] test/lpm: add RCU integration performance tests Ruifeng Wang
2020-07-08 12:37       ` Medvedkin, Vladimir
2020-07-08 14:07         ` Ruifeng Wang
2020-07-09  8:02   ` [dpdk-dev] [PATCH v8 0/3] RCU integration with LPM library Ruifeng Wang
2020-07-09  8:02     ` [dpdk-dev] [PATCH v8 1/3] lib/lpm: integrate RCU QSBR Ruifeng Wang
2020-07-09 11:49       ` David Marchand
2020-07-09 14:35         ` Ruifeng Wang
2020-07-09  8:02     ` [dpdk-dev] [PATCH v8 2/3] test/lpm: add LPM RCU integration functional tests Ruifeng Wang
2020-07-09  8:02     ` [dpdk-dev] [PATCH v8 3/3] test/lpm: add RCU integration performance tests Ruifeng Wang
2020-07-09 15:42   ` [dpdk-dev] [PATCH v9 0/3] RCU integration with LPM library Ruifeng Wang
2020-07-09 15:42     ` [dpdk-dev] [PATCH v9 1/3] lib/lpm: integrate RCU QSBR Ruifeng Wang
2020-07-09 15:42     ` [dpdk-dev] [PATCH v9 2/3] test/lpm: add LPM RCU integration functional tests Ruifeng Wang
2020-07-09 15:42     ` [dpdk-dev] [PATCH v9 3/3] test/lpm: add RCU integration performance tests Ruifeng Wang
2020-07-10  2:22   ` [dpdk-dev] [PATCH v10 0/3] RCU integration with LPM library Ruifeng Wang
2020-07-10  2:22     ` [dpdk-dev] [PATCH v10 1/3] lib/lpm: integrate RCU QSBR Ruifeng Wang
2020-07-10  2:29       ` Ruifeng Wang
2020-07-10  2:22     ` [dpdk-dev] [PATCH v10 2/3] test/lpm: add LPM RCU integration functional tests Ruifeng Wang
2020-07-10  2:22     ` [dpdk-dev] [PATCH v10 3/3] test/lpm: add RCU integration performance tests Ruifeng Wang
2020-07-10  2:29       ` Ruifeng Wang
2020-07-10 12:21     ` [dpdk-dev] [PATCH v10 0/3] RCU integration with LPM library David Marchand
2020-07-10 14:34       ` Ruifeng Wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=VE1PR08MB514912CDFC19476AF82B197F989F0@VE1PR08MB5149.eurprd08.prod.outlook.com \
    --to=honnappa.nagarahalli@arm.com \
    --cc=Dharmik.Thakkar@arm.com \
    --cc=Ruifeng.Wang@arm.com \
    --cc=dev@dpdk.org \
    --cc=konstantin.ananyev@intel.com \
    --cc=nd@arm.com \
    --cc=paulmck@linux.ibm.com \
    --cc=stephen@networkplumber.org \
    --cc=vladimir.medvedkin@intel.com \
    --cc=yipeng1.wang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).