[dpdk-dev,1/2] eal/mempool: introduce check for external mempool availability
Commit Message
External offloaded mempool may not be available always. This check enables
run time verification of the presence of external mempool before the
mempool ops are installed.
An application built with a specific external mempool may work fine
on host. But, may not work on VM, specificaly if non-hw specific interfaces
are used e.g. virtio-net.
This is required to make sure that same application can work in all
environment for a given hw platform.
The solution proposed here is that rte_mempool_set_ops_byname should return
specific error in case the current execution environment is not supporting
the given mempool. Thereby allowing it to fallback on software mempool
implementation e.g. "ring_mp_mc"
This patch introduces new optional "pool_verify" as mempool ops function
to check if external mempool instance is available or not.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_mempool/rte_mempool.h | 21 +++++++++++++++++++++
lib/librte_mempool/rte_mempool_ops.c | 18 ++++++++++++++++++
lib/librte_mempool/rte_mempool_ring.c | 4 ++++
lib/librte_mempool/rte_mempool_stack.c | 3 ++-
4 files changed, 45 insertions(+), 1 deletion(-)
@@ -385,6 +385,12 @@ typedef int (*rte_mempool_dequeue_t)(struct rte_mempool *mp,
*/
typedef unsigned (*rte_mempool_get_count)(const struct rte_mempool *mp);
+/**
+ * Return if the given external mempool is available for this instance.
+ * it is optional to implement for mempools
+ */
+typedef int (*rte_mempool_pool_verify)(const struct rte_mempool *mp);
+
/** Structure defining mempool operations structure */
struct rte_mempool_ops {
char name[RTE_MEMPOOL_OPS_NAMESIZE]; /**< Name of mempool ops struct. */
@@ -393,6 +399,8 @@ struct rte_mempool_ops {
rte_mempool_enqueue_t enqueue; /**< Enqueue an object. */
rte_mempool_dequeue_t dequeue; /**< Dequeue an object. */
rte_mempool_get_count get_count; /**< Get qty of available objs. */
+ rte_mempool_pool_verify pool_verify;
+ /**< Verify if external mempool is available for usages*/
} __rte_cache_aligned;
#define RTE_MEMPOOL_MAX_OPS_IDX 16 /**< Max registered ops structs */
@@ -514,6 +522,18 @@ void
rte_mempool_ops_free(struct rte_mempool *mp);
/**
+ * @internal wrapper to verify the external mempool availability
+ *
+ * @param mp
+ * Pointer to the memory pool.
+ * @return
+ * 0: Success; external mempool instance is available
+ * - <0: Error; external mempool instance is not available
+ */
+int
+rte_mempool_ops_pool_verify(const struct rte_mempool *mp);
+
+/**
* Set the ops of a mempool.
*
* This can only be done on a mempool that is not populated, i.e. just after
@@ -529,6 +549,7 @@ rte_mempool_ops_free(struct rte_mempool *mp);
* - 0: Success; the mempool is now using the requested ops functions.
* - -EINVAL - Invalid ops struct name provided.
* - -EEXIST - mempool already has an ops struct assigned.
+ * - -EOPNOTSUPP - mempool instance not available.
*/
int
rte_mempool_set_ops_byname(struct rte_mempool *mp, const char *name,
@@ -123,6 +123,18 @@ rte_mempool_ops_get_count(const struct rte_mempool *mp)
return ops->get_count(mp);
}
+/* wrapper to check if given external mempool is available for this instance.*/
+int
+rte_mempool_ops_pool_verify(const struct rte_mempool *mp)
+{
+ struct rte_mempool_ops *ops;
+
+ ops = rte_mempool_get_ops(mp->ops_index);
+ if (ops->pool_verify)
+ return ops->pool_verify(mp);
+ return 0;
+}
+
/* sets mempool ops previously registered by rte_mempool_register_ops. */
int
rte_mempool_set_ops_byname(struct rte_mempool *mp, const char *name,
@@ -146,6 +158,12 @@ rte_mempool_set_ops_byname(struct rte_mempool *mp, const char *name,
if (ops == NULL)
return -EINVAL;
+ /*verify if the given mempool is available for this instance */
+ if (ops->pool_verify) {
+ if (ops->pool_verify(mp))
+ return -EOPNOTSUPP;
+ }
+
mp->ops_index = i;
mp->pool_config = pool_config;
return 0;
@@ -126,6 +126,7 @@ static const struct rte_mempool_ops ops_mp_mc = {
.enqueue = common_ring_mp_enqueue,
.dequeue = common_ring_mc_dequeue,
.get_count = common_ring_get_count,
+ .pool_verify = NULL,
};
static const struct rte_mempool_ops ops_sp_sc = {
@@ -135,6 +136,7 @@ static const struct rte_mempool_ops ops_sp_sc = {
.enqueue = common_ring_sp_enqueue,
.dequeue = common_ring_sc_dequeue,
.get_count = common_ring_get_count,
+ .pool_verify = NULL,
};
static const struct rte_mempool_ops ops_mp_sc = {
@@ -144,6 +146,7 @@ static const struct rte_mempool_ops ops_mp_sc = {
.enqueue = common_ring_mp_enqueue,
.dequeue = common_ring_sc_dequeue,
.get_count = common_ring_get_count,
+ .pool_verify = NULL,
};
static const struct rte_mempool_ops ops_sp_mc = {
@@ -153,6 +156,7 @@ static const struct rte_mempool_ops ops_sp_mc = {
.enqueue = common_ring_sp_enqueue,
.dequeue = common_ring_mc_dequeue,
.get_count = common_ring_get_count,
+ .pool_verify = NULL,
};
MEMPOOL_REGISTER_OPS(ops_mp_mc);
@@ -141,7 +141,8 @@ static struct rte_mempool_ops ops_stack = {
.free = stack_free,
.enqueue = stack_enqueue,
.dequeue = stack_dequeue,
- .get_count = stack_get_count
+ .get_count = stack_get_count,
+ .pool_verify = NULL,
};
MEMPOOL_REGISTER_OPS(ops_stack);