Skip to content

Commit bd446f5

Browse files
AndybnACTpalmer-dabbelt
authored andcommitted
riscv: vector: use kmem_cache to manage vector context
The allocation size of thread.vstate.datap is always riscv_v_vsize. So it is possbile to use kmem_cache_* to manage the allocation. This gives users more information regarding allocation of vector context via /proc/slabinfo. And it potentially reduces the latency of the first-use trap because of the allocation caches. Signed-off-by: Andy Chiu <[email protected]> Tested-by: Björn Töpel <[email protected]> Tested-by: Lad Prabhakar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 5b6048f commit bd446f5

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

arch/riscv/include/asm/vector.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ void kernel_vector_begin(void);
2626
void kernel_vector_end(void);
2727
void get_cpu_vector_context(void);
2828
void put_cpu_vector_context(void);
29+
void riscv_v_thread_free(struct task_struct *tsk);
30+
void __init riscv_v_setup_ctx_cache(void);
2931

3032
static inline u32 riscv_v_flags(void)
3133
{
@@ -227,6 +229,8 @@ static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
227229
#define __switch_to_vector(__prev, __next) do {} while (0)
228230
#define riscv_v_vstate_off(regs) do {} while (0)
229231
#define riscv_v_vstate_on(regs) do {} while (0)
232+
#define riscv_v_thread_free(tsk) do {} while (0)
233+
#define riscv_v_setup_ctx_cache() do {} while (0)
230234

231235
#endif /* CONFIG_RISCV_ISA_V */
232236

arch/riscv/kernel/process.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ void arch_release_task_struct(struct task_struct *tsk)
179179
{
180180
/* Free the vector context of datap. */
181181
if (has_vector())
182-
kfree(tsk->thread.vstate.datap);
182+
riscv_v_thread_free(tsk);
183183
}
184184

185185
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
@@ -228,3 +228,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
228228
p->thread.sp = (unsigned long)childregs; /* kernel sp */
229229
return 0;
230230
}
231+
232+
void __init arch_task_cache_init(void)
233+
{
234+
riscv_v_setup_ctx_cache();
235+
}

arch/riscv/kernel/vector.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <asm/bug.h>
2222

2323
static bool riscv_v_implicit_uacc = IS_ENABLED(CONFIG_RISCV_ISA_V_DEFAULT_ENABLE);
24+
static struct kmem_cache *riscv_v_user_cachep;
2425

2526
unsigned long riscv_v_vsize __read_mostly;
2627
EXPORT_SYMBOL_GPL(riscv_v_vsize);
@@ -47,6 +48,16 @@ int riscv_v_setup_vsize(void)
4748
return 0;
4849
}
4950

51+
void __init riscv_v_setup_ctx_cache(void)
52+
{
53+
if (!has_vector())
54+
return;
55+
56+
riscv_v_user_cachep = kmem_cache_create_usercopy("riscv_vector_ctx",
57+
riscv_v_vsize, 16, SLAB_PANIC,
58+
0, riscv_v_vsize, NULL);
59+
}
60+
5061
static bool insn_is_vector(u32 insn_buf)
5162
{
5263
u32 opcode = insn_buf & __INSN_OPCODE_MASK;
@@ -84,7 +95,7 @@ static int riscv_v_thread_zalloc(void)
8495
{
8596
void *datap;
8697

87-
datap = kzalloc(riscv_v_vsize, GFP_KERNEL);
98+
datap = kmem_cache_zalloc(riscv_v_user_cachep, GFP_KERNEL);
8899
if (!datap)
89100
return -ENOMEM;
90101

@@ -94,6 +105,12 @@ static int riscv_v_thread_zalloc(void)
94105
return 0;
95106
}
96107

108+
void riscv_v_thread_free(struct task_struct *tsk)
109+
{
110+
if (tsk->thread.vstate.datap)
111+
kmem_cache_free(riscv_v_user_cachep, tsk->thread.vstate.datap);
112+
}
113+
97114
#define VSTATE_CTRL_GET_CUR(x) ((x) & PR_RISCV_V_VSTATE_CTRL_CUR_MASK)
98115
#define VSTATE_CTRL_GET_NEXT(x) (((x) & PR_RISCV_V_VSTATE_CTRL_NEXT_MASK) >> 2)
99116
#define VSTATE_CTRL_MAKE_NEXT(x) (((x) << 2) & PR_RISCV_V_VSTATE_CTRL_NEXT_MASK)

0 commit comments

Comments
 (0)