[linux] 01/01: [mips*] Fix PR_SET_FPMODE issues with multi-threaded programs.

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Tue May 10 22:18:55 UTC 2016


This is an automated email from the git hooks/post-receive script.

aurel32 pushed a commit to branch sid
in repository linux.

commit b101f08c765a1c1c91afc4bb79d8a7375ce88021
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Wed May 11 00:15:41 2016 +0200

    [mips*] Fix PR_SET_FPMODE issues with multi-threaded programs.
---
 debian/changelog                                   |   7 ++
 ...le-preemption-during-prctl-PR_SET_FP_MODE.patch |  42 +++++++++
 ...CPUs-to-lose-FP-context-during-mode-switc.patch | 104 +++++++++++++++++++++
 debian/patches/series                              |   2 +
 4 files changed, 155 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index f01683d..76dd3fe 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+linux (4.5.3-3) UNRELEASED; urgency=medium
+
+  [ Aurelien Jarno ]
+  * [mips*] Fix PR_SET_FPMODE issues with multi-threaded programs.
+
+ -- Aurelien Jarno <aurel32 at debian.org>  Tue, 10 May 2016 23:58:07 +0200
+
 linux (4.5.3-2) unstable; urgency=medium
 
   * [s390x] PCI: Ignore zpci ABI changes; these functions are not used by
diff --git a/debian/patches/bugfix/mips/MIPS-Disable-preemption-during-prctl-PR_SET_FP_MODE.patch b/debian/patches/bugfix/mips/MIPS-Disable-preemption-during-prctl-PR_SET_FP_MODE.patch
new file mode 100644
index 0000000..4aac015
--- /dev/null
+++ b/debian/patches/bugfix/mips/MIPS-Disable-preemption-during-prctl-PR_SET_FP_MODE.patch
@@ -0,0 +1,42 @@
+From: Paul Burton <paul.burton at imgtec.com>
+Date: Thu, 21 Apr 2016 12:43:57 +0100
+Subject: [1/2] MIPS: Disable preemption during prctl(PR_SET_FP_MODE, ...)
+Origin: https://patchwork.linux-mips.org/patch/13144/
+
+Whilst a PR_SET_FP_MODE prctl is performed there are decisions made
+based upon whether the task is executing on the current CPU. This may
+change if we're preempted, so disable preemption to avoid such changes
+for the lifetime of the mode switch.
+
+Signed-off-by: Paul Burton <paul.burton at imgtec.com>
+Fixes: 9791554b45a2 ("MIPS,prctl: add PR_[GS]ET_FP_MODE prctl options for MIPS")
+Cc: stable <stable at vger.kernel.org> # v4.0+
+---
+ arch/mips/kernel/process.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
+index 92880ce..ce55ea0 100644
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -601,6 +601,9 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
+ 	if (!(value & PR_FP_MODE_FR) && cpu_has_fpu && cpu_has_mips_r6)
+ 		return -EOPNOTSUPP;
+ 
++	/* Proceed with the mode switch */
++	preempt_disable();
++
+ 	/* Save FP & vector context, then disable FPU & MSA */
+ 	if (task->signal == current->signal)
+ 		lose_fpu(1);
+@@ -659,6 +662,7 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
+ 
+ 	/* Allow threads to use FP again */
+ 	atomic_set(&task->mm->context.fp_mode_switching, 0);
++	preempt_enable();
+ 
+ 	return 0;
+ }
+-- 
+2.8.1
+
diff --git a/debian/patches/bugfix/mips/MIPS-Force-CPUs-to-lose-FP-context-during-mode-switc.patch b/debian/patches/bugfix/mips/MIPS-Force-CPUs-to-lose-FP-context-during-mode-switc.patch
new file mode 100644
index 0000000..9619c58
--- /dev/null
+++ b/debian/patches/bugfix/mips/MIPS-Force-CPUs-to-lose-FP-context-during-mode-switc.patch
@@ -0,0 +1,104 @@
+From: Paul Burton <paul.burton at imgtec.com>
+Date: Thu, 21 Apr 2016 12:43:58 +0100
+Subject: [2/2] MIPS: Force CPUs to lose FP context during mode switches
+Origin: https://patchwork.linux-mips.org/patch/13145/
+
+Commit 9791554b45a2 ("MIPS,prctl: add PR_[GS]ET_FP_MODE prctl options
+for MIPS") added support for the PR_SET_FP_MODE prctl, which allows a
+userland program to modify its FP mode at runtime. This is most notably
+required if dynamic linking leads to the FP mode requirement changing at
+runtime from that indicated in the initial executable's ELF header. In
+order to avoid overhead in the general FP context restore code, it aimed
+to have threads in the process become unable to enable the FPU during a
+mode switch & have the thread calling the prctl syscall wait for all
+other threads in the process to be context switched at least once. Once
+that happens we can know that no thread in the process whose mode will
+be switched has live FP context, and it's safe to perform the mode
+switch. However in the (rare) case of modeswitches occurring in
+multithreaded programs this can lead to indeterminate delays for the
+thread invoking the prctl syscall, and the code monitoring for those
+context switches was woefully inadequate for all but the simplest cases.
+
+Fix this by broadcasting an IPI if other CPUs may have live FP context
+for an affected thread, with a handler causing those CPUs to relinquish
+their FPU ownership. Threads will then be allowed to continue running
+but will stall on the wait_on_atomic_t in enable_restore_fp_context if
+they attempt to use FP again whilst the mode switch is still in
+progress. The end result is less fragile poking at scheduler context
+switch counts & a more expedient completion of the mode switch.
+
+Signed-off-by: Paul Burton <paul.burton at imgtec.com>
+Fixes: 9791554b45a2 ("MIPS,prctl: add PR_[GS]ET_FP_MODE prctl options for MIPS")
+Cc: stable <stable at vger.kernel.org> # v4.0+
+---
+ arch/mips/kernel/process.c | 40 +++++++++++++++++-----------------------
+ 1 file changed, 17 insertions(+), 23 deletions(-)
+
+diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
+index ce55ea0..e1b36a4 100644
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -580,11 +580,19 @@ int mips_get_process_fp_mode(struct task_struct *task)
+ 	return value;
+ }
+ 
++static void prepare_for_fp_mode_switch(void *info)
++{
++	struct mm_struct *mm = info;
++
++	if (current->mm == mm)
++		lose_fpu(1);
++}
++
+ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
+ {
+ 	const unsigned int known_bits = PR_FP_MODE_FR | PR_FP_MODE_FRE;
+-	unsigned long switch_count;
+ 	struct task_struct *t;
++	int max_users;
+ 
+ 	/* Check the value is valid */
+ 	if (value & ~known_bits)
+@@ -613,31 +621,17 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
+ 	smp_mb__after_atomic();
+ 
+ 	/*
+-	 * If there are multiple online CPUs then wait until all threads whose
+-	 * FP mode is about to change have been context switched. This approach
+-	 * allows us to only worry about whether an FP mode switch is in
+-	 * progress when FP is first used in a tasks time slice. Pretty much all
+-	 * of the mode switch overhead can thus be confined to cases where mode
+-	 * switches are actually occuring. That is, to here. However for the
+-	 * thread performing the mode switch it may take a while...
++	 * If there are multiple online CPUs then force any which are running
++	 * threads in this process to lose their FPU context, which they can't
++	 * regain until fp_mode_switching is cleared later.
+ 	 */
+ 	if (num_online_cpus() > 1) {
+-		spin_lock_irq(&task->sighand->siglock);
+-
+-		for_each_thread(task, t) {
+-			if (t == current)
+-				continue;
+-
+-			switch_count = t->nvcsw + t->nivcsw;
+-
+-			do {
+-				spin_unlock_irq(&task->sighand->siglock);
+-				cond_resched();
+-				spin_lock_irq(&task->sighand->siglock);
+-			} while ((t->nvcsw + t->nivcsw) == switch_count);
+-		}
++		/* No need to send an IPI for the local CPU */
++		max_users = (task->mm == current->mm) ? 1 : 0;
+ 
+-		spin_unlock_irq(&task->sighand->siglock);
++		if (atomic_read(&current->mm->mm_users) > max_users)
++			smp_call_function(prepare_for_fp_mode_switch,
++					  (void *)current->mm, 1);
+ 	}
+ 
+ 	/*
+-- 
+2.8.1
+
diff --git a/debian/patches/series b/debian/patches/series
index d4fe692..7bacabe 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -46,6 +46,8 @@ bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch
 
 # Arch bug fixes
 bugfix/mips/MIPS-Allow-emulation-for-unaligned-LSDXC1-instructions.patch
+bugfix/mips/MIPS-Disable-preemption-during-prctl-PR_SET_FP_MODE.patch
+bugfix/mips/MIPS-Force-CPUs-to-lose-FP-context-during-mode-switc.patch
 bugfix/x86/vmxnet3-fix-lock-imbalance-in-vmxnet3_tq_xmit.patch
 bugfix/x86/acpi-processor-request-native-thermal-interrupt-hand.patch
 bugfix/arm/arm-dts-kirkwood-fix-sd-slot-default-configuration-f.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list