All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Tejun Heo" <tj@kernel.org>
Cc: sched-ext@lists.linux.dev
Subject: Re: [PATCH 2/3] sched_ext: Add scx_cmask_test() and scx_cmask_for_each_cid()
Date: Wed, 03 Jun 2026 17:41:26 +0000	[thread overview]
Message-ID: <20260603174127.0679E1F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260603172153.3081861-3-tj@kernel.org>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] scx_cmask_for_each_cid yields out-of-bounds phantom CIDs due to an overestimated loop bound and stale padding words.
--

commit edd3ffa1eb6aa37c70fee16c5770f542f1484a83
Author: Tejun Heo <tj@kernel.org>
Subject: sched_ext: Add scx_cmask_test() and scx_cmask_for_each_cid()

Add single-bit test and iterator over set cids in an scx_cmask.

> diff --git a/kernel/sched/ext_cid.h b/kernel/sched/ext_cid.h
> index abea22ba2cc25..d4c3ebba74162 100644
> --- a/kernel/sched/ext_cid.h
> +++ b/kernel/sched/ext_cid.h

[ ... ]

> @@ -218,11 +218,42 @@ static inline void scx_cmask_reframe(struct scx_cmask *m, u32 base, u32 nr_cids)
>  	m->nr_cids = nr_cids;
>  }
>  
> -static inline void __scx_cmask_set(struct scx_cmask *m, u32 cid)
> +static inline void __scx_cmask_set(u32 cid, struct scx_cmask *m)
>  {
> -	if (!__scx_cmask_contains(m, cid))
> +	if (!__scx_cmask_contains(cid, m))
>  		return;
> -	*__scx_cmask_word(m, cid) |= BIT_U64(cid & 63);
> +	*__scx_cmask_word(cid, m) |= BIT_U64(cid & 63);
>  }
>  
> +/**
> + * scx_cmask_test - test whether @cid is set in @m
> + * @cid: cid to test
> + * @m: cmask to test
> + *
> + * Return %false if @cid is outside @m's active range. Otherwise return the
> + * bit's value. Read via READ_ONCE so callers can race set/clear writers.
> + */
> +static inline bool scx_cmask_test(u32 cid, const struct scx_cmask *m)
> +{
> +	if (!__scx_cmask_contains(cid, m))
> +		return false;
> +	return READ_ONCE(*__scx_cmask_word(cid, m)) & BIT_U64(cid & 63);
> +}
> +
> +/**
> + * scx_cmask_for_each_cid - iterate set cids in @m
> + * @cid: s32 loop var that receives each set cid in turn
> + * @m: cmask to iterate
> + *
> + * Visits set bits within @m's active range in ascending order. Relies on the
> + * head/tail-zero invariant of bits[], so no per-cid range check is needed.
> + */
> +#define scx_cmask_for_each_cid(cid, m)						\
> +	for (u64 __bs = (m)->base & ~63u, __wi = 0,				\
> +		     __nw = SCX_CMASK_NR_WORDS((m)->nr_cids);			\
> +	     __wi < __nw; __wi++)						\
> +		for (u64 __w = READ_ONCE((m)->bits[__wi]);			\
> +		     __w && ((cid) = __bs + __wi * 64 + __ffs64(__w), true);	\
> +		     __w &= __w - 1)
> +
>  #endif /* _KERNEL_SCHED_EXT_CID_H */

[Severity: High]
Does this iterator yield phantom CIDs outside of the mask's active range?

Since SCX_CMASK_NR_WORDS() overestimates worst-case capacity (e.g. for
nr_cids=1, it evaluates to 2), __nw will be larger than necessary. The
iterator lacks a strict cid < base + nr_cids bound check to compensate.

When scx_cmask_reframe() shrinks a mask, it clears only m->bits[0] and
m->bits[last_word]:

kernel/sched/ext_cid.h:scx_cmask_reframe() {
        if (nr_cids) {
                u32 last_word = ((base & 63) + nr_cids - 1) / 64;

                m->bits[0] = 0;
                m->bits[last_word] = 0;
        }
        ...
}

Any words beyond last_word remain uncleared. If a mask is reframed to a
smaller size (like nr_cids=1), SCX_CMASK_NR_WORDS(1) is 2, so the loop bound
__nw is 2. The iterator will process the stale, uncleared bits in m->bits[1],
yielding CIDs outside the active range.

Similarly, if nr_cids is 0, scx_cmask_reframe() skips clearing entirely, but
SCX_CMASK_NR_WORDS(0) is 1. The iterator will traverse m->bits[0] and yield
CIDs for an empty mask.

Is a strict boundary check inside the loop needed?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260603172153.3081861-1-tj@kernel.org?part=2

  reply	other threads:[~2026-06-03 17:41 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-03 17:21 [PATCHSET sched_ext/for-7.2] sched_ext: cid/cmask interface prep Tejun Heo
2026-06-03 17:21 ` [PATCH 1/3] sched_ext: Order single-cid cmask helpers as (cid, mask) Tejun Heo
2026-06-03 17:31   ` sashiko-bot
2026-06-03 17:21 ` [PATCH 2/3] sched_ext: Add scx_cmask_test() and scx_cmask_for_each_cid() Tejun Heo
2026-06-03 17:41   ` sashiko-bot [this message]
2026-06-03 17:21 ` [PATCH 3/3] sched_ext: Make scx_bpf_kick_cid() return s32 Tejun Heo
2026-06-03 18:38   ` Andrea Righi
2026-06-03 18:41 ` [PATCHSET sched_ext/for-7.2] sched_ext: cid/cmask interface prep Andrea Righi

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=20260603174127.0679E1F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=sched-ext@lists.linux.dev \
    --cc=tj@kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.