[dpdk-dev,2/2] mem: fix freeing an IVSHMEM memzone
Commit Message
There is no sync between host and guest to allow removal of memzones,
and freeing them result in undefined behavior.
In the guest, we identify IVSHMEM memsegs/memzones by having
ioremap_addr != 0. In the host, nothing is done to the memzone, meaning
ioremap_addr == 0.
As a solution, mark memzones being added to IVSHMEM in the host, by
setting ioremap_addr, then return an error whenever we try to free an
IVSHMEM memzone.
Fixes: ff909fe21f0 ("mem: introduce memzone freeing")
Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
lib/librte_eal/common/eal_common_memzone.c | 8 ++++++++
lib/librte_eal/common/include/rte_memzone.h | 4 +++-
lib/librte_ivshmem/rte_ivshmem.c | 15 +++++++++++++++
3 files changed, 26 insertions(+), 1 deletion(-)
Comments
2015-08-07 16:27, Sergio Gonzalez Monroy:
> There is no sync between host and guest to allow removal of memzones,
> and freeing them result in undefined behavior.
>
> In the guest, we identify IVSHMEM memsegs/memzones by having
> ioremap_addr != 0. In the host, nothing is done to the memzone, meaning
> ioremap_addr == 0.
>
> As a solution, mark memzones being added to IVSHMEM in the host, by
> setting ioremap_addr, then return an error whenever we try to free an
> IVSHMEM memzone.
>
> Fixes: ff909fe21f0 ("mem: introduce memzone freeing")
>
> Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
Series applied, thanks
@@ -322,6 +322,14 @@ rte_memzone_free(const struct rte_memzone *mz)
idx = idx / sizeof(struct rte_memzone);
addr = mcfg->memzone[idx].addr;
+#ifdef RTE_LIBRTE_IVSHMEM
+ /*
+ * If ioremap_addr is set, it's an IVSHMEM memzone and we cannot
+ * free it.
+ */
+ if (mcfg->memzone[idx].ioremap_addr != 0)
+ ret = -EINVAL;
+#endif
if (addr == NULL)
ret = -EINVAL;
else if (mcfg->memzone_cnt == 0) {
@@ -258,10 +258,12 @@ const struct rte_memzone *rte_memzone_reserve_bounded(const char *name,
/**
* Free a memzone.
*
+ * Note: an IVSHMEM zone cannot be freed.
+ *
* @param mz
* A pointer to the memzone
* @return
- * -EINVAL - invalid parameter
+ * -EINVAL - invalid parameter, IVSHMEM memzone.
* 0 - success
*/
int rte_memzone_free(const struct rte_memzone *mz);
@@ -504,7 +504,22 @@ add_memzone_to_metadata(const struct rte_memzone * mz,
config->metadata->name);
goto fail;
}
+#ifdef RTE_LIBRTE_IVSHMEM
+ struct rte_mem_config *mcfg;
+ unsigned int idx;
+ mcfg = rte_eal_get_configuration()->mem_config;
+
+ rte_rwlock_write_lock(&mcfg->mlock);
+
+ idx = ((uintptr_t)mz - (uintptr_t)mcfg->memzone);
+ idx = idx / sizeof(struct rte_memzone);
+
+ /* mark the memzone not freeable */
+ mcfg->memzone[idx].ioremap_addr = mz->phys_addr;
+
+ rte_rwlock_write_unlock(&mcfg->mlock);
+#endif
rte_spinlock_unlock(&config->sl);
return 0;
fail: