* Re: What's cooking in zh_CN (Jul 2026, #02)
From: Weijie Yuan @ 2026-07-14 18:17 UTC (permalink / raw)
To: Doehyun Baek
Cc: linux-doc, Alex Shi, Yanteng Si, Dongliang Mu, Ben Guo, Gary Guo,
Yan Zhu, Jiandong Qiu, chengyaqiang, Haoyang Liu
In-Reply-To: <CAN-j9Uo2f4dmWo8bMkdtXg7g6uayK_XZatkGs5iKv6-dNZ_Y-g@mail.gmail.com>
On Tue, Jul 14, 2026 at 07:56:28PM +0200, Doehyun Baek wrote:
> > Btw, for example, my patch (Weijie Yuan · docs/zh_CN: add docs-next
> > checkout workaround) is actually directly discarded after we reached
> > a consensus during our communication (with Dongliang). But it's
> > obvious that we didn't say it explicitly. So your website can't
> > recognize it automaticly right now. Perhaps we can think about how
> > to deal with this situation later.
>
> Yeah, this is a downside of an automated approach: it can miss details
> that are only implicit in the discussion. I see roughly three ways to
> handle such cases:
>
> 1. Allow authors to mark a patch explicitly by replying with a
> recognized phrase, such as `Patch-status: withdrawn`.
> 2. Use natural-language reasoning, perhaps with an LLM, to infer the
> outcome from the discussion. I leaned against it due to cost and
> complexity.
> 3. Leave the patch pending and let it move to "Cold" automatically
> after 30 days.
Junio originally uses "Stalled", but I don't think there's a difference
though :-)
> I think either the first or the third option makes sense in this situation.
Agreed.
^ permalink raw reply
* Re: What's cooking in zh_CN (Jul 2026, #02)
From: Doehyun Baek @ 2026-07-14 17:56 UTC (permalink / raw)
To: Weijie Yuan
Cc: linux-doc, Alex Shi, Yanteng Si, Dongliang Mu, Ben Guo, Gary Guo,
Yan Zhu, Jiandong Qiu, chengyaqiang, Haoyang Liu
In-Reply-To: <alZ1AzLX8LrB-JFK@wyuan.org>
> Btw, for example, my patch (Weijie Yuan · docs/zh_CN: add docs-next
checkout workaround) is actually directly discarded after we reached
a consensus during our communication (with Dongliang). But it's
obvious that we didn't say it explicitly. So your website can't
recognize it automaticly right now. Perhaps we can think about how
to deal with this situation later.
Yeah, this is a downside of an automated approach: it can miss details
that are only implicit in the discussion. I see roughly three ways to
handle such cases:
1. Allow authors to mark a patch explicitly by replying with a
recognized phrase, such as `Patch-status: withdrawn`.
2. Use natural-language reasoning, perhaps with an LLM, to infer the
outcome from the discussion. I leaned against it due to cost and
complexity.
3. Leave the patch pending and let it move to “Cold” automatically
after 30 days.
I think either the first or the third option makes sense in this situation.
Thanks,
Doehyun
^ permalink raw reply
* Re: [PATCH v8 0/8] mm/hmm: Add mmap lock-drop support for userfaultfd-backed mappings
From: Andrew Morton @ 2026-07-14 17:57 UTC (permalink / raw)
To: Stanislav Kinsburskii
Cc: airlied, akhilesh, corbet, dakr, david, decui, haiyangz, jgg,
kees, kys, leon, liam, lizhi.hou, ljs, longli, lyude,
maarten.lankhorst, mamin506, mhocko, mripard, nouveau, ogabbay,
oleg, rppt, shuah, simona, skhan, surenb, tzimmermann, vbabka,
wei.liu, dri-devel, linux-mm, linux-doc, linux-hyperv,
linux-kernel, linux-kselftest, linux-rdma
In-Reply-To: <alZfTxfypj39OrCE@skinsburskii>
On Tue, 14 Jul 2026 09:09:51 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> wrote:
> On Mon, Jul 13, 2026 at 03:45:35PM -0700, Andrew Morton wrote:
> > On Mon, 13 Jul 2026 13:57:55 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> wrote:
> >
> > > > > I rebased this series on top of mm-new right before sending it out.
> > > > > Should I have used a different branch?
> > > >
> > > > mm-new is good - Sashiko attempts that. But it's changing rapidly at
> > > > this point in the development cycle.
> > > >
> > >
> > > I’d like to send another revision addressing a few comments and also
> > > replace the `max/max_t` check with something simpler.
> > >
> > > Which branch should I base it on so that Sashiko can apply it
> > > successfully?
> >
> > mainline Linus would be safest.
> >
>
> Looks like linux-next/master has been updated with the v8 of the series.
That's because v8 is in mm.git's mm-unstable branch.
> I have v9 with a few small fixes, but it is too late to send it out already?
It's called "unstable" for a reason! Material in mm-unstable is still
under review, test and the latest stages of development. Getting
things finalized for movement into the non-rebasing mm-stable branch,
then into mainline.
So altering or replacing patchsets while they're in mm-unstable is
perfectly OK and expected.
> If it's not, then what should I base it on?
Well it's a bit tricky to replace a series when it's in mm-unstable.
One can do a git-checkout of the commit which precedes the v8 series.
Or base on current Linus mainline, which usually works out.
Sending little fixup patches against what's presently in mm-unstable
also works. I'll queue each one immediately behind the patch which it
alters then squash them into their parent patch before moving the series
into mm-stable.
A third alternative is for me to drop v8 from mm-unstable, then you
wait until that has propagated onto the servers or into linux-next,
then base on that. This approach is OK but I kinda unprefer it because
there's a bit of latency and it makes it harder for me to prepare my
"here's how v9 altered mm.git" summaries.
Which would you prefer?
^ permalink raw reply
* Re: [PATCH v5 0/3] x86,fs/resctrl,arm_mpam: Factor MBA parse-time conversion to be per-arch
From: Reinette Chatre @ 2026-07-14 17:45 UTC (permalink / raw)
To: Ben Horgan, bp, x86
Cc: james.morse, fenghuay, linux-kernel, linux-arm-kernel, tglx,
mingo, dave.hansen, hpa, corbet, linux-doc, dave.martin
In-Reply-To: <20260709093111.367851-1-ben.horgan@arm.com>
Dear x86 maintainers,
Could you please consider this series for inclusion? It applies cleanly on top
of x86/cache with HEAD at
2566b5cd6a27 ("fs/resctrl: Fix UAF from worker threads when domains are removed")
Please note that this is the first instance of a series that touches resctrl fs, x86, and
Arm. Since this is a resctrl fs API change these patches should stay together. You will
find in Ben's message below that patch routing via tip is supported by Arm.
Thank you very much
Reinette
On 7/9/26 2:31 AM, Ben Horgan wrote:
> This version fixes a couple of non-functional mistakes in v4 pointed out by Reinette.
>
> The patches should stay together so please could this all go via tip.
>
> Changelogs in patches.
>
> From cover letter of v3:
>
> This is a new version of Dave Martin's patch [1] to delegate rounding of
> bandwidth control user values to the arch code. As there is now more than one
> architecture using resctrl, I split the original patch into two, a core resctrl
> patch and an x86 patch, and added an MPAM patch. Please let me know if the patch
> break down and ordering is sensible and whether the pattern should be followed
> for any future similar changes.
>
> This does have a user visible effect on MB schema when using MPAM hardware
> with 'bandwidth_gran' greater than 1. I'm not sure if MPAM hardware with such
> coarse controls exists in the wild but it is spec compliant and I've tested it
> on a model.
>
> [1] https://lore.kernel.org/lkml/20251031154225.14799-1-Dave.Martin@arm.com/
>
> v3: https://lore.kernel.org/lkml/20260515140612.1205251-1-ben.horgan@arm.com/
> v4: https://lore.kernel.org/lkml/20260706160639.2136674-1-ben.horgan@arm.com/
>
> Based on v7.2-rc2
>
> Ben Horgan (1):
> arm_mpam: resctrl: Add pass-through resctrl_arch_preconvert_bw()
>
> Dave Martin (2):
> x86,fs/resctrl: Add resctrl_arch_preconvert_bw()
> fs/resctrl: Factor MBA parse-time conversion to be per-arch
>
> Documentation/filesystems/resctrl.rst | 17 +++++++++--------
> arch/x86/kernel/cpu/resctrl/ctrlmondata.c | 6 ++++++
> drivers/resctrl/mpam_resctrl.c | 5 +++++
> fs/resctrl/ctrlmondata.c | 6 +++---
> include/linux/resctrl.h | 19 +++++++++++++++++++
> 5 files changed, 42 insertions(+), 11 deletions(-)
>
^ permalink raw reply
* Re: What's cooking in zh_CN (Jul 2026, #02)
From: Weijie Yuan @ 2026-07-14 17:42 UTC (permalink / raw)
To: Doehyun Baek
Cc: linux-doc, Alex Shi, Yanteng Si, Dongliang Mu, Ben Guo, Gary Guo,
Yan Zhu, Jiandong Qiu, chengyaqiang, Haoyang Liu
In-Reply-To: <CAN-j9UoUHQ2i4H+9G-XK_mOfKKyE9K9-mwUgPc+4yOVfiizgmA@mail.gmail.com>
On Tue, Jul 14, 2026 at 07:05:28PM +0200, Doehyun Baek wrote:
> I "cooked" up a small website this evening that attempts to automate them:
>
> https://doehyunbaek.github.io/cook-linux-zhcn/
>
> Every hour, a GitHub Actions workflow scans recent `docs/zh_CN` patches on
> the linux-doc mailing list, groups rerolls, and compares their subjects
> with Alex´s `docs-next` tree to determine whether they have been applied.
> Pending series with no update for more than 30 days are classified as
> "Cold."
>
> This is still an experimental prototype, and its heuristics may have bugs,
> particularly when threads or patch subjects change. The source is available
> here:
>
> https://github.com/doehyunbaek/cook-linux-zhcn
>
> Issues, suggestions, and pull requests are welcome!
Hi Doehyun,
Wow, at first glance, it seemed quite good, as a prototype.
I feel like your UI is kind of similar to sashiko? I'm fine with it.
I guess this might be the thing that Dongliang had in mind. Let's
wait for the comments from those in the UTC+8 time zone after they
wake up ;-)
Btw, for example, my patch (Weijie Yuan · docs/zh_CN: add docs-next
checkout workaround) is actually directly discarded after we reached
a consensus during our communication (with Dongliang). But it's
obvious that we didn't say it explicitly. So your website can't
recognize it automaticly right now. Perhaps we can think about how
to deal with this situation later.
Thanks for your effort,
Weijie
--
seems that your email doesn't show up as expected on
lore.kernel.org til now, confused..
^ permalink raw reply
* Re: [PATCH v7 06/10] ACPI: APEI: GHES: move CXL CPER helpers
From: Alison Schofield @ 2026-07-14 17:33 UTC (permalink / raw)
To: Ahmed Tiba
Cc: Rafael J. Wysocki, Tony Luck, Borislav Petkov, Hanjun Guo,
Mauro Carvalho Chehab, Shuai Xue, Len Brown, Saket Dumbre,
Davidlohr Bueso, Jonathan Cameron, Dave Jiang, Vishal Verma,
Dan Williams, Ira Weiny, Li Ming, Mahesh J Salgaonkar,
Oliver O'Halloran, Bjorn Helgaas, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Corbet, Shuah Khan,
linux-kernel, linux-acpi, acpica-devel, linux-cxl, linuxppc-dev,
linux-pci, devicetree, linux-edac, linux-doc, Dmitry.Lamerov
In-Reply-To: <e77d0367-ab24-4b6d-beaa-034dd793cef6@arm.com>
On Tue, Jul 14, 2026 at 10:27:01AM +0100, Ahmed Tiba wrote:
> On 14/07/2026 03:45, Alison Schofield wrote:
> > On Wed, Jul 08, 2026 at 02:59:05PM +0100, Ahmed Tiba wrote:
> > > Move the CXL CPER handling paths out of ghes.c and into ghes_cper.c so the
> > > helpers can be reused. The code is moved as-is, with the public
> > > prototypes updated so GHES keeps calling into the new translation unit.
> > >
> > > While moving this code, also add CXL CPER section length checks and use
> > > spinlock_irqsave() in CXL register/unregister paths for locking
> > > consistency.
> >
> > NAK on moving and changing in the same patch, and esp in a patch
> > whose subject only says MOVE.
> Hi Alison,
>
> I understand the concern.
>
> I kept those changes in 06/10 because they address pre-existing issues
> reported specifically against this patch by Sashiko, and I wanted to avoid
> carrying known defects forward in the series. I did this following Boris'
> feedback to address review-reported issues in-series rather than carry them
> forward unchanged.
>
> I can also add a dedicated "Sashiko findings addressed" section and update
> the commit description to state clearly that this patch is not pure move.
>
> Please advise your preferred way to address Sashiko findings per patch in
> this series.
I think you can address the Sashiko pre-exists in series without
them being hidden in a move patch.
To be strictly like Boris seems to be asking (fixes first), do:
add CXL CPER section length checks
use spinlock_irqsave() in CXL (un-)register paths
move CXL CPER helpers
-- Alison
>
> Thanks,
> Ahmed
^ permalink raw reply
* Re: [PATCH net-next 9/9] net: document RFC6724 rule 5.5 implementation
From: Jonathan Corbet @ 2026-07-14 17:31 UTC (permalink / raw)
To: David 'equinox' Lamparter; +Cc: netdev, linux-doc
In-Reply-To: <alZvBEPH86WqH56m@eidolon.nox.tf>
David 'equinox' Lamparter <equinox@diac24.net> writes:
> On Tue, Jul 14, 2026 at 07:01:13AM -0600, Jonathan Corbet wrote:
>> David 'equinox' Lamparter <equinox@diac24.net> writes:
>> > create mode 100644 Documentation/networking/ipv6-addrsel.rst
>>
>> You need to add this new document to the index.rst file or it won't be
>> part of the docs build...you should have seen a warning when you built
>> the docs.
>
> Indeed... I missed it between the other warnings. Downside of doing
> clean runs without a sphinx cache, sigh.
*Sigh* ... one of these years we'll clean up all those warnings, and
have them actually stay cleaned...
>> > +====================================
>> > +IPv6 source address selection trivia
>> > +====================================
>> > +
>> > +
>> > +RFC6724 rule 5.5 support
>> > +------------------------
>>
>> Please stick with the section markup guidelines in
>> Documentation/doc-guide/sphinx.rst.
>
> Oh, you mean I shouldn't skip the "Chapter" level?
>
> Now that you mention it, maybe I should include the file from ipv6.rst,
> and remove the document title entirely - it looks quite weird in the TOC
> with the direct reference from index.rst. (Or rather, I've made weird
> choices with the headings.) Does that sound good to you?
>
> (Or, I could just put the entire text into ipv6.rst...)
I would take that latter approach myself. But others may differ :)
>> > +RFC6724 rule 5.5 is a very short paragraph in a complex RFC that has turned
>> > +out quite tricky, but also immensely useful in multihoming scenarios. For
>> > +reference, it says:
>> > +
>> > +::
>>
>> You'll likely get more visually pleasing results if you just leave out
>> the "::" here; you don't need literal formatting.
>
> I did that because RFCs are historically shipped & cited monospaced, and
> that's direct from the RFC. My tendency is to keep it this way for
> "established convention" reasons, but I don't care that much - does
> anyone have stronger feelings?
You're writing the document, it's up to you in the end.
(But if you keep it that way, you can end the previous paragraph with
"it says::" and drop the separate "::" line).
Thanks,
jon
^ permalink raw reply
* Re: [PATCH RFC v2 5/9] leds: Add trigger_may_offload attribute
From: Rong Zhang @ 2026-07-14 17:23 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Lee Jones, Pavel Machek, Jonathan Corbet, Shuah Khan,
Benson Leung, Guenter Roeck, Marek Behún, Mark Pearson,
Derek J. Clark, Hans de Goede, Ilpo Järvinen, Ike Panhc,
Andrew Lunn, Jakub Kicinski, Vishnu Sankar, Vishnu Sankar,
linux-leds, netdev, linux-doc, linux-kernel, chrome-platform,
platform-driver-x86
In-Reply-To: <b36aa937-b100-4fa3-bbc9-631c4c39ba40@t-8ch.de>
Hi Thomas,
Thanks for reviewing the series!
On Mon, 2026-07-13 at 22:36 +0200, Thomas Weißschuh wrote:
> On 2026-06-18 00:47:59+0800, Rong Zhang wrote:
> > There are multiple triggers implementing hardware control. Only "netdev"
> > provides a custom attribute to determine if it's offloaded to hardware
> > (i.e., in hardware control). For other triggers, there is no obvious way
> > for userspace to determine the trigger state programmatically. Moreover,
> > userspace can't query if an LED device supports hardware control or
> > identifies these triggers.
> >
> > Add a new attribute "trigger_may_offload" to the LED core, so that
> > userspace can determine:
> >
> > - if the LED device supports hardware control (supported => visible)
> > - which trigger is the hardware control trigger selected by the LED
> > device
> > - if the trigger is selected ("<foo_trigger>")
> > - if the trigger is offloaded ("[foo_trigger]")
> >
> > Note: the documentation describes the attribute as "returning a list"
> > despite the LED core currently only supports one hardware control
> > trigger per LED device. This is intentional to make the attribute
> > extensible in the future without breaking userspace.
>
> Maybe also mention that the old 'offloaded' attribute is deprecated.
> However, does it really need to be deprecated?
Hmm, retaining the old one is indeed harmless.
I will leave the "offloaded" attribute as is, and add a short note to
the documentation of "trigger_may_offload" to briefly introduce the
relation between them.
>
> > Signed-off-by: Rong Zhang <i@rong.moe>
> > ---
> > .../ABI/obsolete/sysfs-class-led-trigger-netdev | 16 ++++++++
> > Documentation/ABI/testing/sysfs-class-led | 22 +++++++++++
> > .../ABI/testing/sysfs-class-led-trigger-netdev | 13 -------
> > Documentation/leds/leds-class.rst | 8 ++++
> > drivers/leds/led-class.c | 23 +++++++++++
> > drivers/leds/led-triggers.c | 45 ++++++++++++++++++++++
> > drivers/leds/leds.h | 2 +
> > drivers/leds/trigger/ledtrig-netdev.c | 2 +
> > 8 files changed, 118 insertions(+), 13 deletions(-)
> >
> > diff --git a/Documentation/ABI/obsolete/sysfs-class-led-trigger-netdev b/Documentation/ABI/obsolete/sysfs-class-led-trigger-netdev
> > new file mode 100644
> > index 000000000000..8d2fbfaf50c3
> > --- /dev/null
> > +++ b/Documentation/ABI/obsolete/sysfs-class-led-trigger-netdev
> > @@ -0,0 +1,16 @@
> > +What: /sys/class/leds/<led>/offloaded
> > +Date: June 2026
> > +KernelVersion: 7.3
> > +Contact: linux-leds@vger.kernel.org
> > +Description:
> > + Communicate whether the LED trigger modes are offloaded to
> > + hardware or whether software fallback is used.
> > +
> > + If 0, the LED is using software fallback to blink.
> > +
> > + If 1, the LED blinking in requested mode is offloaded to
> > + hardware.
> > +
> > + /sys/class/leds/<led>/trigger_may_offload provides a generic
> > + method to query the offloaded state of supported triggers,
> > + superseding this attribute.
> > diff --git a/Documentation/ABI/testing/sysfs-class-led b/Documentation/ABI/testing/sysfs-class-led
> > index 0313b82644f2..edd5a9a74dfd 100644
> > --- a/Documentation/ABI/testing/sysfs-class-led
> > +++ b/Documentation/ABI/testing/sysfs-class-led
> > @@ -78,6 +78,28 @@ Description:
> > (which would often be configured in the device tree for the
> > hardware).
> >
> > +What: /sys/class/leds/<led>/trigger_may_offload
> > +Date: June 2026
> > +KernelVersion: 7.3
> > +Contact: linux-leds@vger.kernel.org
> > +Description:
> > + Names and states of triggers that may be offloaded to hardware.
> > + Such triggers are also called "hw control trigger" in some
> > + context.
> > +
> > + Only exists when the LED supports trigger offload.
> > +
> > + Reading this file returns a list of triggers that are capable to
> > + be offloaded. The optional brackets around the trigger name
> > + indicate the state of the current trigger:
> > +
> > + - `foo_trigger`: the trigger is not selected.
> > + - `<foo_trigger>`: the trigger is selected, but falls back to
> > + software blink for some reason (e.g., incompatible trigger
> > + parameters)
> > + - `[foo_trigger]`: the trigger is selected and offloaded to
> > + hardware.
> > +
> > What: /sys/class/leds/<led>/inverted
> > Date: January 2011
> > KernelVersion: 2.6.38
> > diff --git a/Documentation/ABI/testing/sysfs-class-led-trigger-netdev b/Documentation/ABI/testing/sysfs-class-led-trigger-netdev
> > index ed46b37ab8a2..396d37a4b820 100644
> > --- a/Documentation/ABI/testing/sysfs-class-led-trigger-netdev
> > +++ b/Documentation/ABI/testing/sysfs-class-led-trigger-netdev
> > @@ -62,19 +62,6 @@ Description:
> > When offloaded is true, the blink interval is controlled by
> > hardware and won't reflect the value set in interval.
> >
> > -What: /sys/class/leds/<led>/offloaded
> > -Date: Jun 2023
> > -KernelVersion: 6.5
> > -Contact: linux-leds@vger.kernel.org
> > -Description:
> > - Communicate whether the LED trigger modes are offloaded to
> > - hardware or whether software fallback is used.
> > -
> > - If 0, the LED is using software fallback to blink.
> > -
> > - If 1, the LED blinking in requested mode is offloaded to
> > - hardware.
> > -
> > What: /sys/class/leds/<led>/link_10
> > Date: Jun 2023
> > KernelVersion: 6.5
> > diff --git a/Documentation/leds/leds-class.rst b/Documentation/leds/leds-class.rst
> > index 84665200a88d..41342ecb5f6b 100644
> > --- a/Documentation/leds/leds-class.rst
> > +++ b/Documentation/leds/leds-class.rst
> > @@ -179,6 +179,9 @@ ops and needs to declare specific support for the supported triggers.
> >
> > With hw control we refer to the LED driven by hardware.
> >
> > +A sysfs attribute `trigger_may_offload` is provided for userspace to
> > +query supported triggers and their states.
> > +
> > LED driver must define the following value to support hw control:
> >
> > - hw_control_trigger:
> > @@ -240,6 +243,11 @@ LED trigger must implement the following API to support hw control:
> > return a boolean indicating if the trigger is offloaded to
> > hardware.
> >
> > + If an LED driver specifies a hw control trigger but the
> > + latter doesn't implement this callback, a dev_err_once will
> > + be emitted and the LED trigger will be assumed to be not
> > + offloaded.
>
> Not sure if this needs to be documented.
> I would make this optional initally and enforce it after all the drivers
> have been changed in the series.
Makes sense. Will remove the paragraph and rearrange the series so that
the attribute is introduced first while driver implementations are added
later.
ACK on all remaining comments as well as those in other replies. And
thanks a lot for your tag for cros_ec ;-)
Thanks,
Rong
>
> > +
> > LED driver can activate additional modes by default to workaround the
> > impossibility of supporting each different mode on the supported trigger.
> > Examples are hardcoding the blink speed to a set interval, enable special
> > diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
> > index 9e14ae588f78..0ac80b93b8b5 100644
> > --- a/drivers/leds/led-class.c
> > +++ b/drivers/leds/led-class.c
> > @@ -90,8 +90,31 @@ static const struct bin_attribute *const led_trigger_bin_attrs[] = {
> > &bin_attr_trigger,
> > NULL,
> > };
> > +
> > +static DEVICE_ATTR(trigger_may_offload, 0444, led_trigger_may_offload_show, NULL);
>
> DEVICE_ATTR_RO()
>
> > +static struct attribute *led_trigger_attrs[] = {
> > + &dev_attr_trigger_may_offload.attr,
> > + NULL,
>
> No comma after the sentinel.
>
> > +};
> > +
> > +static umode_t led_trigger_is_visible(struct kobject *kobj,
> > + struct attribute *attr,
> > + int idx)
> > +{
> > + struct device *dev = kobj_to_dev(kobj);
> > + struct led_classdev *led_cdev = dev_get_drvdata(dev);
> > +
> > + if (attr == &dev_attr_trigger_may_offload.attr &&
> > + !led_cdev->hw_control_trigger)
>
> Can be a single line.
>
> > + return 0;
> > +
> > + return attr->mode;
> > +}
> > +
> > static const struct attribute_group led_trigger_group = {
> > .bin_attrs = led_trigger_bin_attrs,
> > + .attrs = led_trigger_attrs,
> > + .is_visible = led_trigger_is_visible,
> > };
> > #endif
> >
> > diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
> > index b1223218bda1..c43229d9c4c1 100644
> > --- a/drivers/leds/led-triggers.c
> > +++ b/drivers/leds/led-triggers.c
> > @@ -313,6 +313,51 @@ void led_trigger_set_default(struct led_classdev *led_cdev)
> > }
> > EXPORT_SYMBOL_GPL(led_trigger_set_default);
> >
> > +/*
> > + * Caller must ensure led_cdev->trigger_lock held,
>
> Use lockdep_assert_held() to document and validate locking invariants.
>
> > + * and led_cdev->trigger->name must match led_cdev->hw_control_trigger.
> > + */
> > +static bool led_trigger_get_offloaded(struct led_classdev *led_cdev)
> > +{
> > + if (likely(led_cdev->trigger->offloaded))
> > + return led_cdev->trigger->offloaded(led_cdev);
> > +
> > + dev_err_once(led_cdev->dev,
> > + "hw control trigger %s doesn't implement offloaded(), this is a bug\n",
> > + led_cdev->trigger->name);
> > + return false;
> > +}
> > +
> > +ssize_t led_trigger_may_offload_show(struct device *dev,
> > + struct device_attribute *attr, char *buf)
> > +{
> > + struct led_classdev *led_cdev = dev_get_drvdata(dev);
> > + bool hit, offloaded = false;
> > + struct led_trigger *trig;
> > + int len;
> > +
> > + mutex_lock(&led_cdev->led_access);
> > + down_read(&led_cdev->trigger_lock);
>
> guard()?
>
> > +
> > + trig = led_cdev->trigger;
> > +
> > + hit = trig && !strcmp(led_cdev->hw_control_trigger, trig->name);
> > + if (hit)
> > + offloaded = led_trigger_get_offloaded(led_cdev);
> > +
> > + /* [offloaded] <active_but_not_offloaded> inactive */
> > + len = sysfs_emit(buf, "%s%s%s\n",
> > + offloaded ? "[" : (hit ? "<" : ""),
> > + led_cdev->hw_control_trigger,
> > + offloaded ? "]" : (hit ? ">" : ""));
> > +
> > + up_read(&led_cdev->trigger_lock);
> > + mutex_unlock(&led_cdev->led_access);
> > +
> > + return len;
> > +}
> > +EXPORT_SYMBOL_GPL(led_trigger_may_offload_show);
> > +
> > /* LED Trigger Interface */
> >
> > int led_trigger_register(struct led_trigger *trig)
> > diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
> > index bee46651e068..9177e098989b 100644
> > --- a/drivers/leds/leds.h
> > +++ b/drivers/leds/leds.h
> > @@ -27,6 +27,8 @@ ssize_t led_trigger_read(struct file *filp, struct kobject *kobj,
> > ssize_t led_trigger_write(struct file *filp, struct kobject *kobj,
> > const struct bin_attribute *bin_attr, char *buf,
> > loff_t pos, size_t count);
> > +ssize_t led_trigger_may_offload_show(struct device *dev,
> > + struct device_attribute *attr, char *buf);
> >
> > extern struct rw_semaphore leds_list_lock;
> > extern struct list_head leds_list;
> > diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
> > index a26109ca4b1c..21f22eea4ab8 100644
> > --- a/drivers/leds/trigger/ledtrig-netdev.c
> > +++ b/drivers/leds/trigger/ledtrig-netdev.c
> > @@ -487,6 +487,8 @@ static ssize_t offloaded_show(struct device *dev,
> > {
> > struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
> >
> > + dev_warn_once(dev, "offloaded attribute has been deprecated, see trigger_may_offload.\n");
> > +
> > return sprintf(buf, "%d\n", trigger_data->hw_control);
> > }
> >
> >
> > --
> > 2.53.0
> >
^ permalink raw reply
* Re: [PATCH net-next 9/9] net: document RFC6724 rule 5.5 implementation
From: David 'equinox' Lamparter @ 2026-07-14 17:16 UTC (permalink / raw)
To: Jonathan Corbet; +Cc: netdev, linux-doc
In-Reply-To: <87zeztg1ye.fsf@trenco.lwn.net>
On Tue, Jul 14, 2026 at 07:01:13AM -0600, Jonathan Corbet wrote:
> David 'equinox' Lamparter <equinox@diac24.net> writes:
> > create mode 100644 Documentation/networking/ipv6-addrsel.rst
>
> You need to add this new document to the index.rst file or it won't be
> part of the docs build...you should have seen a warning when you built
> the docs.
Indeed... I missed it between the other warnings. Downside of doing
clean runs without a sphinx cache, sigh.
> > +====================================
> > +IPv6 source address selection trivia
> > +====================================
> > +
> > +
> > +RFC6724 rule 5.5 support
> > +------------------------
>
> Please stick with the section markup guidelines in
> Documentation/doc-guide/sphinx.rst.
Oh, you mean I shouldn't skip the "Chapter" level?
Now that you mention it, maybe I should include the file from ipv6.rst,
and remove the document title entirely - it looks quite weird in the TOC
with the direct reference from index.rst. (Or rather, I've made weird
choices with the headings.) Does that sound good to you?
(Or, I could just put the entire text into ipv6.rst...)
> > +RFC6724 rule 5.5 is a very short paragraph in a complex RFC that has turned
> > +out quite tricky, but also immensely useful in multihoming scenarios. For
> > +reference, it says:
> > +
> > +::
>
> You'll likely get more visually pleasing results if you just leave out
> the "::" here; you don't need literal formatting.
I did that because RFCs are historically shipped & cited monospaced, and
that's direct from the RFC. My tendency is to keep it this way for
"established convention" reasons, but I don't care that much - does
anyone have stronger feelings?
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index f3218abefd0c..4edf48362a07 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -18912,6 +18912,7 @@ F: Documentation/netlink/specs/rt-addr.yaml
> > F: Documentation/netlink/specs/rt-neigh.yaml
> > F: Documentation/netlink/specs/rt-route.yaml
> > F: Documentation/netlink/specs/rt-rule.yaml
> > +F: Documentation/networking/ipv6-addrsel.rst
>
> It seems weird to add this one file here - I wonder why there isn't just
> an entry for Documentation/networking ?
There is, the difference is "NETWORKING [GENERAL]" vs "NETWORKING
[IPv4/IPv6]". I wasn't sure how much this matters & decided to err on
the side of caution (and also because checkpatch complained.) I'll go
drop the line.
Thanks,
-equi
^ permalink raw reply
* Re: [PATCH net v3] tun/tap & vhost-net: make qdisc backpressure opt-in via IFF_BACKPRESSURE
From: Simon Schippers @ 2026-07-14 16:50 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Willem de Bruijn, Jason Wang, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, netdev, Simon Horman,
Jonathan Corbet, Shuah Khan, Andrew Lunn, Tim Gebauer,
Brett Sheffield, linux-doc, linux-kernel
In-Reply-To: <20260714092506-mutt-send-email-mst@kernel.org>
On 7/14/26 15:40, Michael S. Tsirkin wrote:
> On Thu, Jul 09, 2026 at 11:55:11AM +0200, Simon Schippers wrote:
>> Commit 1d6e569b7d0c ("tun/tap & vhost-net: avoid ptr_ring tail-drop
>> when a qdisc is present") did not show a relevant performance regression
>> in my testing but on Brett Sheffield's librecast testbed it shows a
>> significant performance drop in a IPv6 multicast testcase. The regression
>> can be pinpointed when multiple iperf3 TCP threads are sending. For 8
>> threads the performance dropped from 13.5 Gbit/s to 9.13 Gbit/s. This is
>> the reason why this patch makes the qdisc backpressure behavior opt-in.
>>
>> One option to accomplish the opt-in would be to set the default qdisc to
>> noqueue at init. However this may also break userspace as users might
>> have chosen a custom qdisc even though most of the qdiscs did nothing
>> for tun/tap in the past due to missing backpressure...
>>
>> This is the reason why in this patch, the flag IFF_BACKPRESSURE is
>> introduced instead which is required to enable the backpressure logic.
>> This means the stopping logic in tun_net_xmit() and the waking logic in
>> __tun_wake_queue() are skipped if the flag is disabled. Setting
>> IFF_BACKPRESSURE makes an attached qdisc effective by stopping the queue
>> instead of tail-dropping when the internal ring is full.
>>
>> To avoid a possible stall due to disabling IFF_BACKPRESSURE, the new
>> helper tun_force_wake_queue() is implemented. The helper safely wakes the
>> respective netdev queue and resets cons_cnt while the consumer_lock and
>> the producer_lock of the ring are held. The helper is run in tun_attach()
>> when a queue (re)attaches, in tun_set_iff() for attached tfiles, and
>> in tun_queue_resize().
>>
>> The documentation in tuntap.rst is updated accordingly.
>>
>> Fixes: 1d6e569b7d0c ("tun/tap & vhost-net: avoid ptr_ring tail-drop when a qdisc is present")
>> Reported-by: Brett Sheffield <brett@librecast.net>
>> Closes: https://lore.kernel.org/netdev/akVnoOYQOrt8k-Gu@karahi.librecast.net/T/#u
>> Signed-off-by: Simon Schippers <simon.schippers@tu-dortmund.de>
>
>
> The patch itself is fine:
>
> Acked-by: Michael S. Tsirkin <mst@redhat.com>
>
> What bothers me is the timing: we
> are past freeze and this new interface hasn't been tested
> much.
>
> We can either apply this, or revert the original patch for now
> and reapply with this for next.
I prefer applying it, but you maintainers must decide that.
>
>> ---
>> V2 -> V3:
>> - As suggested by MST: Clarify in tuntap.rst and the UAPI header what
>> enabling IFF_BACKPRESSURE opts into: an attached qdisc becomes effective
>> instead of the driver tail-dropping when the internal ring is full.
>> - Avoid lines over 75 characters.
>> - Update comment in tun_net_xmit() to include IFF_BACKPRESSURE.
>> - Brett: Update in commit message that the referenced tests were TCP.
>>
>> V1 -> V2:
>> - Sashiko: Ensure detached queues are woken on re-attach by calling the
>> new tun_force_wake_queue() helper from tun_attach(), and reuse it
>> across the existing wake paths.
>> - Specify the failing test case in the commit message.
>>
>> V1: https://lore.kernel.org/netdev/20260704112058.95421-1-simon.schippers@tu-dortmund.de/T/#u
>> V2: https://lore.kernel.org/netdev/20260706094242.115992-1-simon.schippers@tu-dortmund.de/T/#u
>>
>> Documentation/networking/tuntap.rst | 22 +++++++++++++
>> drivers/net/tun.c | 51 ++++++++++++++++++++---------
>> include/uapi/linux/if_tun.h | 4 +++
>> tools/include/uapi/linux/if_tun.h | 1 +
>> 4 files changed, 62 insertions(+), 16 deletions(-)
>>
>> diff --git a/Documentation/networking/tuntap.rst b/Documentation/networking/tuntap.rst
>> index 4d7087f727be..5921a924c2ae 100644
>> --- a/Documentation/networking/tuntap.rst
>> +++ b/Documentation/networking/tuntap.rst
>> @@ -206,6 +206,28 @@ enable is true we enable it, otherwise we disable it::
>> return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
>> }
>>
>> +3.4 qdisc backpressure
>> +----------------------
>> +
>> +Starting with Linux 7.2, IFF_BACKPRESSURE can be set to enable qdisc
>> +backpressure. Without it, TX drops occur when the internal ring buffer
>> +is full, so any attached qdisc is effectively bypassed and applications
>> +only learn about congestion through those drops.
>> +
>> +With it, the kernel stops instead, letting the qdisc hold and schedule
>> +packets, so its AQM, shaping and fairness actually apply. This helps
>> +protocols like TCP, which cut throughput in reaction to packet drops.
>> +With IFF_BACKPRESSURE, drops then only occur as a rare race. Backpressure
>> +requires a qdisc to be attached and has no effect with noqueue.
>> +
>> +The txqueuelen can be reduced alongside this flag to further shift
>> +buffering into the qdisc and reduce bufferbloat, but comes at possible
>> +performance cost.
>> +
>> +When running multiple network streams in parallel through a single
>> +TUN/TAP queue, the flag may reduce performance due to the extra overhead
>> +of the backpressure mechanism.
>> +
>> Universal TUN/TAP device driver Frequently Asked Question
>> =========================================================
>>
>> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
>> index ffbe6f13fb1f..5941e8f302ea 100644
>> --- a/drivers/net/tun.c
>> +++ b/drivers/net/tun.c
>> @@ -98,7 +98,8 @@ static void tun_default_link_ksettings(struct net_device *dev,
>> #define TUN_FASYNC IFF_ATTACH_QUEUE
>>
>> #define TUN_FEATURES (IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR | \
>> - IFF_MULTI_QUEUE | IFF_NAPI | IFF_NAPI_FRAGS)
>> + IFF_MULTI_QUEUE | IFF_NAPI | IFF_NAPI_FRAGS | \
>> + IFF_BACKPRESSURE)
>>
>> #define GOODCOPY_LEN 128
>>
>> @@ -694,6 +695,20 @@ static void tun_detach_all(struct net_device *dev)
>> module_put(THIS_MODULE);
>> }
>>
>> +static void tun_force_wake_queue(struct tun_struct *tun,
>> + struct tun_file *tfile)
>> +{
>> + /* Ensure that the producer can not stop the
>> + * queue concurrently by taking locks.
>> + */
>> + spin_lock_bh(&tfile->tx_ring.consumer_lock);
>> + spin_lock(&tfile->tx_ring.producer_lock);
>> + netif_wake_subqueue(tun->dev, tfile->queue_index);
>> + tfile->cons_cnt = 0;
>> + spin_unlock(&tfile->tx_ring.producer_lock);
>> + spin_unlock_bh(&tfile->tx_ring.consumer_lock);
>> +}
>> +
>> static int tun_attach(struct tun_struct *tun, struct file *file,
>> bool skip_filter, bool napi, bool napi_frags,
>> bool publish_tun)
>> @@ -737,11 +752,9 @@ static int tun_attach(struct tun_struct *tun, struct file *file,
>> goto out;
>> }
>>
>> - spin_lock(&tfile->tx_ring.consumer_lock);
>> - tfile->cons_cnt = 0;
>> - spin_unlock(&tfile->tx_ring.consumer_lock);
>> tfile->queue_index = tun->numqueues;
>> tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN;
>> + tun_force_wake_queue(tun, tfile);
>>
>> if (tfile->detached) {
>> /* Re-attach detached tfile, updating XDP queue_index */
>> @@ -1077,7 +1090,8 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
>>
>> spin_lock(&tfile->tx_ring.producer_lock);
>> ret = __ptr_ring_produce(&tfile->tx_ring, skb);
>> - if (!qdisc_txq_has_no_queue(queue) &&
>> + if ((tun->flags & IFF_BACKPRESSURE) &&
>> + !qdisc_txq_has_no_queue(queue) &&
>> __ptr_ring_check_produce(&tfile->tx_ring) == -ENOSPC) {
>> netif_tx_stop_queue(queue);
>> /* Paired with smp_mb() in __tun_wake_queue() */
>> @@ -1088,8 +1102,8 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
>> spin_unlock(&tfile->tx_ring.producer_lock);
>>
>> if (ret) {
>> - /* This should be a rare case if a qdisc is present, but
>> - * can happen due to lltx.
>> + /* This should be a rare case if IFF_BACKPRESSURE is enabled and
>> + * a qdisc is present, but can happen due to lltx.
>> * Since skb_tx_timestamp(), skb_orphan(),
>> * run_ebpf_filter() and pskb_trim() could have tinkered
>> * with the SKB, returning NETDEV_TX_BUSY is unsafe and
>> @@ -2151,8 +2165,12 @@ static ssize_t tun_put_user(struct tun_struct *tun,
>> static void __tun_wake_queue(struct tun_struct *tun,
>> struct tun_file *tfile, int consumed)
>> {
>> - struct netdev_queue *txq = netdev_get_tx_queue(tun->dev,
>> - tfile->queue_index);
>> + struct netdev_queue *txq;
>> +
>> + if (!(tun->flags & IFF_BACKPRESSURE))
>> + return;
>> +
>> + txq = netdev_get_tx_queue(tun->dev, tfile->queue_index);
>>
>> /* Paired with smp_mb__after_atomic() in tun_net_xmit() */
>> smp_mb();
>> @@ -2764,7 +2782,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
>> struct tun_struct *tun;
>> struct tun_file *tfile = file->private_data;
>> struct net_device *dev;
>> - int err;
>> + int err, i;
>>
>> if (tfile->detached)
>> return -EINVAL;
>> @@ -2893,8 +2911,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
>> /* Make sure persistent devices do not get stuck in
>> * xoff state.
>> */
>> - if (netif_running(tun->dev))
>> - netif_tx_wake_all_queues(tun->dev);
>> + if (netif_running(tun->dev)) {
>> + for (i = 0; i < tun->numqueues; i++) {
>> + tfile = rtnl_dereference(tun->tfiles[i]);
>> + tun_force_wake_queue(tun, tfile);
>> + }
>> + }
>>
>> strscpy(ifr->ifr_name, tun->dev->name);
>> return 0;
>> @@ -3693,10 +3715,7 @@ static int tun_queue_resize(struct tun_struct *tun)
>> if (!ret) {
>> for (i = 0; i < tun->numqueues; i++) {
>> tfile = rtnl_dereference(tun->tfiles[i]);
>> - spin_lock(&tfile->tx_ring.consumer_lock);
>> - netif_wake_subqueue(tun->dev, tfile->queue_index);
>> - tfile->cons_cnt = 0;
>> - spin_unlock(&tfile->tx_ring.consumer_lock);
>> + tun_force_wake_queue(tun, tfile);
>> }
>> }
>>
>> diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h
>> index 79d53c7a1ebd..a0ddc50a7534 100644
>> --- a/include/uapi/linux/if_tun.h
>> +++ b/include/uapi/linux/if_tun.h
>> @@ -69,6 +69,10 @@
>> #define IFF_NAPI_FRAGS 0x0020
>> /* Used in TUNSETIFF to bring up tun/tap without carrier */
>> #define IFF_NO_CARRIER 0x0040
>> +/* Stop the queue instead of dropping when the internal ring is full, so an
>> + * attached qdisc applies backpressure instead of being bypassed.
>> + */
>> +#define IFF_BACKPRESSURE 0x0080
>> #define IFF_NO_PI 0x1000
>> /* This flag has no real effect */
>> #define IFF_ONE_QUEUE 0x2000
>> diff --git a/tools/include/uapi/linux/if_tun.h b/tools/include/uapi/linux/if_tun.h
>> index 2ec07de1d73b..97b670f5bc0a 100644
>> --- a/tools/include/uapi/linux/if_tun.h
>> +++ b/tools/include/uapi/linux/if_tun.h
>> @@ -67,6 +67,7 @@
>> #define IFF_TAP 0x0002
>> #define IFF_NAPI 0x0010
>> #define IFF_NAPI_FRAGS 0x0020
>> +#define IFF_BACKPRESSURE 0x0080
>> #define IFF_NO_PI 0x1000
>> /* This flag has no real effect */
>> #define IFF_ONE_QUEUE 0x2000
>> --
>> 2.43.0
>
^ permalink raw reply
* Re: [PATCH 1/2] mm/zswap: Fix global shrinker when memory cgroup is disabled
From: Yosry Ahmed @ 2026-07-14 16:52 UTC (permalink / raw)
To: Hao Jia, akpm
Cc: tj, hannes, shakeel.butt, mhocko, mkoutny, nphamcs,
chengming.zhou, muchun.song, roman.gushchin, linux-mm,
linux-kernel, linux-doc, Hao Jia, stable
In-Reply-To: <20260714081510.16895-2-jiahao.kernel@gmail.com>
On Tue, Jul 14, 2026 at 1:15 AM Hao Jia <jiahao.kernel@gmail.com> wrote:
>
> From: Hao Jia <jiahao1@lixiang.com>
>
> When memory cgroup is disabled, mem_cgroup_iter() always returns NULL.
> Therefore, the global shrinker shrink_worker() always takes the !memcg
> branch. After MAX_RECLAIM_RETRIES empty walks, the worker simply gives up,
> so it fails to write back anything.
>
> Therefore, when memory cgroup is disabled, fall through with the !memcg
> branch and shrink the root memcg directly.
>
> With memcg disabled, shrink_memcg() only returns -ENOENT when the root
> LRU is empty, which means the total pages are already below thr. The
> loop then safely bails out via the zswap_total_pages() <= thr check.
> For any other return value from shrink_memcg(), the loop is guaranteed
> to terminate, either after MAX_RECLAIM_RETRIES failures or once the
> threshold is met.
>
> Fixes: a65b0e7607cc ("zswap: make shrinking memcg-aware")
> Cc: stable@vger.kernel.org
> Suggested-by: Nhat Pham <nphamcs@gmail.com>
> Acked-by: Nhat Pham <nphamcs@gmail.com>
> Acked-by: Yosry Ahmed <yosry@kernel.org>
> Reported-by: Yosry Ahmed <yosry@kernel.org>
> Closes: https://lore.kernel.org/all/CAO9r8zPVzMKFbCixxD-qgtRrkFxWVrHiZZeLc=eyTPKPVQgX4g@mail.gmail.com
> Signed-off-by: Hao Jia <jiahao1@lixiang.com>
Patch 2 doesn't really depend on this one, right?
If that's the case I think this can (and should be) picked up
separately as a hotfix. Andrew, WDYT?
> ---
> mm/zswap.c | 11 ++++++-----
> 1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/mm/zswap.c b/mm/zswap.c
> index b5a17ea20237..3d697a1a5365 100644
> --- a/mm/zswap.c
> +++ b/mm/zswap.c
> @@ -1356,11 +1356,12 @@ static void shrink_worker(struct work_struct *w)
> } while (memcg && !mem_cgroup_tryget_online(memcg));
> spin_unlock(&zswap_shrink_lock);
>
> - if (!memcg) {
> - /*
> - * Continue shrinking without incrementing failures if
> - * we found candidate memcgs in the last tree walk.
> - */
> + /*
> + * A NULL memcg ends a full hierarchy pass (except when memcg is
> + * disabled, where it is always NULL: fall through to the root LRU).
> + * Count a failure only if the last pass found no candidates.
> + */
> + if (!memcg && !mem_cgroup_disabled()) {
> if (!attempts && ++failures == MAX_RECLAIM_RETRIES)
> break;
>
> --
> 2.34.1
>
^ permalink raw reply
* Re: [PATCH 2/2] mm/zswap: Support batch writeback in shrink_memcg()
From: Yosry Ahmed @ 2026-07-14 16:52 UTC (permalink / raw)
To: Hao Jia
Cc: akpm, tj, hannes, shakeel.butt, mhocko, mkoutny, nphamcs,
chengming.zhou, muchun.song, roman.gushchin, linux-mm,
linux-kernel, linux-doc, Hao Jia
In-Reply-To: <20260714081510.16895-3-jiahao.kernel@gmail.com>
On Tue, Jul 14, 2026 at 1:15 AM Hao Jia <jiahao.kernel@gmail.com> wrote:
>
> From: Hao Jia <jiahao1@lixiang.com>
>
> Currently, shrink_memcg() writes back at most one entry per-node during
> its traversal. This makes shrink_worker() inefficient, as it must
> repeatedly re-enter shrink_memcg() to make any substantial progress.
Please also mention the case about writeback being slow to keep up
with refaults in some cases, leading to zswap store failures and pages
skipping zswap and going directly to disk, which is an LRU inversion.
>
> To address this, extend shrink_memcg() and rewrite its LRU iteration logic
> to support batch writeback. Introduce the nr_to_scan parameter to bound how
> many pages are scanned per call. This enables batch writeback in the
> shrink_worker() path, while maintaining a low scan budget in the
> zswap_store() path.
>
> Additionally, to prepare for future proactive writeback, update the return
> value semantics of shrink_memcg(): a positive value now represents the
> actual number of compressed bytes written back, 0 indicates that candidates
> existed but no writeback succeeded, and a negative value represents an
> error code.
This part should be dropped for now, and added with the proactive
writeback, as it's currently unused AFAICT. Removing
zswap_shrink_walk_arg will simplify the patch and make it focused on
the batching part.
>
> Test Setup:
> Total memory: 32 GB.
> zswap settings: max_pool_percent=1, accept_threshold_percent=50,
> shrinker_enabled=N.
> Allocate 512MB of anonymous pages and fill them with random data (to avoid
> compression), then use cgroup memory.reclaim to force a large amount of
> anonymous pages into zswap. At an interval of 2ms, allocate a 4K anonymous
> page where the first 4 bytes are random numbers and the rest are zeros, and
> then trigger a reclamation of this 4K anonymous page through cgroup
> memory.reclaim. When the pool threshold is reached, shrink_memcg() will
> be triggered.
>
> The test data after running for 120s is as follows:
> Baseline Patched
> shrink_worker wakeups 5363 85
> shrink_memcg calls 11,345,012 188,264
> written_back 40214 40275
>
> Conclusion:
> Under the same workload and run duration, the patched kernel shows a
> significant reduction in both shrink_worker wakeups and shrink_memcg calls.
Please also include data from the case where zswap store failures are
observed and pages go to disk, and compare before and after this
patch. I think that part is also really important.
>
> Suggested-by: Yosry Ahmed <yosry@kernel.org>
> Signed-off-by: Hao Jia <jiahao1@lixiang.com>
> ---
> mm/zswap.c | 89 ++++++++++++++++++++++++++++++++++++++++++------------
> 1 file changed, 69 insertions(+), 20 deletions(-)
>
> diff --git a/mm/zswap.c b/mm/zswap.c
> index 3d697a1a5365..6d492762957a 100644
> --- a/mm/zswap.c
> +++ b/mm/zswap.c
> @@ -160,6 +160,11 @@ struct zswap_pool {
> char tfm_name[CRYPTO_MAX_ALG_NAME];
> };
>
> +struct zswap_shrink_walk_arg {
> + unsigned long bytes_written;
> + bool encountered_page_in_swapcache;
> +};
> +
> /* Global LRU lists shared by all zswap pools. */
> static struct list_lru zswap_list_lru;
>
> @@ -1089,8 +1094,9 @@ static enum lru_status shrink_memcg_cb(struct list_head *item, struct list_lru_o
> void *arg)
> {
> struct zswap_entry *entry = container_of(item, struct zswap_entry, lru);
> - bool *encountered_page_in_swapcache = (bool *)arg;
> + struct zswap_shrink_walk_arg *walk_arg = arg;
> swp_entry_t swpentry;
> + unsigned int length;
> enum lru_status ret = LRU_REMOVED_RETRY;
> int writeback_result;
>
> @@ -1133,10 +1139,11 @@ static enum lru_status shrink_memcg_cb(struct list_head *item, struct list_lru_o
>
> /*
> * Once the lru lock is dropped, the entry might get freed. The
> - * swpentry is copied to the stack, and entry isn't deref'd again
> - * until the entry is verified to still be alive in the tree.
> + * needed fields are copied to the stack, and entry isn't deref'd
> + * again until it is verified to still be alive in the tree.
> */
> swpentry = entry->swpentry;
> + length = entry->length;
>
> /*
> * It's safe to drop the lock here because we return either
> @@ -1155,12 +1162,13 @@ static enum lru_status shrink_memcg_cb(struct list_head *item, struct list_lru_o
> * into the warmer region. We should terminate shrinking (if we're in the dynamic
> * shrinker context).
> */
> - if (writeback_result == -EEXIST && encountered_page_in_swapcache) {
> + if (writeback_result == -EEXIST) {
> ret = LRU_STOP;
> - *encountered_page_in_swapcache = true;
> + walk_arg->encountered_page_in_swapcache = true;
> }
> } else {
> zswap_written_back_pages++;
> + walk_arg->bytes_written += length;
> }
>
> return ret;
> @@ -1169,8 +1177,11 @@ static enum lru_status shrink_memcg_cb(struct list_head *item, struct list_lru_o
> static unsigned long zswap_shrinker_scan(struct shrinker *shrinker,
> struct shrink_control *sc)
> {
> + struct zswap_shrink_walk_arg walk_arg = {
> + .bytes_written = 0,
> + .encountered_page_in_swapcache = false,
> + };
> unsigned long shrink_ret;
> - bool encountered_page_in_swapcache = false;
>
> if (!zswap_shrinker_enabled ||
> !mem_cgroup_zswap_writeback_enabled(sc->memcg)) {
> @@ -1179,9 +1190,9 @@ static unsigned long zswap_shrinker_scan(struct shrinker *shrinker,
> }
>
> shrink_ret = list_lru_shrink_walk(&zswap_list_lru, sc, &shrink_memcg_cb,
> - &encountered_page_in_swapcache);
> + &walk_arg);
>
> - if (encountered_page_in_swapcache)
> + if (walk_arg.encountered_page_in_swapcache)
> return SHRINK_STOP;
>
> return shrink_ret ? shrink_ret : SHRINK_STOP;
> @@ -1275,9 +1286,31 @@ static struct shrinker *zswap_alloc_shrinker(void)
> return shrinker;
> }
>
> -static int shrink_memcg(struct mem_cgroup *memcg)
> +#define NR_ZSWAP_WB_BATCH 64UL
> +
> +/*
> + * Scan up to @nr_to_scan pages across the per-node zswap LRUs of @memcg
> + * and write back the reclaimable ones.
> + *
> + * Since the second-chance algorithm rotates referenced entries to the
> + * LRU tail, the per-node scan is capped at the current LRU length so
> + * each entry is scanned at most once per call. It is up to the caller
> + * to handle retries, deciding whether to scan another memcg to complete
> + * the full iteration, or to rescan the current memcg to drain its zswap
> + * entries.
> + *
> + * Return: The number of compressed bytes written back (>= 0), or -ENOENT
> + * if @memcg has writeback disabled, is a zombie cgroup, or has empty
> + * zswap LRUs.
> + */
> +static long shrink_memcg(struct mem_cgroup *memcg, unsigned long nr_to_scan)
> {
> - int nid, shrunk = 0, scanned = 0;
> + struct zswap_shrink_walk_arg walk_arg = {
> + .bytes_written = 0,
> + .encountered_page_in_swapcache = false,
> + };
> + unsigned long nr_remaining = nr_to_scan;
> + int nid;
>
> if (!mem_cgroup_zswap_writeback_enabled(memcg))
> return -ENOENT;
> @@ -1290,24 +1323,40 @@ static int shrink_memcg(struct mem_cgroup *memcg)
> return -ENOENT;
>
> for_each_node_state(nid, N_NORMAL_MEMORY) {
> - unsigned long nr_to_walk = 1;
> + unsigned long nr_to_walk;
>
> - shrunk += list_lru_walk_one(&zswap_list_lru, nid, memcg,
> - &shrink_memcg_cb, NULL, &nr_to_walk);
> - scanned += 1 - nr_to_walk;
> + /*
> + * Cap the scan at per-node LRU length so each entry is scanned
> + * at most once per call.
> + */
> + nr_to_walk = min(nr_remaining,
> + list_lru_count_one(&zswap_list_lru, nid, memcg));
> + if (!nr_to_walk)
> + continue;
> +
> + nr_remaining -= nr_to_walk;
> + list_lru_walk_one(&zswap_list_lru, nid, memcg, &shrink_memcg_cb,
> + &walk_arg, &nr_to_walk);
> + /* Return the unused share of the budget to the pool. */
> + nr_remaining += nr_to_walk;
> +
> + if (!nr_remaining)
> + break;
> }
>
> - if (!scanned)
> + /* Nothing was scanned: every LRU under @memcg was empty. */
> + if (nr_remaining == nr_to_scan)
> return -ENOENT;
>
> - return shrunk ? 0 : -EAGAIN;
> + return walk_arg.bytes_written;
> }
>
> static void shrink_worker(struct work_struct *w)
> {
> struct mem_cgroup *memcg;
> - int ret, failures = 0, attempts = 0;
> + int failures = 0, attempts = 0;
> unsigned long thr;
> + long ret;
>
> /* Reclaim down to the accept threshold */
> thr = zswap_accept_thr_pages();
> @@ -1369,7 +1418,7 @@ static void shrink_worker(struct work_struct *w)
> goto resched;
> }
>
> - ret = shrink_memcg(memcg);
> + ret = shrink_memcg(memcg, NR_ZSWAP_WB_BATCH);
> /* drop the extra reference */
> mem_cgroup_put(memcg);
>
> @@ -1383,7 +1432,7 @@ static void shrink_worker(struct work_struct *w)
> continue;
> ++attempts;
>
> - if (ret && ++failures == MAX_RECLAIM_RETRIES)
> + if (ret <= 0 && ++failures == MAX_RECLAIM_RETRIES)
> break;
> resched:
> cond_resched();
> @@ -1493,7 +1542,7 @@ bool zswap_store(struct folio *folio)
> objcg = get_obj_cgroup_from_folio(folio);
> if (objcg && !obj_cgroup_may_zswap(objcg)) {
> memcg = get_mem_cgroup_from_objcg(objcg);
> - if (shrink_memcg(memcg)) {
> + if (shrink_memcg(memcg, 1) <= 0) {
> mem_cgroup_put(memcg);
> goto put_objcg;
> }
> --
> 2.34.1
>
^ permalink raw reply
* Re: [PATCH v14 1/5] docs: driver-api: gpio: rpmsg gpio driver over rpmsg bus
From: Mathieu Poirier @ 2026-07-14 16:35 UTC (permalink / raw)
To: Shenwei Wang (OSS)
Cc: Linus Walleij, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Frank Li,
Sascha Hauer, Shuah Khan, linux-gpio@vger.kernel.org,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
Pengutronix Kernel Team, Fabio Estevam, Shenwei Wang, Peng Fan,
devicetree@vger.kernel.org, linux-remoteproc@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
dl-linux-imx, Arnaud POULIQUEN, b-padhi@ti.com, Andrew Lunn
In-Reply-To: <PAXPR04MB91852808D2C7491AEF98CF1589F92@PAXPR04MB9185.eurprd04.prod.outlook.com>
On Tue, Jul 14, 2026 at 02:29:12PM +0000, Shenwei Wang (OSS) wrote:
>
>
> > -----Original Message-----
> > From: Mathieu Poirier <mathieu.poirier@linaro.org>
> > Sent: Monday, July 13, 2026 12:17 PM
> > To: Shenwei Wang (OSS) <shenwei.wang@oss.nxp.com>
> > Cc: Linus Walleij <linusw@kernel.org>; Bartosz Golaszewski <brgl@kernel.org>;
> > Jonathan Corbet <corbet@lwn.net>; Rob Herring <robh@kernel.org>; Krzysztof
> > Kozlowski <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Bjorn
> > Andersson <andersson@kernel.org>; Frank Li <frank.li@nxp.com>; Sascha Hauer
> > <s.hauer@pengutronix.de>; Shuah Khan <skhan@linuxfoundation.org>; linux-
> > gpio@vger.kernel.org; linux-doc@vger.kernel.org; linux-kernel@vger.kernel.org;
> > Pengutronix Kernel Team <kernel@pengutronix.de>; Fabio Estevam
> > <festevam@gmail.com>; Shenwei Wang <shenwei.wang@nxp.com>; Peng Fan
> > <peng.fan@nxp.com>; devicetree@vger.kernel.org; linux-
> > remoteproc@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> > kernel@lists.infradead.org; dl-linux-imx <linux-imx@nxp.com>; Arnaud
> > POULIQUEN <arnaud.pouliquen@foss.st.com>; b-padhi@ti.com; Andrew Lunn
> > <andrew@lunn.ch>
> > Subject: Re: [PATCH v14 1/5] docs: driver-api: gpio: rpmsg gpio driver over rpmsg
> > bus
> >
> > On Thu, Jun 25, 2026 at 10:54:26AM -0500, Shenwei Wang wrote:
> > > From: Shenwei Wang <shenwei.wang@nxp.com>
> > >
> > > Describes the gpio rpmsg transport protocol over the rpmsg bus between
> > > the remote system and Linux.
> > >
> > > Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
> > > ---
> > > Documentation/driver-api/gpio/gpio-rpmsg.rst | 271 +++++++++++++++++++
> > > Documentation/driver-api/gpio/index.rst | 1 +
> > > 2 files changed, 272 insertions(+)
> > > create mode 100644 Documentation/driver-api/gpio/gpio-rpmsg.rst
> > >
> > > diff --git a/Documentation/driver-api/gpio/gpio-rpmsg.rst
> > > b/Documentation/driver-api/gpio/gpio-rpmsg.rst
> > > new file mode 100644
> > > index 000000000000..7d351ff0adb0
> > > --- /dev/null
> > > +++ b/Documentation/driver-api/gpio/gpio-rpmsg.rst
> > > @@ -0,0 +1,271 @@
> > > +.. SPDX-License-Identifier: GPL-2.0-or-later
> > > +
> > > +GPIO RPMSG (Remote Processor Messaging) Protocol
> > > +================================================
> > > +
> > > +The GPIO RPMSG transport protocol is used for communication and
> > > +interaction with GPIO controllers on remote processors via the RPMSG bus.
> > > +
> > > +Message Format
> > > +--------------
> > > +
> > > +The RPMSG message consists of a 8-byte packet with the following layout:
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+------+------+------+------+------+------+------+
> > > + | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
> > > + | cmd | line | value |
> > > + +------+------+------+------+------+------+------+------+
> > > +
> > > +- **cmd**: Command code, used for GPIO_RPMSG_SEND messages.
> > > +
> > > +- **line**: The GPIO line (pin) index of the port.
> >
> > Here and throughout, please remove any mention of 'port'. This is handled by the
> > endpoint device, i.e one GPIO controller (port) per endpoint.
> >
> > > +
> > > +- **value**: See details in the command description below.
> > > +
> > > +
> > > +GPIO Commands
> > > +-------------
> > > +
> > > +Commands are specified in the **Cmd** field.
> > > +
> > > +The SEND message is always sent from Linux to the remote firmware.
> > > +Each SEND corresponds to a single REPLY message. The GPIO driver
> > > +should serialize messages and determine whether a REPLY message is
> > > +required. If a REPLY message is expected but not received within the
> > > +specified timeout period (currently 1 second in the Linux driver),
> > > +the driver should return -ETIMEOUT.
> > > +
> > > +GET_DIRECTION (Cmd=2)
> > > +~~~~~~~~~~~~~~~~~~~~~
> > > +
> > > +**Request:**
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+------+------+------+------+------+------+------+
> > > + | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
> > > + | 2 | line | 0 |
> > > + +------+------+------+------+------+------+------+------+
> > > +
> > > +**Reply:**
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+--------+--------+
> > > + | 0x00 | 0x01 | 0x02 |
> > > + | 1 | status | value |
> > > + +------+--------+--------+
> > > +
> > > +- **status**:
> > > +
> > > + - 0: Ok
> > > + - 1: Error
> > > +
> > > +- **value**: Direction.
> > > +
> > > + - 0: None
> > > + - 1: Output
> > > + - 2: Input
> > > +
> > > +
> > > +SET_DIRECTION (Cmd=3)
> > > +~~~~~~~~~~~~~~~~~~~~~
> > > +
> > > +**Request:**
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+------+------+------+------+------+------+------+
> > > + | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
> > > + | 3 | line | value |
> > > + +------+------+------+------+------+------+------+------+
> > > +
> > > +- **value**: Direction.
> > > +
> > > + - 0: None
> > > + - 1: Output
> > > + - 2: Input
> > > +
> > > +**Reply:**
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+--------+--------+
> > > + | 0x00 | 0x01 | 0x02 |
> > > + | 1 | status | 0 |
> > > + +------+--------+--------+
> > > +
> > > +- **status**:
> > > +
> > > + - 0: Ok
> > > + - 1: Error
> > > +
> > > +
> > > +GET_VALUE (Cmd=4)
> > > +~~~~~~~~~~~~~~~~~
> > > +
> > > +**Request:**
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+------+------+------+------+------+------+------+
> > > + | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
> > > + | 4 | line | 0 |
> > > + +------+------+------+------+------+------+------+------+
> > > +
> > > +**Reply:**
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+--------+--------+
> > > + | 0x00 | 0x01 | 0x02 |
> > > + | 1 | status | value |
> > > + +------+--------+--------+
> > > +
> > > +- **status**:
> > > +
> > > + - 0: Ok
> > > + - 1: Error
> > > +
> > > +- **value**: Level.
> > > +
> > > + - 0: Low
> > > + - 1: High
> > > +
> > > +
> > > +SET_VALUE (Cmd=5)
> > > +~~~~~~~~~~~~~~~~~
> > > +
> > > +**Request:**
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+------+------+------+------+------+------+------+
> > > + | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
> > > + | 5 | line | value |
> > > + +------+------+------+------+------+------+------+------+
> > > +
> > > +- **value**: Output level.
> > > +
> > > + - 0: Low
> > > + - 1: High
> > > +
> > > +**Reply:**
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+--------+--------+
> > > + | 0x00 | 0x01 | 0x02 |
> > > + | 1 | status | 0 |
> > > + +------+--------+--------+
> > > +
> > > +- **status**:
> > > +
> > > + - 0: Ok
> > > + - 1: Error
> > > +
> > > +
> > > +SET_IRQ_TYPE (Cmd=6)
> > > +~~~~~~~~~~~~~~~~~~~~
> > > +
> > > +**Request:**
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+------+------+------+------+------+------+------+
> > > + | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
> > > + | 6 | line | value |
> > > + +------+------+------+------+------+------+------+------+
> > > +
> > > +- **value**: IRQ types.
> > > +
> > > + - 0: Interrupt disabled
> > > + - 1: Rising edge trigger
> > > + - 2: Falling edge trigger
> > > + - 3: Both edge trigger
> > > + - 4: High level trigger
> > > + - 8: Low level trigger
> >
> > I'm in agreement with cmd 3, 4, 5 and 6.
> >
>
> How about cmd 2?
Yes, I forgot cmd 2.
>
> > > +
> > > +**Reply:**
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+--------+--------+
> > > + | 0x00 | 0x01 | 0x02 |
> > > + | 1 | status | 0 |
> > > + +------+--------+--------+
> > > +
> > > +- **status**:
> > > +
> > > + - 0: Ok
> > > + - 1: Error
> > > +
> > > +SET_WAKEUP (Cmd=16)
> > > +~~~~~~~~~~~~~~~~~~~
> >
> > I already commented on messages that are not part of the virtio-gpio
> > specification.
> >
>
> I don't believe virtio-gpio needs a SET_WAKEUP command.
>
> In the RPMSG case, SET_WAKEUP is required because it performs an operation on the
> remote processor, so the remote side must be explicitly notified.
What operations would that be?
>
> For virtio-gpio, however, everything is handled locally. The other side does not need to
> perform any action, so sending a SET_WAKEUP command appears unnecessary.
What is "everything"?
>
>
> > > +
> > > +**Request:**
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+------+------+------+------+------+------+------+
> > > + | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
> > > + | 1 | line | value |
> > > + +------+------+------+------+------+------+------+------+
> > > +
> > > +- **value**: Wakeup enable.
> > > +
> > > + The remote system should always aim to stay in a power-efficient
> > > + state by shutting down or clock-gating the GPIO blocks that aren't
> > > + in use. Since the remoteproc driver is responsible for managing the
> > > + power states of the remote firmware, the GPIO driver does not
> > > + require to know the firmware's running states.
> > > +
> > > + When the wakeup bit is set, the remote firmware should configure
> > > + the line as a wakeup source. The firmware should send the
> > > + notification message to Linux after it is woken from the GPIO line.
> > > +
> > > + - 0: Disable wakeup from GPIO
> > > + - 1: Enable wakeup from GPIO
> > > +
> > > +**Reply:**
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+--------+--------+
> > > + | 0x00 | 0x01 | 0x02 |
> > > + | 1 | status | 0 |
> > > + +------+--------+--------+
> > > +
> > > +- **status**:
> > > +
> > > + - 0: Ok
> > > + - 1: Error
> > > +
> > > +Notification Message
> > > +--------------------
> >
> > "Interrupt Messages"
> >
> > > +
> > > +Notifications are sent by the remote core and they have
> > > +**Type=2 (GPIO_RPMSG_NOTIFY)**:
> > > +
> > > +When a GPIO line asserts an interrupt on the remote processor, the
> > > +firmware should immediately mask the corresponding interrupt source
> > > +and send a notification message to the Linux. Upon completion of the
> > > +interrupt handling on the Linux side, the driver should issue a
> > > +command **SET_IRQ_TYPE** to the firmware to unmask the interrupt.
> > > +
> > > +A Notification message can arrive between a SEND and its REPLY
> > > +message, and the driver is expected to handle this scenario.
> > > +
> > > +.. code-block:: none
> > > +
> > > + +------+------+--------+
> > > + | 0x00 | 0x01 | 0x02 |
> > > + | 2 | line | trigger|
> > > + +------+------+--------+
> >
> > 2 things here:
> >
> > 1) You did not include messages that mask and unmask interrupts at the driver
> > side.
>
> Interrupt masking and unmasking are handled entirely on the local processor.
>
> When an interrupt occurs, the remote system masks the interrupt and then sends a notification
> to Linux. After Linux processes the notification, it sends a SET_IRQ_TYPE message back to the
> remote system, which then unmasks the interrupt.
This is the kind of information that should be part of this documentation.
>
> Thanks,
> Shenwei
>
> >
> > 2) We are carrying virtio-gpio messages on top of RPMSG and as such, this whole
> > protocol should be about thar:
> >
> > +------+------+--------+--------
> > | 0x00 | payload |
> > | Q | |
> > +------+------+--------+--------
> >
> > Q = 0 requestq
> > Q = 1 eventq
> >
> > The "payload" part is simply the format of the messages as found in the virtio-
> > gpio specification. From there, the only thing left to mention is which messages
> > are not supported, i.e get line names.
> >
> > > +
> > > +- **line**: The GPIO line (pin) index of the port.
> > > +
> > > +- **trigger**: Optional parameter to indicate the trigger event type.
> >
> > Not part of the spec - remove.
> >
> > Given the refactoring work that is still needed, I will not look at the
> > implementation.
> >
> > Thanks,
> > Mathieu
> >
> > > +
> > > diff --git a/Documentation/driver-api/gpio/index.rst
> > > b/Documentation/driver-api/gpio/index.rst
> > > index bee58f709b9a..e5eb1f82f01f 100644
> > > --- a/Documentation/driver-api/gpio/index.rst
> > > +++ b/Documentation/driver-api/gpio/index.rst
> > > @@ -16,6 +16,7 @@ Contents:
> > > drivers-on-gpio
> > > bt8xxgpio
> > > pca953x
> > > + gpio-rpmsg
> > >
> > > Core
> > > ====
> > > --
> > > 2.43.0
> > >
^ permalink raw reply
* htmldocs: Documentation/networking/ipv6-addrsel.rst: WARNING: document isn't included in any toctree [toc.not_included]
From: kernel test robot @ 2026-07-14 16:21 UTC (permalink / raw)
To: David 'equinox' Lamparter; +Cc: oe-kbuild-all, 0day robot, linux-doc
tree: https://github.com/intel-lab-lkp/linux/commits/David-equinox-Lamparter/net-ipv6-fix-lookup-for-0-non-subtree-route/20260714-174919
head: 745e2c3a79e2e0369ee5dbd1e650b1fddbed477f
commit: 745e2c3a79e2e0369ee5dbd1e650b1fddbed477f net: document RFC6724 rule 5.5 implementation
date: 6 hours ago
compiler: clang version 22.1.8 (https://github.com/llvm/llvm-project ca7933e47d3a3451d81e72ac174dcb5aa28b59d1)
docutils: docutils (Docutils 0.21.2, Python 3.13.5, on linux)
reproduce: (https://download.01.org/0day-ci/archive/20260714/202607141831.ujAOXbq1-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202607141831.ujAOXbq1-lkp@intel.com/
All warnings (new ones prefixed by >>):
Documentation/userspace-api/landlock:596: ./include/uapi/linux/landlock.h:58: ERROR: Unknown target name: "network flags". [docutils]
Documentation/userspace-api/landlock:596: ./include/uapi/linux/landlock.h:63: ERROR: Unknown target name: "scope flags". [docutils]
Documentation/userspace-api/landlock:596: ./include/uapi/linux/landlock.h:24: ERROR: Unknown target name: "filesystem flags". [docutils]
Documentation/userspace-api/landlock:605: ./include/uapi/linux/landlock.h:228: ERROR: Unknown target name: "filesystem flags". [docutils]
Documentation/userspace-api/landlock:605: ./include/uapi/linux/landlock.h:251: ERROR: Unknown target name: "network flags". [docutils]
>> Documentation/networking/ipv6-addrsel.rst: WARNING: document isn't included in any toctree [toc.not_included]
Documentation/networking/checksum-offloads:157: ./include/linux/skbuff.h:181: WARNING: Failed to create a cross reference. A title or caption not found: 'crc' [ref.ref]
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v8 0/8] mm/hmm: Add mmap lock-drop support for userfaultfd-backed mappings
From: Stanislav Kinsburskii @ 2026-07-14 16:09 UTC (permalink / raw)
To: Andrew Morton
Cc: airlied, akhilesh, corbet, dakr, david, decui, haiyangz, jgg,
kees, kys, leon, liam, lizhi.hou, ljs, longli, lyude,
maarten.lankhorst, mamin506, mhocko, mripard, nouveau, ogabbay,
oleg, rppt, shuah, simona, skhan, surenb, tzimmermann, vbabka,
wei.liu, dri-devel, linux-mm, linux-doc, linux-hyperv,
linux-kernel, linux-kselftest, linux-rdma
In-Reply-To: <20260713154535.7656b3a630e2f6f076b4e76e@linux-foundation.org>
On Mon, Jul 13, 2026 at 03:45:35PM -0700, Andrew Morton wrote:
> On Mon, 13 Jul 2026 13:57:55 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> wrote:
>
> > > > I rebased this series on top of mm-new right before sending it out.
> > > > Should I have used a different branch?
> > >
> > > mm-new is good - Sashiko attempts that. But it's changing rapidly at
> > > this point in the development cycle.
> > >
> >
> > I’d like to send another revision addressing a few comments and also
> > replace the `max/max_t` check with something simpler.
> >
> > Which branch should I base it on so that Sashiko can apply it
> > successfully?
>
> mainline Linus would be safest.
>
Looks like linux-next/master has been updated with the v8 of the series.
I have v9 with a few small fixes, but it is too late to send it out already?
If it's not, then what should I base it on?
Thanks,
Stanislav
> > Or would it be better to send fixups against `mm-new`?
>
> That should work as well, but it doesn't give us a Sashiko scan of the
> whole patchset.
^ permalink raw reply
* [PATCH v5 20/20] vfio: selftests: Add continuous DMA to vfio_pci_liveupdate_kexec_test
From: Vipin Sharma @ 2026-07-14 15:15 UTC (permalink / raw)
To: kexec, linux-kernel, linux-doc, kvm, linux-mm, linux-kselftest
Cc: ajayachandra, alex, amastro, ankita, apopple, bhelgaas, chrisl,
christian.koenig, corbet, dmatlack, graf, jacob.pan, jgg, jgg,
jrhilke, julianr, kees, kevin.tian, leon, leonro, lukas, mattev,
michal.winiarski, parav, pasha.tatashin, praan, pratyush, rananta,
rientjes, rodrigo.vivi, rppt, saeedm, schnelle, skhan, skhawaja,
vipinsh, vivek.kasireddy, witu, yanjun.zhu, yi.l.liu
In-Reply-To: <20260714151505.3466855-1-vipinsh@google.com>
From: David Matlack <dmatlack@google.com>
Add a long-running DMA memcpy operation to
vfio_pci_liveupdate_kexec_test so that the device attempts to perform
DMAs continuously during the Live Update.
At this point iommufd preservation is not supported and bus mastering is
not kept enabled on the device across the kexec, so most of these DMAs
will be dropped. However this test ensures that the current device
preservation support does not lead to system instability or crashes if
the device is active. And once iommufd and bus mastering are preserved,
this test can be relaxed to check that the DMA operations completed
successfully.
Signed-off-by: David Matlack <dmatlack@google.com>
Signed-off-by: Vipin Sharma <vipinsh@google.com>
---
.../vfio/vfio_pci_liveupdate_kexec_test.c | 129 ++++++++++++++++++
1 file changed, 129 insertions(+)
diff --git a/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c b/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c
index ec3fe8f19502..51b2f24f352c 100644
--- a/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c
+++ b/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c
@@ -1,8 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/sizes.h>
+#include <sys/mman.h>
+
#include <libliveupdate.h>
#include <libvfio.h>
+#define MEMCPY_SIZE SZ_1G
+#define DRIVER_SIZE SZ_1M
+#define MEMFD_SIZE (MEMCPY_SIZE + DRIVER_SIZE)
+
+static struct dma_region memcpy_region;
static const char *device_bdf;
static char state_session[LIVEUPDATE_SESSION_NAME_LENGTH];
@@ -11,8 +19,89 @@ static char device_session[LIVEUPDATE_SESSION_NAME_LENGTH];
enum {
STATE_TOKEN,
DEVICE_TOKEN,
+ MEMFD_TOKEN,
};
+static void dma_memcpy_one(struct vfio_pci_device *device)
+{
+ void *src = memcpy_region.vaddr, *dst;
+ u64 size;
+
+ size = min_t(u64, memcpy_region.size / 2, device->driver.max_memcpy_size);
+ dst = src + size;
+
+ memset(src, 1, size);
+ memset(dst, 0, size);
+
+ printf("Kicking off 1 DMA memcpy operations of size 0x%lx...\n", size);
+ vfio_pci_driver_memcpy(device,
+ to_iova(device, src),
+ to_iova(device, dst),
+ size);
+
+ VFIO_ASSERT_EQ(memcmp(src, dst, size), 0);
+}
+
+static void dma_memcpy_start(struct vfio_pci_device *device)
+{
+ void *src = memcpy_region.vaddr, *dst;
+ u64 count, size;
+
+ size = min_t(u64, memcpy_region.size / 2, device->driver.max_memcpy_size);
+ dst = src + size;
+
+ /*
+ * Rough Math: If we assume the device will perform memcpy at a rate of
+ * 30GB/s then 7200GB of transfers will run for about 4 minutes.
+ */
+ count = (u64)7200 * SZ_1G / size;
+ count = min_t(u64, count, device->driver.max_memcpy_count);
+
+ memset(src, 1, size / 2);
+ memset(dst, 0, size / 2);
+
+ printf("Kicking off %lu DMA memcpy operations of size 0x%lx...\n", count, size);
+ vfio_pci_driver_memcpy_start(device,
+ to_iova(device, src),
+ to_iova(device, dst),
+ size, count);
+}
+
+static void dma_memfd_map(struct vfio_pci_device *device, int fd)
+{
+ void *vaddr;
+
+ vaddr = mmap(NULL, MEMFD_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ VFIO_ASSERT_NE(vaddr, MAP_FAILED);
+
+ memcpy_region.iova = SZ_4G;
+ memcpy_region.size = MEMCPY_SIZE;
+ memcpy_region.vaddr = vaddr;
+ iommu_map(device->iommu, &memcpy_region);
+
+ device->driver.region.iova = memcpy_region.iova + memcpy_region.size;
+ device->driver.region.size = DRIVER_SIZE;
+ device->driver.region.vaddr = vaddr + memcpy_region.size;
+ iommu_map(device->iommu, &device->driver.region);
+}
+
+static void dma_memfd_setup(struct vfio_pci_device *device, int session_fd)
+{
+ int fd, ret;
+
+ fd = memfd_create("dma-buffer", 0);
+ VFIO_ASSERT_GE(fd, 0);
+
+ ret = fallocate(fd, 0, 0, MEMFD_SIZE);
+ VFIO_ASSERT_EQ(ret, 0);
+
+ printf("Preserving memfd of size 0x%x in session\n", MEMFD_SIZE);
+ ret = luo_session_preserve_fd(session_fd, fd, MEMFD_TOKEN);
+ VFIO_ASSERT_EQ(ret, 0);
+
+ dma_memfd_map(device, fd);
+}
+
static void before_kexec(int luo_fd)
{
struct vfio_pci_device *device;
@@ -32,6 +121,27 @@ static void before_kexec(int luo_fd)
ret = luo_session_preserve_fd(session_fd, device->fd, DEVICE_TOKEN);
VFIO_ASSERT_EQ(ret, 0);
+ dma_memfd_setup(device, session_fd);
+
+ /*
+ * If the device has a selftests driver, kick off a long-running DMA
+ * operation to exercise the device trying to DMA during a Live Update.
+ * Since iommufd preservation is not supported yet, these DMAs should be
+ * dropped. So this is just looking to verify that the system does not
+ * fall over and crash as a result of a busy device being preserved.
+ */
+ if (device->driver.ops) {
+ vfio_pci_driver_init(device);
+ dma_memcpy_start(device);
+
+ /*
+ * Disable interrupts on the device or freeze() will fail.
+ * Unfortunately there isn't a way to easily have a test for
+ * that here since the check happens during shutdown.
+ */
+ vfio_pci_msix_disable(device);
+ }
+
close(luo_fd);
daemonize_and_wait();
}
@@ -78,6 +188,7 @@ static void after_kexec(int luo_fd, int state_session_fd)
struct iommu *iommu;
int session_fd;
int device_fd;
+ int memfd;
int stage;
check_open_vfio_device_fails();
@@ -88,6 +199,10 @@ static void after_kexec(int luo_fd, int state_session_fd)
session_fd = luo_retrieve_session(luo_fd, device_session);
VFIO_ASSERT_GE(session_fd, 0);
+ printf("Retrieving memfd from LUO\n");
+ memfd = luo_session_retrieve_fd(session_fd, MEMFD_TOKEN);
+ VFIO_ASSERT_GE(memfd, 0);
+
printf("Finishing the session before retrieving the device (should fail)\n");
VFIO_ASSERT_NE(luo_session_finish(session_fd), 0);
@@ -109,9 +224,23 @@ static void after_kexec(int luo_fd, int state_session_fd)
*/
device = __vfio_pci_device_init(device_bdf, iommu, device_fd);
+ dma_memfd_map(device, memfd);
+
printf("Finishing the session\n");
VFIO_ASSERT_EQ(luo_session_finish(session_fd), 0);
+ /*
+ * Once iommufd preservation is supported and the device is kept fully
+ * running across the Live Update, this should wait for the long-
+ * running DMA memcpy operation kicked off in before_kexec() to
+ * complete. But for now we expect the device to be reset so just
+ * trigger a single memcpy to make sure it's still functional.
+ */
+ if (device->driver.ops) {
+ vfio_pci_driver_init(device);
+ dma_memcpy_one(device);
+ }
+
vfio_pci_device_cleanup(device);
iommu_cleanup(iommu);
}
--
2.55.0.795.g602f6c329a-goog
^ permalink raw reply related
* [PATCH v5 19/20] vfio: selftests: Verify that opening VFIO device fails during Live Update
From: Vipin Sharma @ 2026-07-14 15:15 UTC (permalink / raw)
To: kexec, linux-kernel, linux-doc, kvm, linux-mm, linux-kselftest
Cc: ajayachandra, alex, amastro, ankita, apopple, bhelgaas, chrisl,
christian.koenig, corbet, dmatlack, graf, jacob.pan, jgg, jgg,
jrhilke, julianr, kees, kevin.tian, leon, leonro, lukas, mattev,
michal.winiarski, parav, pasha.tatashin, praan, pratyush, rananta,
rientjes, rodrigo.vivi, rppt, saeedm, schnelle, skhan, skhawaja,
vipinsh, vivek.kasireddy, witu, yanjun.zhu, yi.l.liu
In-Reply-To: <20260714151505.3466855-1-vipinsh@google.com>
From: David Matlack <dmatlack@google.com>
Verify that opening a VFIO device through its cdev file and via
VFIO_GROUP_GET_DEVICE_FD both fail with -EBUSY if the device was
preserved across a Live Update. When a device file is preserved across a
Live Update, the file must be retrieved from /dev/liveupdate, not from
VFIO directly.
Signed-off-by: David Matlack <dmatlack@google.com>
Signed-off-by: Vipin Sharma <vipinsh@google.com>
---
.../vfio/vfio_pci_liveupdate_kexec_test.c | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c b/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c
index 15b3e3af91d1..ec3fe8f19502 100644
--- a/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c
+++ b/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c
@@ -36,6 +36,42 @@ static void before_kexec(int luo_fd)
daemonize_and_wait();
}
+static void check_open_vfio_device_fails(void)
+{
+ const char *cdev_path = vfio_pci_get_cdev_path(device_bdf);
+ struct vfio_pci_device *device;
+ struct iommu *iommu;
+ int ret, i;
+
+ printf("Checking open(%s) fails\n", cdev_path);
+ ret = open(cdev_path, O_RDWR);
+ VFIO_ASSERT_EQ(ret, -1);
+ VFIO_ASSERT_EQ(errno, EBUSY);
+ free((void *)cdev_path);
+
+ for (i = 0; i < nr_iommu_modes; i++) {
+ if (!iommu_modes[i].container_path)
+ continue;
+
+ iommu = iommu_init(iommu_modes[i].name);
+
+ device = vfio_pci_device_alloc(device_bdf, iommu);
+ vfio_pci_group_setup(device, device_bdf);
+ vfio_container_set_iommu(device);
+
+ printf("Checking ioctl(group_fd, VFIO_GROUP_GET_DEVICE_FD, \"%s\") fails (%s)\n",
+ device_bdf, iommu_modes[i].name);
+
+ ret = ioctl(device->group_fd, VFIO_GROUP_GET_DEVICE_FD, device->bdf);
+ VFIO_ASSERT_EQ(ret, -1);
+ VFIO_ASSERT_EQ(errno, EBUSY);
+
+ close(device->group_fd);
+ free(device);
+ iommu_cleanup(iommu);
+ }
+}
+
static void after_kexec(int luo_fd, int state_session_fd)
{
struct vfio_pci_device *device;
@@ -44,6 +80,8 @@ static void after_kexec(int luo_fd, int state_session_fd)
int device_fd;
int stage;
+ check_open_vfio_device_fails();
+
restore_and_read_stage(state_session_fd, STATE_TOKEN, &stage);
VFIO_ASSERT_EQ(stage, 2);
--
2.55.0.795.g602f6c329a-goog
^ permalink raw reply related
* [PATCH v5 18/20] vfio: selftests: Expose iommu_modes to tests
From: Vipin Sharma @ 2026-07-14 15:15 UTC (permalink / raw)
To: kexec, linux-kernel, linux-doc, kvm, linux-mm, linux-kselftest
Cc: ajayachandra, alex, amastro, ankita, apopple, bhelgaas, chrisl,
christian.koenig, corbet, dmatlack, graf, jacob.pan, jgg, jgg,
jrhilke, julianr, kees, kevin.tian, leon, leonro, lukas, mattev,
michal.winiarski, parav, pasha.tatashin, praan, pratyush, rananta,
rientjes, rodrigo.vivi, rppt, saeedm, schnelle, skhan, skhawaja,
vipinsh, vivek.kasireddy, witu, yanjun.zhu, yi.l.liu
In-Reply-To: <20260714151505.3466855-1-vipinsh@google.com>
From: David Matlack <dmatlack@google.com>
Expose the list of iommu_modes to enable tests that want to iterate
through all possible iommu modes.
Signed-off-by: David Matlack <dmatlack@google.com>
Signed-off-by: Vipin Sharma <vipinsh@google.com>
---
tools/testing/selftests/vfio/lib/include/libvfio/iommu.h | 2 ++
tools/testing/selftests/vfio/lib/iommu.c | 4 +++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h b/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h
index e9a3386a4719..4b9cbe262159 100644
--- a/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h
+++ b/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h
@@ -15,6 +15,8 @@ struct iommu_mode {
unsigned long iommu_type;
};
+extern const struct iommu_mode iommu_modes[];
+extern const int nr_iommu_modes;
extern const char *default_iommu_mode;
struct dma_region {
diff --git a/tools/testing/selftests/vfio/lib/iommu.c b/tools/testing/selftests/vfio/lib/iommu.c
index 035dac069d60..95a494f829d2 100644
--- a/tools/testing/selftests/vfio/lib/iommu.c
+++ b/tools/testing/selftests/vfio/lib/iommu.c
@@ -23,7 +23,7 @@
const char *default_iommu_mode = MODE_IOMMUFD;
/* Reminder: Keep in sync with FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(). */
-static const struct iommu_mode iommu_modes[] = {
+const struct iommu_mode iommu_modes[] = {
{
.name = MODE_VFIO_TYPE1_IOMMU,
.container_path = "/dev/vfio/vfio",
@@ -49,6 +49,8 @@ static const struct iommu_mode iommu_modes[] = {
},
};
+const int nr_iommu_modes = ARRAY_SIZE(iommu_modes);
+
static const struct iommu_mode *lookup_iommu_mode(const char *iommu_mode)
{
int i;
--
2.55.0.795.g602f6c329a-goog
^ permalink raw reply related
* [PATCH v5 17/20] vfio: selftests: Add vfio_pci_liveupdate_kexec_test
From: Vipin Sharma @ 2026-07-14 15:15 UTC (permalink / raw)
To: kexec, linux-kernel, linux-doc, kvm, linux-mm, linux-kselftest
Cc: ajayachandra, alex, amastro, ankita, apopple, bhelgaas, chrisl,
christian.koenig, corbet, dmatlack, graf, jacob.pan, jgg, jgg,
jrhilke, julianr, kees, kevin.tian, leon, leonro, lukas, mattev,
michal.winiarski, parav, pasha.tatashin, praan, pratyush, rananta,
rientjes, rodrigo.vivi, rppt, saeedm, schnelle, skhan, skhawaja,
vipinsh, vivek.kasireddy, witu, yanjun.zhu, yi.l.liu
In-Reply-To: <20260714151505.3466855-1-vipinsh@google.com>
Add a selftest to exercise preserving a vfio-pci device across a Live
Update. For now the test is extremely simple and just verifies that the
device file can be preserved and retrieved. In the future this test will
be extended to verify more parts about device preservation as they are
implemented.
This test is added to TEST_GEN_PROGS_EXTENDED since it must be run
manually along with a kexec.
To run this test manually:
$ tools/testing/selftests/vfio/scripts/setup.sh 0000:00:04.0
$ tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test --stage 1 0000:00:04.0
$ kexec ... # NOTE: Exact method will be distro-dependent
$ tools/testing/selftests/vfio/scripts/setup.sh 0000:00:04.0
$ tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test --stage 2 0000:00:04.0
The second call to setup.sh is necessary because preserved devices are
not bound to a driver after Live Update. Such devices must be manually
bound by userspace after Live Update via driver_override.
This test is considered passing if all commands exit with 0.
Co-developed-by: David Matlack <dmatlack@google.com>
Signed-off-by: David Matlack <dmatlack@google.com>
Signed-off-by: Vipin Sharma <vipinsh@google.com>
---
tools/testing/selftests/vfio/Makefile | 4 +
.../vfio/vfio_pci_liveupdate_kexec_test.c | 89 +++++++++++++++++++
2 files changed, 93 insertions(+)
create mode 100644 tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c
diff --git a/tools/testing/selftests/vfio/Makefile b/tools/testing/selftests/vfio/Makefile
index 591f1a52c310..a2f0a459e1f4 100644
--- a/tools/testing/selftests/vfio/Makefile
+++ b/tools/testing/selftests/vfio/Makefile
@@ -15,6 +15,10 @@ TEST_GEN_PROGS += vfio_pci_driver_test
TEST_GEN_PROGS += vfio_pci_sriov_uapi_test
TEST_GEN_PROGS += vfio_pci_liveupdate_uapi_test
+# This test must be run manually since it requires the user/automation to
+# perform a kexec during the test.
+TEST_GEN_PROGS_EXTENDED += vfio_pci_liveupdate_kexec_test
+
TEST_FILES += scripts/cleanup.sh
TEST_FILES += scripts/lib.sh
TEST_FILES += scripts/run.sh
diff --git a/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c b/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c
new file mode 100644
index 000000000000..15b3e3af91d1
--- /dev/null
+++ b/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <libliveupdate.h>
+#include <libvfio.h>
+
+static const char *device_bdf;
+
+static char state_session[LIVEUPDATE_SESSION_NAME_LENGTH];
+static char device_session[LIVEUPDATE_SESSION_NAME_LENGTH];
+
+enum {
+ STATE_TOKEN,
+ DEVICE_TOKEN,
+};
+
+static void before_kexec(int luo_fd)
+{
+ struct vfio_pci_device *device;
+ struct iommu *iommu;
+ int session_fd;
+ int ret;
+
+ iommu = iommu_init("iommufd");
+ device = vfio_pci_device_init(device_bdf, iommu);
+
+ create_state_file(luo_fd, state_session, STATE_TOKEN, /*next_stage=*/2);
+
+ session_fd = luo_create_session(luo_fd, device_session);
+ VFIO_ASSERT_GE(session_fd, 0);
+
+ printf("Preserving device in session\n");
+ ret = luo_session_preserve_fd(session_fd, device->fd, DEVICE_TOKEN);
+ VFIO_ASSERT_EQ(ret, 0);
+
+ close(luo_fd);
+ daemonize_and_wait();
+}
+
+static void after_kexec(int luo_fd, int state_session_fd)
+{
+ struct vfio_pci_device *device;
+ struct iommu *iommu;
+ int session_fd;
+ int device_fd;
+ int stage;
+
+ restore_and_read_stage(state_session_fd, STATE_TOKEN, &stage);
+ VFIO_ASSERT_EQ(stage, 2);
+
+ session_fd = luo_retrieve_session(luo_fd, device_session);
+ VFIO_ASSERT_GE(session_fd, 0);
+
+ printf("Finishing the session before retrieving the device (should fail)\n");
+ VFIO_ASSERT_NE(luo_session_finish(session_fd), 0);
+
+ printf("Retrieving the device FD from LUO\n");
+ device_fd = luo_session_retrieve_fd(session_fd, DEVICE_TOKEN);
+ VFIO_ASSERT_GE(device_fd, 0);
+
+ printf("Finishing the session before binding to iommufd (should fail)\n");
+ VFIO_ASSERT_NE(luo_session_finish(session_fd), 0);
+
+ printf("Binding the device to an iommufd and setting it up\n");
+ iommu = iommu_init("iommufd");
+
+ /*
+ * This will invoke various ioctls on device_fd such as
+ * VFIO_DEVICE_GET_INFO. So this is a decent sanity test
+ * that LUO actually handed us back a valid VFIO device
+ * file and not something else.
+ */
+ device = __vfio_pci_device_init(device_bdf, iommu, device_fd);
+
+ printf("Finishing the session\n");
+ VFIO_ASSERT_EQ(luo_session_finish(session_fd), 0);
+
+ vfio_pci_device_cleanup(device);
+ iommu_cleanup(iommu);
+}
+
+int main(int argc, char *argv[])
+{
+ device_bdf = vfio_selftests_get_bdf(&argc, argv);
+
+ sprintf(device_session, "device-%s", device_bdf);
+ sprintf(state_session, "state-%s", device_bdf);
+
+ return luo_test(argc, argv, state_session, before_kexec, after_kexec);
+}
--
2.55.0.795.g602f6c329a-goog
^ permalink raw reply related
* [PATCH v5 16/20] vfio: selftests: Add Makefile support for TEST_GEN_PROGS_EXTENDED
From: Vipin Sharma @ 2026-07-14 15:15 UTC (permalink / raw)
To: kexec, linux-kernel, linux-doc, kvm, linux-mm, linux-kselftest
Cc: ajayachandra, alex, amastro, ankita, apopple, bhelgaas, chrisl,
christian.koenig, corbet, dmatlack, graf, jacob.pan, jgg, jgg,
jrhilke, julianr, kees, kevin.tian, leon, leonro, lukas, mattev,
michal.winiarski, parav, pasha.tatashin, praan, pratyush, rananta,
rientjes, rodrigo.vivi, rppt, saeedm, schnelle, skhan, skhawaja,
vipinsh, vivek.kasireddy, witu, yanjun.zhu, yi.l.liu
In-Reply-To: <20260714151505.3466855-1-vipinsh@google.com>
From: David Matlack <dmatlack@google.com>
Add Makefile support for TEST_GEN_PROGS_EXTENDED targets. These tests
are not run by default.
TEST_GEN_PROGS_EXTENDED will be used for Live Update selftests in
subsequent commits. These selftests must be run manually because they
require the user/runner to perform additional actions, such as kexec,
during the test.
Signed-off-by: David Matlack <dmatlack@google.com>
Signed-off-by: Vipin Sharma <vipinsh@google.com>
---
tools/testing/selftests/vfio/Makefile | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/vfio/Makefile b/tools/testing/selftests/vfio/Makefile
index dc06fddcf855..591f1a52c310 100644
--- a/tools/testing/selftests/vfio/Makefile
+++ b/tools/testing/selftests/vfio/Makefile
@@ -36,16 +36,18 @@ LDLIBS += -luuid
LIBS_O := $(LIBVFIO_O)
LIBS_O += $(LIBLIVEUPDATE_O)
-$(TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(LIBS_O)
+$(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/%: $(OUTPUT)/%.o $(LIBS_O)
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $< $(LIBS_O) $(LDLIBS) -o $@
-TEST_GEN_PROGS_O = $(patsubst %, %.o, $(TEST_GEN_PROGS))
-$(TEST_GEN_PROGS_O): $(OUTPUT)/%.o: %.c
+TESTS_O := $(patsubst %, %.o, $(TEST_GEN_PROGS))
+TESTS_O += $(patsubst %, %.o, $(TEST_GEN_PROGS_EXTENDED))
+
+$(TESTS_O): $(OUTPUT)/%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-TEST_DEP_FILES = $(patsubst %.o, %.d, $(TEST_GEN_PROGS_O) $(LIBS_O))
+TEST_DEP_FILES = $(patsubst %.o, %.d, $(TESTS_O) $(LIBS_O))
-include $(TEST_DEP_FILES)
-EXTRA_CLEAN += $(TEST_GEN_PROGS_O) $(TEST_DEP_FILES)
+EXTRA_CLEAN += $(TESTS_O) $(TEST_DEP_FILES)
endif
--
2.55.0.795.g602f6c329a-goog
^ permalink raw reply related
* [PATCH v5 15/20] vfio: selftests: Initialize vfio_pci_device using a VFIO cdev FD
From: Vipin Sharma @ 2026-07-14 15:15 UTC (permalink / raw)
To: kexec, linux-kernel, linux-doc, kvm, linux-mm, linux-kselftest
Cc: ajayachandra, alex, amastro, ankita, apopple, bhelgaas, chrisl,
christian.koenig, corbet, dmatlack, graf, jacob.pan, jgg, jgg,
jrhilke, julianr, kees, kevin.tian, leon, leonro, lukas, mattev,
michal.winiarski, parav, pasha.tatashin, praan, pratyush, rananta,
rientjes, rodrigo.vivi, rppt, saeedm, schnelle, skhan, skhawaja,
vipinsh, vivek.kasireddy, witu, yanjun.zhu, yi.l.liu
In-Reply-To: <20260714151505.3466855-1-vipinsh@google.com>
Use the given VFIO cdev FD to initialize vfio_pci_device in VFIO
selftests. Add the assertion to make sure that passed cdev FD is not
used with legacy VFIO APIs. If VFIO cdev FD is provided then do not open
the device instead use the FD for any interaction with the device.
This API will allow writing selftests where VFIO device FD is preserved
using liveupdate and retrieved later using liveupdate ioctl after kexec.
Co-developed-by: David Matlack <dmatlack@google.com>
Signed-off-by: David Matlack <dmatlack@google.com>
Signed-off-by: Vipin Sharma <vipinsh@google.com>
---
.../lib/include/libvfio/vfio_pci_device.h | 3 +++
.../selftests/vfio/lib/vfio_pci_device.c | 25 ++++++++++++++-----
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h b/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h
index 3eabead717bb..66fc29662daa 100644
--- a/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h
+++ b/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h
@@ -40,6 +40,9 @@ struct vfio_pci_device {
struct vfio_pci_device *vfio_pci_device_alloc(const char *bdf, struct iommu *iommu);
void vfio_pci_device_free(struct vfio_pci_device *device);
+struct vfio_pci_device *__vfio_pci_device_init(const char *bdf,
+ struct iommu *iommu,
+ int device_fd);
struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu *iommu);
void vfio_pci_device_cleanup(struct vfio_pci_device *device);
diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/testing/selftests/vfio/lib/vfio_pci_device.c
index 94dc5fcecbeb..a6e0e7c6e18e 100644
--- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c
+++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c
@@ -414,9 +414,13 @@ void vfio_pci_cdev_open(struct vfio_pci_device *device, const char *bdf)
}
static void vfio_pci_iommufd_setup(struct vfio_pci_device *device,
- const char *bdf, const char *vf_token)
+ const char *bdf, int device_fd,
+ const char *vf_token)
{
- vfio_pci_cdev_open(device, bdf);
+ if (device_fd >= 0)
+ device->fd = device_fd;
+ else
+ vfio_pci_cdev_open(device, bdf);
vfio_device_bind_iommufd(device->fd, device->iommu->iommufd, vf_token);
vfio_device_attach_iommufd_pt(device->fd, device->iommu->ioas_id);
}
@@ -440,16 +444,20 @@ void vfio_pci_device_free(struct vfio_pci_device *device)
free(device);
}
-struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu *iommu)
+struct vfio_pci_device *__vfio_pci_device_init(const char *bdf,
+ struct iommu *iommu,
+ int device_fd)
{
struct vfio_pci_device *device;
device = vfio_pci_device_alloc(bdf, iommu);
- if (iommu->mode->container_path)
+ if (iommu->mode->container_path) {
+ VFIO_ASSERT_EQ(device_fd, -1);
vfio_pci_container_setup(device, bdf, NULL);
- else
- vfio_pci_iommufd_setup(device, bdf, NULL);
+ } else {
+ vfio_pci_iommufd_setup(device, bdf, device_fd, NULL);
+ }
vfio_pci_device_setup(device);
vfio_pci_driver_probe(device);
@@ -457,6 +465,11 @@ struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu *iomm
return device;
}
+struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu *iommu)
+{
+ return __vfio_pci_device_init(bdf, iommu, /*device_fd=*/-1);
+}
+
void vfio_pci_device_cleanup(struct vfio_pci_device *device)
{
int i;
--
2.55.0.795.g602f6c329a-goog
^ permalink raw reply related
* [PATCH v5 14/20] vfio: selftests: Add vfio_pci_liveupdate_uapi_test
From: Vipin Sharma @ 2026-07-14 15:14 UTC (permalink / raw)
To: kexec, linux-kernel, linux-doc, kvm, linux-mm, linux-kselftest
Cc: ajayachandra, alex, amastro, ankita, apopple, bhelgaas, chrisl,
christian.koenig, corbet, dmatlack, graf, jacob.pan, jgg, jgg,
jrhilke, julianr, kees, kevin.tian, leon, leonro, lukas, mattev,
michal.winiarski, parav, pasha.tatashin, praan, pratyush, rananta,
rientjes, rodrigo.vivi, rppt, saeedm, schnelle, skhan, skhawaja,
vipinsh, vivek.kasireddy, witu, yanjun.zhu, yi.l.liu
In-Reply-To: <20260714151505.3466855-1-vipinsh@google.com>
From: David Matlack <dmatlack@google.com>
Add a selftest to exercise preserving various VFIO files through
/dev/liveupdate. Ensure that VFIO cdev device files can be preserved and
everything else (group-based device files, group files, and container
files) all fail.
Signed-off-by: David Matlack <dmatlack@google.com>
Signed-off-by: Vipin Sharma <vipinsh@google.com>
---
tools/testing/selftests/vfio/Makefile | 1 +
.../vfio/vfio_pci_liveupdate_uapi_test.c | 97 +++++++++++++++++++
2 files changed, 98 insertions(+)
create mode 100644 tools/testing/selftests/vfio/vfio_pci_liveupdate_uapi_test.c
diff --git a/tools/testing/selftests/vfio/Makefile b/tools/testing/selftests/vfio/Makefile
index 4c8a30f950c4..dc06fddcf855 100644
--- a/tools/testing/selftests/vfio/Makefile
+++ b/tools/testing/selftests/vfio/Makefile
@@ -13,6 +13,7 @@ TEST_GEN_PROGS += vfio_pci_device_test
TEST_GEN_PROGS += vfio_pci_device_init_perf_test
TEST_GEN_PROGS += vfio_pci_driver_test
TEST_GEN_PROGS += vfio_pci_sriov_uapi_test
+TEST_GEN_PROGS += vfio_pci_liveupdate_uapi_test
TEST_FILES += scripts/cleanup.sh
TEST_FILES += scripts/lib.sh
diff --git a/tools/testing/selftests/vfio/vfio_pci_liveupdate_uapi_test.c b/tools/testing/selftests/vfio/vfio_pci_liveupdate_uapi_test.c
new file mode 100644
index 000000000000..f81c8ab21db3
--- /dev/null
+++ b/tools/testing/selftests/vfio/vfio_pci_liveupdate_uapi_test.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <libliveupdate.h>
+#include <libvfio.h>
+#include <kselftest_harness.h>
+
+static const char *device_bdf;
+
+FIXTURE(vfio_pci_liveupdate_uapi_test) {
+ int luo_fd;
+ int session_fd;
+ struct iommu *iommu;
+ struct vfio_pci_device *device;
+};
+
+FIXTURE_VARIANT(vfio_pci_liveupdate_uapi_test) {
+ const char *iommu_mode;
+};
+
+#define FIXTURE_VARIANT_ADD_IOMMU_MODE(_iommu_mode) \
+FIXTURE_VARIANT_ADD(vfio_pci_liveupdate_uapi_test, _iommu_mode) { \
+ .iommu_mode = #_iommu_mode, \
+}
+
+FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES();
+#undef FIXTURE_VARIANT_ADD_IOMMU_MODE
+
+FIXTURE_SETUP(vfio_pci_liveupdate_uapi_test)
+{
+ self->luo_fd = luo_open_device();
+ ASSERT_GT(self->luo_fd, 0);
+
+ self->session_fd = luo_create_session(self->luo_fd, "session");
+ ASSERT_GT(self->session_fd, 0);
+
+ self->iommu = iommu_init(variant->iommu_mode);
+ self->device = vfio_pci_device_init(device_bdf, self->iommu);
+}
+
+FIXTURE_TEARDOWN(vfio_pci_liveupdate_uapi_test)
+{
+ if (self->device)
+ vfio_pci_device_cleanup(self->device);
+ if (self->iommu)
+ iommu_cleanup(self->iommu);
+ if (self->session_fd > 0)
+ close(self->session_fd);
+ if (self->luo_fd > 0)
+ close(self->luo_fd);
+}
+
+TEST_F(vfio_pci_liveupdate_uapi_test, preserve_device)
+{
+ int ret;
+
+ ret = luo_session_preserve_fd(self->session_fd, self->device->fd, 0);
+
+ /* Preservation should only be supported for VFIO cdev files. */
+ ASSERT_EQ(ret, self->iommu->iommufd ? 0 : -ENOENT);
+}
+
+TEST_F(vfio_pci_liveupdate_uapi_test, preserve_group_fails)
+{
+ int ret;
+
+ if (self->iommu->iommufd)
+ SKIP(return, "iommufd-mode does not have group files");
+
+ ret = luo_session_preserve_fd(self->session_fd, self->device->group_fd, 0);
+ ASSERT_EQ(ret, -ENOENT);
+}
+
+TEST_F(vfio_pci_liveupdate_uapi_test, preserve_container_fails)
+{
+ int ret;
+
+ if (self->iommu->iommufd)
+ SKIP(return, "iommufd-mode does not have container files");
+
+ ret = luo_session_preserve_fd(self->session_fd, self->iommu->container_fd, 0);
+ ASSERT_EQ(ret, -ENOENT);
+}
+
+int main(int argc, char *argv[])
+{
+ int fd;
+
+ fd = luo_open_device();
+ if (fd < 0)
+ ksft_exit_skip("open(%s) failed: %s, skipping\n",
+ LUO_DEVICE, strerror(errno));
+
+ close(fd);
+
+ device_bdf = vfio_selftests_get_bdf(&argc, argv);
+ return test_harness_run(argc, argv);
+}
--
2.55.0.795.g602f6c329a-goog
^ permalink raw reply related
* [PATCH v5 13/20] vfio: selftests: Build liveupdate library in VFIO selftests
From: Vipin Sharma @ 2026-07-14 15:14 UTC (permalink / raw)
To: kexec, linux-kernel, linux-doc, kvm, linux-mm, linux-kselftest
Cc: ajayachandra, alex, amastro, ankita, apopple, bhelgaas, chrisl,
christian.koenig, corbet, dmatlack, graf, jacob.pan, jgg, jgg,
jrhilke, julianr, kees, kevin.tian, leon, leonro, lukas, mattev,
michal.winiarski, parav, pasha.tatashin, praan, pratyush, rananta,
rientjes, rodrigo.vivi, rppt, saeedm, schnelle, skhan, skhawaja,
vipinsh, vivek.kasireddy, witu, yanjun.zhu, yi.l.liu
In-Reply-To: <20260714151505.3466855-1-vipinsh@google.com>
Import and build liveupdate selftest library in VFIO selftests.
It allows using liveupdate ioctls in VFIO selftests
Co-developed-by: David Matlack <dmatlack@google.com>
Signed-off-by: David Matlack <dmatlack@google.com>
Signed-off-by: Vipin Sharma <vipinsh@google.com>
---
tools/testing/selftests/vfio/Makefile | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/vfio/Makefile b/tools/testing/selftests/vfio/Makefile
index e6e8cb52ab03..4c8a30f950c4 100644
--- a/tools/testing/selftests/vfio/Makefile
+++ b/tools/testing/selftests/vfio/Makefile
@@ -21,6 +21,7 @@ TEST_FILES += scripts/setup.sh
include ../lib.mk
include lib/libvfio.mk
+include ../liveupdate/lib/libliveupdate.mk
CFLAGS += -I$(top_srcdir)/tools/include
CFLAGS += -MD
@@ -31,14 +32,17 @@ LDFLAGS += -pthread
LDLIBS += -luuid
-$(TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(LIBVFIO_O)
- $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $< $(LIBVFIO_O) $(LDLIBS) -o $@
+LIBS_O := $(LIBVFIO_O)
+LIBS_O += $(LIBLIVEUPDATE_O)
+
+$(TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(LIBS_O)
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $< $(LIBS_O) $(LDLIBS) -o $@
TEST_GEN_PROGS_O = $(patsubst %, %.o, $(TEST_GEN_PROGS))
$(TEST_GEN_PROGS_O): $(OUTPUT)/%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-TEST_DEP_FILES = $(patsubst %.o, %.d, $(TEST_GEN_PROGS_O) $(LIBVFIO_O))
+TEST_DEP_FILES = $(patsubst %.o, %.d, $(TEST_GEN_PROGS_O) $(LIBS_O))
-include $(TEST_DEP_FILES)
EXTRA_CLEAN += $(TEST_GEN_PROGS_O) $(TEST_DEP_FILES)
--
2.55.0.795.g602f6c329a-goog
^ permalink raw reply related
* [PATCH v5 12/20] docs: liveupdate: Add documentation for VFIO PCI
From: Vipin Sharma @ 2026-07-14 15:14 UTC (permalink / raw)
To: kexec, linux-kernel, linux-doc, kvm, linux-mm, linux-kselftest
Cc: ajayachandra, alex, amastro, ankita, apopple, bhelgaas, chrisl,
christian.koenig, corbet, dmatlack, graf, jacob.pan, jgg, jgg,
jrhilke, julianr, kees, kevin.tian, leon, leonro, lukas, mattev,
michal.winiarski, parav, pasha.tatashin, praan, pratyush, rananta,
rientjes, rodrigo.vivi, rppt, saeedm, schnelle, skhan, skhawaja,
vipinsh, vivek.kasireddy, witu, yanjun.zhu, yi.l.liu
In-Reply-To: <20260714151505.3466855-1-vipinsh@google.com>
From: David Matlack <dmatlack@google.com>
Add documentation for preserving VFIO device files across a Live Update,
generated from the kernel-doc comments in the code.
Signed-off-by: David Matlack <dmatlack@google.com>
Signed-off-by: Vipin Sharma <vipinsh@google.com>
---
Documentation/core-api/liveupdate.rst | 1 +
.../driver-api/vfio_pci_liveupdate.rst | 23 +++++++++++++++++++
MAINTAINERS | 1 +
3 files changed, 25 insertions(+)
create mode 100644 Documentation/driver-api/vfio_pci_liveupdate.rst
diff --git a/Documentation/core-api/liveupdate.rst b/Documentation/core-api/liveupdate.rst
index 2bce2644eba2..20f1d2e20508 100644
--- a/Documentation/core-api/liveupdate.rst
+++ b/Documentation/core-api/liveupdate.rst
@@ -38,6 +38,7 @@ The following types of file descriptors can be preserved
:maxdepth: 1
../mm/memfd_preservation
+ ../driver-api/vfio_pci_liveupdate
Public API
==========
diff --git a/Documentation/driver-api/vfio_pci_liveupdate.rst b/Documentation/driver-api/vfio_pci_liveupdate.rst
new file mode 100644
index 000000000000..1098b84e5ecd
--- /dev/null
+++ b/Documentation/driver-api/vfio_pci_liveupdate.rst
@@ -0,0 +1,23 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+====================================
+VFIO PCI Device Preservation via LUO
+====================================
+
+.. kernel-doc:: drivers/vfio/pci/vfio_pci_liveupdate.c
+ :doc: VFIO PCI Preservation via LUO
+
+VFIO PCI Preservation ABI
+=========================
+
+.. kernel-doc:: include/linux/kho/abi/vfio_pci.h
+ :doc: VFIO PCI Live Update ABI
+
+.. kernel-doc:: include/linux/kho/abi/vfio_pci.h
+ :internal:
+
+See Also
+========
+
+- :doc:`/core-api/liveupdate`
+- :doc:`/core-api/kho/index`
diff --git a/MAINTAINERS b/MAINTAINERS
index 77a35742de0a..43b3165d1c68 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -28328,6 +28328,7 @@ T: git https://github.com/awilliam/linux-vfio.git
F: Documentation/ABI/testing/debugfs-vfio
F: Documentation/ABI/testing/sysfs-devices-vfio-dev
F: Documentation/driver-api/vfio.rst
+F: Documentation/driver-api/vfio_pci_liveupdate.rst
F: drivers/vfio/
F: include/linux/kho/abi/vfio_pci.h
F: include/linux/vfio.h
--
2.55.0.795.g602f6c329a-goog
^ permalink raw reply related
* [PATCH v5 11/20] vfio: Enforce preserved devices are retrieved via LIVEUPDATE_SESSION_RETRIEVE_FD
From: Vipin Sharma @ 2026-07-14 15:14 UTC (permalink / raw)
To: kexec, linux-kernel, linux-doc, kvm, linux-mm, linux-kselftest
Cc: ajayachandra, alex, amastro, ankita, apopple, bhelgaas, chrisl,
christian.koenig, corbet, dmatlack, graf, jacob.pan, jgg, jgg,
jrhilke, julianr, kees, kevin.tian, leon, leonro, lukas, mattev,
michal.winiarski, parav, pasha.tatashin, praan, pratyush, rananta,
rientjes, rodrigo.vivi, rppt, saeedm, schnelle, skhan, skhawaja,
vipinsh, vivek.kasireddy, witu, yanjun.zhu, yi.l.liu
In-Reply-To: <20260714151505.3466855-1-vipinsh@google.com>
From: David Matlack <dmatlack@google.com>
Enforce that files for incoming (preserved by previous kernel) VFIO
devices are retrieved via LIVEUPDATE_SESSION_RETRIEVE_FD rather than by
opening the corresponding VFIO character device or via
VFIO_GROUP_GET_DEVICE_FD.
Both of these methods would result in VFIO initializing the device
without access to the preserved state of the device passed by the
previous kernel.
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Signed-off-by: David Matlack <dmatlack@google.com>
Co-developed-by: Vipin Sharma <vipinsh@google.com>
Signed-off-by: Vipin Sharma <vipinsh@google.com>
---
drivers/vfio/device_cdev.c | 8 ++++++++
drivers/vfio/group.c | 9 +++++++++
drivers/vfio/pci/vfio_pci_liveupdate.c | 6 ++++++
drivers/vfio/vfio.h | 18 ++++++++++++++++++
4 files changed, 41 insertions(+)
diff --git a/drivers/vfio/device_cdev.c b/drivers/vfio/device_cdev.c
index 970932f22ecb..0050f0fe456b 100644
--- a/drivers/vfio/device_cdev.c
+++ b/drivers/vfio/device_cdev.c
@@ -49,6 +49,14 @@ static int vfio_device_cdev_open(struct vfio_device *device, struct file **filep
}
*filep = file;
+ } else if (vfio_liveupdate_incoming_is_preserved(device)) {
+ /*
+ * Since it is live update preserved device, it must be
+ * retrieved via LIVEUPDATE_SESSION_RETRIEVE_FD instead of
+ * opening /dev/vfio/devices/vfioX.
+ */
+ ret = -EBUSY;
+ goto err_free_device_file;
}
file->private_data = df;
diff --git a/drivers/vfio/group.c b/drivers/vfio/group.c
index b2299e5bc6df..62b4eaabc829 100644
--- a/drivers/vfio/group.c
+++ b/drivers/vfio/group.c
@@ -316,6 +316,15 @@ static int vfio_group_ioctl_get_device_fd(struct vfio_group *group,
if (IS_ERR(device))
return PTR_ERR(device);
+ /*
+ * This device was preserved across a Live Update. Accessing it via
+ * VFIO_GROUP_GET_DEVICE_FD is not allowed.
+ */
+ if (vfio_liveupdate_incoming_is_preserved(device)) {
+ vfio_device_put_registration(device);
+ return -EBUSY;
+ }
+
fd = FD_ADD(O_CLOEXEC, vfio_device_open_file(device));
if (fd < 0)
vfio_device_put_registration(device);
diff --git a/drivers/vfio/pci/vfio_pci_liveupdate.c b/drivers/vfio/pci/vfio_pci_liveupdate.c
index 4baac80d03f0..f0ea37d98696 100644
--- a/drivers/vfio/pci/vfio_pci_liveupdate.c
+++ b/drivers/vfio/pci/vfio_pci_liveupdate.c
@@ -47,6 +47,12 @@
* ...
* ioctl(session_fd, LIVEUPDATE_SESSION_FINISH, ...);
*
+ * .. note::
+ * After kexec, if a device was preserved by the previous kernel, attempting
+ * to open a new file for the device via its character device
+ * (``/dev/vfio/devices/X``) or via ``VFIO_GROUP_GET_DEVICE_FD`` will fail
+ * with ``-EBUSY``.
+ *
* Restrictions
* ============
*
diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h
index e4b72e79b7e3..496180950eb6 100644
--- a/drivers/vfio/vfio.h
+++ b/drivers/vfio/vfio.h
@@ -11,6 +11,7 @@
#include <linux/cdev.h>
#include <linux/module.h>
#include <linux/vfio.h>
+#include <linux/pci.h>
struct iommufd_ctx;
struct iommu_group;
@@ -461,4 +462,21 @@ static inline void vfio_device_debugfs_init(struct vfio_device *vdev) { }
static inline void vfio_device_debugfs_exit(struct vfio_device *vdev) { }
#endif /* CONFIG_VFIO_DEBUGFS */
+#ifdef CONFIG_VFIO_PCI_LIVEUPDATE
+static inline bool vfio_liveupdate_incoming_is_preserved(struct vfio_device *device)
+{
+ struct device *d = device->dev;
+
+ if (dev_is_pci(d))
+ return pci_liveupdate_is_incoming(to_pci_dev(d));
+
+ return false;
+}
+#else
+static inline bool vfio_liveupdate_incoming_is_preserved(struct vfio_device *device)
+{
+ return false;
+}
+#endif /* CONFIG_VFIO_PCI_LIVEUPDATE */
+
#endif
--
2.55.0.795.g602f6c329a-goog
^ 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