Skip to content

Commit 0ff7c3b

Browse files
zongboxpalmer-dabbelt
authored andcommitted
riscv: Use text_mutex instead of patch_lock
We don't need the additional lock protection when patching the text. There are two patching interfaces here: - patch_text: patch code and always synchronize with stop_machine() - patch_text_nosync: patch code without synchronization, it's caller's responsibility to synchronize all CPUs if needed. For the first one, stop_machine() is protected by its own mutex, and also the irq is already disabled here. For the second one, in risc-v real case now, it would be used to ftrace patching the mcount function, since it already running under kstop_machine(), no other thread will run, so we could use text_mutex on ftrace side. Signed-off-by: Zong Li <[email protected]> Reviewed-by: Masami Hiramatsu <[email protected]> Reviewed-by: Palmer Dabbelt <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 5303df2 commit 0ff7c3b

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

arch/riscv/kernel/ftrace.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,23 @@
77

88
#include <linux/ftrace.h>
99
#include <linux/uaccess.h>
10+
#include <linux/memory.h>
1011
#include <asm/cacheflush.h>
1112
#include <asm/patch.h>
1213

1314
#ifdef CONFIG_DYNAMIC_FTRACE
15+
int ftrace_arch_code_modify_prepare(void) __acquires(&text_mutex)
16+
{
17+
mutex_lock(&text_mutex);
18+
return 0;
19+
}
20+
21+
int ftrace_arch_code_modify_post_process(void) __releases(&text_mutex)
22+
{
23+
mutex_unlock(&text_mutex);
24+
return 0;
25+
}
26+
1427
static int ftrace_check_current_call(unsigned long hook_pos,
1528
unsigned int *expected)
1629
{

arch/riscv/kernel/patch.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <linux/spinlock.h>
77
#include <linux/mm.h>
8+
#include <linux/memory.h>
89
#include <linux/uaccess.h>
910
#include <linux/stop_machine.h>
1011
#include <asm/kprobes.h>
@@ -18,8 +19,6 @@ struct patch_insn {
1819
};
1920

2021
#ifdef CONFIG_MMU
21-
static DEFINE_RAW_SPINLOCK(patch_lock);
22-
2322
static void *patch_map(void *addr, int fixmap)
2423
{
2524
uintptr_t uintaddr = (uintptr_t) addr;
@@ -49,10 +48,14 @@ static int patch_insn_write(void *addr, const void *insn, size_t len)
4948
{
5049
void *waddr = addr;
5150
bool across_pages = (((uintptr_t) addr & ~PAGE_MASK) + len) > PAGE_SIZE;
52-
unsigned long flags = 0;
5351
int ret;
5452

55-
raw_spin_lock_irqsave(&patch_lock, flags);
53+
/*
54+
* Before reaching here, it was expected to lock the text_mutex
55+
* already, so we don't need to give another lock here and could
56+
* ensure that it was safe between each cores.
57+
*/
58+
lockdep_assert_held(&text_mutex);
5659

5760
if (across_pages)
5861
patch_map(addr + len, FIX_TEXT_POKE1);
@@ -66,8 +69,6 @@ static int patch_insn_write(void *addr, const void *insn, size_t len)
6669
if (across_pages)
6770
patch_unmap(FIX_TEXT_POKE1);
6871

69-
raw_spin_unlock_irqrestore(&patch_lock, flags);
70-
7172
return ret;
7273
}
7374
NOKPROBE_SYMBOL(patch_insn_write);

0 commit comments

Comments
 (0)