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 <smokewood@qq.com>
This commit is contained in:
Shell 2024-09-04 10:06:16 +08:00 committed by GitHub
parent cea7670e7f
commit d2160d352c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 14 additions and 12 deletions

View File

@ -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) static void _mutex_before_delete_detach(rt_mutex_t mutex)
{ {
rt_sched_lock_level_t slvl; rt_sched_lock_level_t slvl;
rt_bool_t need_schedule; rt_bool_t need_schedule = RT_FALSE;
rt_spin_lock(&(mutex->spinlock)); rt_spin_lock(&(mutex->spinlock));
/* wakeup all suspended threads */ /* wakeup all suspended threads */
rt_susp_list_resume_all(&(mutex->parent.suspend_thread), RT_ERROR); rt_susp_list_resume_all(&(mutex->parent.suspend_thread), RT_ERROR);
rt_sched_lock(&slvl);
/* remove mutex from thread's taken list */ /* remove mutex from thread's taken list */
rt_list_remove(&mutex->taken_list); rt_list_remove(&mutex->taken_list);
/* whether change the thread priority */ /* whether change the thread priority */
if (mutex->owner) if (mutex->owner)
{ {
rt_sched_lock(&slvl);
need_schedule = _check_and_update_prio(mutex->owner, mutex); need_schedule = _check_and_update_prio(mutex->owner, mutex);
}
if (need_schedule) if (need_schedule)
{ {
rt_sched_unlock_n_resched(slvl); rt_sched_unlock_n_resched(slvl);
} }
else else
{ {
rt_sched_unlock(slvl); rt_sched_unlock(slvl);
}
} }
/* unlock and do necessary reschedule if required */ /* 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 no hold */
if (mutex->hold == 0) if (mutex->hold == 0)
{ {
rt_sched_lock(&slvl);
/* remove mutex from thread's taken list */ /* remove mutex from thread's taken list */
rt_list_remove(&mutex->taken_list); rt_list_remove(&mutex->taken_list);
rt_sched_lock(&slvl);
/* whether change the thread priority */ /* whether change the thread priority */
need_schedule = _check_and_update_prio(thread, mutex); need_schedule = _check_and_update_prio(thread, mutex);