linux-trace-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Gabriele Monaco" <gmonaco@redhat.com>
Cc: linux-trace-kernel@vger.kernel.org
Subject: Re: [PATCH 07/10] rv: Add throttle deadline monitor
Date: Tue, 29 Sep 2026 13:18:46 +0000	[thread overview]
Message-ID: <20260929131847.32B1D1F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260929124908.177676-8-gmonaco@redhat.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] rv: timer overflow in runtime_left_ns() allows monitor evasion
- [High] rv: speculative monitor allocation causes memory leak and Use-After-Free
- [High] rv: concurrent hash table modifications in tracepoints corrupt monitor lists
- [Medium] rv: handle_sched_switch() skips switch-out events for background servers
- [Medium] rv: monitor timer is cancelled before syscall validation allowing evasion
--

commit 59f095bf10c27a9ddbf78eaa030f99a4df14f9eb
Author: Gabriele Monaco <gmonaco@redhat.com>

rv: Add throttle deadline monitor
    
This commit adds a monitor to validate the behavior of the deadline
scheduler, specifically ensuring that deadline entities are throttled when
they use up their runtime.

> --- /dev/null
> +++ b/kernel/trace/rv/monitors/throttle/throttle.c
[ ... ]
> +static inline u64 runtime_left_ns(struct ha_monitor *ha_mon)
> +{
> +	return ha_get_target(ha_mon)->runtime + RUNTIME_THRESH;
> +}

[Severity: High]
Can the implicit conversion to u64 here cause a timer overflow? 

ha_get_target(ha_mon)->runtime is a signed 64-bit value that can be
negative when a task overruns its budget. Returning it as a u64 casts it
to a huge positive value, which is then passed to ha_start_timer_ns(). 

Will this push the enforcement timer far into the future and effectively
blind the monitor to task overruns?

[ ... ]
> +static void handle_sched_switch(void *data, bool preempt,
> +				struct task_struct *prev,
> +				struct task_struct *next,
> +				unsigned int prev_state)
> +{
[ ... ]
> +	/*
> +	 * The server is available in next only if the next task is boosted,
> +	 * otherwise we need to retrieve it.
> +	 * Here the server continues in the state running/armed until actually
> +	 * stopped, this works since we continue expecting a throttle.
> +	 */
> +	if (next->dl_server) {
> +		da_handle_start_event(EXPAND_ID(next->dl_server, cpu,
> +						get_server_type(next)),
> +				      sched_switch_in_throttle);
> +	} else {
> +		handle_server_switch(next, cpu, DL_SERVER_FAIR);
> +		if (IS_ENABLED(CONFIG_SCHED_CLASS_EXT))
> +			handle_server_switch(next, cpu, DL_SERVER_EXT);
> +	}
> +}

[Severity: Medium]
Does this skip switch-out events for background servers?

If next->dl_server is non-NULL, we enter this branch and send a switch-in
event. However, this skips the else block entirely, meaning the preempted
fair or ext server on that CPU never receives its sched_switch_out_throttle
event.

Won't this leave the fair server incorrectly armed or running, potentially
causing false positive timer failures?

[ ... ]
> +static void handle_sys_enter(void *data, struct pt_regs *regs, long id)
> +{
> +	struct task_struct *p;
> +	int new_policy = -1;
> +	pid_t pid = 0;
> +
> +	new_policy = extract_params(regs, id, &pid);
> +	if (new_policy < 0)
> +		return;
> +	guard(rcu)();
> +	p = pid ? find_task_by_vpid(pid) : current;
> +	if (unlikely(!p) || new_policy == p->policy)
> +		return;
> +
> +	if (p->policy == SCHED_DEADLINE)
> +		da_reset(EXPAND_ID_TASK(p));

[Severity: Medium]
Can a user evade the monitor by spamming invalid syscalls?

Calling da_reset() permanently cancels the enforcement timer via
ha_cancel_timer() before the syscall is validated. If the syscall fails
and returns an error code, the task remains in SCHED_DEADLINE but the
monitor's timer stays disabled for the remainder of the execution slice.

> +	else if (new_policy == SCHED_DEADLINE)
> +		da_create_or_get(EXPAND_ID_TASK(p));
> +}

[Severity: High]
Does this speculative allocation create a memory leak and use-after-free?

da_create_or_get() is called here before the sched_setscheduler syscall
completes or validates permissions. If the syscall fails, the task's
policy remains unchanged.

When the task eventually exits, handle_exit() only destroys storage if
the task's current policy is SCHED_DEADLINE, leaving the speculatively
allocated monitor storage permanently leaked.

Furthermore, if the PID is later reused and the new task enters
SCHED_DEADLINE, da_create_or_get() will find the leaked storage without
updating the target pointer, potentially causing a use-after-free when
the monitor accesses target->runtime.

[Severity: High]
Is it safe to concurrently modify the RCU hash table here?

da_create_or_get() adds to the hash table via hash_add_rcu(), but it is
called directly from a tracepoint protected only by a read-side lock
(guard(rcu)()). 

Since tracepoints can trigger concurrently on different CPUs, won't this
race on the hlist pointers and corrupt the monitor lists? The same concern
applies to the hash_del_rcu() call in handle_exit() registered to the
sched_process_exit tracepoint below.

[ ... ]
> +static int enable_throttle(void)
> +{
[ ... ]
> +	rv_attach_trace_probe("throttle", sched_switch, handle_sched_switch);
> +	if (!should_skip_syscall_handle())
> +		rv_attach_trace_probe("throttle", sys_enter, handle_sys_enter);
> +	rv_attach_trace_probe("throttle", task_newtask, handle_newtask);
> +	rv_attach_trace_probe("throttle", sched_dl_server_stop_tp, handle_dl_server_stop);
> +	rv_attach_trace_probe("throttle", sched_process_exit, handle_exit);
> +
> +	return 0;
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929124908.177676-1-gmonaco@redhat.com?part=7

  reply	other threads:[~2026-09-29 13:18 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-29 12:48 [PATCH 00/10] rv: Add remaining deadline monitors Gabriele Monaco
2026-09-29 12:48 ` [PATCH 01/10] rv: Force environment reset action on HA monitor start Gabriele Monaco
2026-09-29 12:49 ` [PATCH 02/10] rv: Remove unused ha_monitor_env_invalid() Gabriele Monaco
2026-09-29 12:49 ` [PATCH 03/10] rv: Cache timer budget when starting HA timers Gabriele Monaco
2026-09-29 13:06   ` sashiko-bot
2026-09-29 12:49 ` [PATCH 04/10] tools/rvgen: Default to HA_TIMER_WHEEL for jiffy clocks Gabriele Monaco
2026-09-29 12:49 ` [PATCH 05/10] sched: Add task enqueue/dequeue trace points Gabriele Monaco
2026-09-29 12:49 ` [PATCH 06/10] rv: Add enqueue/dequeue to snroc monitor Gabriele Monaco
2026-09-29 12:49 ` [PATCH 07/10] rv: Add throttle deadline monitor Gabriele Monaco
2026-09-29 13:18   ` sashiko-bot [this message]
2026-09-29 12:49 ` [PATCH 08/10] rv: Add dl_server specific monitors Gabriele Monaco
2026-09-29 13:24   ` sashiko-bot
2026-09-29 12:49 ` [PATCH 09/10] rv: Add KUnit test for throttle monitor Gabriele Monaco
2026-09-29 13:18   ` sashiko-bot
2026-09-29 12:49 ` [PATCH 10/10] selftests/verification: Lower stressor priority in rv_deadline Gabriele Monaco

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=20260929131847.32B1D1F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=gmonaco@redhat.com \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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;
as well as URLs for NNTP newsgroup(s).