aboutsummaryrefslogtreecommitdiffstats
path: root/features/rt/arm64-fpsimd-Delay-freeing-memory-in-fpsimd_flush_th.patch
diff options
context:
space:
mode:
Diffstat (limited to 'features/rt/arm64-fpsimd-Delay-freeing-memory-in-fpsimd_flush_th.patch')
-rw-r--r--features/rt/arm64-fpsimd-Delay-freeing-memory-in-fpsimd_flush_th.patch65
1 files changed, 65 insertions, 0 deletions
diff --git a/features/rt/arm64-fpsimd-Delay-freeing-memory-in-fpsimd_flush_th.patch b/features/rt/arm64-fpsimd-Delay-freeing-memory-in-fpsimd_flush_th.patch
new file mode 100644
index 00000000..75e9f204
--- /dev/null
+++ b/features/rt/arm64-fpsimd-Delay-freeing-memory-in-fpsimd_flush_th.patch
@@ -0,0 +1,65 @@
+From c17705510939368390130106b37160bb2ff08e1c Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 25 Jul 2018 14:02:38 +0200
+Subject: [PATCH 176/191] 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(-)
+
+diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
+index 062b21f30f94..0ea2df6554e5 100644
+--- a/arch/arm64/kernel/fpsimd.c
++++ b/arch/arm64/kernel/fpsimd.c
+@@ -226,6 +226,16 @@ static void sve_free(struct task_struct *task)
+ __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
+@@ -1022,6 +1032,7 @@ void fpsimd_thread_switch(struct task_struct *next)
+ void fpsimd_flush_thread(void)
+ {
+ int vl, supported_vl;
++ void *mem = NULL;
+
+ if (!system_supports_fpsimd())
+ return;
+@@ -1034,7 +1045,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.
+@@ -1068,6 +1079,7 @@ void fpsimd_flush_thread(void)
+ }
+
+ put_cpu_fpsimd_context();
++ kfree(mem);
+ }
+
+ /*
+--
+2.19.1
+