Skip to content

Commit b3134b8

Browse files
guoren83palmer-dabbelt
authored andcommitted
riscv: Fixup boot failure when CONFIG_DEBUG_RT_MUTEXES=y
When CONFIG_DEBUG_RT_MUTEXES=y, mutex_lock->rt_mutex_try_acquire would change from rt_mutex_cmpxchg_acquire to rt_mutex_slowtrylock(): raw_spin_lock_irqsave(&lock->wait_lock, flags); ret = __rt_mutex_slowtrylock(lock); raw_spin_unlock_irqrestore(&lock->wait_lock, flags); Because queued_spin_#ops to ticket_#ops is changed one by one by jump_label, raw_spin_lock/unlock would cause a deadlock during the changing. That means in arch/riscv/kernel/jump_label.c: 1. arch_jump_label_transform_queue() -> mutex_lock(&text_mutex); +-> raw_spin_lock -> queued_spin_lock |-> raw_spin_unlock -> queued_spin_unlock patch_insn_write -> change the raw_spin_lock to ticket_lock mutex_unlock(&text_mutex); ... 2. /* Dirty the lock value */ arch_jump_label_transform_queue() -> mutex_lock(&text_mutex); +-> raw_spin_lock -> *ticket_lock* |-> raw_spin_unlock -> *queued_spin_unlock* /* BUG: ticket_lock with queued_spin_unlock */ patch_insn_write -> change the raw_spin_unlock to ticket_unlock mutex_unlock(&text_mutex); ... 3. /* Dead lock */ arch_jump_label_transform_queue() -> mutex_lock(&text_mutex); +-> raw_spin_lock -> ticket_lock /* deadlock! */ |-> raw_spin_unlock -> ticket_unlock patch_insn_write -> change other raw_spin_#op -> ticket_#op mutex_unlock(&text_mutex); So, the solution is to disable mutex usage of arch_jump_label_transform_queue() during early_boot_irqs_disabled, just like we have done for stop_machine. Reported-by: Conor Dooley <[email protected]> Signed-off-by: Guo Ren <[email protected]> Signed-off-by: Guo Ren <[email protected]> Fixes: ab83647 ("riscv: Add qspinlock support") Link: https://lore.kernel.org/linux-riscv/CAJF2gTQwYTGinBmCSgVUoPv0_q4EPt_+WiyfUA1HViAKgUzxAg@mail.gmail.com/T/#mf488e6347817fca03bb93a7d34df33d8615b3775 Cc: Palmer Dabbelt <[email protected]> Cc: Alexandre Ghiti <[email protected]> Tested-by: Conor Dooley <[email protected]> Reviewed-by: Alexandre Ghiti <[email protected]> Tested-by: Alexandre Ghiti <[email protected]> Tested-by: Nam Cao <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent fac04ef commit b3134b8

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

arch/riscv/kernel/jump_label.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,15 @@ bool arch_jump_label_transform_queue(struct jump_entry *entry,
3636
insn = RISCV_INSN_NOP;
3737
}
3838

39-
mutex_lock(&text_mutex);
40-
patch_insn_write(addr, &insn, sizeof(insn));
41-
mutex_unlock(&text_mutex);
39+
if (early_boot_irqs_disabled) {
40+
riscv_patch_in_stop_machine = 1;
41+
patch_insn_write(addr, &insn, sizeof(insn));
42+
riscv_patch_in_stop_machine = 0;
43+
} else {
44+
mutex_lock(&text_mutex);
45+
patch_insn_write(addr, &insn, sizeof(insn));
46+
mutex_unlock(&text_mutex);
47+
}
4248

4349
return true;
4450
}

0 commit comments

Comments
 (0)