From aa43a0215d2806e032f93b88152d88e87fcda7f0 Mon Sep 17 00:00:00 2001 From: ligd Date: Mon, 21 Jun 2021 16:20:44 +0800 Subject: [PATCH] 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 --- 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 b82f629151e..07796b7d2d1 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 987ddfaf9f6..b1d13f6bbac 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 ea46914cbe5..dff0748c303 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 0801eae5d54..9ac227b33ca 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 86b18615017..5aa0528b26f 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);