From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:47:39
Hi folks,
This is the long-awaited v6 of these patches which I last posted at the
end of last year:
v1: https://lore.kernel.org/r/20201027215118.27003-1-will@kernel.org
v2: https://lore.kernel.org/r/20201109213023.15092-1-will@kernel.org
v3: https://lore.kernel.org/r/20201113093720.21106-1-will@kernel.org
v4: https://lore.kernel.org/r/20201124155039.13804-1-will@kernel.org
v5: https://lore.kernel.org/r/20201208132835.6151-1-will@kernel.org
There was also a nice LWN writeup in case you've forgotten what this is
about:
https://lwn.net/Articles/838339/
It's taken me a while to get a v6 of this together, partly due to
addressing the review feedback on v5, but also because this has now seen
testing on real hardware which threw up some surprises in suspend/resume,
SCHED_DEADLINE and compat hwcap reporting. Thanks to Quentin for helping
me to debug those issues.
The aim of this series is to allow 32-bit ARM applications to run on
arm64 SoCs where not all of the CPUs support the 32-bit instruction set.
Unfortunately, such SoCs are real and will continue to be productised
over the next few years at least. I can assure you that I'm not just
doing this for fun.
Changes in v6 include:
* Save/restore the affinity mask across execve() to 32-bit and back to
64-bit again.
* Allow 32-bit deadline tasks, but skip straight to fallback path when
determining new affinity mask on execve().
* Fixed resume-from-suspend path when the resuming CPU is 64-bit-only
by deferring wake-ups for 32-bit tasks until the secondary CPUs are
back online.
* Bug fixes (compat hwcaps, memory leak, cpuset fallback path).
* Documentation for arm64. It's in the divisive .rst format, but please
take a look anyway!
I'm pretty happy with this now and it seems to do the right thing,
although the new patches in this revision would certainly benefit from
review. Series based on v5.13-rc1.
Cheers,
Will
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Morten Rasmussen <redacted>
Cc: Qais Yousef <redacted>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Quentin Perret <redacted>
Cc: Tejun Heo <tj@kernel.org>
Cc: Li Zefan <redacted>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: "Rafael J. Wysocki" <redacted>
Cc: kernel-team@android.com
--->8
Will Deacon (21):
arm64: cpuinfo: Split AArch32 registers out into a separate struct
arm64: Allow mismatched 32-bit EL0 support
KVM: arm64: Kill 32-bit vCPUs on systems with mismatched EL0 support
arm64: Kill 32-bit applications scheduled on 64-bit-only CPUs
arm64: Advertise CPUs capable of running 32-bit applications in sysfs
sched: Introduce task_cpu_possible_mask() to limit fallback rq
selection
cpuset: Don't use the cpu_possible_mask as a last resort for cgroup v1
cpuset: Honour task_cpu_possible_mask() in guarantee_online_cpus()
sched: Reject CPU affinity changes based on task_cpu_possible_mask()
sched: Introduce task_struct::user_cpus_ptr to track requested
affinity
sched: Split the guts of sched_setaffinity() into a helper function
sched: Allow task CPU affinity to be restricted on asymmetric systems
sched: Admit forcefully-affined tasks into SCHED_DEADLINE
freezer: Add frozen_or_skipped() helper function
sched: Defer wakeup in ttwu() for unschedulable frozen tasks
arm64: Implement task_cpu_possible_mask()
arm64: exec: Adjust affinity for compat tasks with mismatched 32-bit
EL0
arm64: Prevent offlining first CPU with 32-bit EL0 on mismatched
system
arm64: Hook up cmdline parameter to allow mismatched 32-bit EL0
arm64: Remove logic to kill 32-bit tasks on 64-bit-only cores
Documentation: arm64: describe asymmetric 32-bit support
.../ABI/testing/sysfs-devices-system-cpu | 9 +
.../admin-guide/kernel-parameters.txt | 11 +
Documentation/arm64/asymmetric-32bit.rst | 149 ++++++++
Documentation/arm64/index.rst | 1 +
arch/arm64/include/asm/cpu.h | 44 +--
arch/arm64/include/asm/cpucaps.h | 3 +-
arch/arm64/include/asm/cpufeature.h | 8 +-
arch/arm64/include/asm/mmu_context.h | 13 +
arch/arm64/kernel/cpufeature.c | 227 +++++++++---
arch/arm64/kernel/cpuinfo.c | 53 +--
arch/arm64/kernel/process.c | 21 +-
arch/arm64/kvm/arm.c | 11 +-
include/linux/cpuset.h | 3 +-
include/linux/freezer.h | 6 +
include/linux/mmu_context.h | 8 +
include/linux/sched.h | 15 +
init/init_task.c | 1 +
kernel/cgroup/cpuset.c | 45 ++-
kernel/fork.c | 2 +
kernel/freezer.c | 10 +-
kernel/hung_task.c | 4 +-
kernel/sched/core.c | 323 ++++++++++++++----
kernel/sched/sched.h | 1 +
23 files changed, 781 insertions(+), 187 deletions(-)
create mode 100644 Documentation/arm64/asymmetric-32bit.rst
--
2.31.1.751.gd2f1c929bd-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:47:44
In preparation for late initialisation of the "sanitised" AArch32 register
state, move the AArch32 registers out of 'struct cpuinfo' and into their
own struct definition.
Signed-off-by: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/cpu.h | 44 +++++++++++----------
arch/arm64/kernel/cpufeature.c | 71 ++++++++++++++++++----------------
arch/arm64/kernel/cpuinfo.c | 53 +++++++++++++------------
3 files changed, 89 insertions(+), 79 deletions(-)
@@ -54,6 +35,29 @@ struct cpuinfo_arm64 {u32reg_mvfr0;u32reg_mvfr1;u32reg_mvfr2;+};++structcpuinfo_arm64{+structcpucpu;+structkobjectkobj;+u32reg_ctr;+u32reg_cntfrq;+u32reg_dczid;+u32reg_midr;+u32reg_revidr;++u64reg_id_aa64dfr0;+u64reg_id_aa64dfr1;+u64reg_id_aa64isar0;+u64reg_id_aa64isar1;+u64reg_id_aa64mmfr0;+u64reg_id_aa64mmfr1;+u64reg_id_aa64mmfr2;+u64reg_id_aa64pfr0;+u64reg_id_aa64pfr1;+u64reg_id_aa64zfr0;++structcpuinfo_32bitaarch32;/* pseudo-ZCR for recording maximum ZCR_EL1 LEN value: */u64reg_zcr;
@@ -863,6 +863,31 @@ static void __init init_cpu_hwcaps_indirect_list(void)staticvoid__initsetup_boot_cpu_capabilities(void);+staticvoid__initinit_32bit_cpu_features(structcpuinfo_32bit*info)+{+init_cpu_ftr_reg(SYS_ID_DFR0_EL1,info->reg_id_dfr0);+init_cpu_ftr_reg(SYS_ID_DFR1_EL1,info->reg_id_dfr1);+init_cpu_ftr_reg(SYS_ID_ISAR0_EL1,info->reg_id_isar0);+init_cpu_ftr_reg(SYS_ID_ISAR1_EL1,info->reg_id_isar1);+init_cpu_ftr_reg(SYS_ID_ISAR2_EL1,info->reg_id_isar2);+init_cpu_ftr_reg(SYS_ID_ISAR3_EL1,info->reg_id_isar3);+init_cpu_ftr_reg(SYS_ID_ISAR4_EL1,info->reg_id_isar4);+init_cpu_ftr_reg(SYS_ID_ISAR5_EL1,info->reg_id_isar5);+init_cpu_ftr_reg(SYS_ID_ISAR6_EL1,info->reg_id_isar6);+init_cpu_ftr_reg(SYS_ID_MMFR0_EL1,info->reg_id_mmfr0);+init_cpu_ftr_reg(SYS_ID_MMFR1_EL1,info->reg_id_mmfr1);+init_cpu_ftr_reg(SYS_ID_MMFR2_EL1,info->reg_id_mmfr2);+init_cpu_ftr_reg(SYS_ID_MMFR3_EL1,info->reg_id_mmfr3);+init_cpu_ftr_reg(SYS_ID_MMFR4_EL1,info->reg_id_mmfr4);+init_cpu_ftr_reg(SYS_ID_MMFR5_EL1,info->reg_id_mmfr5);+init_cpu_ftr_reg(SYS_ID_PFR0_EL1,info->reg_id_pfr0);+init_cpu_ftr_reg(SYS_ID_PFR1_EL1,info->reg_id_pfr1);+init_cpu_ftr_reg(SYS_ID_PFR2_EL1,info->reg_id_pfr2);+init_cpu_ftr_reg(SYS_MVFR0_EL1,info->reg_mvfr0);+init_cpu_ftr_reg(SYS_MVFR1_EL1,info->reg_mvfr1);+init_cpu_ftr_reg(SYS_MVFR2_EL1,info->reg_mvfr2);+}+void__initinit_cpu_features(structcpuinfo_arm64*info){/* Before we start using the tables, make sure it is sorted */
@@ -371,31 +397,8 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)info->reg_id_aa64pfr1=read_cpuid(ID_AA64PFR1_EL1);info->reg_id_aa64zfr0=read_cpuid(ID_AA64ZFR0_EL1);-/* Update the 32bit ID registers only if AArch32 is implemented */-if(id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)){-info->reg_id_dfr0=read_cpuid(ID_DFR0_EL1);-info->reg_id_dfr1=read_cpuid(ID_DFR1_EL1);-info->reg_id_isar0=read_cpuid(ID_ISAR0_EL1);-info->reg_id_isar1=read_cpuid(ID_ISAR1_EL1);-info->reg_id_isar2=read_cpuid(ID_ISAR2_EL1);-info->reg_id_isar3=read_cpuid(ID_ISAR3_EL1);-info->reg_id_isar4=read_cpuid(ID_ISAR4_EL1);-info->reg_id_isar5=read_cpuid(ID_ISAR5_EL1);-info->reg_id_isar6=read_cpuid(ID_ISAR6_EL1);-info->reg_id_mmfr0=read_cpuid(ID_MMFR0_EL1);-info->reg_id_mmfr1=read_cpuid(ID_MMFR1_EL1);-info->reg_id_mmfr2=read_cpuid(ID_MMFR2_EL1);-info->reg_id_mmfr3=read_cpuid(ID_MMFR3_EL1);-info->reg_id_mmfr4=read_cpuid(ID_MMFR4_EL1);-info->reg_id_mmfr5=read_cpuid(ID_MMFR5_EL1);-info->reg_id_pfr0=read_cpuid(ID_PFR0_EL1);-info->reg_id_pfr1=read_cpuid(ID_PFR1_EL1);-info->reg_id_pfr2=read_cpuid(ID_PFR2_EL1);--info->reg_mvfr0=read_cpuid(MVFR0_EL1);-info->reg_mvfr1=read_cpuid(MVFR1_EL1);-info->reg_mvfr2=read_cpuid(MVFR2_EL1);-}+if(id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))+__cpuinfo_store_cpu_32bit(&info->aarch32);if(IS_ENABLED(CONFIG_ARM64_SVE)&&id_aa64pfr0_sve(info->reg_id_aa64pfr0))
--
2.31.1.751.gd2f1c929bd-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Tue, May 18, 2021 at 10:47:05AM +0100, Will Deacon wrote:
In preparation for late initialisation of the "sanitised" AArch32 register
state, move the AArch32 registers out of 'struct cpuinfo' and into their
own struct definition.
Signed-off-by: Will Deacon <will@kernel.org>
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:47:52
When confronted with a mixture of CPUs, some of which support 32-bit
applications and others which don't, we quite sensibly treat the system
as 64-bit only for userspace and prevent execve() of 32-bit binaries.
Unfortunately, some crazy folks have decided to build systems like this
with the intention of running 32-bit applications, so relax our
sanitisation logic to continue to advertise 32-bit support to userspace
on these systems and track the real 32-bit capable cores in a cpumask
instead. For now, the default behaviour remains but will be tied to
a command-line option in a later patch.
Signed-off-by: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/cpucaps.h | 3 +-
arch/arm64/include/asm/cpufeature.h | 8 +-
arch/arm64/kernel/cpufeature.c | 114 ++++++++++++++++++++++++----
3 files changed, 110 insertions(+), 15 deletions(-)
@@ -2426,7 +2482,7 @@ static bool cpus_have_elf_hwcap(const struct arm64_cpu_capabilities *cap)returnrc;}-staticvoid__initsetup_elf_hwcaps(conststructarm64_cpu_capabilities*hwcaps)+staticvoidsetup_elf_hwcaps(conststructarm64_cpu_capabilities*hwcaps){/* We support emulation of accesses to CPU ID feature registers */cpu_set_named_feature(CPUID);
We may have discussed this before: AFAICT this will print 32-bit EL0
detected even if there's no 32-bit EL0 on any CPU. Should we instead
print 32-bit EL0 detected on CPU X when allow_mismatched_32bit_el0 is
passed? It would also give us an indication of the system configuration
when people start reporting bugs.
--
Catalin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
We may have discussed this before: AFAICT this will print 32-bit EL0
detected even if there's no 32-bit EL0 on any CPU. Should we instead
print 32-bit EL0 detected on CPU X when allow_mismatched_32bit_el0 is
passed? It would also give us an indication of the system configuration
when people start reporting bugs.
The function above only runs if we've detected 32-bit support via
aa64pfr0_el1, so I think we're ok. We also have a print when we detect the
mismatch (see enable_mismatched_32bit_el0()).
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
We may have discussed this before: AFAICT this will print 32-bit EL0
detected even if there's no 32-bit EL0 on any CPU. Should we instead
print 32-bit EL0 detected on CPU X when allow_mismatched_32bit_el0 is
passed? It would also give us an indication of the system configuration
when people start reporting bugs.
The function above only runs if we've detected 32-bit support via
aa64pfr0_el1, so I think we're ok. We also have a print when we detect the
mismatch (see enable_mismatched_32bit_el0()).
It makes sense, you removed the .desc from the arm64_features entry as
well.
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Tue, May 18, 2021 at 10:47:06AM +0100, Will Deacon wrote:
+static int enable_mismatched_32bit_el0(unsigned int cpu)
+{
+ struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu);
+ bool cpu_32bit = id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0);
+
+ if (cpu_32bit) {
+ cpumask_set_cpu(cpu, cpu_32bit_el0_mask);
+ static_branch_enable_cpuslocked(&arm64_mismatched_32bit_el0);
It may be worth only calling static_branch_enable_cpuslocked() if not
already set, in case you try this on a system with lots of CPUs.
--
Catalin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-05-24 12:10:13
On Fri, May 21, 2021 at 11:41:56AM +0100, Catalin Marinas wrote:
On Tue, May 18, 2021 at 10:47:06AM +0100, Will Deacon wrote:
quoted
+static int enable_mismatched_32bit_el0(unsigned int cpu)
+{
+ struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu);
+ bool cpu_32bit = id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0);
+
+ if (cpu_32bit) {
+ cpumask_set_cpu(cpu, cpu_32bit_el0_mask);
+ static_branch_enable_cpuslocked(&arm64_mismatched_32bit_el0);
It may be worth only calling static_branch_enable_cpuslocked() if not
already set, in case you try this on a system with lots of CPUs.
static_key_enable_cpuslocked() already checks this early on, so I don't
think we need another check here (note that we're not calling stop_machine()
here _anyway_; the '_cpuslocked' suffix just says that we're already holding
cpu_hotplug_lock via the notifier).
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Mon, May 24, 2021 at 01:09:59PM +0100, Will Deacon wrote:
On Fri, May 21, 2021 at 11:41:56AM +0100, Catalin Marinas wrote:
quoted
On Tue, May 18, 2021 at 10:47:06AM +0100, Will Deacon wrote:
quoted
+static int enable_mismatched_32bit_el0(unsigned int cpu)
+{
+ struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu);
+ bool cpu_32bit = id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0);
+
+ if (cpu_32bit) {
+ cpumask_set_cpu(cpu, cpu_32bit_el0_mask);
+ static_branch_enable_cpuslocked(&arm64_mismatched_32bit_el0);
It may be worth only calling static_branch_enable_cpuslocked() if not
already set, in case you try this on a system with lots of CPUs.
static_key_enable_cpuslocked() already checks this early on, so I don't
think we need another check here (note that we're not calling stop_machine()
here _anyway_; the '_cpuslocked' suffix just says that we're already holding
cpu_hotplug_lock via the notifier).
When confronted with a mixture of CPUs, some of which support 32-bit
applications and others which don't, we quite sensibly treat the system
as 64-bit only for userspace and prevent execve() of 32-bit binaries.
Unfortunately, some crazy folks have decided to build systems like this
with the intention of running 32-bit applications, so relax our
sanitisation logic to continue to advertise 32-bit support to userspace
on these systems and track the real 32-bit capable cores in a cpumask
instead. For now, the default behaviour remains but will be tied to
a command-line option in a later patch.
Signed-off-by: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/cpucaps.h | 3 +-
Heads up. I just tried to apply this on 5.13-rc2 and it failed because cpucaps.
was removed; it's autogenerated now.
See commit 0c6c2d3615ef: ()"arm64: Generate cpucaps.h")
Cheers
--
Qais Youesf
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-05-24 20:21:56
On Fri, May 21, 2021 at 04:22:55PM +0100, Qais Yousef wrote:
On 05/18/21 10:47, Will Deacon wrote:
quoted
When confronted with a mixture of CPUs, some of which support 32-bit
applications and others which don't, we quite sensibly treat the system
as 64-bit only for userspace and prevent execve() of 32-bit binaries.
Unfortunately, some crazy folks have decided to build systems like this
with the intention of running 32-bit applications, so relax our
sanitisation logic to continue to advertise 32-bit support to userspace
on these systems and track the real 32-bit capable cores in a cpumask
instead. For now, the default behaviour remains but will be tied to
a command-line option in a later patch.
Signed-off-by: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/cpucaps.h | 3 +-
Heads up. I just tried to apply this on 5.13-rc2 and it failed because cpucaps.
was removed; it's autogenerated now.
See commit 0c6c2d3615ef: ()"arm64: Generate cpucaps.h")
Yup, cheers. I'll sort that out once we're at the stage where we're merging
patches.
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:47:54
If a vCPU is caught running 32-bit code on a system with mismatched
support at EL0, then we should kill it.
Acked-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Will Deacon <will@kernel.org>
---
arch/arm64/kvm/arm.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
On Tue, May 18, 2021 at 10:47:07AM +0100, Will Deacon wrote:
If a vCPU is caught running 32-bit code on a system with mismatched
support at EL0, then we should kill it.
Acked-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Will Deacon <will@kernel.org>
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:47:56
Scheduling a 32-bit application on a 64-bit-only CPU is a bad idea.
Ensure that 32-bit applications always take the slow-path when returning
to userspace on a system with mismatched support at EL0, so that we can
avoid trying to run on a 64-bit-only CPU and force a SIGKILL instead.
Signed-off-by: Will Deacon <will@kernel.org>
---
arch/arm64/kernel/process.c | 19 ++++++++++++++++++-
arch/arm64/kernel/signal.c | 26 ++++++++++++++++++++++++++
2 files changed, 44 insertions(+), 1 deletion(-)
@@ -633,8 +643,15 @@ unsigned long arch_align_stack(unsigned long sp)*/voidarch_setup_new_exec(void){-current->mm->context.flags=is_compat_task()?MMCF_AARCH32:0;+unsignedlongmmflags=0;++if(is_compat_task()){+mmflags=MMCF_AARCH32;+if(static_branch_unlikely(&arm64_mismatched_32bit_el0))+set_tsk_thread_flag(current,TIF_NOTIFY_RESUME);+}+current->mm->context.flags=mmflags;ptrauth_thread_init_user();mte_thread_init_user();
On Tue, May 18, 2021 at 10:47:08AM +0100, Will Deacon wrote:
Scheduling a 32-bit application on a 64-bit-only CPU is a bad idea.
Ensure that 32-bit applications always take the slow-path when returning
to userspace on a system with mismatched support at EL0, so that we can
avoid trying to run on a 64-bit-only CPU and force a SIGKILL instead.
Signed-off-by: Will Deacon <will@kernel.org>
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:48:00
Since 32-bit applications will be killed if they are caught trying to
execute on a 64-bit-only CPU in a mismatched system, advertise the set
of 32-bit capable CPUs to userspace in sysfs.
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Will Deacon <will@kernel.org>
---
.../ABI/testing/sysfs-devices-system-cpu | 9 +++++++++
arch/arm64/kernel/cpufeature.c | 19 +++++++++++++++++++
2 files changed, 28 insertions(+)
@@ -494,6 +494,15 @@ Description: AArch64 CPU registers 'identification' directory exposes the CPU ID registers for identifying model and revision of the CPU.+What: /sys/devices/system/cpu/aarch32_el0+Date: May 2021+Contact: Linux ARM Kernel Mailing list <linux-arm-kernel@lists.infradead.org>+Description: Identifies the subset of CPUs in the system that can execute+ AArch32 (32-bit ARM) applications. If present, the same format as+ /sys/devices/system/cpu/{offline,online,possible,present} is used.+ If absent, then all or none of the CPUs can execute AArch32+ applications and execve() will behave accordingly.+ What: /sys/devices/system/cpu/cpu#/cpu_capacity Date: December 2016 Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
On Tue, May 18, 2021 at 10:47:09AM +0100, Will Deacon wrote:
Since 32-bit applications will be killed if they are caught trying to
execute on a 64-bit-only CPU in a mismatched system, advertise the set
of 32-bit capable CPUs to userspace in sysfs.
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Will Deacon <will@kernel.org>
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:48:11
Asymmetric systems may not offer the same level of userspace ISA support
across all CPUs, meaning that some applications cannot be executed by
some CPUs. As a concrete example, upcoming arm64 big.LITTLE designs do
not feature support for 32-bit applications on both clusters.
On such a system, we must take care not to migrate a task to an
unsupported CPU when forcefully moving tasks in select_fallback_rq()
in response to a CPU hot-unplug operation.
Introduce a task_cpu_possible_mask() hook which, given a task argument,
allows an architecture to return a cpumask of CPUs that are capable of
executing that task. The default implementation returns the
cpu_possible_mask, since sane machines do not suffer from per-cpu ISA
limitations that affect scheduling. The new mask is used when selecting
the fallback runqueue as a last resort before forcing a migration to the
first active CPU.
Reviewed-by: Quentin Perret <redacted>
Signed-off-by: Will Deacon <will@kernel.org>
---
include/linux/mmu_context.h | 8 ++++++++
kernel/sched/core.c | 10 ++++++----
2 files changed, 14 insertions(+), 4 deletions(-)
@@ -1813,8 +1813,11 @@ static inline bool is_cpu_allowed(struct task_struct *p, int cpu)returncpu_online(cpu);/* Non kernel threads are not allowed during either online or offline. */-if(!(p->flags&PF_KTHREAD))-returncpu_active(cpu);+if(!(p->flags&PF_KTHREAD)){+if(cpu_active(cpu))+returncpumask_test_cpu(cpu,task_cpu_possible_mask(p));+returnfalse;+}/* KTHREAD_IS_PER_CPU is always allowed. */if(kthread_is_per_cpu(p))
@@ -1813,8 +1813,11 @@ static inline bool is_cpu_allowed(struct task_struct *p, int cpu)returncpu_online(cpu);/* Non kernel threads are not allowed during either online or offline. */if(!(p->flags&PF_KTHREAD))-returncpu_active(cpu);
@@ -1813,8 +1813,11 @@ static inline bool is_cpu_allowed(struct task_struct *p, int cpu)returncpu_online(cpu);/* Non kernel threads are not allowed during either online or offline. */if(!(p->flags&PF_KTHREAD))-returncpu_active(cpu);
/* KTHREAD_IS_PER_CPU is always allowed. */
if (kthread_is_per_cpu(p))
Would something like that make sense?
I think this is probably the only place that we could use the helper, but
it's also one of the places where architectures that don't have to worry
about asymmetry end up with the check so, yes, I'll do that for v7.
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:48:39
If the scheduler cannot find an allowed CPU for a task,
cpuset_cpus_allowed_fallback() will widen the affinity to cpu_possible_mask
if cgroup v1 is in use.
In preparation for allowing architectures to provide their own fallback
mask, just return early if we're either using cgroup v1 or we're using
cgroup v2 with a mask that contains invalid CPUs. This will allow
select_fallback_rq() to figure out the mask by itself.
Cc: Li Zefan <redacted>
Cc: Tejun Heo <tj@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Quentin Perret <redacted>
Signed-off-by: Will Deacon <will@kernel.org>
---
include/linux/cpuset.h | 1 +
kernel/cgroup/cpuset.c | 12 ++++++++++--
2 files changed, 11 insertions(+), 2 deletions(-)
If the scheduler cannot find an allowed CPU for a task,
cpuset_cpus_allowed_fallback() will widen the affinity to cpu_possible_mask
if cgroup v1 is in use.
In preparation for allowing architectures to provide their own fallback
mask, just return early if we're either using cgroup v1 or we're using
cgroup v2 with a mask that contains invalid CPUs. This will allow
select_fallback_rq() to figure out the mask by itself.
Cc: Li Zefan <redacted>
Cc: Tejun Heo <tj@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Quentin Perret <redacted>
Signed-off-by: Will Deacon <will@kernel.org>
---
include/linux/cpuset.h | 1 +
kernel/cgroup/cpuset.c | 12 ++++++++++--
2 files changed, 11 insertions(+), 2 deletions(-)
Yes, and that's what the '!cpumask_subset()' check is doing above. Either
we use the valid subset of the cpuset mask (which is the intersection with
the possible mask) or we bail if that set is empty.
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:48:50
Asymmetric systems may not offer the same level of userspace ISA support
across all CPUs, meaning that some applications cannot be executed by
some CPUs. As a concrete example, upcoming arm64 big.LITTLE designs do
not feature support for 32-bit applications on both clusters.
Modify guarantee_online_cpus() to take task_cpu_possible_mask() into
account when trying to find a suitable set of online CPUs for a given
task. This will avoid passing an invalid mask to set_cpus_allowed_ptr()
during ->attach() and will subsequently allow the cpuset hierarchy to be
taken into account when forcefully overriding the affinity mask for a
task which requires migration to a compatible CPU.
Cc: Li Zefan <redacted>
Cc: Tejun Heo <tj@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Will Deacon <will@kernel.org>
---
include/linux/cpuset.h | 2 +-
kernel/cgroup/cpuset.c | 33 +++++++++++++++++++--------------
2 files changed, 20 insertions(+), 15 deletions(-)
Asymmetric systems may not offer the same level of userspace ISA support
across all CPUs, meaning that some applications cannot be executed by
some CPUs. As a concrete example, upcoming arm64 big.LITTLE designs do
not feature support for 32-bit applications on both clusters.
Modify guarantee_online_cpus() to take task_cpu_possible_mask() into
account when trying to find a suitable set of online CPUs for a given
task. This will avoid passing an invalid mask to set_cpus_allowed_ptr()
during ->attach() and will subsequently allow the cpuset hierarchy to be
taken into account when forcefully overriding the affinity mask for a
task which requires migration to a compatible CPU.
Cc: Li Zefan <redacted>
Cc: Tejun Heo <tj@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Will Deacon <will@kernel.org>
---
include/linux/cpuset.h | 2 +-
kernel/cgroup/cpuset.c | 33 +++++++++++++++++++--------------
2 files changed, 20 insertions(+), 15 deletions(-)
task_cs() requires rcu_read_lock(), but I can't see how the lock is obtained
from cpuset_attach() path, did I miss it? Running with lockdep should spill
suspicious RCU usage warning.
Maybe it makes more sense to move the rcu_read_lock() inside the function now
with task_cs()?
Thanks
--
Qais Yousef
quoted hunk
+ const struct cpumask *possible_mask = task_cpu_possible_mask(tsk);
+
+ if (WARN_ON(!cpumask_and(pmask, possible_mask, cpu_online_mask)))
+ cpumask_copy(pmask, cpu_online_mask);
+
+ while (!cpumask_intersects(cs->effective_cpus, pmask)) {
cs = parent_cs(cs);
if (unlikely(!cs)) {
/*
@@ -393,11 +401,10 @@ static void guarantee_online_cpus(struct cpuset *cs, struct cpumask *pmask) * cpuset's effective_cpus is on its way to be * identical to cpu_online_mask. */- cpumask_copy(pmask, cpu_online_mask); return; } }- cpumask_and(pmask, cs->effective_cpus, cpu_online_mask);+ cpumask_and(pmask, pmask, cs->effective_cpus); } /*
@@ -2199,15 +2206,13 @@ static void cpuset_attach(struct cgroup_taskset *tset) percpu_down_write(&cpuset_rwsem);- /* prepare for attach */- if (cs == &top_cpuset)- cpumask_copy(cpus_attach, cpu_possible_mask);- else- guarantee_online_cpus(cs, cpus_attach);- guarantee_online_mems(cs, &cpuset_attach_nodemask_to); cgroup_taskset_for_each(task, css, tset) {+ if (cs != &top_cpuset)+ guarantee_online_cpus(task, cpus_attach);+ else+ cpumask_copy(cpus_attach, task_cpu_possible_mask(task)); /* * can_attach beforehand should guarantee that this doesn't * fail. TODO: have a better way to handle failure here
From: Will Deacon <will@kernel.org> Date: 2021-05-24 21:09:45
On Fri, May 21, 2021 at 05:25:24PM +0100, Qais Yousef wrote:
On 05/18/21 10:47, Will Deacon wrote:
quoted
Asymmetric systems may not offer the same level of userspace ISA support
across all CPUs, meaning that some applications cannot be executed by
some CPUs. As a concrete example, upcoming arm64 big.LITTLE designs do
not feature support for 32-bit applications on both clusters.
Modify guarantee_online_cpus() to take task_cpu_possible_mask() into
account when trying to find a suitable set of online CPUs for a given
task. This will avoid passing an invalid mask to set_cpus_allowed_ptr()
during ->attach() and will subsequently allow the cpuset hierarchy to be
taken into account when forcefully overriding the affinity mask for a
task which requires migration to a compatible CPU.
Cc: Li Zefan <redacted>
Cc: Tejun Heo <tj@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Will Deacon <will@kernel.org>
---
include/linux/cpuset.h | 2 +-
kernel/cgroup/cpuset.c | 33 +++++++++++++++++++--------------
2 files changed, 20 insertions(+), 15 deletions(-)
task_cs() requires rcu_read_lock(), but I can't see how the lock is obtained
from cpuset_attach() path, did I miss it? Running with lockdep should spill
suspicious RCU usage warning.
Maybe it makes more sense to move the rcu_read_lock() inside the function now
with task_cs()?
Well spotted! I'll add the rcu_read_[un]lock() calls to
guarantee_online_cpus().
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:49:02
Reject explicit requests to change the affinity mask of a task via
set_cpus_allowed_ptr() if the requested mask is not a subset of the
mask returned by task_cpu_possible_mask(). This ensures that the
'cpus_mask' for a given task cannot contain CPUs which are incapable of
executing it, except in cases where the affinity is forced.
Reviewed-by: Quentin Perret <redacted>
Signed-off-by: Will Deacon <will@kernel.org>
---
kernel/sched/core.c | 4 ++++
1 file changed, 4 insertions(+)
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:49:10
In preparation for saving and restoring the user-requested CPU affinity
mask of a task, add a new cpumask_t pointer to 'struct task_struct'.
If the pointer is non-NULL, then the mask is copied across fork() and
freed on task exit.
Signed-off-by: Will Deacon <will@kernel.org>
---
include/linux/sched.h | 13 +++++++++++++
init/init_task.c | 1 +
kernel/fork.c | 2 ++
kernel/sched/core.c | 20 ++++++++++++++++++++
4 files changed, 36 insertions(+)
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:49:15
In preparation for replaying user affinity requests using a saved mask,
split sched_setaffinity() up so that the initial task lookup and
security checks are only performed when the request is coming directly
from userspace.
Signed-off-by: Will Deacon <will@kernel.org>
---
kernel/sched/core.c | 110 +++++++++++++++++++++++---------------------
1 file changed, 58 insertions(+), 52 deletions(-)
In preparation for replaying user affinity requests using a saved mask,
split sched_setaffinity() up so that the initial task lookup and
security checks are only performed when the request is coming directly
from userspace.
Signed-off-by: Will Deacon <will@kernel.org>
---
kernel/sched/core.c | 110 +++++++++++++++++++++++---------------------
1 file changed, 58 insertions(+), 52 deletions(-)
From: Will Deacon <will@kernel.org> Date: 2021-05-24 21:16:37
On Fri, May 21, 2021 at 05:41:01PM +0100, Qais Yousef wrote:
On 05/18/21 10:47, Will Deacon wrote:
quoted
In preparation for replaying user affinity requests using a saved mask,
split sched_setaffinity() up so that the initial task lookup and
security checks are only performed when the request is coming directly
from userspace.
Signed-off-by: Will Deacon <will@kernel.org>
---
kernel/sched/core.c | 110 +++++++++++++++++++++++---------------------
1 file changed, 58 insertions(+), 52 deletions(-)
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:49:21
Asymmetric systems may not offer the same level of userspace ISA support
across all CPUs, meaning that some applications cannot be executed by
some CPUs. As a concrete example, upcoming arm64 big.LITTLE designs do
not feature support for 32-bit applications on both clusters.
Although userspace can carefully manage the affinity masks for such
tasks, one place where it is particularly problematic is execve()
because the CPU on which the execve() is occurring may be incompatible
with the new application image. In such a situation, it is desirable to
restrict the affinity mask of the task and ensure that the new image is
entered on a compatible CPU. From userspace's point of view, this looks
the same as if the incompatible CPUs have been hotplugged off in the
task's affinity mask. Similarly, if a subsequent execve() reverts to
a compatible image, then the old affinity is restored if it is still
valid.
In preparation for restricting the affinity mask for compat tasks on
arm64 systems without uniform support for 32-bit applications, introduce
{force,relax}_compatible_cpus_allowed_ptr(), which respectively restrict
and restore the affinity mask for a task based on the compatible CPUs.
Reviewed-by: Quentin Perret <redacted>
Signed-off-by: Will Deacon <will@kernel.org>
---
include/linux/sched.h | 2 +
kernel/sched/core.c | 165 ++++++++++++++++++++++++++++++++++++++----
kernel/sched/sched.h | 1 +
3 files changed, 152 insertions(+), 16 deletions(-)
@@ -2430,20 +2425,158 @@ static int __set_cpus_allowed_ptr(struct task_struct *p,__do_set_cpus_allowed(p,new_mask,flags);-returnaffine_move_task(rq,p,&rf,dest_cpu,flags);+if(flags&SCA_USER)+release_user_cpus_ptr(p);++returnaffine_move_task(rq,p,rf,dest_cpu,flags);out:-task_rq_unlock(rq,p,&rf);+task_rq_unlock(rq,p,rf);returnret;}+/*+*Changeagiventask'sCPUaffinity.Migratethethreadtoa+*properCPUandscheduleitawayiftheCPUit'sexecutingon+*isremovedfromtheallowedbitmask.+*+*NOTE:thecallermusthaveavalidreferencetothetask,the+*taskmustnotexit()&deallocateitselfprematurely.The+*callisnotatomic;nospinlocksmaybeheld.+*/+staticint__set_cpus_allowed_ptr(structtask_struct*p,+conststructcpumask*new_mask,u32flags)+{+structrq_flagsrf;+structrq*rq;++rq=task_rq_lock(p,&rf);+return__set_cpus_allowed_ptr_locked(p,new_mask,flags,rq,&rf);+}+intset_cpus_allowed_ptr(structtask_struct*p,conststructcpumask*new_mask){return__set_cpus_allowed_ptr(p,new_mask,0);}EXPORT_SYMBOL_GPL(set_cpus_allowed_ptr);+/*+*Changeagiventask'sCPUaffinitytotheintersectionofitscurrent+*affinitymaskand@subset_mask,writingtheresultingmaskto@new_mask+*andpointing@p->user_cpus_ptrtoacopyoftheoldmask.+*Iftheresultingmaskisempty,leavetheaffinityunchangedandreturn+*-EINVAL.+*/+staticintrestrict_cpus_allowed_ptr(structtask_struct*p,+structcpumask*new_mask,+conststructcpumask*subset_mask)+{+structrq_flagsrf;+structrq*rq;+interr;+structcpumask*user_mask=NULL;++if(!p->user_cpus_ptr)+user_mask=kmalloc(cpumask_size(),GFP_KERNEL);++rq=task_rq_lock(p,&rf);++/*+*We'reabouttobutcherthetaskaffinity,sokeeptrackofwhat+*theuseraskedforincasewe'reabletorestoreitlateron.+*/+if(user_mask){+cpumask_copy(user_mask,p->cpus_ptr);+p->user_cpus_ptr=user_mask;+}++/*+*Forcefullyrestrictingtheaffinityofadeadlinetaskis+*likelytocauseproblems,sofailandnoisilyoverridethe+*maskentirely.+*/+if(task_has_dl_policy(p)&&dl_bandwidth_enabled()){+err=-EPERM;+gotoerr_unlock;+}++if(!cpumask_and(new_mask,&p->cpus_mask,subset_mask)){+err=-EINVAL;+gotoerr_unlock;+}++return__set_cpus_allowed_ptr_locked(p,new_mask,false,rq,&rf);++err_unlock:+task_rq_unlock(rq,p,&rf);+returnerr;+}++/*+*RestricttheCPUaffinityoftask@psothatitisasubsetof+*task_cpu_possible_mask()andpoint@p->user_cpu_ptrtoacopyofthe+*oldaffinitymask.Iftheresultingmaskisempty,wewarnandwalk+*upthecpusethierarchyuntilwefindasuitablemask.+*/+voidforce_compatible_cpus_allowed_ptr(structtask_struct*p)+{+cpumask_var_tnew_mask;+conststructcpumask*override_mask=task_cpu_possible_mask(p);++if(!alloc_cpumask_var(&new_mask,GFP_KERNEL))+gotoout_set_mask;++if(!restrict_cpus_allowed_ptr(p,new_mask,override_mask))+gotoout_free_mask;++/*+*Wefailedtofindavalidsubsetoftheaffinitymaskforthe+*task,sooverrideitbasedonitscpusethierarchy.+*/+cpuset_cpus_allowed(p,new_mask);+override_mask=new_mask;++out_set_mask:+if(printk_ratelimit()){+printk_deferred("Overriding affinity for process %d (%s) to CPUs %*pbl\n",+task_pid_nr(p),p->comm,+cpumask_pr_args(override_mask));+}++set_cpus_allowed_ptr(p,override_mask);+out_free_mask:+free_cpumask_var(new_mask);+}++staticint+__sched_setaffinity(structtask_struct*p,conststructcpumask*mask);++/*+*Restoretheaffinityofatask@pwhichwaspreviouslyrestrictedbya+*calltoforce_compatible_cpus_allowed_ptr().Thiswillclear(andfree)+*@p->user_cpus_ptr.+*/+voidrelax_compatible_cpus_allowed_ptr(structtask_struct*p)+{+unsignedlongflags;+structcpumask*mask=p->user_cpus_ptr;++if(!mask)+return;++/*+*Trytorestoretheoldaffinitymask.Ifthisfails,then+*wefreethemaskexplicitlytoavoiditbeinginheritedacross+*asubsequentfork().+*/+if(__sched_setaffinity(p,mask)){+raw_spin_lock_irqsave(&p->pi_lock,flags);+release_user_cpus_ptr(p);+raw_spin_unlock_irqrestore(&p->pi_lock,flags);+}+}+voidset_task_cpu(structtask_struct*p,unsignedintnew_cpu){#ifdef CONFIG_SCHED_DEBUG
Asymmetric systems may not offer the same level of userspace ISA support
across all CPUs, meaning that some applications cannot be executed by
some CPUs. As a concrete example, upcoming arm64 big.LITTLE designs do
not feature support for 32-bit applications on both clusters.
Although userspace can carefully manage the affinity masks for such
tasks, one place where it is particularly problematic is execve()
because the CPU on which the execve() is occurring may be incompatible
with the new application image. In such a situation, it is desirable to
restrict the affinity mask of the task and ensure that the new image is
entered on a compatible CPU. From userspace's point of view, this looks
the same as if the incompatible CPUs have been hotplugged off in the
task's affinity mask. Similarly, if a subsequent execve() reverts to
a compatible image, then the old affinity is restored if it is still
valid.
In preparation for restricting the affinity mask for compat tasks on
arm64 systems without uniform support for 32-bit applications, introduce
{force,relax}_compatible_cpus_allowed_ptr(), which respectively restrict
and restore the affinity mask for a task based on the compatible CPUs.
Reviewed-by: Quentin Perret <redacted>
Signed-off-by: Will Deacon <will@kernel.org>
---
include/linux/sched.h | 2 +
kernel/sched/core.c | 165 ++++++++++++++++++++++++++++++++++++++----
kernel/sched/sched.h | 1 +
3 files changed, 152 insertions(+), 16 deletions(-)
@@ -2430,20 +2425,158 @@ static int __set_cpus_allowed_ptr(struct task_struct *p,__do_set_cpus_allowed(p,new_mask,flags);-returnaffine_move_task(rq,p,&rf,dest_cpu,flags);+if(flags&SCA_USER)+release_user_cpus_ptr(p);
Why do we need to release the pointer here?
Doesn't this mean if a 32bit task requests to change its affinity, then we'll
lose this info and a subsequent execve() to a 64bit application means we won't
be able to restore the original mask?
ie:
p0-64bit
execve(32bit_app)
// p1-32bit created
p1-32bit.change_affinity()
relase_user_cpus_ptr()
execve(64bit_app) // lost info about p0 affinity?
Hmm I think this helped me to get the answer. p1 changed its affinity, then
there's nothing to be inherited by a new execve(), so yes we no longer need
this info.
+/*
+ * Change a given task's CPU affinity to the intersection of its current
+ * affinity mask and @subset_mask, writing the resulting mask to @new_mask
+ * and pointing @p->user_cpus_ptr to a copy of the old mask.
+ * If the resulting mask is empty, leave the affinity unchanged and return
+ * -EINVAL.
+ */
+static int restrict_cpus_allowed_ptr(struct task_struct *p,
+ struct cpumask *new_mask,
+ const struct cpumask *subset_mask)
+{
+ struct rq_flags rf;
+ struct rq *rq;
+ int err;
+ struct cpumask *user_mask = NULL;
+
+ if (!p->user_cpus_ptr)
+ user_mask = kmalloc(cpumask_size(), GFP_KERNEL);
+
+ rq = task_rq_lock(p, &rf);
+
+ /*
+ * We're about to butcher the task affinity, so keep track of what
+ * the user asked for in case we're able to restore it later on.
+ */
+ if (user_mask) {
+ cpumask_copy(user_mask, p->cpus_ptr);
+ p->user_cpus_ptr = user_mask;
+ }
+
+ /*
+ * Forcefully restricting the affinity of a deadline task is
+ * likely to cause problems, so fail and noisily override the
+ * mask entirely.
+ */
+ if (task_has_dl_policy(p) && dl_bandwidth_enabled()) {
+ err = -EPERM;
+ goto err_unlock;
Why do we need to release the pointer here?
Doesn't this mean if a 32bit task requests to change its affinity, then we'll
lose this info and a subsequent execve() to a 64bit application means we won't
be able to restore the original mask?
ie:
p0-64bit
execve(32bit_app)
// p1-32bit created
p1-32bit.change_affinity()
relase_user_cpus_ptr()
execve(64bit_app) // lost info about p0 affinity?
Hmm I think this helped me to get the answer. p1 changed its affinity, then
there's nothing to be inherited by a new execve(), so yes we no longer need
this info.
Yup, you got it.
quoted
+static int restrict_cpus_allowed_ptr(struct task_struct *p,
+ struct cpumask *new_mask,
+ const struct cpumask *subset_mask)
+{
+ struct rq_flags rf;
+ struct rq *rq;
+ int err;
+ struct cpumask *user_mask = NULL;
+
+ if (!p->user_cpus_ptr)
+ user_mask = kmalloc(cpumask_size(), GFP_KERNEL);
+
+ rq = task_rq_lock(p, &rf);
+
+ /*
+ * We're about to butcher the task affinity, so keep track of what
+ * the user asked for in case we're able to restore it later on.
+ */
+ if (user_mask) {
+ cpumask_copy(user_mask, p->cpus_ptr);
+ p->user_cpus_ptr = user_mask;
+ }
+
+ /*
+ * Forcefully restricting the affinity of a deadline task is
+ * likely to cause problems, so fail and noisily override the
+ * mask entirely.
+ */
+ if (task_has_dl_policy(p) && dl_bandwidth_enabled()) {
+ err = -EPERM;
+ goto err_unlock;
We free the mask when the task exits so we don't actually need to clean up
here. I left it like this on the assumption that failing here means that
it's very likely that either the task will exit or retry very soon.
However I agree that it would be clearer to free the thing anyway, so I'll
rejig the code to do that.
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-05-18 09:49:23
On asymmetric systems where the affinity of a task is restricted to
contain only the CPUs capable of running it, admission to the deadline
scheduler is likely to fail because the span of the sched domain
contains incompatible CPUs. Although this is arguably the right thing to
do, it is inconsistent with the case where the affinity of a task is
restricted after already having been admitted to the deadline scheduler.
For example, on an arm64 system where not all CPUs support 32-bit
applications, a 64-bit deadline task can exec() a 32-bit image and have
its affinity forcefully restricted.
Rather than reject these tasks altogether, favour the requested user
affinity saved in 'task_struct::user_cpus_ptr' over the actual affinity
of the task which has been restricted by the kernel.
Signed-off-by: Will Deacon <will@kernel.org>
---
kernel/sched/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
On Tuesday 18 May 2021 at 10:47:17 (+0100), Will Deacon wrote:
On asymmetric systems where the affinity of a task is restricted to
contain only the CPUs capable of running it, admission to the deadline
scheduler is likely to fail because the span of the sched domain
contains incompatible CPUs. Although this is arguably the right thing to
do, it is inconsistent with the case where the affinity of a task is
restricted after already having been admitted to the deadline scheduler.
For example, on an arm64 system where not all CPUs support 32-bit
applications, a 64-bit deadline task can exec() a 32-bit image and have
its affinity forcefully restricted.
So I guess the alternative would be to fail exec-ing into 32bit from a
64bit DL task, and then drop this patch?
The nice thing about your approach is that existing applications won't
really notice a difference (execve would still 'work'), but on the cons
side it breaks admission control, which is sad.
I don't expect this weird execve-to-32bit pattern from DL to be that
common in practice (at the very least not in Android), so maybe we could
start with the stricter version (fail the execve), and wait to see if
folks complain? Making things stricter later will be harder.
Thoughts?
Thanks,
Quentin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-05-18 10:28:47
[Dropping Li Zefan as his mail is bouncing]
On Tue, May 18, 2021 at 10:20:38AM +0000, Quentin Perret wrote:
On Tuesday 18 May 2021 at 10:47:17 (+0100), Will Deacon wrote:
quoted
On asymmetric systems where the affinity of a task is restricted to
contain only the CPUs capable of running it, admission to the deadline
scheduler is likely to fail because the span of the sched domain
contains incompatible CPUs. Although this is arguably the right thing to
do, it is inconsistent with the case where the affinity of a task is
restricted after already having been admitted to the deadline scheduler.
For example, on an arm64 system where not all CPUs support 32-bit
applications, a 64-bit deadline task can exec() a 32-bit image and have
its affinity forcefully restricted.
So I guess the alternative would be to fail exec-ing into 32bit from a
64bit DL task, and then drop this patch?
The nice thing about your approach is that existing applications won't
really notice a difference (execve would still 'work'), but on the cons
side it breaks admission control, which is sad.
Right, with your suggestion here we would forbid any 32-bit deadline tasks
on an asymmetric system, even if you'd gone to the extraordinary effort
to cater for that (e.g. by having a separate root domain).
I don't expect this weird execve-to-32bit pattern from DL to be that
common in practice (at the very least not in Android), so maybe we could
start with the stricter version (fail the execve), and wait to see if
folks complain? Making things stricter later will be harder.
Thoughts?
I don't have strong opinions on this, but I _do_ want the admission via
sched_setattr() to be consistent with execve(). What you're suggesting
ticks that box, but how many applications are prepared to handle a failed
execve()? I suspect it will be fatal.
Probably also worth pointing out that the approach here will at least
warn in the execve() case when the affinity is overridden for a deadline
task.
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Tuesday 18 May 2021 at 11:28:34 (+0100), Will Deacon wrote:
I don't have strong opinions on this, but I _do_ want the admission via
sched_setattr() to be consistent with execve(). What you're suggesting
ticks that box, but how many applications are prepared to handle a failed
execve()? I suspect it will be fatal.
Yep, probably.
Probably also worth pointing out that the approach here will at least
warn in the execve() case when the affinity is overridden for a deadline
task.
Right so I think either way will be imperfect, so I agree with the
above.
Maybe one thing though is that, IIRC, userspace _can_ disable admission
control if it wants to. In this case I'd have no problem with allowing
this weird behaviour when admission control is off -- the kernel won't
provide any guarantees. But if it's left on, then it's a different
story.
So what about we say, if admission control is off, we allow execve() and
sched_setattr() with appropriate warnings as you suggest, but if
admission control is on then we fail both?
We might still see random failures in the wild if admission control is
left enabled on those devices but then I think these could qualify as
a device misconfiguration, not as a kernel bug.
Thoughts?
Thanks,
Quentin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-05-18 11:00:00
On Tue, May 18, 2021 at 10:48:07AM +0000, Quentin Perret wrote:
On Tuesday 18 May 2021 at 11:28:34 (+0100), Will Deacon wrote:
quoted
I don't have strong opinions on this, but I _do_ want the admission via
sched_setattr() to be consistent with execve(). What you're suggesting
ticks that box, but how many applications are prepared to handle a failed
execve()? I suspect it will be fatal.
Yep, probably.
quoted
Probably also worth pointing out that the approach here will at least
warn in the execve() case when the affinity is overridden for a deadline
task.
Right so I think either way will be imperfect, so I agree with the
above.
Maybe one thing though is that, IIRC, userspace _can_ disable admission
control if it wants to. In this case I'd have no problem with allowing
this weird behaviour when admission control is off -- the kernel won't
provide any guarantees. But if it's left on, then it's a different
story.
So what about we say, if admission control is off, we allow execve() and
sched_setattr() with appropriate warnings as you suggest, but if
admission control is on then we fail both?
That's an interesting idea. The part that I'm not super keen about is
that it means admission control _also_ has an effect on the behaviour of
execve(), so practically you'd have to have it disabled as long as you
have the possibility of 32-bit deadline tasks anywhere in the system,
which impacts 64-bit tasks which may well want admission control enabled.
So perhaps my initial position of trying to keep sched_setattr() and
execve() consistent with each other is flawed and actually we can say:
* Disable admission control if you want to admit a 32-bit task explicitly
via sched_setattr()
* If a 64-bit deadline task execve()s a 32-bit program then we warn
and override the affinity (i.e. you should avoid doing this if you
care about the deadlines).
That amounts to dropping this patch and tweaking the documentation.
Dunno, what do you think?
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Tuesday 18 May 2021 at 11:59:51 (+0100), Will Deacon wrote:
On Tue, May 18, 2021 at 10:48:07AM +0000, Quentin Perret wrote:
quoted
On Tuesday 18 May 2021 at 11:28:34 (+0100), Will Deacon wrote:
quoted
I don't have strong opinions on this, but I _do_ want the admission via
sched_setattr() to be consistent with execve(). What you're suggesting
ticks that box, but how many applications are prepared to handle a failed
execve()? I suspect it will be fatal.
Yep, probably.
quoted
Probably also worth pointing out that the approach here will at least
warn in the execve() case when the affinity is overridden for a deadline
task.
Right so I think either way will be imperfect, so I agree with the
above.
Maybe one thing though is that, IIRC, userspace _can_ disable admission
control if it wants to. In this case I'd have no problem with allowing
this weird behaviour when admission control is off -- the kernel won't
provide any guarantees. But if it's left on, then it's a different
story.
So what about we say, if admission control is off, we allow execve() and
sched_setattr() with appropriate warnings as you suggest, but if
admission control is on then we fail both?
That's an interesting idea. The part that I'm not super keen about is
that it means admission control _also_ has an effect on the behaviour of
execve()
Right, that's a good point. And it looks like fork() behaves the same
regardless of admission control being enabled or not -- it is forbidden
from DL either way. So I can't say there is a precedent :/
so practically you'd have to have it disabled as long as you
have the possibility of 32-bit deadline tasks anywhere in the system,
which impacts 64-bit tasks which may well want admission control enabled.
Indeed, this is a bit sad, but I don't know if the kernel should pretend
it can guarantee to meet your deadlines and at the same time allow to do
something that wrecks the underlying theory.
I'd personally be happy with saying that admission control should be
disabled on these dumb systems (and have that documented), at least
until DL gets proper support for affinities. ISTR there was work going
in that direction, but some folks in the CC list will know better.
@Juri, maybe you would know if that's still planned?
Thanks,
Quentin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Juri Lelli <juri.lelli@redhat.com> Date: 2021-05-20 09:13:48
Hi Quentin and Will,
Apologies for the delay in replying.
On 18/05/21 13:19, Quentin Perret wrote:
On Tuesday 18 May 2021 at 11:59:51 (+0100), Will Deacon wrote:
quoted
On Tue, May 18, 2021 at 10:48:07AM +0000, Quentin Perret wrote:
quoted
On Tuesday 18 May 2021 at 11:28:34 (+0100), Will Deacon wrote:
quoted
I don't have strong opinions on this, but I _do_ want the admission via
sched_setattr() to be consistent with execve(). What you're suggesting
ticks that box, but how many applications are prepared to handle a failed
execve()? I suspect it will be fatal.
Yep, probably.
quoted
Probably also worth pointing out that the approach here will at least
warn in the execve() case when the affinity is overridden for a deadline
task.
Right so I think either way will be imperfect, so I agree with the
above.
Maybe one thing though is that, IIRC, userspace _can_ disable admission
control if it wants to. In this case I'd have no problem with allowing
this weird behaviour when admission control is off -- the kernel won't
provide any guarantees. But if it's left on, then it's a different
story.
So what about we say, if admission control is off, we allow execve() and
sched_setattr() with appropriate warnings as you suggest, but if
admission control is on then we fail both?
That's an interesting idea. The part that I'm not super keen about is
that it means admission control _also_ has an effect on the behaviour of
execve()
Right, that's a good point. And it looks like fork() behaves the same
regardless of admission control being enabled or not -- it is forbidden
from DL either way. So I can't say there is a precedent :/
quoted
so practically you'd have to have it disabled as long as you
have the possibility of 32-bit deadline tasks anywhere in the system,
which impacts 64-bit tasks which may well want admission control enabled.
Indeed, this is a bit sad, but I don't know if the kernel should pretend
it can guarantee to meet your deadlines and at the same time allow to do
something that wrecks the underlying theory.
I'd personally be happy with saying that admission control should be
disabled on these dumb systems (and have that documented), at least
until DL gets proper support for affinities. ISTR there was work going
in that direction, but some folks in the CC list will know better.
@Juri, maybe you would know if that's still planned?
I won't go as far as saying planned, but that is still under "our" radar
for sure. Daniel was working on it, but I don't think he had any time to
resume that bit of work lately.
So, until we have that, I think we have been as conservative as we could
for this type of decisions. I'm a little afraid that allowing
configuration to break admission control (even with a non fatal warning
is emitted) is still risky. I'd go with fail hard if AC is on, let it
pass if AC is off (supposedly the user knows what to do). But I'm not
familiar with the mixed 32/64 apps usecase you describe, so I might be
missing details.
Best,
Juri
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-05-20 11:47:22
Hi Juri,
On Thu, May 20, 2021 at 11:13:39AM +0200, Juri Lelli wrote:
Apologies for the delay in replying.
Not at all!
On 18/05/21 13:19, Quentin Perret wrote:
quoted
On Tuesday 18 May 2021 at 11:59:51 (+0100), Will Deacon wrote:
quoted
On Tue, May 18, 2021 at 10:48:07AM +0000, Quentin Perret wrote:
quoted
On Tuesday 18 May 2021 at 11:28:34 (+0100), Will Deacon wrote:
quoted
I don't have strong opinions on this, but I _do_ want the admission via
sched_setattr() to be consistent with execve(). What you're suggesting
ticks that box, but how many applications are prepared to handle a failed
execve()? I suspect it will be fatal.
Yep, probably.
quoted
Probably also worth pointing out that the approach here will at least
warn in the execve() case when the affinity is overridden for a deadline
task.
Right so I think either way will be imperfect, so I agree with the
above.
Maybe one thing though is that, IIRC, userspace _can_ disable admission
control if it wants to. In this case I'd have no problem with allowing
this weird behaviour when admission control is off -- the kernel won't
provide any guarantees. But if it's left on, then it's a different
story.
So what about we say, if admission control is off, we allow execve() and
sched_setattr() with appropriate warnings as you suggest, but if
admission control is on then we fail both?
That's an interesting idea. The part that I'm not super keen about is
that it means admission control _also_ has an effect on the behaviour of
execve()
Right, that's a good point. And it looks like fork() behaves the same
regardless of admission control being enabled or not -- it is forbidden
from DL either way. So I can't say there is a precedent :/
quoted
so practically you'd have to have it disabled as long as you
have the possibility of 32-bit deadline tasks anywhere in the system,
which impacts 64-bit tasks which may well want admission control enabled.
Indeed, this is a bit sad, but I don't know if the kernel should pretend
it can guarantee to meet your deadlines and at the same time allow to do
something that wrecks the underlying theory.
I'd personally be happy with saying that admission control should be
disabled on these dumb systems (and have that documented), at least
until DL gets proper support for affinities. ISTR there was work going
in that direction, but some folks in the CC list will know better.
@Juri, maybe you would know if that's still planned?
I won't go as far as saying planned, but that is still under "our" radar
for sure. Daniel was working on it, but I don't think he had any time to
resume that bit of work lately.
So, until we have that, I think we have been as conservative as we could
for this type of decisions. I'm a little afraid that allowing
configuration to break admission control (even with a non fatal warning
is emitted) is still risky. I'd go with fail hard if AC is on, let it
pass if AC is off (supposedly the user knows what to do). But I'm not
familiar with the mixed 32/64 apps usecase you describe, so I might be
missing details.
Ok, thanks for the insight. In which case, I'll go with what we discussed:
require admission control to be disabled for sched_setattr() but allow
execve() to a 32-bit task from a 64-bit deadline task with a warning (this
is probably similar to CPU hotplug?).
I'll update that for v8, and this patch will disappear.
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Thursday 20 May 2021 at 11:16:41 (+0100), Will Deacon wrote:
Ok, thanks for the insight. In which case, I'll go with what we discussed:
require admission control to be disabled for sched_setattr() but allow
execve() to a 32-bit task from a 64-bit deadline task with a warning (this
is probably similar to CPU hotplug?).
Still not sure that we can let execve go through ... It will break AC
all the same, so it should probably fail as well if AC is on IMO
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Juri Lelli <juri.lelli@redhat.com> Date: 2021-05-20 12:38:35
On 20/05/21 10:33, Quentin Perret wrote:
On Thursday 20 May 2021 at 11:16:41 (+0100), Will Deacon wrote:
quoted
Ok, thanks for the insight. In which case, I'll go with what we discussed:
require admission control to be disabled for sched_setattr() but allow
execve() to a 32-bit task from a 64-bit deadline task with a warning (this
is probably similar to CPU hotplug?).
Still not sure that we can let execve go through ... It will break AC
all the same, so it should probably fail as well if AC is on IMO
From: Daniel Bristot de Oliveira <hidden> Date: 2021-05-20 12:39:20
On 5/20/21 12:33 PM, Quentin Perret wrote:
On Thursday 20 May 2021 at 11:16:41 (+0100), Will Deacon wrote:
quoted
Ok, thanks for the insight. In which case, I'll go with what we discussed:
require admission control to be disabled for sched_setattr() but allow
execve() to a 32-bit task from a 64-bit deadline task with a warning (this
is probably similar to CPU hotplug?).
Still not sure that we can let execve go through ... It will break AC
all the same, so it should probably fail as well if AC is on IMO
If the cpumask of the 32-bit task is != of the 64-bit task that is executing it,
the admission control needs to be re-executed, and it could fail. So I see this
operation equivalent to sched_setaffinity(). This will likely be true for future
schedulers that will allow arbitrary affinities (AC should run on affinity
change, and could fail).
I would vote with Juri: "I'd go with fail hard if AC is on, let it
pass if AC is off (supposedly the user knows what to do)," (also hope nobody
complains until we add better support for affinity, and use this as a motivation
to get back on this front).
-- Daniel
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On 20/05/2021 14:38, Daniel Bristot de Oliveira wrote:
On 5/20/21 12:33 PM, Quentin Perret wrote:
quoted
On Thursday 20 May 2021 at 11:16:41 (+0100), Will Deacon wrote:
quoted
Ok, thanks for the insight. In which case, I'll go with what we discussed:
require admission control to be disabled for sched_setattr() but allow
execve() to a 32-bit task from a 64-bit deadline task with a warning (this
is probably similar to CPU hotplug?).
Still not sure that we can let execve go through ... It will break AC
all the same, so it should probably fail as well if AC is on IMO
If the cpumask of the 32-bit task is != of the 64-bit task that is executing it,
the admission control needs to be re-executed, and it could fail. So I see this
operation equivalent to sched_setaffinity(). This will likely be true for future
schedulers that will allow arbitrary affinities (AC should run on affinity
change, and could fail).
I would vote with Juri: "I'd go with fail hard if AC is on, let it
pass if AC is off (supposedly the user knows what to do)," (also hope nobody
complains until we add better support for affinity, and use this as a motivation
to get back on this front).
-- Daniel
(1) # chrt -d -T 5000000 -P 16666666 0 ./32bit_app
(2) # ./32bit_app &
# chrt -d -T 5000000 -P 16666666 -p 0 pid_of(32bit_app)
Wouldn't the behaviour of (1) and (2) be different w/o this patch?
In (1) __sched_setscheduler() happens before execve so it operates on
p->cpus_ptr equal span.
In (2) span != p->cpus_ptr so DL AC will fail.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Daniel Bristot de Oliveira <hidden> Date: 2021-05-20 16:00:40
On 5/20/21 5:06 PM, Dietmar Eggemann wrote:
On 20/05/2021 14:38, Daniel Bristot de Oliveira wrote:
quoted
On 5/20/21 12:33 PM, Quentin Perret wrote:
quoted
On Thursday 20 May 2021 at 11:16:41 (+0100), Will Deacon wrote:
quoted
Ok, thanks for the insight. In which case, I'll go with what we discussed:
require admission control to be disabled for sched_setattr() but allow
execve() to a 32-bit task from a 64-bit deadline task with a warning (this
is probably similar to CPU hotplug?).
Still not sure that we can let execve go through ... It will break AC
all the same, so it should probably fail as well if AC is on IMO
If the cpumask of the 32-bit task is != of the 64-bit task that is executing it,
the admission control needs to be re-executed, and it could fail. So I see this
operation equivalent to sched_setaffinity(). This will likely be true for future
schedulers that will allow arbitrary affinities (AC should run on affinity
change, and could fail).
I would vote with Juri: "I'd go with fail hard if AC is on, let it
pass if AC is off (supposedly the user knows what to do)," (also hope nobody
complains until we add better support for affinity, and use this as a motivation
to get back on this front).
-- Daniel
(1) # chrt -d -T 5000000 -P 16666666 0 ./32bit_app
(2) # ./32bit_app &
# chrt -d -T 5000000 -P 16666666 -p 0 pid_of(32bit_app)
Wouldn't the behaviour of (1) and (2) be different w/o this patch?
In (1) __sched_setscheduler() happens before execve so it operates on
p->cpus_ptr equal span.
In (2) span != p->cpus_ptr so DL AC will fail.
As far as I got, the case (1) would be spitted in two steps:
- __sched_setscheduler() will work, then
- execv() would fail because (span != p->cpus_ptr)
So... at the end, both (1) and (2) would result in a failure...
am I missing something?
-- Daniel
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On 20/05/2021 18:00, Daniel Bristot de Oliveira wrote:
On 5/20/21 5:06 PM, Dietmar Eggemann wrote:
quoted
On 20/05/2021 14:38, Daniel Bristot de Oliveira wrote:
quoted
On 5/20/21 12:33 PM, Quentin Perret wrote:
quoted
On Thursday 20 May 2021 at 11:16:41 (+0100), Will Deacon wrote:
quoted
Ok, thanks for the insight. In which case, I'll go with what we discussed:
require admission control to be disabled for sched_setattr() but allow
execve() to a 32-bit task from a 64-bit deadline task with a warning (this
is probably similar to CPU hotplug?).
Still not sure that we can let execve go through ... It will break AC
all the same, so it should probably fail as well if AC is on IMO
If the cpumask of the 32-bit task is != of the 64-bit task that is executing it,
the admission control needs to be re-executed, and it could fail. So I see this
operation equivalent to sched_setaffinity(). This will likely be true for future
schedulers that will allow arbitrary affinities (AC should run on affinity
change, and could fail).
I would vote with Juri: "I'd go with fail hard if AC is on, let it
pass if AC is off (supposedly the user knows what to do)," (also hope nobody
complains until we add better support for affinity, and use this as a motivation
to get back on this front).
-- Daniel
(1) # chrt -d -T 5000000 -P 16666666 0 ./32bit_app
(2) # ./32bit_app &
# chrt -d -T 5000000 -P 16666666 -p 0 pid_of(32bit_app)
Wouldn't the behaviour of (1) and (2) be different w/o this patch?
In (1) __sched_setscheduler() happens before execve so it operates on
p->cpus_ptr equal span.
In (2) span != p->cpus_ptr so DL AC will fail.
As far as I got, the case (1) would be spitted in two steps:
- __sched_setscheduler() will work, then
- execv() would fail because (span != p->cpus_ptr)
So... at the end, both (1) and (2) would result in a failure...
am I missing something?
Not sure. Reading this thread I was under the assumption that the only
change would be the drop of this patch. But I assume there is also this
'if DL AC is on then let sched_setattr() fail for this 32bit task'.
IMHO, the current patch-stack w/o this patch should let (1) succeed with
DL AC.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-05-20 18:03:33
Hi Dietmar,
On Thu, May 20, 2021 at 07:55:27PM +0200, Dietmar Eggemann wrote:
On 20/05/2021 18:00, Daniel Bristot de Oliveira wrote:
quoted
On 5/20/21 5:06 PM, Dietmar Eggemann wrote:
quoted
(1) # chrt -d -T 5000000 -P 16666666 0 ./32bit_app
(2) # ./32bit_app &
# chrt -d -T 5000000 -P 16666666 -p 0 pid_of(32bit_app)
Wouldn't the behaviour of (1) and (2) be different w/o this patch?
In (1) __sched_setscheduler() happens before execve so it operates on
p->cpus_ptr equal span.
In (2) span != p->cpus_ptr so DL AC will fail.
As far as I got, the case (1) would be spitted in two steps:
- __sched_setscheduler() will work, then
- execv() would fail because (span != p->cpus_ptr)
So... at the end, both (1) and (2) would result in a failure...
am I missing something?
Not sure. Reading this thread I was under the assumption that the only
change would be the drop of this patch. But I assume there is also this
'if DL AC is on then let sched_setattr() fail for this 32bit task'.
IMHO, the current patch-stack w/o this patch should let (1) succeed with
DL AC.