* Re: [PATCH] watchdog: ixp4xx: fix reference leak on platform_device_register() failure
From: Guenter Roeck @ 2026-04-19 21:07 UTC (permalink / raw)
To: Linus Walleij, Guangshuo Li
Cc: Imre Kaloz, Daniel Lezcano, Thomas Gleixner, linux-arm-kernel,
linux-kernel, stable
In-Reply-To: <CAD++jLnC5MGg1e_Suv6BD_=XKbsn1aLxHxRfCdD3Nos+2XRzfw@mail.gmail.com>
On 4/19/26 13:22, Linus Walleij wrote:
> Hi Guangshuo,
>
> thanks for your patch!
>
> On Mon, Apr 13, 2026 at 5:47 PM Guangshuo Li <lgs201920130244@gmail.com> wrote:
>
>> ixp4xx_timer_probe() directly returns the result of
>> platform_device_register(&ixp4xx_watchdog_device). When registration
>> fails, the embedded struct device in ixp4xx_watchdog_device has already
>> been initialized by device_initialize(), but the failure path does not
>> drop the device reference, leading to a reference leak.
> (...)
>
>> - return platform_device_register(&ixp4xx_watchdog_device);
>> + ret = platform_device_register(&ixp4xx_watchdog_device);
>> + if (ret)
>> + platform_device_put(&ixp4xx_watchdog_device);
>
> If the problem in the description is indeed there, it seems the bug
> is inside platform_device_register(), surely a function returning an
> error code is supposed to clean up any resources it takes before
> returning an error. It seems wrong to try to fix this in all the
> consumers.
>
From platform_device_register():
/**
* platform_device_register - add a platform-level device
* @pdev: platform device we're adding
*
* NOTE: _Never_ directly free @pdev after calling this function, even if it
* returned an error! Always use platform_device_put() to give up the
* reference initialised in this function instead.
*/
Not that any code actually does that as far as I can see, but isn't
the above doing exactly what the comment suggests ?
Thanks,
Guenter
^ permalink raw reply
* [PATCH] scsi: isci: fix use-after-free in device removal path
From: Michael Bommarito @ 2026-04-19 21:04 UTC (permalink / raw)
To: James E . J . Bottomley, Martin K . Petersen, linux-scsi
Cc: linux-kernel, stable
The ISCI completion tasklet is initialized in isci_host_alloc()
(drivers/scsi/isci/init.c:496) and scheduled from both MSI-X and
legacy interrupt handlers (drivers/scsi/isci/host.c:223,613).
isci_host_deinit() stops the controller and waits for stop
completion, but it never kills completion_tasklet before teardown
continues. A top-of-function tasklet_kill() is not sufficient here:
interrupts are only disabled when isci_host_stop_complete() runs, so
until wait_for_stop() returns the IRQ handlers can still requeue the
tasklet. The tasklet callback also re-enables interrupts after
draining completions, so killing the tasklet before the source is
quiesced leaves the same race open.
Once wait_for_stop() returns, no further IRQ-driven scheduling can
occur. Kill completion_tasklet there so teardown cannot race a queued
tasklet running on a dead ihost. On remove or unload, the stale
callback can otherwise dereference ihost and touch ihost->smu_registers
after the host lifetime ends.
A UML + KASAN analogue reproduced the failure class both with no
tasklet_kill() and with tasklet_kill() placed before source quiesce,
and stayed clean once the kill happened after quiescing the scheduling
source.
This mirrors commit f6ab594672d4 ("scsi: aic94xx: fix use-after-free
in device removal path"), but ISCI needs the kill after
wait_for_stop().
Fixes: 6f231dda6808 ("isci: Intel(R) C600 Series Chipset Storage Control Unit Driver")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Assisted-by: Codex:gpt-5-4
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
---
drivers/scsi/isci/host.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 6d2f4c831df7..ff199bab5d1a 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1252,6 +1252,9 @@ void isci_host_deinit(struct isci_host *ihost)
wait_for_stop(ihost);
+ /* No further IRQ-driven scheduling can happen past wait_for_stop(). */
+ tasklet_kill(&ihost->completion_tasklet);
+
/* phy stop is after controller stop to allow port and device to
* go idle before shutting down the phys, but the expectation is
* that i/o has been shut off well before we reach this
--
2.53.0
^ permalink raw reply related
* [PATCH 4/4] ALSA: usb-audio: Update US-16x08 EQ/comp shadow state after successful writes
From: Cássio Gabriel @ 2026-04-19 20:30 UTC (permalink / raw)
To: Takashi Iwai, Chris J Arges, Detlef Urban, Jaroslav Kysela
Cc: linux-sound, linux-kernel, Cássio Gabriel, stable
In-Reply-To: <20260419-usb-write-error-propagation-v1-0-5a3bd4a673ae@gmail.com>
snd_us16x08_comp_put() and snd_us16x08_eq_put() update their
software stores before sending the USB write. If the transfer
fails, later get callbacks report a value the hardware never
accepted.
Build the outgoing message from the current store plus the
pending value, then commit the store only after a successful
write.
Fixes: d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk")
Cc: stable@vger.kernel.org
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
sound/usb/mixer_us16x08.c | 78 +++++++++++++++++++++++++++++++----------------
1 file changed, 52 insertions(+), 26 deletions(-)
diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c
index fcf7dfa4aa84..ebff185cbd2c 100644
--- a/sound/usb/mixer_us16x08.c
+++ b/sound/usb/mixer_us16x08.c
@@ -435,6 +435,7 @@ static int snd_us16x08_comp_put(struct snd_kcontrol *kcontrol,
int index = ucontrol->id.index;
char buf[sizeof(comp_msg)];
int val_idx, val;
+ int threshold, ratio, attack, release, gain, switch_on;
int err;
val = ucontrol->value.integer.value[0];
@@ -447,36 +448,61 @@ static int snd_us16x08_comp_put(struct snd_kcontrol *kcontrol,
/* new control value incl. bias*/
val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE;
- store->val[val_idx][index] = ucontrol->value.integer.value[0];
+ threshold = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)]
+ [index];
+ ratio = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index];
+ attack = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index];
+ release = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)]
+ [index];
+ gain = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
+ switch_on = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)]
+ [index];
+
+ switch (val_idx) {
+ case COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD):
+ threshold = val;
+ break;
+ case COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO):
+ ratio = val;
+ break;
+ case COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK):
+ attack = val;
+ break;
+ case COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE):
+ release = val;
+ break;
+ case COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN):
+ gain = val;
+ break;
+ case COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH):
+ switch_on = val;
+ break;
+ }
/* prepare compressor URB message from template */
memcpy(buf, comp_msg, sizeof(comp_msg));
/* place comp values in message buffer watch bias! */
- buf[8] = store->val[
- COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][index]
- - SND_US16X08_COMP_THRESHOLD_BIAS;
- buf[11] = ratio_map[store->val[
- COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index]];
- buf[14] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index]
- + SND_US16X08_COMP_ATTACK_BIAS;
- buf[17] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][index]
- + SND_US16X08_COMP_RELEASE_BIAS;
- buf[20] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
- buf[26] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][index];
+ buf[8] = threshold - SND_US16X08_COMP_THRESHOLD_BIAS;
+ buf[11] = ratio_map[ratio];
+ buf[14] = attack + SND_US16X08_COMP_ATTACK_BIAS;
+ buf[17] = release + SND_US16X08_COMP_RELEASE_BIAS;
+ buf[20] = gain;
+ buf[26] = switch_on;
/* place channel selector in message buffer */
buf[5] = index + 1;
err = snd_us16x08_send_urb(chip, buf, sizeof(comp_msg));
- if (err > 0) {
- elem->cached |= 1 << index;
- elem->cache_val[index] = val;
- } else {
+ if (err < 0) {
usb_audio_dbg(chip, "Failed to set compressor, err:%d\n", err);
+ return err;
}
+ store->val[val_idx][index] = val;
+ elem->cached |= 1 << index;
+ elem->cache_val[index] = val;
return 1;
}
@@ -578,11 +604,10 @@ static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol,
/* copy URB buffer from EQ template */
memcpy(buf, eqs_msq, sizeof(eqs_msq));
- store->val[b_idx][p_idx][index] = val;
- buf[20] = store->val[b_idx][3][index];
- buf[17] = store->val[b_idx][2][index];
- buf[14] = store->val[b_idx][1][index];
- buf[11] = store->val[b_idx][0][index];
+ buf[20] = p_idx == 3 ? val : store->val[b_idx][3][index];
+ buf[17] = p_idx == 2 ? val : store->val[b_idx][2][index];
+ buf[14] = p_idx == 1 ? val : store->val[b_idx][1][index];
+ buf[11] = p_idx == 0 ? val : store->val[b_idx][0][index];
/* place channel index in URB buffer */
buf[5] = index + 1;
@@ -592,14 +617,15 @@ static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol,
err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
- if (err > 0) {
- /* store new value in EQ band cache */
- elem->cached |= 1 << index;
- elem->cache_val[index] = val;
- } else {
+ if (err < 0) {
usb_audio_dbg(chip, "Failed to set eq param, err:%d\n", err);
+ return err;
}
+ store->val[b_idx][p_idx][index] = val;
+ /* store new value in EQ band cache */
+ elem->cached |= 1 << index;
+ elem->cache_val[index] = val;
return 1;
}
--
2.53.0
^ permalink raw reply related
* [PATCH 3/4] ALSA: usb-audio: Propagate US-16x08 write errors in route/mix EQ-switch put callbacks
From: Cássio Gabriel @ 2026-04-19 20:30 UTC (permalink / raw)
To: Takashi Iwai, Chris J Arges, Detlef Urban, Jaroslav Kysela
Cc: linux-sound, linux-kernel, Cássio Gabriel, stable
In-Reply-To: <20260419-usb-write-error-propagation-v1-0-5a3bd4a673ae@gmail.com>
Several US-16x08 mixer put callbacks log failed control URBs but
still return success to userspace. That hides device write failures
even though the requested value was not applied.
Return the negative write error instead in the route, master, bus,
channel, and EQ switch put callbacks.
Fixes: d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk")
Cc: stable@vger.kernel.org
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
sound/usb/mixer_us16x08.c | 49 +++++++++++++++++++++++------------------------
1 file changed, 24 insertions(+), 25 deletions(-)
diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c
index 8a02964e5d7b..fcf7dfa4aa84 100644
--- a/sound/usb/mixer_us16x08.c
+++ b/sound/usb/mixer_us16x08.c
@@ -224,14 +224,14 @@ static int snd_us16x08_route_put(struct snd_kcontrol *kcontrol,
err = snd_us16x08_send_urb(chip, buf, sizeof(route_msg));
- if (err > 0) {
- elem->cached |= 1 << index;
- elem->cache_val[index] = val;
- } else {
+ if (err < 0) {
usb_audio_dbg(chip, "Failed to set routing, err:%d\n", err);
+ return err;
}
- return err > 0 ? 1 : 0;
+ elem->cached |= 1 << index;
+ elem->cache_val[index] = val;
+ return 1;
}
static int snd_us16x08_master_info(struct snd_kcontrol *kcontrol,
@@ -283,14 +283,14 @@ static int snd_us16x08_master_put(struct snd_kcontrol *kcontrol,
buf[5] = index + 1;
err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
- if (err > 0) {
- elem->cached |= 1 << index;
- elem->cache_val[index] = val;
- } else {
+ if (err < 0) {
usb_audio_dbg(chip, "Failed to set master, err:%d\n", err);
+ return err;
}
- return err > 0 ? 1 : 0;
+ elem->cached |= 1 << index;
+ elem->cache_val[index] = val;
+ return 1;
}
static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol,
@@ -324,14 +324,14 @@ static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol,
break;
}
- if (err > 0) {
- elem->cached |= 1;
- elem->cache_val[0] = val;
- } else {
+ if (err < 0) {
usb_audio_dbg(chip, "Failed to set bus parameter, err:%d\n", err);
+ return err;
}
- return err > 0 ? 1 : 0;
+ elem->cached |= 1;
+ elem->cache_val[0] = val;
+ return 1;
}
static int snd_us16x08_bus_get(struct snd_kcontrol *kcontrol,
@@ -392,14 +392,14 @@ static int snd_us16x08_channel_put(struct snd_kcontrol *kcontrol,
err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_in));
- if (err > 0) {
- elem->cached |= 1 << index;
- elem->cache_val[index] = val;
- } else {
+ if (err < 0) {
usb_audio_dbg(chip, "Failed to set channel, err:%d\n", err);
+ return err;
}
- return err > 0 ? 1 : 0;
+ elem->cached |= 1 << index;
+ elem->cache_val[index] = val;
+ return 1;
}
static int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol,
@@ -529,13 +529,13 @@ static int snd_us16x08_eqswitch_put(struct snd_kcontrol *kcontrol,
msleep(15);
}
- if (err > 0) {
- elem->cached |= 1 << index;
- elem->cache_val[index] = val;
- } else {
+ if (err < 0) {
usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err);
+ return err;
}
+ elem->cached |= 1 << index;
+ elem->cache_val[index] = val;
return 1;
}
@@ -1418,4 +1418,3 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
return 0;
}
-
--
2.53.0
^ permalink raw reply related
* [PATCH 2/4] ALSA: usb-audio: Propagate errors in scarlett_ctl_enum_put()
From: Cássio Gabriel @ 2026-04-19 20:30 UTC (permalink / raw)
To: Takashi Iwai, Chris J Arges, Detlef Urban, Jaroslav Kysela
Cc: linux-sound, linux-kernel, Cássio Gabriel, stable
In-Reply-To: <20260419-usb-write-error-propagation-v1-0-5a3bd4a673ae@gmail.com>
scarlett_ctl_enum_put() ignores the return value from
snd_usb_set_cur_mix_value() and reports success whenever the
requested enum value differs from the current one.
If the SET_CUR request fails, the callback still returns success even
though neither the hardware state nor the cached mixer value changed.
Fixes: 76b188c4b370 ("ALSA: usb-audio: Scarlett mixer interface for 6i6, 18i6, 18i8 and 18i20")
Cc: stable@vger.kernel.org
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
sound/usb/mixer_scarlett.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sound/usb/mixer_scarlett.c b/sound/usb/mixer_scarlett.c
index 1bb01e827654..673eb8d8724d 100644
--- a/sound/usb/mixer_scarlett.c
+++ b/sound/usb/mixer_scarlett.c
@@ -680,7 +680,9 @@ static int scarlett_ctl_enum_put(struct snd_kcontrol *kctl,
val = ucontrol->value.integer.value[0];
val = val + opt->start;
if (val != oval) {
- snd_usb_set_cur_mix_value(elem, 0, 0, val);
+ err = snd_usb_set_cur_mix_value(elem, 0, 0, val);
+ if (err < 0)
+ return err;
return 1;
}
return 0;
--
2.53.0
^ permalink raw reply related
* [PATCH 0/4] usb-audio: fix mixer write failure handling
From: Cássio Gabriel @ 2026-04-19 20:30 UTC (permalink / raw)
To: Takashi Iwai, Chris J Arges, Detlef Urban, Jaroslav Kysela
Cc: linux-sound, linux-kernel, Cássio Gabriel, stable
This series fixes usb-audio mixer put() paths that currently report
success even when the underlying device write fails.
The issue exists in the generic mixer core callbacks, the Scarlett
Gen1 enum path, and several Tascam US-16x08 put() callbacks.
The US-16x08 EQ and compressor callbacks have an additional bug: they
update their software shadow state before sending the USB write, so a
failed transfer can leave later get() results out of sync with the
hardware state.
The series is split into four patches:
- propagate write failures in the generic mixer core callbacks
- fix the Scarlett Gen1 enum callback
- propagate write failures in the simple US-16x08 put() callbacks
- commit the US-16x08 EQ and compressor shadow state only after a
successful write
Successful writes are unchanged. Failed writes are now reported
correctly, and the US-16x08 shadow state remains coherent with the
hardware after write errors.
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
Cássio Gabriel (4):
ALSA: usb-audio: Propagate write errors in generic mixer put callbacks
ALSA: usb-audio: Propagate errors in scarlett_ctl_enum_put()
ALSA: usb-audio: Propagate US-16x08 write errors in route/mix EQ-switch put callbacks
ALSA: usb-audio: Update US-16x08 EQ/comp shadow state after successful writes
sound/usb/mixer.c | 17 ++++--
sound/usb/mixer_scarlett.c | 4 +-
sound/usb/mixer_us16x08.c | 127 +++++++++++++++++++++++++++------------------
3 files changed, 92 insertions(+), 56 deletions(-)
---
base-commit: 99c71f13f9841f8c67fa7595bf0834d3045f5d24
change-id: 20260416-usb-write-error-propagation-20c69e2c5cab
Best regards,
--
Cássio Gabriel <cassiogabrielcontato@gmail.com>
^ permalink raw reply
* Re: [PATCH] watchdog: ixp4xx: fix reference leak on platform_device_register() failure
From: Linus Walleij @ 2026-04-19 20:22 UTC (permalink / raw)
To: Guangshuo Li
Cc: Imre Kaloz, Daniel Lezcano, Thomas Gleixner, Guenter Roeck,
linux-arm-kernel, linux-kernel, stable
In-Reply-To: <20260413154727.3051321-1-lgs201920130244@gmail.com>
Hi Guangshuo,
thanks for your patch!
On Mon, Apr 13, 2026 at 5:47 PM Guangshuo Li <lgs201920130244@gmail.com> wrote:
> ixp4xx_timer_probe() directly returns the result of
> platform_device_register(&ixp4xx_watchdog_device). When registration
> fails, the embedded struct device in ixp4xx_watchdog_device has already
> been initialized by device_initialize(), but the failure path does not
> drop the device reference, leading to a reference leak.
(...)
> - return platform_device_register(&ixp4xx_watchdog_device);
> + ret = platform_device_register(&ixp4xx_watchdog_device);
> + if (ret)
> + platform_device_put(&ixp4xx_watchdog_device);
If the problem in the description is indeed there, it seems the bug
is inside platform_device_register(), surely a function returning an
error code is supposed to clean up any resources it takes before
returning an error. It seems wrong to try to fix this in all the
consumers.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH 6.1 00/55] 6.1.169-rc1 review
From: Linus Walleij @ 2026-04-19 20:04 UTC (permalink / raw)
To: Guenter Roeck
Cc: Greg Kroah-Hartman, stable, patches, linux-kernel, torvalds, akpm,
shuah, patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr,
Vladimir Oltean
In-Reply-To: <8bb67921-d8e7-4535-bbec-249e9702ce62@roeck-us.net>
On Sun, Apr 19, 2026 at 4:31 PM Guenter Roeck <linux@roeck-us.net> wrote:
> Looking through my test logs, I find that the following build error has been
> reported since v6.1.166.
Ugh not good, but no disaster, OpenWrt is the only downstream using stable
and it only used v6.12 and v6.18.
> I have copied the patch authors for advice.
I'd just pull them both out again. It's fixing a runtime crash that appear
only when you use ethtool. Annoying, but fringe system and not appearing
in normal use.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v2 1/4] HID: pass the buffer size to hid_report_raw_event
From: Icenowy Zheng @ 2026-04-19 16:26 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, Filipe Laíns,
Bastien Nocera, Ping Cheng, Jason Gerecke, Viresh Kumar,
Johan Hovold, Alex Elder, Greg Kroah-Hartman, Lee Jones
Cc: linux-input, linux-kernel, greybus-dev, linux-staging, linux-usb,
stable
In-Reply-To: <20260416-wip-fix-core-v2-1-be92570e5627@kernel.org>
在 2026-04-16四的 16:48 +0200,Benjamin Tissoires写道:
> commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing
> bogus memset()") enforced the provided data to be at least the size
> of
> the declared buffer in the report descriptor to prevent a buffer
> overflow. However, we can try to be smarter by providing both the
> buffer
> size and the data size, meaning that hid_report_raw_event() can make
> better decision whether we should plaining reject the buffer (buffer
> overflow attempt) or if we can safely memset it to 0 and pass it to
> the
> rest of the stack.
>
> Fixes: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing
> bogus memset()")
> Cc: stable@vger.kernel.org
> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
> ---
> drivers/hid/bpf/hid_bpf_dispatch.c | 6 ++++--
> drivers/hid/hid-core.c | 42 +++++++++++++++++++++++++---
> ----------
> drivers/hid/hid-gfrm.c | 4 ++--
> drivers/hid/hid-logitech-hidpp.c | 2 +-
> drivers/hid/hid-multitouch.c | 2 +-
> drivers/hid/hid-primax.c | 2 +-
> drivers/hid/hid-vivaldi-common.c | 2 +-
> drivers/hid/wacom_sys.c | 6 +++---
> drivers/staging/greybus/hid.c | 2 +-
> include/linux/hid.h | 4 ++--
> include/linux/hid_bpf.h | 14 ++++++++-----
> 11 files changed, 53 insertions(+), 33 deletions(-)
============ 8< ===================
> diff --git a/drivers/staging/greybus/hid.c
> b/drivers/staging/greybus/hid.c
> index 1f58c907c036..37e8605c6767 100644
> --- a/drivers/staging/greybus/hid.c
> +++ b/drivers/staging/greybus/hid.c
> @@ -201,7 +201,7 @@ static void gb_hid_init_report(struct gb_hid
> *ghid, struct hid_report *report)
> * we just need to setup the input fields, so using
> * hid_report_raw_event is safe.
> */
> - hid_report_raw_event(ghid->hid, report->type, ghid->inbuf,
> size, 1);
> + hid_report_raw_event(ghid->hid, report->type, ghid->inbuf,
> ghib->bufsize, size, 1);
Oops, "ghid" is misspelled here...
Found this when building some gaint kernel with this patchset.
Thanks,
Icenowy
> }
>
> static void gb_hid_init_reports(struct gb_hid *ghid)
^ permalink raw reply
* [PATCH v3 3/3] mm/damon/stat: detect and use fresh enabled value
From: SeongJae Park @ 2026-04-19 16:10 UTC (permalink / raw)
To: Andrew Morton; +Cc: SeongJae Park, # 6 . 17 . x, damon, linux-kernel, linux-mm
In-Reply-To: <20260419161003.79176-1-sj@kernel.org>
DAMON_STAT updates 'enabled' parameter value, which represents the
running status of its kdamond, when the user explicitly requests
start/stop of the kdamond. The kdamond can, however, be stopped even if
the user explicitly requested the stop, if ctx->regions_score_histogram
allocation failure at beginning of the execution of the kdamond. Hence,
if the kdamond is stopped by the allocation failure, the value of the
parameter can be stale.
Users could show the stale value and be confused. The problem will only
rarely happen in real and common setups because the allocation is
arguably too small to fail. Also, unlike the similar bugs that are now
fixed in DAMON_RECLAIM and DAMON_LRU_SORT, kdamond can be restarted in
this case, because DAMON_STAT force-updates the enabled parameter value
for user inputs. The bug is a bug, though.
The issue stems from the fact that there are multiple events that can
change the status, and following all the events is challenging.
Dynamically detect and use the fresh status for the parameters when
those are requested.
The issue was dicovered [1] by Sashiko.
[1] https://lore.kernel.org/20260416040602.88665-1-sj@kernel.org
Fixes: 369c415e6073 ("mm/damon: introduce DAMON_STAT module")
Cc: <stable@vger.kernel.org> # 6.17.x
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/stat.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/mm/damon/stat.c b/mm/damon/stat.c
index 99ba346f9e325..3951b762cbddf 100644
--- a/mm/damon/stat.c
+++ b/mm/damon/stat.c
@@ -19,14 +19,17 @@
static int damon_stat_enabled_store(
const char *val, const struct kernel_param *kp);
+static int damon_stat_enabled_load(char *buffer,
+ const struct kernel_param *kp);
+
static const struct kernel_param_ops enabled_param_ops = {
.set = damon_stat_enabled_store,
- .get = param_get_bool,
+ .get = damon_stat_enabled_load,
};
static bool enabled __read_mostly = IS_ENABLED(
CONFIG_DAMON_STAT_ENABLED_DEFAULT);
-module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
+module_param_cb(enabled, &enabled_param_ops, NULL, 0600);
MODULE_PARM_DESC(enabled, "Enable of disable DAMON_STAT");
static unsigned long estimated_memory_bandwidth __read_mostly;
@@ -273,17 +276,23 @@ static void damon_stat_stop(void)
damon_stat_context = NULL;
}
+static bool damon_stat_enabled(void)
+{
+ if (!damon_stat_context)
+ return false;
+ return damon_is_running(damon_stat_context);
+}
+
static int damon_stat_enabled_store(
const char *val, const struct kernel_param *kp)
{
- bool is_enabled = enabled;
int err;
err = kstrtobool(val, &enabled);
if (err)
return err;
- if (is_enabled == enabled)
+ if (damon_stat_enabled() == enabled)
return 0;
if (!damon_initialized())
@@ -293,16 +302,17 @@ static int damon_stat_enabled_store(
*/
return 0;
- if (enabled) {
- err = damon_stat_start();
- if (err)
- enabled = false;
- return err;
- }
+ if (enabled)
+ return damon_stat_start();
damon_stat_stop();
return 0;
}
+static int damon_stat_enabled_load(char *buffer, const struct kernel_param *kp)
+{
+ return sprintf(buffer, "%c\n", damon_stat_enabled() ? 'Y' : 'N');
+}
+
static int __init damon_stat_init(void)
{
int err = 0;
--
2.47.3
^ permalink raw reply related
* [PATCH v3 2/3] mm/damon/lru_sort: detect and use fresh enabled and kdamond_pid values
From: SeongJae Park @ 2026-04-19 16:10 UTC (permalink / raw)
To: Andrew Morton
Cc: SeongJae Park, # 6 . 0 . x, damon, linux-kernel, linux-mm,
Liew Rui Yan
In-Reply-To: <20260419161003.79176-1-sj@kernel.org>
DAMON_LRU_SORT updates 'enabled' and 'kdamond_pid' parameter values,
which represents the running status of its kdamond, when the user
explicitly requests start/stop of the kdamond. The kdamond can,
however, be stopped in events other than the explicit user request in
the following three events.
1. ctx->regions_score_histogram allocation failure at beginning of the
execution,
2. damon_commit_ctx() failure due to invalid user input, and
3. damon_commit_ctx() failure due to its internal allocation failures.
Hence, if the kdamond is stopped by the above three events, the values
of the status parameters can be stale. Users could show the stale
values and be confused. This is already bad, but the real consequence
is worse. DAMON_LRU_SORT avoids unnecessary damon_start() and
damon_stop() calls based on the 'enabled' parameter value. And the
update of 'enabled' parameter value depends on the damon_start() and
damon_stop() call results. Hence, once the kdamond has stopped by the
unintentional events, the user cannot restart the kdamond before the
system reboot. For example, the issue can be reproduced via below
steps.
# cd /sys/module/damon_lru_sort/parameters
#
# # start DAMON_LRU_SORT
# echo Y > enabled
# ps -ef | grep kdamond
root 806 2 0 17:53 ? 00:00:00 [kdamond.0]
root 808 803 0 17:53 pts/4 00:00:00 grep kdamond
#
# # commit wrong input to stop kdamond withou explicit stop request
# echo 3 > addr_unit
# echo Y > commit_inputs
bash: echo: write error: Invalid argument
#
# # confirm kdamond is stopped
# ps -ef | grep kdamond
root 811 803 0 17:53 pts/4 00:00:00 grep kdamond
#
# # users casn now show stable status
# cat enabled
Y
# cat kdamond_pid
806
#
# # even after fixing the wrong parameter,
# # kdamond cannot be restarted.
# echo 1 > addr_unit
# echo Y > enabled
# ps -ef | grep kdamond
root 815 803 0 17:54 pts/4 00:00:00 grep kdamond
The problem will only rarely happen in real and common setups for the
following reasons. The allocation failures are unlikely in such setups
since those allocations are arguably too small to fail. Also sane users
on real production environments may not commit wrong input parameters.
But once it happens, the consequence is quite bad. And the bug is a
bug.
The issue stems from the fact that there are multiple events that can
change the status, and following all the events is challenging.
Dynamically detect and use the fresh status for the parameters when
those are requested.
Fixes: 40e983cca927 ("mm/damon: introduce DAMON-based LRU-lists Sorting")
Cc: <stable@vger.kernel.org> # 6.0.x
Co-developed-by: Liew Rui Yan <aethernet65535@gmail.com>
Signed-off-by: Liew Rui Yan <aethernet65535@gmail.com>
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/lru_sort.c | 85 +++++++++++++++++++++++++++++----------------
1 file changed, 55 insertions(+), 30 deletions(-)
diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
index 554559d729760..8494040b1ee48 100644
--- a/mm/damon/lru_sort.c
+++ b/mm/damon/lru_sort.c
@@ -161,15 +161,6 @@ module_param(monitor_region_end, ulong, 0600);
*/
static unsigned long addr_unit __read_mostly = 1;
-/*
- * PID of the DAMON thread
- *
- * If DAMON_LRU_SORT is enabled, this becomes the PID of the worker thread.
- * Else, -1.
- */
-static int kdamond_pid __read_mostly = -1;
-module_param(kdamond_pid, int, 0400);
-
static struct damos_stat damon_lru_sort_hot_stat;
DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(damon_lru_sort_hot_stat,
lru_sort_tried_hot_regions, lru_sorted_hot_regions,
@@ -386,12 +377,8 @@ static int damon_lru_sort_turn(bool on)
{
int err;
- if (!on) {
- err = damon_stop(&ctx, 1);
- if (!err)
- kdamond_pid = -1;
- return err;
- }
+ if (!on)
+ return damon_stop(&ctx, 1);
err = damon_lru_sort_apply_parameters();
if (err)
@@ -400,9 +387,6 @@ static int damon_lru_sort_turn(bool on)
err = damon_start(&ctx, 1, true);
if (err)
return err;
- kdamond_pid = damon_kdamond_pid(ctx);
- if (kdamond_pid < 0)
- return kdamond_pid;
return damon_call(ctx, &call_control);
}
@@ -430,42 +414,83 @@ module_param_cb(addr_unit, &addr_unit_param_ops, &addr_unit, 0600);
MODULE_PARM_DESC(addr_unit,
"Scale factor for DAMON_LRU_SORT to ops address conversion (default: 1)");
+static bool damon_lru_sort_enabled(void)
+{
+ if (!ctx)
+ return false;
+ return damon_is_running(ctx);
+}
+
static int damon_lru_sort_enabled_store(const char *val,
const struct kernel_param *kp)
{
- bool is_enabled = enabled;
- bool enable;
int err;
- err = kstrtobool(val, &enable);
+ err = kstrtobool(val, &enabled);
if (err)
return err;
- if (is_enabled == enable)
+ if (damon_lru_sort_enabled() == enabled)
return 0;
/* Called before init function. The function will handle this. */
if (!damon_initialized())
- goto set_param_out;
+ return 0;
- err = damon_lru_sort_turn(enable);
- if (err)
- return err;
+ return damon_lru_sort_turn(enabled);
+}
-set_param_out:
- enabled = enable;
- return err;
+static int damon_lru_sort_enabled_load(char *buffer,
+ const struct kernel_param *kp)
+{
+ return sprintf(buffer, "%c\n", damon_lru_sort_enabled() ? 'Y' : 'N');
}
static const struct kernel_param_ops enabled_param_ops = {
.set = damon_lru_sort_enabled_store,
- .get = param_get_bool,
+ .get = damon_lru_sort_enabled_load,
};
module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
MODULE_PARM_DESC(enabled,
"Enable or disable DAMON_LRU_SORT (default: disabled)");
+static int damon_lru_sort_kdamond_pid_store(const char *val,
+ const struct kernel_param *kp)
+{
+ /*
+ * kdamond_pid is read-only, but kernel command line could write it.
+ * Do nothing here.
+ */
+ return 0;
+}
+
+static int damon_lru_sort_kdamond_pid_load(char *buffer,
+ const struct kernel_param *kp)
+{
+ int kdamond_pid = -1;
+
+ if (ctx) {
+ kdamond_pid = damon_kdamond_pid(ctx);
+ if (kdamond_pid < 0)
+ kdamond_pid = -1;
+ }
+ return sprintf(buffer, "%d\n", kdamond_pid);
+}
+
+static const struct kernel_param_ops kdamond_pid_param_ops = {
+ .set = damon_lru_sort_kdamond_pid_store,
+ .get = damon_lru_sort_kdamond_pid_load,
+};
+
+/*
+ * PID of the DAMON thread
+ *
+ * If DAMON_LRU_SORT is enabled, this becomes the PID of the worker thread.
+ * Else, -1.
+ */
+module_param_cb(kdamond_pid, &kdamond_pid_param_ops, NULL, 0400);
+
static int __init damon_lru_sort_init(void)
{
int err;
--
2.47.3
^ permalink raw reply related
* [PATCH v3 1/3] mm/damon/reclaim: detect and use fresh enabled and kdamond_pid values
From: SeongJae Park @ 2026-04-19 16:10 UTC (permalink / raw)
To: Andrew Morton
Cc: SeongJae Park, # 5 . 19 . x, damon, linux-kernel, linux-mm,
Liew Rui Yan
In-Reply-To: <20260419161003.79176-1-sj@kernel.org>
DAMON_RECLAIM updates 'enabled' and 'kdamond_pid' parameter values,
which represents the running status of its kdamond, when the user
explicitly requests start/stop of the kdamond. The kdamond can,
however, be stopped in events other than the explicit user request in
the following three events.
1. ctx->regions_score_histogram allocation failure at beginning of the
execution,
2. damon_commit_ctx() failure due to invalid user input, and
3. damon_commit_ctx() failure due to its internal allocation failures.
Hence, if the kdamond is stopped by the above three events, the values
of the status parameters can be stale. Users could show the stale
values and be confused. This is already bad, but the real consequence
is worse. DAMON_RECLAIM avoids unnecessary damon_start() and
damon_stop() calls based on the 'enabled' parameter value. And the
update of 'enabled' parameter value depends on the damon_start() and
damon_stop() call results. Hence, once the kdamond has stopped by the
unintentional events, the user cannot restart the kdamond before the
system reboot. For example, the issue can be reproduced via below
steps.
# cd /sys/module/damon_reclaim/parameters
#
# # start DAMON_RECLAIM
# echo Y > enabled
# ps -ef | grep kdamond
root 806 2 0 17:53 ? 00:00:00 [kdamond.0]
root 808 803 0 17:53 pts/4 00:00:00 grep kdamond
#
# # commit wrong input to stop kdamond withou explicit stop request
# echo 3 > addr_unit
# echo Y > commit_inputs
bash: echo: write error: Invalid argument
#
# # confirm kdamond is stopped
# ps -ef | grep kdamond
root 811 803 0 17:53 pts/4 00:00:00 grep kdamond
#
# # users casn now show stable status
# cat enabled
Y
# cat kdamond_pid
806
#
# # even after fixing the wrong parameter,
# # kdamond cannot be restarted.
# echo 1 > addr_unit
# echo Y > enabled
# ps -ef | grep kdamond
root 815 803 0 17:54 pts/4 00:00:00 grep kdamond
The problem will only rarely happen in real and common setups for the
following reasons. The allocation failures are unlikely in such setups
since those allocations are arguably too small to fail. Also sane users
on real production environments may not commit wrong input parameters.
But once it happens, the consequence is quite bad. And the bug is a
bug.
The issue stems from the fact that there are multiple events that can
change the status, and following all the events is challenging.
Dynamically detect and use the fresh status for the parameters when
those are requested.
Fixes: e035c280f6df ("mm/damon/reclaim: support online inputs update")
Cc: <stable@vger.kernel.org> # 5.19.x
Co-developed-by: Liew Rui Yan <aethernet65535@gmail.com>
Signed-off-by: Liew Rui Yan <aethernet65535@gmail.com>
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/reclaim.c | 85 ++++++++++++++++++++++++++++++----------------
1 file changed, 55 insertions(+), 30 deletions(-)
diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
index 86da147786583..fe7fce26cf6ce 100644
--- a/mm/damon/reclaim.c
+++ b/mm/damon/reclaim.c
@@ -144,15 +144,6 @@ static unsigned long addr_unit __read_mostly = 1;
static bool skip_anon __read_mostly;
module_param(skip_anon, bool, 0600);
-/*
- * PID of the DAMON thread
- *
- * If DAMON_RECLAIM is enabled, this becomes the PID of the worker thread.
- * Else, -1.
- */
-static int kdamond_pid __read_mostly = -1;
-module_param(kdamond_pid, int, 0400);
-
static struct damos_stat damon_reclaim_stat;
DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(damon_reclaim_stat,
reclaim_tried_regions, reclaimed_regions, quota_exceeds);
@@ -288,12 +279,8 @@ static int damon_reclaim_turn(bool on)
{
int err;
- if (!on) {
- err = damon_stop(&ctx, 1);
- if (!err)
- kdamond_pid = -1;
- return err;
- }
+ if (!on)
+ return damon_stop(&ctx, 1);
err = damon_reclaim_apply_parameters();
if (err)
@@ -302,9 +289,6 @@ static int damon_reclaim_turn(bool on)
err = damon_start(&ctx, 1, true);
if (err)
return err;
- kdamond_pid = damon_kdamond_pid(ctx);
- if (kdamond_pid < 0)
- return kdamond_pid;
return damon_call(ctx, &call_control);
}
@@ -332,42 +316,83 @@ module_param_cb(addr_unit, &addr_unit_param_ops, &addr_unit, 0600);
MODULE_PARM_DESC(addr_unit,
"Scale factor for DAMON_RECLAIM to ops address conversion (default: 1)");
+static bool damon_reclaim_enabled(void)
+{
+ if (!ctx)
+ return false;
+ return damon_is_running(ctx);
+}
+
static int damon_reclaim_enabled_store(const char *val,
const struct kernel_param *kp)
{
- bool is_enabled = enabled;
- bool enable;
int err;
- err = kstrtobool(val, &enable);
+ err = kstrtobool(val, &enabled);
if (err)
return err;
- if (is_enabled == enable)
+ if (damon_reclaim_enabled() == enabled)
return 0;
/* Called before init function. The function will handle this. */
if (!damon_initialized())
- goto set_param_out;
+ return 0;
- err = damon_reclaim_turn(enable);
- if (err)
- return err;
+ return damon_reclaim_turn(enabled);
+}
-set_param_out:
- enabled = enable;
- return err;
+static int damon_reclaim_enabled_load(char *buffer,
+ const struct kernel_param *kp)
+{
+ return sprintf(buffer, "%c\n", damon_reclaim_enabled() ? 'Y' : 'N');
}
static const struct kernel_param_ops enabled_param_ops = {
.set = damon_reclaim_enabled_store,
- .get = param_get_bool,
+ .get = damon_reclaim_enabled_load,
};
module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
MODULE_PARM_DESC(enabled,
"Enable or disable DAMON_RECLAIM (default: disabled)");
+static int damon_reclaim_kdamond_pid_store(const char *val,
+ const struct kernel_param *kp)
+{
+ /*
+ * kdamond_pid is read-only, but kernel command line could write it.
+ * Do nothing here.
+ */
+ return 0;
+}
+
+static int damon_reclaim_kdamond_pid_load(char *buffer,
+ const struct kernel_param *kp)
+{
+ int kdamond_pid = -1;
+
+ if (ctx) {
+ kdamond_pid = damon_kdamond_pid(ctx);
+ if (kdamond_pid < 0)
+ kdamond_pid = -1;
+ }
+ return sprintf(buffer, "%d\n", kdamond_pid);
+}
+
+static const struct kernel_param_ops kdamond_pid_param_ops = {
+ .set = damon_reclaim_kdamond_pid_store,
+ .get = damon_reclaim_kdamond_pid_load,
+};
+
+/*
+ * PID of the DAMON thread
+ *
+ * If DAMON_RECLAIM is enabled, this becomes the PID of the worker thread.
+ * Else, -1.
+ */
+module_param_cb(kdamond_pid, &kdamond_pid_param_ops, NULL, 0400);
+
static int __init damon_reclaim_init(void)
{
int err;
--
2.47.3
^ permalink raw reply related
* [PATCH v3 0/3] mm/damon/modules: detect and use fresh status
From: SeongJae Park @ 2026-04-19 16:09 UTC (permalink / raw)
To: Andrew Morton; +Cc: SeongJae Park, # 5 . 19 . x, damon, linux-kernel, linux-mm
DAMON modules including DAMON_RECLAIM, DAMON_LRU_SORT and DAMON_STAT
commonly expose the kdamond running status via their parameters. Under
certain scenarios including wrong user inputs and memory allocation
failures, those parameter values can be stale. It can confuse users.
For DAMON_RECLAIM and DAMON_LRU_SORT, it even makes the kdamond unable
to be restarted before the system reboot.
The problem comes from the fact that there are multiple events for the
status changes and it is difficult to follow up all the scenarios. Fix
the issue by detecting and using the status on demand, instead of using
a cached status that is difficult to be updated.
Patches 1-3 fix the bugs in DAMON_RECLAIM, DAMON_LRU_SORT and DAMON_STAT
in the order.
Changes from RFC v2.1
- rfc v2.1: https://lore.kernel.org/20260418222758.39795-1-sj@kernel.org
- Rebase to latest mm-new.
Changes from RFC v2
- rfc v2: https://lore.kernel.org/20260418014439.6353-1-sj@kernel.org
- Set kdamond_pid set callbacks.
- Support multiple enabled parameters setup on boot commandline.
- Acknowledge the third patch was discovered by Sashiko.
Changes from v2
- v2: https://lore.kernel.org/20260413185249.5921-1-aethernet65535@gmail.com
- Add RFC tag back, for sashiko review.
- Detect and use fresh status instead of trying to catch up all scenarios.
- Change Liew from the responsible author to a credit-deserved co-developer.
- Move authorship responsibility to SJ.
- Add DAMON_STAT fix.
- RFC of the fix was posted separately
(https://lore.kernel.org/20260416143857.76146-1-sj@kernel.org), and
only commit message wordsmithing is added in this version.
Changes from RFC
- rfc: https://lore.kernel.org/20260330164347.12772-1-aethernet65535@gmail.com
- Remove RFC tag.
- Remove 'damon_thread_status' structure and damon_update_thread_status()
(SJ pointed out this was too much extension of core API for a problem
that can be fixed more simply).
- Add a fallback in damon_{lru_sort, reclaim}_turn() 'N' path. If
damon_stop() fails but kdamond is not running, forcefully reset the
parameters.
- Reset 'enabled' and 'kdamond_pid' when damon_commit_ctx() fails in
damon_{lru_sort, reclaim}_apply_parameters() (kdamond will terminate
eventually in this case).
SeongJae Park (3):
mm/damon/reclaim: detect and use fresh enabled and kdamond_pid values
mm/damon/lru_sort: detect and use fresh enabled and kdamond_pid values
mm/damon/stat: detect and use fresh enabled value
mm/damon/lru_sort.c | 85 +++++++++++++++++++++++++++++----------------
mm/damon/reclaim.c | 85 +++++++++++++++++++++++++++++----------------
mm/damon/stat.c | 30 ++++++++++------
3 files changed, 130 insertions(+), 70 deletions(-)
base-commit: a51b50e60d2dae1f66329f147bde8723e6b1031e
--
2.47.3
^ permalink raw reply
* Re: [PATCH] perf unwind-libdw: Fix stale object reference in arch/loongarch
From: Icenowy Zheng @ 2026-04-19 15:56 UTC (permalink / raw)
To: Ian Rogers
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, James Clark, Shimin Guo, linux-perf-users,
linux-kernel, stable
In-Reply-To: <CAP-5=fX=+2oNYHDqsNnFrOZya=RxpnPFF_ojZTQP8v8Umt951w@mail.gmail.com>
在 2026-04-19日的 08:01 -0700,Ian Rogers写道:
> On Sun, Apr 19, 2026 at 2:08 AM Icenowy Zheng
> <zhengxingda@iscas.ac.cn> wrote:
> >
> > The arch/loongarch/util/unwind-libdw.c file is already moved to
> > util/,
> > but the Build statement for it is forgot to be removed.
> >
> > Remove the stale Build statement.
> >
> > This fixes the build failure of perf tool in kernel v7.0 on
> > LoongArch.
> >
> > Fixes: e62fae9d9e85 ("perf unwind-libdw: Fix a cross-arch unwinding
> > bug")
> > Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
> > Cc: stable@vger.kernel.org
>
> I think this is already fixed:
> https://web.git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/commit/?h=perf-tools-next
Thanks for pointing out!
Thanks,
Icenowy
> I also sent out a fix, fwiw:
> https://lore.kernel.org/linux-perf-users/20260305221927.3237145-3-irogers@google.com/
>
> Thanks,
> Ian
>
> > ---
> > tools/perf/arch/loongarch/util/Build | 1 -
> > 1 file changed, 1 deletion(-)
> >
> > diff --git a/tools/perf/arch/loongarch/util/Build
> > b/tools/perf/arch/loongarch/util/Build
> > index 3ad73d0289f3e..8d91e78d31c94 100644
> > --- a/tools/perf/arch/loongarch/util/Build
> > +++ b/tools/perf/arch/loongarch/util/Build
> > @@ -1,4 +1,3 @@
> > perf-util-y += header.o
> >
> > perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
> > -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
> > --
> > 2.52.0
> >
^ permalink raw reply
* Re: [PATCH 5.10 491/491] io_uring/poll: correctly handle io_poll_add() return value on update
From: Ben Hutchings @ 2026-04-19 15:45 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable, Jens Axboe
Cc: patches, syzbot+641eec6b7af1f62f2b99
In-Reply-To: <20260413155837.438151458@linuxfoundation.org>
[-- Attachment #1: Type: text/plain, Size: 3884 bytes --]
On Mon, 2026-04-13 at 18:02 +0200, Greg Kroah-Hartman wrote:
> 5.10-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Jens Axboe <axboe@kernel.dk>
>
> Commit 84230ad2d2afbf0c44c32967e525c0ad92e26b4e upstream.
>
> When the core of io_uring was updated to handle completions
> consistently and with fixed return codes, the POLL_REMOVE opcode
> with updates got slightly broken. If a POLL_ADD is pending and
> then POLL_REMOVE is used to update the events of that request, if that
> update causes the POLL_ADD to now trigger, then that completion is lost
> and a CQE is never posted.
>
> Additionally, ensure that if an update does cause an existing POLL_ADD
> to complete, that the completion value isn't always overwritten with
> -ECANCELED. For that case, whatever io_poll_add() set the value to
> should just be retained.
This backport is very different from the upstream version, and I have
some questions about that (inline below).
> Cc: stable@vger.kernel.org
> Fixes: 97b388d70b53 ("io_uring: handle completions in the core")
> Reported-by: syzbot+641eec6b7af1f62f2b99@syzkaller.appspotmail.com
> Tested-by: syzbot+641eec6b7af1f62f2b99@syzkaller.appspotmail.com
> Signed-off-by: Jens Axboe <axboe@kernel.dk>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
> io_uring/io_uring.c | 26 +++++++++++++++++++-------
> 1 file changed, 19 insertions(+), 7 deletions(-)
>
> --- a/io_uring/io_uring.c
> +++ b/io_uring/io_uring.c
> @@ -5980,7 +5980,7 @@ static int io_poll_add_prep(struct io_ki
> return 0;
> }
>
> -static int io_poll_add(struct io_kiocb *req, unsigned int issue_flags)
> +static int __io_poll_add(struct io_kiocb *req, unsigned int issue_flags)
> {
> struct io_poll_iocb *poll = &req->poll;
> struct io_poll_table ipt;
> @@ -5992,11 +5992,21 @@ static int io_poll_add(struct io_kiocb *
> if (!ret && ipt.error)
> req_set_fail(req);
> ret = ret ?: ipt.error;
> - if (ret)
> + if (ret > 0) {
> __io_req_complete(req, issue_flags, ret, 0);
> + return ret;
> + }
> return 0;
> }
>
> +static int io_poll_add(struct io_kiocb *req, unsigned int issue_flags)
> +{
> + int ret;
> +
> + ret = __io_poll_add(req, issue_flags);
> + return ret < 0 ? ret : 0;
__io_poll_add() still never returns a negative result, so why is there a
check for that here?
> +}
> +
> static int io_poll_update(struct io_kiocb *req, unsigned int issue_flags)
> {
> struct io_ring_ctx *ctx = req->ctx;
> @@ -6012,6 +6022,7 @@ static int io_poll_update(struct io_kioc
> ret = preq ? -EALREADY : -ENOENT;
> goto out;
> }
> + preq->result = -ECANCELED;
> spin_unlock(&ctx->completion_lock);
>
> if (req->poll_update.update_events || req->poll_update.update_user_data) {
> @@ -6024,16 +6035,17 @@ static int io_poll_update(struct io_kioc
> if (req->poll_update.update_user_data)
> preq->user_data = req->poll_update.new_user_data;
>
> - ret2 = io_poll_add(preq, issue_flags);
> + ret2 = __io_poll_add(preq, issue_flags);
> /* successfully updated, don't complete poll request */
> if (!ret2)
> goto out;
> + preq->result = ret2;
> +
> }
> - req_set_fail(preq);
> - io_req_complete(preq, -ECANCELED);
> + if (preq->result < 0)
> + req_set_fail(preq);
> + io_req_complete(preq, preq->result);
If __io_poll_add() returned an events mask then it completed preq, but
then we also complete preq here. Is that really correct?
Ben.
> out:
> - if (ret < 0)
> - req_set_fail(req);
> /* complete update request, we're done with it */
> io_req_complete(req, ret);
> io_ring_submit_unlock(ctx, !(issue_flags & IO_URING_F_NONBLOCK));
>
>
--
Ben Hutchings
Any smoothly functioning technology is indistinguishable
from a rigged demo.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [tip: timers/urgent] clockevents: Add missing resets of the next_event_forced flag
From: Linux regression tracking (Thorsten Leemhuis) @ 2026-04-19 15:11 UTC (permalink / raw)
To: Thomas Gleixner, Linus Torvalds
Cc: Hanabishi, Eric Naim, stable, linux-tip-commits, x86,
linux-kernel, Linux kernel regressions list
In-Reply-To: <177636758252.1323100.5283878386670888513.tip-bot2@tip-bot2>
On 4/16/26 21:26, tip-bot2 for Thomas Gleixner wrote:
> The following commit has been merged into the timers/urgent branch of tip:
>
> Commit-ID: 4096fd0e8eaea13ebe5206700b33f49635ae18e5
> Gitweb: https://git.kernel.org/tip/4096fd0e8eaea13ebe5206700b33f49635ae18e5
> Author: Thomas Gleixner <tglx@kernel.org>
> AuthorDate: Tue, 14 Apr 2026 22:55:01 +02:00
> Committer: Thomas Gleixner <tglx@kernel.org>
> CommitterDate: Thu, 16 Apr 2026 21:22:04 +02:00
>
> clockevents: Add missing resets of the next_event_forced flag
Just wondering: what's the plan to mainline this? I wonder if this is
worth mainlining rather quickly and the tell the stable team right
afterwards to queue it up for 7.0.1, as in addition to the two affected
people in this thread (one of which stated that "several users from
CachyOS reported this regression as well") I noticed three more 7.0 bug
reports in the past few days that likely are fixed by the quoted patch:
https://gitlab.freedesktop.org/drm/amd/-/work_items/5178#note_3432195
https://bugzilla.kernel.org/show_bug.cgi?id=221370
https://bugzilla.kernel.org/show_bug.cgi?id=221377
Ciao, Thorsten
> The prevention mechanism against timer interrupt starvation missed to reset
> the next_event_forced flag in a couple of places:
>
> - When the clock event state changes. That can cause the flag to be
> stale over a shutdown/startup sequence
>
> - When a non-forced event is armed, which then prevents rearming before
> that event. If that event is far out in the future this will cause
> missed timer interrupts.
>
> - In the suspend wakeup handler.
>
> That led to stalls which have been reported by several people.
>
> Add the missing resets, which fixes the problems for the reporters.
>
> Fixes: d6e152d905bd ("clockevents: Prevent timer interrupt starvation")
> Reported-by: Hanabishi <i.r.e.c.c.a.k.u.n+kernel.org@gmail.com>
> Reported-by: Eric Naim <dnaim@cachyos.org>
> Signed-off-by: Thomas Gleixner <tglx@kernel.org>
> Tested-by: Hanabishi <i.r.e.c.c.a.k.u.n+kernel.org@gmail.com>
> Tested-by: Eric Naim <dnaim@cachyos.org>
> Cc: stable@vger.kernel.org
> Closes: https://lore.kernel.org/68d1e9ac-2780-4be3-8ee3-0788062dd3a4@gmail.com
> Link: https://patch.msgid.link/87340xfeje.ffs@tglx
> ---
> kernel/time/clockevents.c | 7 ++++++-
> kernel/time/tick-broadcast.c | 1 +
> 2 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
> index b4d7306..5e22697 100644
> --- a/kernel/time/clockevents.c
> +++ b/kernel/time/clockevents.c
> @@ -94,6 +94,9 @@ static int __clockevents_switch_state(struct clock_event_device *dev,
> if (dev->features & CLOCK_EVT_FEAT_DUMMY)
> return 0;
>
> + /* On state transitions clear the forced flag unconditionally */
> + dev->next_event_forced = 0;
> +
> /* Transition with new state-specific callbacks */
> switch (state) {
> case CLOCK_EVT_STATE_DETACHED:
> @@ -366,8 +369,10 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires, b
> if (delta > (int64_t)dev->min_delta_ns) {
> delta = min(delta, (int64_t) dev->max_delta_ns);
> cycles = ((u64)delta * dev->mult) >> dev->shift;
> - if (!dev->set_next_event((unsigned long) cycles, dev))
> + if (!dev->set_next_event((unsigned long) cycles, dev)) {
> + dev->next_event_forced = 0;
> return 0;
> + }
> }
>
> if (dev->next_event_forced)
> diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
> index 7e57fa3..115e0bf 100644
> --- a/kernel/time/tick-broadcast.c
> +++ b/kernel/time/tick-broadcast.c
> @@ -108,6 +108,7 @@ static struct clock_event_device *tick_get_oneshot_wakeup_device(int cpu)
>
> static void tick_oneshot_wakeup_handler(struct clock_event_device *wd)
> {
> + wd->next_event_forced = 0;
> /*
> * If we woke up early and the tick was reprogrammed in the
> * meantime then this may be spurious but harmless.
>
^ permalink raw reply
* Re: [PATCH] perf unwind-libdw: Fix stale object reference in arch/loongarch
From: Ian Rogers @ 2026-04-19 15:01 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, James Clark, Shimin Guo, linux-perf-users,
linux-kernel, stable
In-Reply-To: <20260419090756.2190201-1-zhengxingda@iscas.ac.cn>
On Sun, Apr 19, 2026 at 2:08 AM Icenowy Zheng <zhengxingda@iscas.ac.cn> wrote:
>
> The arch/loongarch/util/unwind-libdw.c file is already moved to util/,
> but the Build statement for it is forgot to be removed.
>
> Remove the stale Build statement.
>
> This fixes the build failure of perf tool in kernel v7.0 on LoongArch.
>
> Fixes: e62fae9d9e85 ("perf unwind-libdw: Fix a cross-arch unwinding bug")
> Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
> Cc: stable@vger.kernel.org
I think this is already fixed:
https://web.git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/commit/?h=perf-tools-next
I also sent out a fix, fwiw:
https://lore.kernel.org/linux-perf-users/20260305221927.3237145-3-irogers@google.com/
Thanks,
Ian
> ---
> tools/perf/arch/loongarch/util/Build | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/tools/perf/arch/loongarch/util/Build b/tools/perf/arch/loongarch/util/Build
> index 3ad73d0289f3e..8d91e78d31c94 100644
> --- a/tools/perf/arch/loongarch/util/Build
> +++ b/tools/perf/arch/loongarch/util/Build
> @@ -1,4 +1,3 @@
> perf-util-y += header.o
>
> perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
> -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
> --
> 2.52.0
>
^ permalink raw reply
* Re: [PATCH 6.1 00/55] 6.1.169-rc1 review
From: Guenter Roeck @ 2026-04-19 14:31 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, shuah, patches,
lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
rwarsow, conor, hargar, broonie, achill, sr, Linus Walleij,
Vladimir Oltean
In-Reply-To: <20260413155724.820472494@linuxfoundation.org>
Hi,
On 4/13/26 09:00, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 6.1.169 release.
> There are 55 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Wed, 15 Apr 2026 15:57:08 +0000.
> Anything received after that time might be too late.
>
Looking through my test logs, I find that the following build error has been
reported since v6.1.166.
Building arm:ixp4xx_defconfig ... failed
--------------
Error log:
drivers/net/ethernet/xscale/ixp4xx_eth.c:390:39: warning: 'struct kernel_hwtstamp_config' declared inside parameter list will not be visible outside of this definition or declaration
390 | struct kernel_hwtstamp_config *cfg,
| ^~~~~~~~~~~~~~~~~~~~~~
drivers/net/ethernet/xscale/ixp4xx_eth.c: In function 'ixp4xx_hwtstamp_set':
drivers/net/ethernet/xscale/ixp4xx_eth.c:408:16: error: invalid use of undefined type 'struct kernel_hwtstamp_config'
Backported patches in that driver are
5195b10c34b8 net: ethernet: xscale: Check for PTP support properly
a94d5447f6bf net: ixp4xx_eth: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set()
where a94d5447f6bf introduces the problem and presumably was applied
to be able to apply 5195b10c34b8 without having to resolve conflicts.
Unfortunately, 'struct kernel_hwtstamp_config' is indeed not available in v6.1,
causing the build failure.
a94d5447f6bf can not be reverted on its own, so both patches would have to
be reverted to fix the problem.
The same problem is seen in v5.15.y since v5.15.202. The commits there are
144dde314698 net: ethernet: xscale: Check for PTP support properly
612c622ab8ef net: ixp4xx_eth: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set()
I have copied the patch authors for advice.
Guenter
^ permalink raw reply
* Re: [PATCH] scsi: mpi3mr: bounds-check phy_number in mpi3mr_update_links()
From: James Bottomley @ 2026-04-19 14:25 UTC (permalink / raw)
To: Junrui Luo, Sathya Prakash Veerichetty, Kashyap Desai,
Sumit Saxena, Sreekanth Reddy, Martin K. Petersen,
Himanshu Madhani
Cc: mpi3mr-linuxdrv.pdl, linux-scsi, linux-kernel, Yuhao Jiang,
stable
In-Reply-To: <SYBPR01MB788162EDBF416DC5E714DFEEAF2E2@SYBPR01MB7881.ausprd01.prod.outlook.com>
On Sun, 2026-04-19 at 20:08 +0800, Junrui Luo wrote:
> mpi3mr_update_links() dereferences mr_sas_node->phy[phy_number] and
> writes attached_handle without verifying that phy_number is within
> the parent node's allocated phy array.
That's right: the phy number is supplied by the expander (or device).
> Two callers feed phy_number from firmware-supplied fields:
> mpi3mr_sastopochg_evt_bh() passes (event_data->start_phy_num + i)
> from the SAS topology change event, and
> mpi3mr_report_tgtdev_to_sas_transport() passes
> tgtdev->dev_spec.sas_sata_inf.phy_id from firmware device
> information.
>
> Since num_phys is a u8, a stray phy_number can reach 255 and index
> past the kzalloc_objs()-sized phy[] array, leading to an out-of-
> bounds.
>
> The sibling mpt3sas driver guards at the topology-change caller by
> discarding entries whose phy_number exceeds max_phys. Apply the
> equivalent check inside mpi3mr_update_links().
Our threat model for hardware is that we assume it behaves correctly
unless someone finds a buggy instance in the field ... have you found
such a buggy device?
Regards,
James
^ permalink raw reply
* [PATCH] dmaengine: idxd: Fix saved engines array leak in config save
From: Guangshuo Li @ 2026-04-19 14:08 UTC (permalink / raw)
To: Vinicius Costa Gomes, Dave Jiang, Vinod Koul, Frank Li,
Fenghua Yu, dmaengine, linux-kernel
Cc: Guangshuo Li, stable
idxd_device_config_save() uses cleanup.h helpers for temporary
allocations while saving device configuration. The saved_groups and
saved_wqs pointer arrays are declared with __free(kfree), and ownership
is transferred to idxd_saved with no_free_ptr() on the success path.
The saved_engines pointer array follows the same ownership pattern on the
success path, but it is not declared with __free(kfree). As a result, if
an error happens after saved_engines is allocated, idxd_free_saved()
frees the saved engine objects but not the saved_engines array itself.
This leaks saved_engines on error paths such as:
- failure to allocate an individual saved engine
- failure to allocate saved_wq_enable_map
- failure to allocate saved_wqs
- failure to allocate an individual saved WQ
Declare saved_engines with __free(kfree) so the array is released
automatically on failure, matching saved_groups and saved_wqs. The success
path is unchanged because ownership is already transferred with
no_free_ptr().
Fixes: 6078a315aec1 ("dmaengine: idxd: Add idxd_device_config_save() and idxd_device_config_restore() helpers")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
drivers/dma/idxd/init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
index f1cfc7790d95..02210f16d391 100644
--- a/drivers/dma/idxd/init.c
+++ b/drivers/dma/idxd/init.c
@@ -880,7 +880,7 @@ static int idxd_device_config_save(struct idxd_device *idxd,
saved_groups[i] = no_free_ptr(saved_group);
}
- struct idxd_engine **saved_engines =
+ struct idxd_engine **saved_engines __free(kfree) =
kcalloc_node(idxd->max_engines,
sizeof(struct idxd_engine *),
GFP_KERNEL, dev_to_node(dev));
--
2.43.0
^ permalink raw reply related
* [PATCH v6 2/2] rust: Makefile: bound rustdoc workaround to affected versions
From: HeeSu Kim @ 2026-04-19 14:06 UTC (permalink / raw)
To: miguel.ojeda.sandonis
Cc: a.hindborg, aliceryhl, bjorn3_gh, boqun, charmitro, dakr, gary,
linux-kbuild, linux-kernel, lossin, mlksvender, nathan, nsc,
ojeda, rust-for-linux, stable, tmgross
In-Reply-To: <cover.1776607331.git.mlksvender@gmail.com>
The `-Cunsafe-allow-abi-mismatch=fixed-x18` workaround was added to
handle a rustdoc bug where target modifiers were not properly saved [1].
An analogous workaround for doctests was added later [2]; since Rust
1.91.0 the `sanitizer` modifier is also appended.
The rustdoc bug is fixed in Rust 1.90.0 [3] and the doctests one is
fixed in Rust 1.92.0, so restrict each workaround to the compiler
versions that are actually affected, letting ABI compatibility checks
run again on newer compilers.
Split the cases into explicit version ranges using
`rustc-min-version` + `rustc-lt-version` combined inline: the rustdoc
workaround applies to 1.88.x and 1.89.x, the doctests workaround to
1.88.x through 1.91.x, and the `sanitizer` modifier is only added
from 1.91.x onwards (when rustc started recognizing it). This layout
makes it easy to drop each entry as the minimum toolchain version is
bumped past the affected range.
[1] https://github.com/rust-lang/rust/issues/144521
[2] https://github.com/rust-lang/rust/issues/146465
[3] https://github.com/rust-lang/rust/pull/144523
Suggested-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/rust-for-linux/DG4JM9PU51M0.1YRGM9HVTY24U@garyguo.net/
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/rust-for-linux/CANiq72nnuKJaKrxrut6+noR13PUiSoWWyyp-pGx-fe_2O6ayFA@mail.gmail.com/
Cc: stable@vger.kernel.org # Useful in 6.18.y and later.
Signed-off-by: HeeSu Kim <mlksvender@gmail.com>
---
rust/Makefile | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/rust/Makefile b/rust/Makefile
index 5c0155b83454..14acc9c57c60 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -134,12 +134,18 @@ pin_init-flags := \
--extern macros \
$(call cfgs-to-flags,$(pin_init-cfgs))
-# `rustdoc` did not save the target modifiers, thus workaround for
-# the time being (https://github.com/rust-lang/rust/issues/144521).
-rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18)
-
-# Similarly, for doctests (https://github.com/rust-lang/rust/issues/146465).
-doctests_modifiers_workaround := $(rustdoc_modifiers_workaround)$(if $(call rustc-min-version,109100),$(comma)sanitizer)
+# `rustdoc` did not save the target modifiers
+# (https://github.com/rust-lang/rust/issues/144521, fixed in Rust 1.90.0).
+# Similarly, for doctests
+# (https://github.com/rust-lang/rust/issues/146465, fixed in Rust 1.92.0).
+ifeq ($(and $(call rustc-min-version,108800),$(call rustc-lt-version,109000)),y)
+rustdoc_modifiers_workaround := -Cunsafe-allow-abi-mismatch=fixed-x18
+doctests_modifiers_workaround := -Cunsafe-allow-abi-mismatch=fixed-x18
+else ifeq ($(and $(call rustc-min-version,109000),$(call rustc-lt-version,109100)),y)
+doctests_modifiers_workaround := -Cunsafe-allow-abi-mismatch=fixed-x18
+else ifeq ($(and $(call rustc-min-version,109100),$(call rustc-lt-version,109200)),y)
+doctests_modifiers_workaround := -Cunsafe-allow-abi-mismatch=fixed-x18,sanitizer
+endif
# `rustc` recognizes `--remap-path-prefix` since 1.26.0, but `rustdoc` only
# since Rust 1.81.0. Moreover, `rustdoc` ICEs on out-of-tree builds since Rust
--
2.52.0
^ permalink raw reply related
* [PATCH v6 1/2] kbuild: add rustc-lt-version macro
From: HeeSu Kim @ 2026-04-19 14:06 UTC (permalink / raw)
To: miguel.ojeda.sandonis
Cc: a.hindborg, aliceryhl, bjorn3_gh, boqun, charmitro, dakr, gary,
linux-kbuild, linux-kernel, lossin, mlksvender, nathan, nsc,
ojeda, rust-for-linux, stable, tmgross
In-Reply-To: <cover.1776607331.git.mlksvender@gmail.com>
Add `rustc-lt-version` macro to `scripts/Makefile.compiler` for version
upper bound checks, mirroring the existing `rustc-min-version`.
Use a non-inclusive (less-than) comparison so that callers can express
clean version boundaries such as `109000` (Rust 1.90.0) rather than
`108999`, which is also easier to remove once the toolchain minimum
version is bumped past the bound.
This will be used to bound workarounds to specific compiler version
ranges.
Originally posted as `rustc-max-version` in v5 [1]; renamed to
`rustc-lt-version` on this respin per Miguel's direction to simplify
the delta and avoid the `99` form [2].
[1] https://lore.kernel.org/rust-for-linux/20260205131522.2942928-1-mlksvender@gmail.com/
[2] https://lore.kernel.org/rust-for-linux/CANiq72n-z0v_deUVPWeg1h0c6KQ+r6xfNDf72o29_0yy6KbqGA@mail.gmail.com/
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/rust-for-linux/CANiq72n39eU9WE=Yh0_yJzmqMxo=QAaU2pN0UqP9jZ7bT7rhgA@mail.gmail.com/
Acked-by: Nathan Chancellor <nathan@kernel.org>
Acked-by: Nicolas Schier <nsc@kernel.org>
Signed-off-by: HeeSu Kim <mlksvender@gmail.com>
---
scripts/Makefile.compiler | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler
index ef91910de265..fd039e228800 100644
--- a/scripts/Makefile.compiler
+++ b/scripts/Makefile.compiler
@@ -71,6 +71,10 @@ clang-min-version = $(call test-ge, $(CONFIG_CLANG_VERSION), $1)
# Usage: rustc-$(call rustc-min-version, 108500) += -Cfoo
rustc-min-version = $(call test-ge, $(CONFIG_RUSTC_VERSION), $1)
+# rustc-lt-version
+# Usage: rustc-$(call rustc-lt-version, 109000) += -Cfoo
+rustc-lt-version = $(if $(call rustc-min-version,$1),,y)
+
# ld-option
# Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y)
ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3))
--
2.52.0
^ permalink raw reply related
* [PATCH v6 0/2] rust: Makefile: bound rustdoc workaround to affected versions
From: HeeSu Kim @ 2026-04-19 14:06 UTC (permalink / raw)
To: miguel.ojeda.sandonis
Cc: a.hindborg, aliceryhl, bjorn3_gh, boqun, charmitro, dakr, gary,
linux-kbuild, linux-kernel, lossin, mlksvender, nathan, nsc,
ojeda, rust-for-linux, stable, tmgross
In-Reply-To: <CANiq72nnuKJaKrxrut6+noR13PUiSoWWyyp-pGx-fe_2O6ayFA@mail.gmail.com>
This series bounds the `-Cunsafe-allow-abi-mismatch=fixed-x18` workaround
in `rust/Makefile` to the compiler versions that are actually affected by
the rustdoc (#144521, fixed in 1.90.0) and doctests (#146465, fixed in
1.92.0) target-modifier bugs, so that ABI compatibility checks run again
on newer toolchains.
Changes since v5 [1] [2]:
- Patch 1/2 is v5 1/2 renamed from `rustc-max-version` to
`rustc-lt-version` per Miguel's plan to rename on apply [3] and to
avoid the `99` form. Nathan's [4] and Nicolas' [5] Acked-bys from
v5 1/2 are carried over as Miguel indicated they would be preserved
through the rename.
- Patch 2/2 reworks v5 2/2 to fix the doctests case that Miguel
pointed out [6]: the v5 form reused `$(rustdoc_modifiers_workaround)`
as a prefix, so on rustc >= 1.91 the doctests variable expanded to
a stray `,sanitizer`. Use Miguel's suggested explicit
`ifeq`/`else ifeq` layout with `rustc-min-version` +
`rustc-lt-version` combined inline, so each affected range is
visible on its own line.
The `rustc-version-range` macro Miguel mentioned as an "improvement on
top" [3] is intentionally left out of this series; I will send it as a
separate follow-up patch once this lands, as Miguel suggested.
Tested by building `make rustdoc` and `make rusttest` on rustc 1.93.0:
both succeed with the workaround disabled (empty expansion), confirming
the bugs really are fixed in 1.92+ and no regressions are introduced.
Macro expansion was also spot-checked across simulated rustc versions
1.87 through 1.93 to verify each range matches the expected flag value.
[1] https://lore.kernel.org/rust-for-linux/20260205131522.2942928-1-mlksvender@gmail.com/
[2] https://lore.kernel.org/rust-for-linux/20260205131815.2943152-2-mlksvender@gmail.com/
[3] https://lore.kernel.org/rust-for-linux/CANiq72n-z0v_deUVPWeg1h0c6KQ+r6xfNDf72o29_0yy6KbqGA@mail.gmail.com/
[4] https://lore.kernel.org/rust-for-linux/20260203221224.GA2703490@ax162/
[5] https://lore.kernel.org/rust-for-linux/aYS9bRugxr1rUvA3@levanger/
[6] https://lore.kernel.org/rust-for-linux/CANiq72nnuKJaKrxrut6+noR13PUiSoWWyyp-pGx-fe_2O6ayFA@mail.gmail.com/
HeeSu Kim (2):
kbuild: add rustc-lt-version macro
rust: Makefile: bound rustdoc workaround to affected versions
rust/Makefile | 18 ++++++++++++------
scripts/Makefile.compiler | 4 ++++
2 files changed, 16 insertions(+), 6 deletions(-)
--
2.52.0
^ permalink raw reply
* [PATCH v6 2/2] rust: Makefile: bound rustdoc workaround to affected versions
From: HeeSu Kim @ 2026-04-19 14:05 UTC (permalink / raw)
To: miguel.ojeda.sandonis
Cc: a.hindborg, aliceryhl, bjorn3_gh, boqun, charmitro, dakr, gary,
linux-kbuild, linux-kernel, lossin, mlksvender, nathan, nsc,
ojeda, rust-for-linux, stable, tmgross
In-Reply-To: <cover.1776607331.git.mlksvender@gmail.com>
The `-Cunsafe-allow-abi-mismatch=fixed-x18` workaround was added to
handle a rustdoc bug where target modifiers were not properly saved [1].
An analogous workaround for doctests was added later [2]; since Rust
1.91.0 the `sanitizer` modifier is also appended.
The rustdoc bug is fixed in Rust 1.90.0 [3] and the doctests one is
fixed in Rust 1.92.0, so restrict each workaround to the compiler
versions that are actually affected, letting ABI compatibility checks
run again on newer compilers.
Split the cases into explicit version ranges using
`rustc-min-version` + `rustc-lt-version` combined inline: the rustdoc
workaround applies to 1.88.x and 1.89.x, the doctests workaround to
1.88.x through 1.91.x, and the `sanitizer` modifier is only added
from 1.91.x onwards (when rustc started recognizing it). This layout
makes it easy to drop each entry as the minimum toolchain version is
bumped past the affected range.
[1] https://github.com/rust-lang/rust/issues/144521
[2] https://github.com/rust-lang/rust/issues/146465
[3] https://github.com/rust-lang/rust/pull/144523
Suggested-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/rust-for-linux/DG4JM9PU51M0.1YRGM9HVTY24U@garyguo.net/
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/rust-for-linux/CANiq72nnuKJaKrxrut6+noR13PUiSoWWyyp-pGx-fe_2O6ayFA@mail.gmail.com/
Cc: stable@vger.kernel.org # Useful in 6.18.y and later.
Signed-off-by: HeeSu Kim <mlksvender@gmail.com>
---
rust/Makefile | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/rust/Makefile b/rust/Makefile
index 5c0155b83454..14acc9c57c60 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -134,12 +134,18 @@ pin_init-flags := \
--extern macros \
$(call cfgs-to-flags,$(pin_init-cfgs))
-# `rustdoc` did not save the target modifiers, thus workaround for
-# the time being (https://github.com/rust-lang/rust/issues/144521).
-rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18)
-
-# Similarly, for doctests (https://github.com/rust-lang/rust/issues/146465).
-doctests_modifiers_workaround := $(rustdoc_modifiers_workaround)$(if $(call rustc-min-version,109100),$(comma)sanitizer)
+# `rustdoc` did not save the target modifiers
+# (https://github.com/rust-lang/rust/issues/144521, fixed in Rust 1.90.0).
+# Similarly, for doctests
+# (https://github.com/rust-lang/rust/issues/146465, fixed in Rust 1.92.0).
+ifeq ($(and $(call rustc-min-version,108800),$(call rustc-lt-version,109000)),y)
+rustdoc_modifiers_workaround := -Cunsafe-allow-abi-mismatch=fixed-x18
+doctests_modifiers_workaround := -Cunsafe-allow-abi-mismatch=fixed-x18
+else ifeq ($(and $(call rustc-min-version,109000),$(call rustc-lt-version,109100)),y)
+doctests_modifiers_workaround := -Cunsafe-allow-abi-mismatch=fixed-x18
+else ifeq ($(and $(call rustc-min-version,109100),$(call rustc-lt-version,109200)),y)
+doctests_modifiers_workaround := -Cunsafe-allow-abi-mismatch=fixed-x18,sanitizer
+endif
# `rustc` recognizes `--remap-path-prefix` since 1.26.0, but `rustdoc` only
# since Rust 1.81.0. Moreover, `rustdoc` ICEs on out-of-tree builds since Rust
--
2.52.0
^ permalink raw reply related
* [PATCH v6 1/2] kbuild: add rustc-lt-version macro
From: HeeSu Kim @ 2026-04-19 14:05 UTC (permalink / raw)
To: miguel.ojeda.sandonis
Cc: a.hindborg, aliceryhl, bjorn3_gh, boqun, charmitro, dakr, gary,
linux-kbuild, linux-kernel, lossin, mlksvender, nathan, nsc,
ojeda, rust-for-linux, stable, tmgross
In-Reply-To: <cover.1776607331.git.mlksvender@gmail.com>
Add `rustc-lt-version` macro to `scripts/Makefile.compiler` for version
upper bound checks, mirroring the existing `rustc-min-version`.
Use a non-inclusive (less-than) comparison so that callers can express
clean version boundaries such as `109000` (Rust 1.90.0) rather than
`108999`, which is also easier to remove once the toolchain minimum
version is bumped past the bound.
This will be used to bound workarounds to specific compiler version
ranges.
Originally posted as `rustc-max-version` in v5 [1]; renamed to
`rustc-lt-version` on this respin per Miguel's direction to simplify
the delta and avoid the `99` form [2].
[1] https://lore.kernel.org/rust-for-linux/20260205131522.2942928-1-mlksvender@gmail.com/
[2] https://lore.kernel.org/rust-for-linux/CANiq72n-z0v_deUVPWeg1h0c6KQ+r6xfNDf72o29_0yy6KbqGA@mail.gmail.com/
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/rust-for-linux/CANiq72n39eU9WE=Yh0_yJzmqMxo=QAaU2pN0UqP9jZ7bT7rhgA@mail.gmail.com/
Acked-by: Nathan Chancellor <nathan@kernel.org>
Acked-by: Nicolas Schier <nsc@kernel.org>
Signed-off-by: HeeSu Kim <mlksvender@gmail.com>
---
scripts/Makefile.compiler | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler
index ef91910de265..fd039e228800 100644
--- a/scripts/Makefile.compiler
+++ b/scripts/Makefile.compiler
@@ -71,6 +71,10 @@ clang-min-version = $(call test-ge, $(CONFIG_CLANG_VERSION), $1)
# Usage: rustc-$(call rustc-min-version, 108500) += -Cfoo
rustc-min-version = $(call test-ge, $(CONFIG_RUSTC_VERSION), $1)
+# rustc-lt-version
+# Usage: rustc-$(call rustc-lt-version, 109000) += -Cfoo
+rustc-lt-version = $(if $(call rustc-min-version,$1),,y)
+
# ld-option
# Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y)
ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3))
--
2.52.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox