[dpdk-dev] ivshmem: fix race condition

Message ID 1459498608-10789-1-git-send-email-mauricio.vasquezbernal@studenti.polito.it (mailing list archive)
State Superseded, archived
Headers

Commit Message

Mauricio Vasquez B April 1, 2016, 8:16 a.m. UTC
  The memory zone could be freed just after adding it to the metadata
file and just before marking it as not freeable.
This patch changes the locking logic in order to prevent it.

Fixes: cd10c42eb5bc ("mem: fix ivshmem freeing")

Signed-off-by: Mauricio Vasquez B <mauricio.vasquezbernal@studenti.polito.it>
---
 lib/librte_ivshmem/rte_ivshmem.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)
  

Comments

Anatoly Burakov April 1, 2016, 9:01 a.m. UTC | #1
Hi Mauricio,

> The memory zone could be freed just after adding it to the metadata
> file and just before marking it as not freeable.
> This patch changes the locking logic in order to prevent it.

Just a nit: if the stated purpose of the patch is to prevent the memzone free
before adding it to metadata, then it probably should check if the memzone
wasn't freed before we got the lock (or if it's a valid memzone in the first place).
Probably just checking if the virtual address of the memzone isn't 0 would be
enough. Otherwise looks fine to me.

Thanks,
Anatoly
  
Mauricio Vasquez B April 1, 2016, 11:17 a.m. UTC | #2
Hi Anatoly,

On Fri, Apr 1, 2016 at 11:01 AM, Burakov, Anatoly <anatoly.burakov@intel.com
> wrote:

> Hi Mauricio,
>
> > The memory zone could be freed just after adding it to the metadata
> > file and just before marking it as not freeable.
> > This patch changes the locking logic in order to prevent it.
>
> Just a nit: if the stated purpose of the patch is to prevent the memzone
> free
> before adding it to metadata, then it probably should check if the memzone
> wasn't freed before we got the lock (or if it's a valid memzone in the
> first place).
> Probably just checking if the virtual address of the memzone isn't 0 would
> be
> enough. Otherwise looks fine to me.
>
>
The purpose of this patch is to avoid a memzone be freed after it has been
added to the metadata but
before it is marked as not freeable. (that small time interval where it is
possible).

Avoid adding an already freed memzone is another case, I will send a v2
that addresses it.
I used the length of the memzone to check whether the memzone is valid or
not.


> Thanks,
> Anatoly
>

Mauricio Vasquez,
  

Patch

diff --git a/lib/librte_ivshmem/rte_ivshmem.c b/lib/librte_ivshmem/rte_ivshmem.c
index 8fc4b57..ed2c276 100644
--- a/lib/librte_ivshmem/rte_ivshmem.c
+++ b/lib/librte_ivshmem/rte_ivshmem.c
@@ -471,10 +471,16 @@  add_memzone_to_metadata(const struct rte_memzone * mz,
 		struct ivshmem_config * config)
 {
 	struct rte_ivshmem_metadata_entry * entry;
-	unsigned i;
+	unsigned i, idx;
+	struct rte_mem_config *mcfg;
 
 	rte_spinlock_lock(&config->sl);
 
+	mcfg = rte_eal_get_configuration()->mem_config;
+
+	/* it prevents the memzone being freed while we add it to the metadata */
+	rte_rwlock_write_lock(&mcfg->mlock);
+
 	/* find free slot in this config */
 	for (i = 0; i < RTE_DIM(config->metadata->entry); i++) {
 		entry = &config->metadata->entry[i];
@@ -504,13 +510,6 @@  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);
@@ -519,10 +518,10 @@  add_memzone_to_metadata(const struct rte_memzone * mz,
 	mcfg->memzone[idx].ioremap_addr = mz->phys_addr;
 
 	rte_rwlock_write_unlock(&mcfg->mlock);
-#endif
 	rte_spinlock_unlock(&config->sl);
 	return 0;
 fail:
+	rte_rwlock_write_unlock(&mcfg->mlock);
 	rte_spinlock_unlock(&config->sl);
 	return -1;
 }