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 <andy.chiu@sifive.com> Tested-by: Björn Töpel <bjorn@rivosinc.com> Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Link: https://lore.kernel.org/r/20240115055929.4736-10-andy.chiu@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
parent
5b6048f2ff
commit
bd446f5df5
@ -26,6 +26,8 @@ void kernel_vector_begin(void);
|
||||
void kernel_vector_end(void);
|
||||
void get_cpu_vector_context(void);
|
||||
void put_cpu_vector_context(void);
|
||||
void riscv_v_thread_free(struct task_struct *tsk);
|
||||
void __init riscv_v_setup_ctx_cache(void);
|
||||
|
||||
static inline u32 riscv_v_flags(void)
|
||||
{
|
||||
@ -227,6 +229,8 @@ static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
|
||||
#define __switch_to_vector(__prev, __next) do {} while (0)
|
||||
#define riscv_v_vstate_off(regs) do {} while (0)
|
||||
#define riscv_v_vstate_on(regs) do {} while (0)
|
||||
#define riscv_v_thread_free(tsk) do {} while (0)
|
||||
#define riscv_v_setup_ctx_cache() do {} while (0)
|
||||
|
||||
#endif /* CONFIG_RISCV_ISA_V */
|
||||
|
||||
|
@ -179,7 +179,7 @@ void arch_release_task_struct(struct task_struct *tsk)
|
||||
{
|
||||
/* Free the vector context of datap. */
|
||||
if (has_vector())
|
||||
kfree(tsk->thread.vstate.datap);
|
||||
riscv_v_thread_free(tsk);
|
||||
}
|
||||
|
||||
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)
|
||||
p->thread.sp = (unsigned long)childregs; /* kernel sp */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init arch_task_cache_init(void)
|
||||
{
|
||||
riscv_v_setup_ctx_cache();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <asm/bug.h>
|
||||
|
||||
static bool riscv_v_implicit_uacc = IS_ENABLED(CONFIG_RISCV_ISA_V_DEFAULT_ENABLE);
|
||||
static struct kmem_cache *riscv_v_user_cachep;
|
||||
|
||||
unsigned long riscv_v_vsize __read_mostly;
|
||||
EXPORT_SYMBOL_GPL(riscv_v_vsize);
|
||||
@ -47,6 +48,16 @@ int riscv_v_setup_vsize(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init riscv_v_setup_ctx_cache(void)
|
||||
{
|
||||
if (!has_vector())
|
||||
return;
|
||||
|
||||
riscv_v_user_cachep = kmem_cache_create_usercopy("riscv_vector_ctx",
|
||||
riscv_v_vsize, 16, SLAB_PANIC,
|
||||
0, riscv_v_vsize, NULL);
|
||||
}
|
||||
|
||||
static bool insn_is_vector(u32 insn_buf)
|
||||
{
|
||||
u32 opcode = insn_buf & __INSN_OPCODE_MASK;
|
||||
@ -84,7 +95,7 @@ static int riscv_v_thread_zalloc(void)
|
||||
{
|
||||
void *datap;
|
||||
|
||||
datap = kzalloc(riscv_v_vsize, GFP_KERNEL);
|
||||
datap = kmem_cache_zalloc(riscv_v_user_cachep, GFP_KERNEL);
|
||||
if (!datap)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -94,6 +105,12 @@ static int riscv_v_thread_zalloc(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void riscv_v_thread_free(struct task_struct *tsk)
|
||||
{
|
||||
if (tsk->thread.vstate.datap)
|
||||
kmem_cache_free(riscv_v_user_cachep, tsk->thread.vstate.datap);
|
||||
}
|
||||
|
||||
#define VSTATE_CTRL_GET_CUR(x) ((x) & PR_RISCV_V_VSTATE_CTRL_CUR_MASK)
|
||||
#define VSTATE_CTRL_GET_NEXT(x) (((x) & PR_RISCV_V_VSTATE_CTRL_NEXT_MASK) >> 2)
|
||||
#define VSTATE_CTRL_MAKE_NEXT(x) (((x) << 2) & PR_RISCV_V_VSTATE_CTRL_NEXT_MASK)
|
||||
|
Loading…
x
Reference in New Issue
Block a user