mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Juri Lelli <juri.lelli@redhat.com>
To: Andrea Parri <parri.andrea@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Vincent Guittot <vincent.guittot@linaro.org>,
	Dietmar Eggemann <dietmar.eggemann@arm.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Ben Segall <bsegall@google.com>, Mel Gorman <mgorman@suse.de>,
	Valentin Schneider <vschneid@redhat.com>,
	K Prateek Nayak <kprateek.nayak@amd.com>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Clark Williams <clrkwllms@kernel.org>,
	Aaron Tomlin <atomlin@atomlin.com>,
	linux-rt-devel@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] sched/deadline: Fix spurious -EPERM for migration-disabled tasks
Date: Tue, 3 Nov 2026 08:07:50 +0100	[thread overview]
Message-ID: <aumIRjQS2M0wWlVq@jlelli-thinkpadt14gen4.remote.csb> (raw)
In-Reply-To: <20261102135420.244745-1-parri.andrea@gmail.com>

Hello,

On 02/11/26 14:54, Andrea Parri wrote:
> sched_setattr() can refuse to make a task SCHED_DEADLINE with -EPERM,
> even though the task's affinity covers the whole root domain. A retry
> can succeed, but the error blames an affinity the task does not have.
> 
> __sched_setscheduler() tests p->cpus_ptr, which is not always the task's
> affinity. When a task is scheduled out inside a migrate_disable() section,
> migrate_disable_switch() points p->cpus_ptr at the current CPU until
> migrate_enable(). On PREEMPT_RT every spinlock_t holder is in such a
> section, so ordinary kernel work opens the window. Elsewhere, seccomp
> filters run in one.
> 
> Test p->cpus_mask instead, which keeps the task's affinity and is what
> sched_getaffinity() reports. This should be safe because an admitted
> task's cpus_mask covers the root domain, so set_cpus_allowed_dl() moves
> no bandwidth when migrate_enable() restores p->cpus_ptr.
> 
> The following program, run as root, had 553679, 453720 and 424623 of its
> 1000000 requests refused on three boots of a 4-CPU PREEMPT_RT guest, and
> 236182, 217174 and 237183 without PREEMPT_RT. With this applied the count
> is 0, also with lockdep, and a task pinned to one CPU is still refused:
> 
>   #define _GNU_SOURCE
>   #include <errno.h>
>   #include <linux/filter.h>
>   #include <linux/seccomp.h>
>   #include <pthread.h>
>   #include <stddef.h>
>   #include <stdint.h>
>   #include <stdio.h>
>   #include <sys/syscall.h>
>   #include <unistd.h>
> 
>   #define REQUESTS 1000000
>   #define INSNS 300
> 
>   struct attr {
>       uint32_t size, policy;
>       uint64_t flags;
>       int32_t nice;
>       uint32_t prio;
>       uint64_t runtime, deadline, period;
>   };
> 
>   static volatile int stop;
>   static volatile pid_t target;
> 
>   static long set(struct attr a)
>   {
>       a.size = sizeof(a);
>       return syscall(SYS_sched_setattr, target, &a, 0);
>   }
> 
>   static void *worker(void *arg)
>   {
>       struct sock_filter f[INSNS + 1];
>       struct sock_fprog prog = { .len = INSNS + 1, .filter = f };
>       int i;
> 
>       /* Reading the arguments keeps seccomp from caching the result */
>       for (i = 0; i < INSNS; i++)
>           f[i] = (struct sock_filter)
>               BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
>                        offsetof(struct seccomp_data, args));
>       f[INSNS] = (struct sock_filter)
>           BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW);
>       syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog);
> 
>       target = syscall(SYS_gettid);
>       while (!stop)
>           syscall(SYS_getppid);
>       return arg;
>   }
> 
>   static void *hog(void *arg)
>   {
>       while (!stop)
>           ;
>       return arg;
>   }
> 
>   int main(void)
>   {
>       pthread_t t[9];
>       long refused = 0;
>       int i;
> 
>       pthread_create(&t[0], NULL, worker, NULL);
>       while (!target)
>           usleep(100);
>       for (i = 1; i < 9; i++)
>           pthread_create(&t[i], NULL, hog, NULL);
>       for (i = 0; i < REQUESTS; i++) {
>           /* SCHED_DEADLINE, 2us every 1s */
>           if (set((struct attr){ .policy = 6, .runtime = 2000,
>                                  .deadline = 1000000000,
>                                  .period = 1000000000 }) && errno == EPERM)
>               refused++;
>           set((struct attr){ .policy = 0 }); /* SCHED_OTHER */
>       }
>       stop = 1;
>       for (i = 0; i < 9; i++)
>           pthread_join(t[i], NULL);
>       printf("%ld of %d requests refused\n", refused, REQUESTS);
>       return 0;
>   }
> 
> An LLM helped find this bug and write this patch and its test.
> 
> Fixes: af449901b84c ("sched: Add migrate_disable()")
> Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
> Cc: stable@vger.kernel.org

The fix makes sense to me.

Acked-by: Juri Lelli <juri.lelli@redhat.com>

I only wonder if we want the reproducer in the changelog. An alternative
might be to move it to https://github.com/jlelli/sched-deadline-tests
where I keep the rest of SCHED_DEADLINE tests. I can probably do that if
you agree and prefer.

Thanks!
Juri


  parent reply	other threads:[~2026-11-03  7:07 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-02 13:54 Andrea Parri
2026-11-02 14:45 ` Aaron Tomlin
2026-11-02 15:14   ` Andrea Parri
2026-11-02 17:00     ` Aaron Tomlin
2026-11-03  7:07 ` Juri Lelli [this message]
2026-11-03 13:20   ` Andrea Parri
2026-11-03  8:11 ` Sebastian Andrzej Siewior
2026-11-03 15:34   ` Andrea Parri

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aumIRjQS2M0wWlVq@jlelli-thinkpadt14gen4.remote.csb \
    --to=juri.lelli@redhat.com \
    --cc=atomlin@atomlin.com \
    --cc=bigeasy@linutronix.de \
    --cc=bsegall@google.com \
    --cc=clrkwllms@kernel.org \
    --cc=dietmar.eggemann@arm.com \
    --cc=kprateek.nayak@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rt-devel@lists.linux.dev \
    --cc=mgorman@suse.de \
    --cc=mingo@redhat.com \
    --cc=parri.andrea@gmail.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®