Revert "kernel/sched: Fix free-memory write when ISRs abort _current"
This reverts commit 61c70626a5
.
This PR introduced 2 regressions in main CI:
71977 & 71978
Let's revert it by now to get main's CI passing again.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
This commit is contained in:
parent
ab41d3ab99
commit
ea26bcf8d3
|
@ -37,8 +37,6 @@ BUILD_ASSERT(K_LOWEST_APPLICATION_THREAD_PRIO
|
||||||
#define Z_ASSERT_VALID_PRIO(prio, entry_point) __ASSERT((prio) == -1, "")
|
#define Z_ASSERT_VALID_PRIO(prio, entry_point) __ASSERT((prio) == -1, "")
|
||||||
#endif /* CONFIG_MULTITHREADING */
|
#endif /* CONFIG_MULTITHREADING */
|
||||||
|
|
||||||
extern struct k_thread _thread_dummies[CONFIG_MP_MAX_NUM_CPUS];
|
|
||||||
|
|
||||||
void z_sched_init(void);
|
void z_sched_init(void);
|
||||||
void z_move_thread_to_end_of_prio_q(struct k_thread *thread);
|
void z_move_thread_to_end_of_prio_q(struct k_thread *thread);
|
||||||
void z_unpend_thread_no_timeout(struct k_thread *thread);
|
void z_unpend_thread_no_timeout(struct k_thread *thread);
|
||||||
|
|
|
@ -650,7 +650,12 @@ FUNC_NORETURN void z_cstart(void)
|
||||||
LOG_CORE_INIT();
|
LOG_CORE_INIT();
|
||||||
|
|
||||||
#if defined(CONFIG_MULTITHREADING)
|
#if defined(CONFIG_MULTITHREADING)
|
||||||
z_dummy_thread_init(&_thread_dummies[0]);
|
/* Note: The z_ready_thread() call in prepare_multithreading() requires
|
||||||
|
* a dummy thread even if CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN=y
|
||||||
|
*/
|
||||||
|
struct k_thread dummy_thread;
|
||||||
|
|
||||||
|
z_dummy_thread_init(&dummy_thread);
|
||||||
#endif /* CONFIG_MULTITHREADING */
|
#endif /* CONFIG_MULTITHREADING */
|
||||||
/* do any necessary initialization of static devices */
|
/* do any necessary initialization of static devices */
|
||||||
z_device_state_init();
|
z_device_state_init();
|
||||||
|
|
|
@ -30,11 +30,6 @@ extern struct k_thread *pending_current;
|
||||||
|
|
||||||
struct k_spinlock _sched_spinlock;
|
struct k_spinlock _sched_spinlock;
|
||||||
|
|
||||||
/* Storage to "complete" the context switch from an invalid/incomplete thread
|
|
||||||
* context (ex: exiting an ISR that aborted _current)
|
|
||||||
*/
|
|
||||||
__incoherent struct k_thread _thread_dummies[CONFIG_MP_MAX_NUM_CPUS];
|
|
||||||
|
|
||||||
static void update_cache(int preempt_ok);
|
static void update_cache(int preempt_ok);
|
||||||
static void halt_thread(struct k_thread *thread, uint8_t new_state);
|
static void halt_thread(struct k_thread *thread, uint8_t new_state);
|
||||||
static void add_to_waitq_locked(struct k_thread *thread, _wait_q_t *wait_q);
|
static void add_to_waitq_locked(struct k_thread *thread, _wait_q_t *wait_q);
|
||||||
|
@ -428,9 +423,8 @@ void z_sched_start(struct k_thread *thread)
|
||||||
* another CPU to catch the IPI we sent and halt. Note that we check
|
* another CPU to catch the IPI we sent and halt. Note that we check
|
||||||
* for ourselves being asynchronously halted first to prevent simple
|
* for ourselves being asynchronously halted first to prevent simple
|
||||||
* deadlocks (but not complex ones involving cycles of 3+ threads!).
|
* deadlocks (but not complex ones involving cycles of 3+ threads!).
|
||||||
* Acts to release the provided lock before returning.
|
|
||||||
*/
|
*/
|
||||||
static void thread_halt_spin(struct k_thread *thread, k_spinlock_key_t key)
|
static k_spinlock_key_t thread_halt_spin(struct k_thread *thread, k_spinlock_key_t key)
|
||||||
{
|
{
|
||||||
if (is_halting(_current)) {
|
if (is_halting(_current)) {
|
||||||
halt_thread(_current,
|
halt_thread(_current,
|
||||||
|
@ -438,11 +432,10 @@ static void thread_halt_spin(struct k_thread *thread, k_spinlock_key_t key)
|
||||||
}
|
}
|
||||||
k_spin_unlock(&_sched_spinlock, key);
|
k_spin_unlock(&_sched_spinlock, key);
|
||||||
while (is_halting(thread)) {
|
while (is_halting(thread)) {
|
||||||
unsigned int k = arch_irq_lock();
|
|
||||||
|
|
||||||
arch_spin_relax(); /* Requires interrupts be masked */
|
|
||||||
arch_irq_unlock(k);
|
|
||||||
}
|
}
|
||||||
|
key = k_spin_lock(&_sched_spinlock);
|
||||||
|
z_sched_switch_spin(thread);
|
||||||
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shared handler for k_thread_{suspend,abort}(). Called with the
|
/* Shared handler for k_thread_{suspend,abort}(). Called with the
|
||||||
|
@ -472,7 +465,8 @@ static void z_thread_halt(struct k_thread *thread, k_spinlock_key_t key,
|
||||||
arch_sched_ipi();
|
arch_sched_ipi();
|
||||||
#endif
|
#endif
|
||||||
if (arch_is_in_isr()) {
|
if (arch_is_in_isr()) {
|
||||||
thread_halt_spin(thread, key);
|
key = thread_halt_spin(thread, key);
|
||||||
|
k_spin_unlock(&_sched_spinlock, key);
|
||||||
} else {
|
} else {
|
||||||
add_to_waitq_locked(_current, wq);
|
add_to_waitq_locked(_current, wq);
|
||||||
z_swap(&_sched_spinlock, key);
|
z_swap(&_sched_spinlock, key);
|
||||||
|
@ -486,10 +480,6 @@ static void z_thread_halt(struct k_thread *thread, k_spinlock_key_t key,
|
||||||
k_spin_unlock(&_sched_spinlock, key);
|
k_spin_unlock(&_sched_spinlock, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* NOTE: the scheduler lock has been released. Don't put
|
|
||||||
* logic here, it's likely to be racy/deadlocky even if you
|
|
||||||
* re-take the lock!
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1289,8 +1279,6 @@ extern void thread_abort_hook(struct k_thread *thread);
|
||||||
*/
|
*/
|
||||||
static void halt_thread(struct k_thread *thread, uint8_t new_state)
|
static void halt_thread(struct k_thread *thread, uint8_t new_state)
|
||||||
{
|
{
|
||||||
bool dummify = false;
|
|
||||||
|
|
||||||
/* We hold the lock, and the thread is known not to be running
|
/* We hold the lock, and the thread is known not to be running
|
||||||
* anywhere.
|
* anywhere.
|
||||||
*/
|
*/
|
||||||
|
@ -1307,16 +1295,6 @@ static void halt_thread(struct k_thread *thread, uint8_t new_state)
|
||||||
}
|
}
|
||||||
(void)z_abort_thread_timeout(thread);
|
(void)z_abort_thread_timeout(thread);
|
||||||
unpend_all(&thread->join_queue);
|
unpend_all(&thread->join_queue);
|
||||||
|
|
||||||
/* Edge case: aborting _current from within an
|
|
||||||
* ISR that preempted it requires clearing the
|
|
||||||
* _current pointer so the upcoming context
|
|
||||||
* switch doesn't clobber the now-freed
|
|
||||||
* memory
|
|
||||||
*/
|
|
||||||
if (thread == _current && arch_is_in_isr()) {
|
|
||||||
dummify = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
unpend_all(&thread->halt_queue);
|
unpend_all(&thread->halt_queue);
|
||||||
|
@ -1355,16 +1333,6 @@ static void halt_thread(struct k_thread *thread, uint8_t new_state)
|
||||||
#ifdef CONFIG_THREAD_ABORT_NEED_CLEANUP
|
#ifdef CONFIG_THREAD_ABORT_NEED_CLEANUP
|
||||||
k_thread_abort_cleanup(thread);
|
k_thread_abort_cleanup(thread);
|
||||||
#endif /* CONFIG_THREAD_ABORT_NEED_CLEANUP */
|
#endif /* CONFIG_THREAD_ABORT_NEED_CLEANUP */
|
||||||
|
|
||||||
/* Do this "set _current to dummy" step last so that
|
|
||||||
* subsystems above can rely on _current being
|
|
||||||
* unchanged. Disabled for posix as that arch
|
|
||||||
* continues to use the _current pointer in its swap
|
|
||||||
* code.
|
|
||||||
*/
|
|
||||||
if (dummify && !IS_ENABLED(CONFIG_ARCH_POSIX)) {
|
|
||||||
z_dummy_thread_init(&_thread_dummies[_current_cpu->id]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,7 @@ static void wait_for_start_signal(atomic_t *start_flag)
|
||||||
|
|
||||||
static inline void smp_init_top(void *arg)
|
static inline void smp_init_top(void *arg)
|
||||||
{
|
{
|
||||||
|
struct k_thread dummy_thread;
|
||||||
struct cpu_start_cb csc = arg ? *(struct cpu_start_cb *)arg : (struct cpu_start_cb){0};
|
struct cpu_start_cb csc = arg ? *(struct cpu_start_cb *)arg : (struct cpu_start_cb){0};
|
||||||
|
|
||||||
/* Let start_cpu() know that this CPU has powered up. */
|
/* Let start_cpu() know that this CPU has powered up. */
|
||||||
|
@ -122,7 +123,7 @@ static inline void smp_init_top(void *arg)
|
||||||
/* Initialize the dummy thread struct so that
|
/* Initialize the dummy thread struct so that
|
||||||
* the scheduler can schedule actual threads to run.
|
* the scheduler can schedule actual threads to run.
|
||||||
*/
|
*/
|
||||||
z_dummy_thread_init(&_thread_dummies[arch_curr_cpu()->id]);
|
z_dummy_thread_init(&dummy_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SYS_CLOCK_EXISTS
|
#ifdef CONFIG_SYS_CLOCK_EXISTS
|
||||||
|
|
Loading…
Reference in a new issue