On 1/31/23 17:17, Will Deacon wrote:
set_cpus_allowed_ptr() will fail with -EINVAL if the requested affinity mask is not a subset of the task_cpu_possible_mask() for the task being updated. Consequently, on a heterogeneous system with cpusets spanning the different CPU types, updates to the cgroup hierarchy can silently fail to update task affinities when the effective affinity mask for the cpuset is expanded. For example, consider an arm64 system with 4 CPUs, where CPUs 2-3 are the only cores capable of executing 32-bit tasks. Attaching a 32-bit task to a cpuset containing CPUs 0-2 will correctly affine the task to CPU 2. Extending the cpuset to CPUs 0-3, however, will fail to extend the affinity mask of the 32-bit task because update_tasks_cpumask() will pass the full 0-3 mask to set_cpus_allowed_ptr(). Extend update_tasks_cpumask() to take a temporary 'cpumask' paramater and use it to mask the 'effective_cpus' mask with the possible mask for each task being updated. Fixes: 431c69fac05b ("cpuset: Honour task_cpu_possible_mask() in guarantee_online_cpus()") Signed-off-by: Will Deacon <will@xxxxxxxxxx> --- Note: We wondered whether it was worth calling guarantee_online_cpus() if the cpumask_and() returns 0 in update_tasks_cpumask(), but given that this path is only called when the effective mask changes, it didn't seem appropriate. Ultimately, if you have 32-bit tasks attached to a cpuset containing only 64-bit cpus, then the affinity is going to be forced.
Now I see how the sched_setaffinity() change is impacting arm64. Instead of putting in the bandage in cpuset. I would suggest doing another cpu masking in __set_cpus_allowed_ptr() similar to what is now done for user_cpus_ptr.
Another suggestion that I have is to add a helper like has_task_cpu_possible_mask() that returns a true/false value. In this way, we only need to do an additional masking if we have some mismatched 32-bit only cpus available in the system running 32-bit binaries so that we can skip this step in most cases compiling them out in non-arm64 systems.
By doing that, we may be able to remove some of the existing usages of task_cpu_possible_mask().
Thought? Cheers, Longman