| From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| Date: Wed, 25 Jul 2018 14:02:38 +0200 |
| Subject: [PATCH] arm64: fpsimd: Delay freeing memory in fpsimd_flush_thread() |
| |
| fpsimd_flush_thread() invokes kfree() via sve_free() within a preempt disabled |
| section which is not working on -RT. |
| |
| Delay freeing of memory until preemption is enabled again. |
| |
| Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| --- |
| arch/arm64/kernel/fpsimd.c | 14 +++++++++++++- |
| 1 file changed, 13 insertions(+), 1 deletion(-) |
| |
| --- a/arch/arm64/kernel/fpsimd.c |
| +++ b/arch/arm64/kernel/fpsimd.c |
| @@ -213,6 +213,16 @@ static void sve_free(struct task_struct |
| __sve_free(task); |
| } |
| |
| +static void *sve_free_atomic(struct task_struct *task) |
| +{ |
| + void *sve_state = task->thread.sve_state; |
| + |
| + WARN_ON(test_tsk_thread_flag(task, TIF_SVE)); |
| + |
| + task->thread.sve_state = NULL; |
| + return sve_state; |
| +} |
| + |
| /* |
| * TIF_SVE controls whether a task can use SVE without trapping while |
| * in userspace, and also the way a task's FPSIMD/SVE state is stored |
| @@ -1010,6 +1020,7 @@ void fpsimd_thread_switch(struct task_st |
| void fpsimd_flush_thread(void) |
| { |
| int vl, supported_vl; |
| + void *mem = NULL; |
| |
| if (!system_supports_fpsimd()) |
| return; |
| @@ -1022,7 +1033,7 @@ void fpsimd_flush_thread(void) |
| |
| if (system_supports_sve()) { |
| clear_thread_flag(TIF_SVE); |
| - sve_free(current); |
| + mem = sve_free_atomic(current); |
| |
| /* |
| * Reset the task vector length as required. |
| @@ -1056,6 +1067,7 @@ void fpsimd_flush_thread(void) |
| } |
| |
| put_cpu_fpsimd_context(); |
| + kfree(mem); |
| } |
| |
| /* |