You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/07/02 09:55:55 UTC

[incubator-nuttx] branch master updated: mm: fix memory corruption when loop create/exit thread in SMP mode

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new aa43a02  mm: fix memory corruption when loop create/exit thread in SMP mode
aa43a02 is described below

commit aa43a0215d2806e032f93b88152d88e87fcda7f0
Author: ligd <li...@xiaomi.com>
AuthorDate: Mon Jun 21 16:20:44 2021 +0800

    mm: fix memory corruption when loop create/exit thread in SMP mode
    
    Root casue:
    when do thread exit, need add free stack operation to mm_delaylist,
    but in SMP mode, CPU0 thread1 exit, at this time, CPU1 call malloc
    and free mm_delaylist.
    
    Fix:
    Divide mm_delaylist for per CPU in SMP mode.
    
    Change-Id: Ibf7d04614ea2f99fb5b506356b7346a0d94f0590
    Signed-off-by: ligd <li...@xiaomi.com>
---
 arch/sim/src/sim/up_heap.c | 19 +++++++++++++------
 mm/mm_heap/mm.h            |  6 +++++-
 mm/mm_heap/mm_free.c       |  4 ++--
 mm/mm_heap/mm_initialize.c | 12 +-----------
 mm/mm_heap/mm_malloc.c     |  4 ++--
 5 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/arch/sim/src/sim/up_heap.c b/arch/sim/src/sim/up_heap.c
index b82f629..07796b7 100644
--- a/arch/sim/src/sim/up_heap.c
+++ b/arch/sim/src/sim/up_heap.c
@@ -48,7 +48,11 @@ struct mm_delaynode_s
 
 struct mm_heap_impl_s
 {
-  struct mm_delaynode_s *mm_delaylist;
+#ifdef CONFIG_SMP
+  struct mm_delaynode_s *mm_delaylist[CONFIG_SMP_NCPUS];
+#else
+  struct mm_delaynode_s *mm_delaylist[1];
+#endif
 };
 
 /****************************************************************************
@@ -65,8 +69,8 @@ static void mm_add_delaylist(FAR struct mm_heap_s *heap, FAR void *mem)
 
   flags = enter_critical_section();
 
-  tmp->flink = heap->mm_impl->mm_delaylist;
-  heap->mm_impl->mm_delaylist = tmp;
+  tmp->flink = heap->mm_impl->mm_delaylist[up_cpu_index()];
+  heap->mm_impl->mm_delaylist[up_cpu_index()] = tmp;
 
   leave_critical_section(flags);
 }
@@ -83,8 +87,8 @@ static void mm_free_delaylist(FAR struct mm_heap_s *heap)
 
   flags = enter_critical_section();
 
-  tmp = heap->mm_impl->mm_delaylist;
-  heap->mm_impl->mm_delaylist = NULL;
+  tmp = heap->mm_impl->mm_delaylist[up_cpu_index()];
+  heap->mm_impl->mm_delaylist[up_cpu_index()] = NULL;
 
   leave_critical_section(flags);
 
@@ -135,8 +139,11 @@ void mm_initialize(FAR struct mm_heap_s *heap, FAR void *heap_start,
                    size_t heap_size)
 {
   FAR struct mm_heap_impl_s *impl;
+
   impl = host_malloc(sizeof(struct mm_heap_impl_s));
-  impl->mm_delaylist = NULL;
+  DEBUGASSERT(impl);
+
+  memset(impl, 0, sizeof(struct mm_heap_impl_s));
   heap->mm_impl = impl;
 }
 
diff --git a/mm/mm_heap/mm.h b/mm/mm_heap/mm.h
index 987ddfa..b1d13f6 100644
--- a/mm/mm_heap/mm.h
+++ b/mm/mm_heap/mm.h
@@ -202,7 +202,11 @@ struct mm_heap_impl_s
 
   /* Free delay list, for some situation can't do free immdiately */
 
-  FAR struct mm_delaynode_s *mm_delaylist;
+#ifdef CONFIG_SMP
+  FAR struct mm_delaynode_s *mm_delaylist[CONFIG_SMP_NCPUS];
+#else
+  FAR struct mm_delaynode_s *mm_delaylist[1];
+#endif
 };
 
 /* Functions contained in mm_sem.c ******************************************/
diff --git a/mm/mm_heap/mm_free.c b/mm/mm_heap/mm_free.c
index ea46914..dff0748 100644
--- a/mm/mm_heap/mm_free.c
+++ b/mm/mm_heap/mm_free.c
@@ -50,8 +50,8 @@ static void mm_add_delaylist(FAR struct mm_heap_s *heap, FAR void *mem)
 
   flags = enter_critical_section();
 
-  tmp->flink = heap_impl->mm_delaylist;
-  heap_impl->mm_delaylist = tmp;
+  tmp->flink = heap_impl->mm_delaylist[up_cpu_index()];
+  heap_impl->mm_delaylist[up_cpu_index()] = tmp;
 
   leave_critical_section(flags);
 }
diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c
index 0801eae..9ac227b 100644
--- a/mm/mm_heap/mm_initialize.c
+++ b/mm/mm_heap/mm_initialize.c
@@ -197,20 +197,10 @@ void mm_initialize(FAR struct mm_heap_s *heap, FAR void *heapstart,
 
   /* Set up global variables */
 
-  heap_impl->mm_heapsize = 0;
-
-#if CONFIG_MM_REGIONS > 1
-  heap_impl->mm_nregions = 0;
-#endif
-
-  /* Initialize mm_delaylist */
-
-  heap_impl->mm_delaylist = NULL;
+  memset(heap_impl, 0, sizeof(struct mm_heap_impl_s));
 
   /* Initialize the node array */
 
-  memset(heap_impl->mm_nodelist, 0,
-         sizeof(struct mm_freenode_s) * MM_NNODES);
   for (i = 1; i < MM_NNODES; i++)
     {
       heap_impl->mm_nodelist[i - 1].flink = &heap_impl->mm_nodelist[i];
diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c
index 86b1861..5aa0528 100644
--- a/mm/mm_heap/mm_malloc.c
+++ b/mm/mm_heap/mm_malloc.c
@@ -59,8 +59,8 @@ static void mm_free_delaylist(FAR struct mm_heap_s *heap)
 
   flags = enter_critical_section();
 
-  tmp = heap_impl->mm_delaylist;
-  heap_impl->mm_delaylist = NULL;
+  tmp = heap_impl->mm_delaylist[up_cpu_index()];
+  heap_impl->mm_delaylist[up_cpu_index()] = NULL;
 
   leave_critical_section(flags);