summaryrefslogtreecommitdiff
path: root/src/ipc.c
diff options
context:
space:
mode:
authorShell <[email protected]>2024-09-04 10:06:16 +0800
committerGitHub <[email protected]>2024-09-03 22:06:16 -0400
commitd2160d352c34c46015eb916f12c23cf16b2b9a66 (patch)
tree216ddd58ac50844fd91b4ee1b0a01f424369b09c /src/ipc.c
parentcea7670e7f19ee2fdf6b3fd3273024e38d97c062 (diff)
fixup: ipc: protect taken_list on shared lock
为什么提交这份PR (why to submit this PR) Issue: using iperf server with sshd together and the kernel will get stuck occasionally. taken_list is accessed from other mutex when updating priority. 你的解决方案是什么 (what is your solution) protect taken_list on shared lock, but not on mutex local spinlock. Signed-off-by: Shell <[email protected]>
Diffstat (limited to 'src/ipc.c')
-rw-r--r--src/ipc.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/src/ipc.c b/src/ipc.c
index 3c6e82949b..a1a9c1f2da 100644
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -945,28 +945,30 @@ static rt_bool_t _check_and_update_prio(rt_thread_t thread, rt_mutex_t mutex)
static void _mutex_before_delete_detach(rt_mutex_t mutex)
{
rt_sched_lock_level_t slvl;
- rt_bool_t need_schedule;
+ rt_bool_t need_schedule = RT_FALSE;
rt_spin_lock(&(mutex->spinlock));
/* wakeup all suspended threads */
rt_susp_list_resume_all(&(mutex->parent.suspend_thread), RT_ERROR);
+
+ rt_sched_lock(&slvl);
+
/* remove mutex from thread's taken list */
rt_list_remove(&mutex->taken_list);
/* whether change the thread priority */
if (mutex->owner)
{
- rt_sched_lock(&slvl);
need_schedule = _check_and_update_prio(mutex->owner, mutex);
+ }
- if (need_schedule)
- {
- rt_sched_unlock_n_resched(slvl);
- }
- else
- {
- rt_sched_unlock(slvl);
- }
+ if (need_schedule)
+ {
+ rt_sched_unlock_n_resched(slvl);
+ }
+ else
+ {
+ rt_sched_unlock(slvl);
}
/* unlock and do necessary reschedule if required */
@@ -1617,11 +1619,11 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
/* if no hold */
if (mutex->hold == 0)
{
+ rt_sched_lock(&slvl);
+
/* remove mutex from thread's taken list */
rt_list_remove(&mutex->taken_list);
- rt_sched_lock(&slvl);
-
/* whether change the thread priority */
need_schedule = _check_and_update_prio(thread, mutex);