Linux virtualization list
 help / color / mirror / Atom feed
* Re: [PATCH v2 03/13] mm: convert __get_unmapped_area() to use vma_flags_t
From: Vlastimil Babka (SUSE) @ 2026-07-22 14:17 UTC (permalink / raw)
  To: Lorenzo Stoakes, Andrew Morton, David Hildenbrand,
	Liam R. Howlett, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Thomas Bogendoerfer, Benjamin LaHaise, Alexander Viro,
	Christian Brauner, Jan Kara, Hugh Dickins, Baolin Wang, Jann Horn,
	Pedro Falcato, Muchun Song, Oscar Salvador, Zi Yan, Nico Pache,
	Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
	Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
	Christophe Leroy (CS GROUP), Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Lucas Stach,
	Russell King, Christian Gmeiner, Inki Dae, Seung-Woo Kim,
	Kyungmin Park, Krzysztof Kozlowski, Peter Griffin, Alim Akhtar,
	Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
	Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
	Sean Paul, Marijn Suijten, Lyude Paul, Danilo Krummrich,
	Tomi Valkeinen, Sandy Huang, Heiko Stübner, Andy Yan,
	Thierry Reding, Mikko Perttunen, Jonathan Hunter, Gerd Hoffmann,
	Dmitry Osipenko, Gurchetan Singh, Chia-I Wu, Zack Rusin,
	Broadcom internal kernel review list, Matthew Brost,
	Thomas Hellström, Oleksandr Andrushchenko, Helge Deller,
	Kees Cook, Jaroslav Kysela, Takashi Iwai, Boris Brezillon,
	Steven Price, Liviu Dudau
  Cc: linux-mm, linux-kernel, linux-mips, linux-aio, linux-fsdevel,
	linuxppc-dev, dri-devel, etnaviv, linux-samsung-soc, intel-gfx,
	linux-arm-msm, freedreno, nouveau, linux-rockchip, linux-tegra,
	virtualization, intel-xe, xen-devel, linux-fbdev, linux-sound
In-Reply-To: <20260711-b4-vma-flags-mm-v2-3-0fa2357d5431@kernel.org>

On 7/11/26 20:45, Lorenzo Stoakes wrote:
> Update __get_unmapped_area() to be parameterised by vma_flags_t rather than
> vm_flags_t as part of the effort to move VMA flags from a system word to a
> bitmap.
> 
> We cascade the changes up to arch_get_unmapped_area_topdown() and
> arch_get_unmapped_area(), where, for now, we use vma_flags_to_legacy() in
> order to propagate the VMA flags.
> 
> No functional change intended.
> 
> Reviewed-by: Lance Yang <lance.yang@linux.dev>
> Reviewed-by: Zi Yan <ziy@nvidia.com>
> Signed-off-by: Lorenzo Stoakes <ljs@kernel.org>

Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>


^ permalink raw reply

* Re: [PATCH v2 02/13] mm/vma: update do_mmap() to use vma_flags_t
From: Vlastimil Babka (SUSE) @ 2026-07-22 13:33 UTC (permalink / raw)
  To: Lorenzo Stoakes, Andrew Morton, David Hildenbrand,
	Liam R. Howlett, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Thomas Bogendoerfer, Benjamin LaHaise, Alexander Viro,
	Christian Brauner, Jan Kara, Hugh Dickins, Baolin Wang, Jann Horn,
	Pedro Falcato, Muchun Song, Oscar Salvador, Zi Yan, Nico Pache,
	Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
	Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
	Christophe Leroy (CS GROUP), Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Lucas Stach,
	Russell King, Christian Gmeiner, Inki Dae, Seung-Woo Kim,
	Kyungmin Park, Krzysztof Kozlowski, Peter Griffin, Alim Akhtar,
	Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
	Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
	Sean Paul, Marijn Suijten, Lyude Paul, Danilo Krummrich,
	Tomi Valkeinen, Sandy Huang, Heiko Stübner, Andy Yan,
	Thierry Reding, Mikko Perttunen, Jonathan Hunter, Gerd Hoffmann,
	Dmitry Osipenko, Gurchetan Singh, Chia-I Wu, Zack Rusin,
	Broadcom internal kernel review list, Matthew Brost,
	Thomas Hellström, Oleksandr Andrushchenko, Helge Deller,
	Kees Cook, Jaroslav Kysela, Takashi Iwai, Boris Brezillon,
	Steven Price, Liviu Dudau
  Cc: linux-mm, linux-kernel, linux-mips, linux-aio, linux-fsdevel,
	linuxppc-dev, dri-devel, etnaviv, linux-samsung-soc, intel-gfx,
	linux-arm-msm, freedreno, nouveau, linux-rockchip, linux-tegra,
	virtualization, intel-xe, xen-devel, linux-fbdev, linux-sound
In-Reply-To: <20260711-b4-vma-flags-mm-v2-2-0fa2357d5431@kernel.org>

On 7/11/26 20:44, Lorenzo Stoakes wrote:
> The core do_mmap() function accepts a vm_flags_t parameter which it then
> manipulates before passing to mmap_region() to do the heavy lifting of the
> memory mapping.
> 
> Update do_mmap() to instead accept a vma_flags_t parameter, and adjust all
> the logic within do_mmap() to manipulate this instead.
> 
> This is as part of the ongoing effort to convert VMA flags from a system
> word size to a bitmap type which allows us to unrestrict the number of VMA
> flags, as well as gain control over how VMA flag manipulation occurs.
> 
> We do not cascade these changes to all functions which accept vm_flags_t,
> but rather use vma_flags_to_legacy() where necessary, specifically
> deferring converting calc_vm_prot_bits(), calc_vm_flag_bits() and
> __get_unmapped_area() to vma_flags_t.
> 
> Also utilise the new vma_flags_can_grow() predicate which correctly handles
> the case of architectures without upward growing stacks.
> 
> As part of this change, introduce VMA_SHADOW_STACK so we can correctly
> handle the case of the shadow stack not being defined.
> 
> No functional change intended.
> 
> Reviewed-by: Lance Yang <lance.yang@linux.dev>
> Reviewed-by: Zi Yan <ziy@nvidia.com>
> Signed-off-by: Lorenzo Stoakes <ljs@kernel.org>

Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>


^ permalink raw reply

* Re: [PATCH v2 01/13] mm: introduce vma_flags_can_grow() and vma_can_grow()
From: Vlastimil Babka (SUSE) @ 2026-07-22 13:26 UTC (permalink / raw)
  To: Lorenzo Stoakes, Andrew Morton, David Hildenbrand,
	Liam R. Howlett, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Thomas Bogendoerfer, Benjamin LaHaise, Alexander Viro,
	Christian Brauner, Jan Kara, Hugh Dickins, Baolin Wang, Jann Horn,
	Pedro Falcato, Muchun Song, Oscar Salvador, Zi Yan, Nico Pache,
	Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
	Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
	Christophe Leroy (CS GROUP), Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Lucas Stach,
	Russell King, Christian Gmeiner, Inki Dae, Seung-Woo Kim,
	Kyungmin Park, Krzysztof Kozlowski, Peter Griffin, Alim Akhtar,
	Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
	Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
	Sean Paul, Marijn Suijten, Lyude Paul, Danilo Krummrich,
	Tomi Valkeinen, Sandy Huang, Heiko Stübner, Andy Yan,
	Thierry Reding, Mikko Perttunen, Jonathan Hunter, Gerd Hoffmann,
	Dmitry Osipenko, Gurchetan Singh, Chia-I Wu, Zack Rusin,
	Broadcom internal kernel review list, Matthew Brost,
	Thomas Hellström, Oleksandr Andrushchenko, Helge Deller,
	Kees Cook, Jaroslav Kysela, Takashi Iwai, Boris Brezillon,
	Steven Price, Liviu Dudau
  Cc: linux-mm, linux-kernel, linux-mips, linux-aio, linux-fsdevel,
	linuxppc-dev, dri-devel, etnaviv, linux-samsung-soc, intel-gfx,
	linux-arm-msm, freedreno, nouveau, linux-rockchip, linux-tegra,
	virtualization, intel-xe, xen-devel, linux-fbdev, linux-sound
In-Reply-To: <20260711-b4-vma-flags-mm-v2-1-0fa2357d5431@kernel.org>

On 7/11/26 20:44, Lorenzo Stoakes wrote:
> These test whether the VMA has stack semantics, i.e. is able to grow
> upwards or downwards depending on the architecture.
> 
> In order to account for arches which do not support upward-growing stacks,
> introduce VMA_GROWSUP whose definition depends on the architecture
> supporting it, and use vma_flags_test_single_mask() in vma_flags_can_grow()
> to account for this.
> 
> No functional change intended.
> 
> Reviewed-by: Zi Yan <ziy@nvidia.com>
> Reviewed-by: Lance Yang <lance.yang@linux.dev>
> Signed-off-by: Lorenzo Stoakes <ljs@kernel.org>

Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>


^ permalink raw reply

* Re: [RFC PATCH 0/4] virtio: SQ/CQ doorbell polling for vhost-scsi
From: rom.wang @ 2026-07-22 11:00 UTC (permalink / raw)
  To: mst, jasowangio, eperezma
  Cc: virtualization, linux-kernel, linux-scsi, kvm, Yufeng Wang
In-Reply-To: <CAJaqyWe_nhVOvfA03So_edVO_+1UeHCC6RGnHRQB9dq7CWS4LQ@mail.gmail.com>

From: Yufeng Wang <wangyufeng@kylinos.cn>

Thank you for the detailed feedback. We've completed benchmark
testing comparing the existing notification mechanisms against the
proposed SQ/CQ polling. The results are informative.


Test Modes Explained
--------------------

To answer your second question with data, we tested four modes:

1. **baseline**: Default vhost-scsi with event_idx auto-negotiated.
   I/O engine: libaio. Submission uses MMIO kick (VM exit), completion
   uses MSI-X interrupt (VM exit). The guest driver dynamically toggles
   NO_NOTIFY/NO_INTERRUPT during completion processing, but these are
   short windows — most I/O still incurs VM exits on both paths.

2. **poll-queue**: This mode combines the existing notification features
   you mentioned:
   - VIRTIO_RING_F_EVENT_IDX: auto-negotiated (same as baseline)
   - VIRTQ_AVAIL_F_NO_INTERRUPT: effectively permanent — poll queue
     VQs have callback=NULL and no MSI-X vector, so the guest never
     receives completion interrupts regardless of the flag state
   - VIRTQ_USED_F_NO_NOTIFY: vhost dynamically toggles this during
     active processing (vhost_disable_notify/enable_notify)
   - VIRTIO_F_NOTIFICATION_DATA: negotiated but vhost kernel does not
     process notification data, so no practical effect
   
   Implemented via virtio-scsi poll queues (virtscsi_poll_queues=16,
   callback=NULL, no MSI-X vector) + io_uring IOPOLL mode (--hipri).
   blk-mq polls the used ring for completions via virtscsi_mq_poll().
   This eliminates completion-side VM exits. However, submission still
   uses MMIO kick (VM exit). Note: libaio cannot use this mode because
   aio.c strips IOCB_HIPRI ("no one is going to poll for this I/O").

3. **sqcq-poll**: The proposed SQ/CQ doorbell polling (this RFC) with
   libaio. Guest writes sq->idx instead of MMIO kick (no VM exit).
   Guest poll thread checks used ring via more_used() (no interrupt).
   NEED_WAKEUP protocol enables adaptive sleep when idle. Eliminates
   VM exits on BOTH submission and completion paths.

4. **sqcq-uring**: Same SQ/CQ polling but with io_uring + --hipri.
   Included to isolate the I/O engine variable from the polling
   mechanism.


Results
-------

Test configuration:
  x86_64: Intel Xeon E5-2680 v4 @ 2.40GHz, 16 vCPUs
          NVMe SAMSUNG MZ1LB960HAJQ-000MV (960GB)
  arm64:  Kunpeng 920 (2.6GHz), 16 vCPUs
          NVMe INTEL SSDPED1K375GA (375GB)
  Backend: vhost-scsi with TCM loopback to NVMe

arm64 IOPS (best of 3 runs, fio 4K random I/O):

  Test              baseline   poll-queue    sqcq-poll   sqcq-uring
  ─────────────     ────────   ──────────    ─────────   ──────────
  randread QD1       23,751      29,892       29,680      26,427
  randread QD32 NJ1  93,221     162,849 *     84,967      70,271
  randread QD32 NJ4 184,939     186,859      340,780     235,310
  randread QD32 NJ8 190,562     188,382      520,946     518,197
  randwrite QD1      24,131          —        25,520      25,485
  randwrite QD32 NJ1 84,725          —        70,652      68,518
  randwrite QD32 NJ4 204,745          —       323,449     312,204
  randwrite QD32 NJ8 193,802          —       522,322     516,448

  * poll-queue NJ1 read shows high IOPS but hangs at NJ≥4 (see below)

x86_64 IOPS (best of 3 runs):

  Test              baseline   poll-queue    sqcq-poll   sqcq-uring
  ─────────────     ────────   ──────────    ─────────   ──────────
  randread QD1        8,316       9,022        9,533       9,489
  randread QD32 NJ1 124,909     146,744      165,761     165,929
  randread QD32 NJ4 305,951     332,139      378,305     379,546
  randread QD32 NJ8 344,223     356,328      374,932     374,976
  randwrite QD1      20,106      24,464       27,265      27,768
  randwrite QD32 NJ1 131,836    153,203      162,145     161,402
  randwrite QD32 NJ4 232,908    234,559      232,976     231,336
  randwrite QD32 NJ8 231,242    229,858      231,828     231,465


Key Findings
------------

1. **poll-queue excels at NJ=1 (arm64)**: On arm64 4K randread QD32
   NJ1, poll-queue achieved 163K IOPS — significantly higher than
   baseline (93K, +75%) and SQ/CQ polling (85K). io_uring IOPOLL
   mode is very efficient for single-queue workloads because the
   submitting task polls for completion directly, avoiding both
   interrupt latency and poll thread scheduling overhead.

2. **SQ/CQ dramatically outperforms poll-queue at NJ≥4 (arm64)**:
   At 4K randread QD32, poll-queue and SQ/CQ diverge sharply:
   - NJ4: poll-queue 187K vs SQ/CQ 341K (+82% over poll-queue)
   - NJ8: poll-queue 188K vs SQ/CQ 521K (+177% over poll-queue)
   SQ/CQ also outperforms baseline by +84% (NJ4) and +173% (NJ8).

3. **libaio incompatibility**: The existing poll queue mechanism
   requires io_uring IOPOLL mode. libaio explicitly strips IOCB_HIPRI
   (fs/aio.c: "no one is going to poll for this I/O"), so poll queues
   are inaccessible to libaio users. SQ/CQ works with any I/O engine
   because the poll thread is independent of the submitting task.


Development Insights
--------------------

Beyond eliminating VM exits, two engineering decisions were critical
to achieving the performance shown above:

1. **TCM completion CPU steering**: Our initial goal was 5-10% IOPS
   improvement at 4K random I/O QD1 NJ1. After implementing the basic
   polling and NEED_WAKEUP protocol, this target was not met. The
   bottleneck was that TCM completions were being scheduled on the same
   CPU as the busy poll thread, starving the completion workqueue. We
   added vhost_sqcq_pick_completion_cpu() to steer TCM completions to
   a free CPU (avoiding busy poll cores), with fallback to next-CPU
   when all cores are occupied. This closed the gap and achieved the
   QD1 target.

2. **Adaptive idle policy with EMA**: After QD1 targets were met,
   we tested higher concurrency (QD32 NJ4/NJ8) and found that
   aggressive polling caused performance degradation under
   multi-queue workloads — likely due to the poll thread consuming
   excessive CPU cycles that competing vCPUs needed. We solved this
   by implementing an EMA-based adaptive spin budget: the poll thread
   spins within a time window derived from recent I/O latency, then
   yields. Combined with the NEED_WAKEUP protocol, this allows the
   poll thread to busy-spin when active but sleep when idle, avoiding
   CPU contention with other vCPUs.


On the vDPA Question
--------------------

The generic vDPA device approach you suggested is indeed a better
direction. The QEMU-side zero-code advantage (leveraging existing
vdpa-dev.c) is very attractive. Our concern is that vhost-scsi's
TCM integration (SCSI CDB, ALUA, persistent reservations) would
need to be wrapped as a vDPA backend. This feels like a 0-to-1
engineering effort, and we're uncertain about the actual scope of
work involved. If there are additional guidelines or examples
available, we'd be very willing to explore this direction.


One More Thing: SQ/CQ + poll-queue Combined
--------------------------------------------

During arm64 testing, we accidentally ran the poll-queue benchmark
(--hipri, io_uring, virtscsi_poll_queues=16) on a kernel that also
had VIRTIO_F_SQCQ_POLL negotiated. This "poll-sqcq" mode combines
both mechanisms simultaneously:

  - Submission: SQ/CQ doorbell (sq->idx write, no VM exit)
  - Completion: both SQ/CQ poll thread AND blk-mq poll via io_uring

The results were surprisingly strong (arm64, 4K random I/O):

  Test              baseline   poll-queue   poll-sqcq   sqcq-poll
  ─────────────     ────────   ──────────   ─────────   ─────────
  randread QD1       23,751      29,892      41,683      29,680
  randread QD32 NJ1  93,221     162,849     193,029      84,967
  randread QD32 NJ4 184,939     186,859     585,445     340,780
  randread QD32 NJ8 190,562     188,382     560,727     520,946
  randwrite QD1      24,131          —       38,591      25,520
  randwrite QD32 NJ1 84,725          —      187,421      70,652
  randwrite QD32 NJ4 204,745          —      598,419     323,449
  randwrite QD32 NJ8 193,802          —      569,890     522,322

poll-sqcq outperforms both individual mechanisms across all test
cases. We haven't fully analyzed why, but suspect the combination
benefits from:
  - SQ/CQ eliminating submission VM exits
  - io_uring IOPOLL providing low-latency completion detection via
    blk-mq (directly in submitting task context)
  - SQ/CQ poll thread as a secondary completion poller covering VQs
    that blk-mq doesn't reach

This is preliminary and accidental data, but we think it's worth
sharing as it suggests the two mechanisms are complementary rather
than mutually exclusive.

Benchmark scripts and raw fio JSON data are available and can be
sent as a follow-up upon request.


Best regards,
Yufeng

Signed-off-by: Yufeng Wang <wangyufeng@kylinos.cn>


^ permalink raw reply

* Re: [PATCH v8 10/11] virt/steal_governor: Implement steal_governor policy loop
From: Shrikanth Hegde @ 2026-07-22 10:27 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-kernel, mingo, peterz, juri.lelli, vincent.guittot,
	yury.norov, kprateek.nayak, iii, corbet, tglx, gregkh, pbonzini,
	seanjc, vschneid, huschle, rostedt, dietmar.eggemann, maddy,
	srikar, hdanton, chleroy, vineeth, frederic, arighi, pauld,
	christian.loehle, tj, tommaso.cucinotta, maz, rafael, rdunlap,
	kernellwp, linux-doc, jgross, virtualization
In-Reply-To: <amBztSFLg2X72P2N@yury>



On 7/22/26 1:09 PM, Yury Norov wrote:
> On Wed, Jul 22, 2026 at 12:44:03PM +0530, Shrikanth Hegde wrote:
>> Hi Yury.
> 
> ...
> 
>>>> +	schedule_delayed_work(&sg_core_ctx.work,
>>>> +			      msecs_to_jiffies(sg_core_ctx.interval_ms));
>>>
>>> If you need jiffies, why don't you have them in the structure, instead of
>>> milliseconds?
>>>
>>> 	schedule_delayed_work(&sg_core_ctx.work, sg_core_ctx.delay);
>>>
>>
>> I would prefer milliseconds as jiffies is very difficult for users to understand.
>> It depends on HZ value and one has to query from configs.
>>
>> HZ can very from 100 to 1000 today. Again I will have to play tricks to schedule
>> the governor at fixed intervals.
>>
>> So i think it is better to use milliseconds here.
>> Correct me if i am not making sense.
> 
> 
> User provides milliseconds, then in init() you convert them into
> jiffies and save in sg.delay. That's it.

Ah ok. That's simpler. Will add a delay filed to the struct.


^ permalink raw reply

* Re: [PATCH RFC v3 0/6] Add Rust virtio bindings and sample device
From: Manos Pitsidianakis @ 2026-07-22  9:55 UTC (permalink / raw)
  To: Eugenio Perez Martin
  Cc: Michael S. Tsirkin, Manos Pitsidianakis, Peter Hilber,
	Stefano Garzarella, Stefan Hajnoczi, Viresh Kumar, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
	Daniel Almeida, rust-for-linux, Jason Wang, Xuan Zhuo,
	virtualization, linux-kernel
In-Reply-To: <CAJaqyWfq=tAdaAzqBtrkKt0fwiQL=SU6QYVydos1q4GhHy-JDg@mail.gmail.com>

On Wed, 22 Jul 2026 12:31, Eugenio Perez Martin <eperezma@redhat.com> wrote:
>On Wed, Jul 22, 2026 at 11:04 AM Manos Pitsidianakis
><manos@pitsidianak.is> wrote:
>>
>> Hi Eugenio,
>>
>> On Wed, 22 Jul 2026 11:49, Eugenio Perez Martin <eperezma@redhat.com> wrote:
>> >On Tue, Jul 21, 2026 at 8:24 AM Manos Pitsidianakis
>> ><manos@pitsidianak.is> wrote:
>> >>
>> >> Ping.
>> >>
>> >> I have a different version of the series WIP with a virtio-rng instead
>> >> of virtio-rtc, based on
>> >> https://lore.kernel.org/lkml/20260529-rust-hw_random-virtio-rng-v1-0-b3153dd90311@pitsidianak.is/
>> >> (which needs a v2 also)
>> >>
>> >> But since this series hasn't gotten any feedback on the virtio part, I'd
>> >> like to ask if there is any before respinning.
>> >>
>> >> Thanks!
>> >>
>> >
>> >I also think this will be a great addition, but I have very little
>> >knowledge of Rust. Is it easy to implement the simplest virtio-net
>> >driver using Rust, without CVQ or extra features, so I can test it and
>> >hopefully build features on top? Would it help?
>>
>> I think so, however it would not be upstreamable right away since (I
>> think) there are no netdev Rust bindings and abstractions yet. I will
>> take a look when I have the time...
>>
>
>How about starting even smaller? Just with the virtio-ring processing
>that all virtio drivers share.

That's already possible with this series (adding inbufs/outbufs). If you 
mean a virtio-net that can react to virtio commands but does not do 
anything with packets, yes we can do that. I can try setting up a 
minimum driver we can work on together if you like.

Manos

>
>> (This is something I am also interested in because I'm working on a
>> different kind of network device)
>>
>> You can definitely play with the sample driver included in this series
>> however!
>>
>> Manos
>>
>>
>> >
>> >Thanks!
>> >
>> >> On Sun, 10 May 2026 16:38, Manos Pitsidianakis <manos@pitsidianak.is> wrote:
>> >> >Hi all, this RFC series adds Rust bindings for Virtio drivers
>> >> >(frontends in virtio parlance).
>> >> >
>> >> >As a PoC, it also adds a sample virtio-rtc driver which performs
>> >> >capability discovery through the virtqueue without registering any clock.
>> >> >
>> >> >Before I send a cleaned-up non-RFC I would like some initial feedback
>> >> >(i.e. is it something the upstream wants?)
>> >> >
>> >> >This was tested with the rust-vmm vhost-device-rtc device backend that I
>> >> >wrote[^0]:
>> >> >
>> >> >[^0]: https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-rtc
>> >> >
>> >> >Instructions:
>> >> >
>> >> >  Run the daemon in a separate terminal:
>> >> >
>> >> >  $ cargo run --bin vhost-device-rtc -- -s /tmp/rtc.sock
>> >> >
>> >> >  Then run the VM:
>> >> >
>> >> >  $ qemu-system-aarch64 \
>> >> >    -machine type=virt,virtualization=off,acpi=on \
>> >> >    -cpu host \
>> >> >    -smp 8 \
>> >> >    -accel kvm \
>> >> >    -drive if=virtio,format=qcow2,file=./debian-13-nocloud-arm64-daily.qcow2 \
>> >> >    -device virtio-net-pci,netdev=unet \
>> >> >    -device virtio-scsi-pci \
>> >> >    -serial mon:stdio \
>> >> >    -m 8192 \
>> >> >    -object memory-backend-memfd,id=mem,size=8G,share=on \
>> >> >    -numa node,memdev=mem \
>> >> >    -display none \
>> >> >    -vga none \
>> >> >    -kernel /path/to/linux/build/arch/arm64/boot/Image \
>> >> >    -device vhost-user-test-device,chardev=rtc,id=rtc,virtio-id=17,num_vqs=2,vq_size=1024 \
>> >> >    -chardev socket,path=/tmp/rtc.sock,id=rtc \
>> >> >    ...
>> >> >
>> >> >  Example output:
>> >> >    [    1.105238] rust_virtio_rtc: Probe Rust virtio driver sample.
>> >> >    [    1.105645] rust_virtio_rtc: Found 1 vqs.
>> >> >    [    1.136050] rust_virtio_rtc: process_requestq got buf 16 bytes
>> >> >    [    1.136125] rust_virtio_rtc: Got response! Ok(RespCfg { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, num_clocks: Le16(3), reserved: [0, 0, 0, 0, 0, 0] })
>> >> >    [    1.136701] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 3, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] })
>> >> >    [    1.136724] rust_virtio_rtc virtio0: cannot expose clock 0 (type 3, variant 0, flags 0) to userspace
>> >> >    [    1.137259] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(1777890485031060388) })
>> >> >    [    1.137277] rust_virtio_rtc: #0 clock reading = 1777890485031060388
>> >> >    [    1.137749] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 1, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] })
>> >> >    [    1.137769] rust_virtio_rtc virtio0: cannot expose clock 1 (type 1, variant 0, flags 0) to userspace
>> >> >    [    1.138247] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(1777890485032086075) })
>> >> >    [    1.138264] rust_virtio_rtc: #1 clock reading = 1777890485032086075
>> >> >    [    1.138730] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 2, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] })
>> >> >    [    1.138751] rust_virtio_rtc virtio0: cannot expose clock 2 (type 2, variant 0, flags 0) to userspace
>> >> >    [    1.139253] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(338567896865557) })
>> >> >    [    1.139270] rust_virtio_rtc: #2 clock reading = 338567896865557
>> >> >
>> >> >Concerns - Notes - TODOs
>> >> >========================
>> >> >
>> >> >- Virtqueue lifetimes don't neatly apply to Rust as expected, so a lot
>> >> >  of times we have to go through unsafe pointer dereferences (though
>> >> >  which are guaranteed by Virtio subsystem to be valid, for example when
>> >> >  a callback is called with the vq argument). There's a potential for
>> >> >  misuse and definitely could use better thinking.
>> >> >- `struct virtio_device` is not reference-counted like other implemented
>> >> >  device types in rust/kernel. Maybe we need to change C API first to
>> >> >  make them reference counted, assuming this doesn't break anything?
>> >> >- The sample driver obviously conflicts with the C implementation, so
>> >> >  this would either need to move out of samples/ or figure out some way
>> >> >  to handle this in kbuild.
>> >> >- kernel::virtio module and its types need a few rustdoc examples that I
>> >> >  will add in followup series
>> >> >- Note that the registration of RTC clocks etc in the sample driver is
>> >> >  not done, I'm putting it off until I receive some feedback first. The
>> >> >  sample driver otherwise does send and receive data from the virtqueue
>> >> >  as a PoC.
>> >> >
>> >> >PS: No LLMs used so any mistakes and goofs are solely written by me.
>> >> >
>> >> >Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
>> >> >---
>> >> >Changes in v3:
>> >> >- Removed unused methods from virtio API
>> >> >- Clean up how scattergather lists are added to virtqueues by using
>> >> >  owned SGTables only, and make the API safe(r)
>> >> >- Add RAII cleanup for find_vqs return value that calls del_vqs
>> >> >- Reset device after remove callback
>> >> >- Significantly clean up sample driver as a result of the other cleanups
>> >> >- Link to v2: https://lore.kernel.org/r/20260509-rust-virtio-v2-0-c1e30ec2bd21@pitsidianak.is
>> >> >
>> >> >Changes in v2:
>> >> >- Move helper ifdefs to helper file (thanks Alice)
>> >> >- Changed CONFIG checks to IS_ENABLED to allow for CONFIG_VIRTIO=m
>> >> >- Split all use imports to one item per line according to style guide
>> >> >- Fixed wait_for_completion_interruptible*() rustdocs
>> >> >- Use Jiffy type alias in wait_for_completion_interruptible_timeout()
>> >> >- Pepper and salt #[inline]s wherever appropriate as per style guide
>> >> >- Split probe() into probe() and init() to allow cleaning up if init
>> >> >  fails
>> >> >- Remove unnecessary Send and Sync unsafe impls for
>> >> >  kernel::virtio::Device
>> >> >- Remove unnecessary LeSize and BeSize
>> >> >- Accept Option<_> for virtqueue callback when creating a VirtqueueInfo
>> >> >- Made all vq buffer adding operations unsafe
>> >> >- Use AtomicU16 instead of Cell<u16> for sample virtio driver
>> >> >- Fix RespHead field types in sample virtio driver
>> >> >- Fix response error checking in sample virtio driver
>> >> >- Change some device contexts in method signatures
>> >> >- Link to v1: https://lore.kernel.org/r/20260505-rust-virtio-v1-0-9563383909e4@pitsidianak.is
>> >> >
>> >> >---
>> >> >Manos Pitsidianakis (6):
>> >> >      rust/bindings: generate virtio bindings
>> >> >      rust/helpers: add virtio.c
>> >> >      rust/kernel/device: return parent at same context
>> >> >      rust: add virtio module
>> >> >      rust: impl interruptible waits for Completion
>> >> >      samples/rust: Add sample virtio-rtc driver [WIP]
>> >> >
>> >> > MAINTAINERS                     |   9 +
>> >> > rust/bindings/bindings_helper.h |   5 +
>> >> > rust/helpers/helpers.c          |   1 +
>> >> > rust/helpers/virtio.c           |  37 ++++
>> >> > rust/kernel/device.rs           |   2 +-
>> >> > rust/kernel/lib.rs              |   2 +
>> >> > rust/kernel/sync/completion.rs  |  42 +++-
>> >> > rust/kernel/virtio.rs           | 423 ++++++++++++++++++++++++++++++++++++++++
>> >> > rust/kernel/virtio/utils.rs     |  57 ++++++
>> >> > rust/kernel/virtio/virtqueue.rs | 314 +++++++++++++++++++++++++++++
>> >> > samples/rust/Kconfig            |  15 ++
>> >> > samples/rust/Makefile           |   1 +
>> >> > samples/rust/rust_virtio_rtc.rs | 403 ++++++++++++++++++++++++++++++++++++++
>> >> > 13 files changed, 1309 insertions(+), 2 deletions(-)
>> >> >---
>> >> >base-commit: 028ef9c96e96197026887c0f092424679298aae8
>> >> >change-id: 20260504-rust-virtio-8523b01dfdc2
>> >> >
>> >> >Best regards,
>> >> >--
>> >> >Manos Pitsidianakis <manos@pitsidianak.is>
>> >> >
>>
>

^ permalink raw reply

* Re: [PATCH v5 5/5] vhost/vsock: add VHOST_RESET_OWNER ioctl
From: Stefano Garzarella @ 2026-07-22  9:43 UTC (permalink / raw)
  To: Andrey Drobyshev
  Cc: linux-kernel, kvm, virtualization, netdev, mst, stefanha,
	dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
	den
In-Reply-To: <20260720102241.371610-6-andrey.drobyshev@virtuozzo.com>

On Mon, Jul 20, 2026 at 01:22:41PM +0300, Andrey Drobyshev wrote:
>From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
>
>This ioctl is needed for QEMU's CPR (checkpoint-restore) migration of
>the guest with vhost-vsock device.  For this to work, we need to reset
>the device ownership on the source side by calling RESET_OWNER, and then
>claim it on the dest side by calling SET_OWNER.  We expect not to lose any
>AF_VSOCK connection while this happens.
>
>To that end, unlike the release path, RESET_OWNER keeps the guest CID
>hashed: established connections survive, and host sends issued while
>the device is between owners simply stay on send_pkt_queue until the
>next device start drains them.
>
>Since the device stays reachable through the CID hash, the lockless
>send/cancel paths can race with the worker teardown in
>vhost_workers_free().  The previous commit ("vhost: synchronize with
>RCU readers when freeing workers") makes that safe.
>
>Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
>Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
>---
> drivers/vhost/vsock.c | 25 +++++++++++++++++++++++++
> 1 file changed, 25 insertions(+)

Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>


^ permalink raw reply

* Re: [PATCH v5 4/5] vhost: synchronize with RCU readers when freeing workers
From: Stefano Garzarella @ 2026-07-22  9:43 UTC (permalink / raw)
  To: Andrey Drobyshev
  Cc: linux-kernel, kvm, virtualization, netdev, mst, stefanha,
	dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
	den
In-Reply-To: <20260720102241.371610-5-andrey.drobyshev@virtuozzo.com>

On Mon, Jul 20, 2026 at 01:22:40PM +0300, Andrey Drobyshev wrote:
>vhost_vq_work_queue() only holds the RCU read lock while it dereferences
>vq->worker and queues work on it.  vhost_workers_free() however clears
>the vq->worker pointers and immediately frees the workers, without
>waiting for a grace period.  A caller that fetched the worker right
>before the pointer was cleared can therefore still be queueing work on
>it while it is freed.  And even when the queueing itself wins the race,
>the work is never run, so its VHOST_WORK_QUEUED bit stays set and all
>future attempts to queue it are silently skipped.
>
>None of the current callers can actually hit this: net and scsi stop
>their virtqueues before the workers are freed, and vsock unhashes the
>device and does synchronize_rcu() of its own in vhost_vsock_dev_release()
>before the workers go away.  But the upcoming VHOST_RESET_OWNER support
>in vhost-vsock keeps the device hashed while its workers are freed, so
>the lockless send/cancel paths become able to race with the teardown.
>
>Fix this by clearing the vq->worker pointers, waiting for a grace
>period, and then flushing the workers so any work the last readers
>queued runs before the workers are freed.
>
>Fixes: 228a27cf78af ("vhost: Allow worker switching while work is queueing")
>Suggested-by: Stefano Garzarella <sgarzare@redhat.com>
>Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
>---
> drivers/vhost/vhost.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)

Sashiko reported some potential issues here:
https://sashiko.dev/#/patchset/20260720102241.371610-1-andrey.drobyshev@virtuozzo.com?part=4

IMO the first one is pre-existing, but not really sure it is a real 
issue since happening when the worker/vmm is going to be killed.

The second one also not sure if it's an issue since the sender is not 
lockless IIUC.

But, please can you double check them?

Thanks,
Stefano

>
>diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
>index 4c525b3e16ea..d6e235c25254 100644
>--- a/drivers/vhost/vhost.c
>+++ b/drivers/vhost/vhost.c
>@@ -729,6 +729,17 @@ static void vhost_workers_free(struct vhost_dev *dev)
>
> 	for (i = 0; i < dev->nvqs; i++)
> 		rcu_assign_pointer(dev->vqs[i]->worker, NULL);
>+
>+	/*
>+	 * vhost_vq_work_queue() reads vq->worker under rcu_read_lock(), so a
>+	 * reader that fetched a worker before we cleared the pointers above
>+	 * may still be queueing work on it.  Wait for those readers to
>+	 * finish, then flush so any work they queued runs (clearing
>+	 * VHOST_WORK_QUEUED) before the workers are freed.
>+	 */
>+	synchronize_rcu();
>+	vhost_dev_flush(dev);
>+
> 	/*
> 	 * Free the default worker we created and cleanup workers userspace
> 	 * created but couldn't clean up (it forgot or crashed).
>-- 
>2.47.1
>


^ permalink raw reply

* Re: [PATCH RFC v3 0/6] Add Rust virtio bindings and sample device
From: Eugenio Perez Martin @ 2026-07-22  9:31 UTC (permalink / raw)
  To: Manos Pitsidianakis
  Cc: Michael S. Tsirkin, Manos Pitsidianakis, Peter Hilber,
	Stefano Garzarella, Stefan Hajnoczi, Viresh Kumar, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
	Daniel Almeida, rust-for-linux, Jason Wang, Xuan Zhuo,
	virtualization, linux-kernel
In-Reply-To: <tikjvp.3n7sct2j96lcx@pitsidianak.is>

On Wed, Jul 22, 2026 at 11:04 AM Manos Pitsidianakis
<manos@pitsidianak.is> wrote:
>
> Hi Eugenio,
>
> On Wed, 22 Jul 2026 11:49, Eugenio Perez Martin <eperezma@redhat.com> wrote:
> >On Tue, Jul 21, 2026 at 8:24 AM Manos Pitsidianakis
> ><manos@pitsidianak.is> wrote:
> >>
> >> Ping.
> >>
> >> I have a different version of the series WIP with a virtio-rng instead
> >> of virtio-rtc, based on
> >> https://lore.kernel.org/lkml/20260529-rust-hw_random-virtio-rng-v1-0-b3153dd90311@pitsidianak.is/
> >> (which needs a v2 also)
> >>
> >> But since this series hasn't gotten any feedback on the virtio part, I'd
> >> like to ask if there is any before respinning.
> >>
> >> Thanks!
> >>
> >
> >I also think this will be a great addition, but I have very little
> >knowledge of Rust. Is it easy to implement the simplest virtio-net
> >driver using Rust, without CVQ or extra features, so I can test it and
> >hopefully build features on top? Would it help?
>
> I think so, however it would not be upstreamable right away since (I
> think) there are no netdev Rust bindings and abstractions yet. I will
> take a look when I have the time...
>

How about starting even smaller? Just with the virtio-ring processing
that all virtio drivers share.

> (This is something I am also interested in because I'm working on a
> different kind of network device)
>
> You can definitely play with the sample driver included in this series
> however!
>
> Manos
>
>
> >
> >Thanks!
> >
> >> On Sun, 10 May 2026 16:38, Manos Pitsidianakis <manos@pitsidianak.is> wrote:
> >> >Hi all, this RFC series adds Rust bindings for Virtio drivers
> >> >(frontends in virtio parlance).
> >> >
> >> >As a PoC, it also adds a sample virtio-rtc driver which performs
> >> >capability discovery through the virtqueue without registering any clock.
> >> >
> >> >Before I send a cleaned-up non-RFC I would like some initial feedback
> >> >(i.e. is it something the upstream wants?)
> >> >
> >> >This was tested with the rust-vmm vhost-device-rtc device backend that I
> >> >wrote[^0]:
> >> >
> >> >[^0]: https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-rtc
> >> >
> >> >Instructions:
> >> >
> >> >  Run the daemon in a separate terminal:
> >> >
> >> >  $ cargo run --bin vhost-device-rtc -- -s /tmp/rtc.sock
> >> >
> >> >  Then run the VM:
> >> >
> >> >  $ qemu-system-aarch64 \
> >> >    -machine type=virt,virtualization=off,acpi=on \
> >> >    -cpu host \
> >> >    -smp 8 \
> >> >    -accel kvm \
> >> >    -drive if=virtio,format=qcow2,file=./debian-13-nocloud-arm64-daily.qcow2 \
> >> >    -device virtio-net-pci,netdev=unet \
> >> >    -device virtio-scsi-pci \
> >> >    -serial mon:stdio \
> >> >    -m 8192 \
> >> >    -object memory-backend-memfd,id=mem,size=8G,share=on \
> >> >    -numa node,memdev=mem \
> >> >    -display none \
> >> >    -vga none \
> >> >    -kernel /path/to/linux/build/arch/arm64/boot/Image \
> >> >    -device vhost-user-test-device,chardev=rtc,id=rtc,virtio-id=17,num_vqs=2,vq_size=1024 \
> >> >    -chardev socket,path=/tmp/rtc.sock,id=rtc \
> >> >    ...
> >> >
> >> >  Example output:
> >> >    [    1.105238] rust_virtio_rtc: Probe Rust virtio driver sample.
> >> >    [    1.105645] rust_virtio_rtc: Found 1 vqs.
> >> >    [    1.136050] rust_virtio_rtc: process_requestq got buf 16 bytes
> >> >    [    1.136125] rust_virtio_rtc: Got response! Ok(RespCfg { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, num_clocks: Le16(3), reserved: [0, 0, 0, 0, 0, 0] })
> >> >    [    1.136701] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 3, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] })
> >> >    [    1.136724] rust_virtio_rtc virtio0: cannot expose clock 0 (type 3, variant 0, flags 0) to userspace
> >> >    [    1.137259] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(1777890485031060388) })
> >> >    [    1.137277] rust_virtio_rtc: #0 clock reading = 1777890485031060388
> >> >    [    1.137749] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 1, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] })
> >> >    [    1.137769] rust_virtio_rtc virtio0: cannot expose clock 1 (type 1, variant 0, flags 0) to userspace
> >> >    [    1.138247] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(1777890485032086075) })
> >> >    [    1.138264] rust_virtio_rtc: #1 clock reading = 1777890485032086075
> >> >    [    1.138730] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 2, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] })
> >> >    [    1.138751] rust_virtio_rtc virtio0: cannot expose clock 2 (type 2, variant 0, flags 0) to userspace
> >> >    [    1.139253] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(338567896865557) })
> >> >    [    1.139270] rust_virtio_rtc: #2 clock reading = 338567896865557
> >> >
> >> >Concerns - Notes - TODOs
> >> >========================
> >> >
> >> >- Virtqueue lifetimes don't neatly apply to Rust as expected, so a lot
> >> >  of times we have to go through unsafe pointer dereferences (though
> >> >  which are guaranteed by Virtio subsystem to be valid, for example when
> >> >  a callback is called with the vq argument). There's a potential for
> >> >  misuse and definitely could use better thinking.
> >> >- `struct virtio_device` is not reference-counted like other implemented
> >> >  device types in rust/kernel. Maybe we need to change C API first to
> >> >  make them reference counted, assuming this doesn't break anything?
> >> >- The sample driver obviously conflicts with the C implementation, so
> >> >  this would either need to move out of samples/ or figure out some way
> >> >  to handle this in kbuild.
> >> >- kernel::virtio module and its types need a few rustdoc examples that I
> >> >  will add in followup series
> >> >- Note that the registration of RTC clocks etc in the sample driver is
> >> >  not done, I'm putting it off until I receive some feedback first. The
> >> >  sample driver otherwise does send and receive data from the virtqueue
> >> >  as a PoC.
> >> >
> >> >PS: No LLMs used so any mistakes and goofs are solely written by me.
> >> >
> >> >Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
> >> >---
> >> >Changes in v3:
> >> >- Removed unused methods from virtio API
> >> >- Clean up how scattergather lists are added to virtqueues by using
> >> >  owned SGTables only, and make the API safe(r)
> >> >- Add RAII cleanup for find_vqs return value that calls del_vqs
> >> >- Reset device after remove callback
> >> >- Significantly clean up sample driver as a result of the other cleanups
> >> >- Link to v2: https://lore.kernel.org/r/20260509-rust-virtio-v2-0-c1e30ec2bd21@pitsidianak.is
> >> >
> >> >Changes in v2:
> >> >- Move helper ifdefs to helper file (thanks Alice)
> >> >- Changed CONFIG checks to IS_ENABLED to allow for CONFIG_VIRTIO=m
> >> >- Split all use imports to one item per line according to style guide
> >> >- Fixed wait_for_completion_interruptible*() rustdocs
> >> >- Use Jiffy type alias in wait_for_completion_interruptible_timeout()
> >> >- Pepper and salt #[inline]s wherever appropriate as per style guide
> >> >- Split probe() into probe() and init() to allow cleaning up if init
> >> >  fails
> >> >- Remove unnecessary Send and Sync unsafe impls for
> >> >  kernel::virtio::Device
> >> >- Remove unnecessary LeSize and BeSize
> >> >- Accept Option<_> for virtqueue callback when creating a VirtqueueInfo
> >> >- Made all vq buffer adding operations unsafe
> >> >- Use AtomicU16 instead of Cell<u16> for sample virtio driver
> >> >- Fix RespHead field types in sample virtio driver
> >> >- Fix response error checking in sample virtio driver
> >> >- Change some device contexts in method signatures
> >> >- Link to v1: https://lore.kernel.org/r/20260505-rust-virtio-v1-0-9563383909e4@pitsidianak.is
> >> >
> >> >---
> >> >Manos Pitsidianakis (6):
> >> >      rust/bindings: generate virtio bindings
> >> >      rust/helpers: add virtio.c
> >> >      rust/kernel/device: return parent at same context
> >> >      rust: add virtio module
> >> >      rust: impl interruptible waits for Completion
> >> >      samples/rust: Add sample virtio-rtc driver [WIP]
> >> >
> >> > MAINTAINERS                     |   9 +
> >> > rust/bindings/bindings_helper.h |   5 +
> >> > rust/helpers/helpers.c          |   1 +
> >> > rust/helpers/virtio.c           |  37 ++++
> >> > rust/kernel/device.rs           |   2 +-
> >> > rust/kernel/lib.rs              |   2 +
> >> > rust/kernel/sync/completion.rs  |  42 +++-
> >> > rust/kernel/virtio.rs           | 423 ++++++++++++++++++++++++++++++++++++++++
> >> > rust/kernel/virtio/utils.rs     |  57 ++++++
> >> > rust/kernel/virtio/virtqueue.rs | 314 +++++++++++++++++++++++++++++
> >> > samples/rust/Kconfig            |  15 ++
> >> > samples/rust/Makefile           |   1 +
> >> > samples/rust/rust_virtio_rtc.rs | 403 ++++++++++++++++++++++++++++++++++++++
> >> > 13 files changed, 1309 insertions(+), 2 deletions(-)
> >> >---
> >> >base-commit: 028ef9c96e96197026887c0f092424679298aae8
> >> >change-id: 20260504-rust-virtio-8523b01dfdc2
> >> >
> >> >Best regards,
> >> >--
> >> >Manos Pitsidianakis <manos@pitsidianak.is>
> >> >
>


^ permalink raw reply

* Re: [PATCH v5 3/5] vhost/vsock: re-scan TX virtqueue on device start
From: Stefano Garzarella @ 2026-07-22  9:14 UTC (permalink / raw)
  To: Andrey Drobyshev
  Cc: linux-kernel, kvm, virtualization, netdev, mst, stefanha,
	dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
	den
In-Reply-To: <20260720102241.371610-4-andrey.drobyshev@virtuozzo.com>

On Mon, Jul 20, 2026 at 01:22:39PM +0300, Andrey Drobyshev wrote:
>During QEMU CPR live-update (and VHOST_RESET_OWNER in general) the guest
>keeps running while the host drops and later re-attaches vhost backends.
>If the guest adds a buffer to the TX virtqueue (guest->host) and kicks
>while the backend is temporarily NULL (between vhost_vsock_drop_backends()
>and the next vhost_vsock_start()), then the kick is delivered to the
>vhost worker, handle_tx_kick() sees a NULL backend and returns, and the
>kick signal is consumed.  The buffer is then left in the ring.
>
>Then upon device start vhost_vsock_start() only re-kicks the RX send
>worker, never the TX VQ, so the buffer is processed only if the guest
>happens to kick again.  But if the guest itself is now waiting for data
>from the host, it will never kick TX VQ again, and we end up in a
>deadlock.
>
>The issue itself is pre-existing, but it only manifests during a device
>pause caused by VHOST_RESET_OWNER.  Namely, the deadlock is reproduced
>during active host->guest socat data transfer under multiple consecutive
>CPR live-update's.
>
>To fix this, in vhost_vsock_start(), after kicking the RX send worker, also
>queue the TX vq poll so any buffers the guest enqueued while we were paused
>get scanned.
>
>The VHOST_RESET_OWNER ioctl itself is implemented in the following
>patch, thus this patch is a preparation to support VHOST_RESET_OWNER.
>
>Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
>Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
>---
> drivers/vhost/vsock.c | 7 +++++++
> 1 file changed, 7 insertions(+)

Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>


^ permalink raw reply

* Re: [PATCH v5 2/5] vhost/vsock: suppress EHOSTUNREACH fast-fail during CPR pause
From: Stefano Garzarella @ 2026-07-22  9:14 UTC (permalink / raw)
  To: Andrey Drobyshev
  Cc: linux-kernel, kvm, virtualization, netdev, mst, stefanha,
	dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
	den
In-Reply-To: <20260720102241.371610-3-andrey.drobyshev@virtuozzo.com>

On Mon, Jul 20, 2026 at 01:22:38PM +0300, Andrey Drobyshev wrote:
>Earlier commit bb26ed5f3a8b ("vhost/vsock: Refuse the connection
>immediately when guest isn't ready") added a fast-fail in
>vhost_transport_send_pkt().  It rejects every host send with -EHOSTUNREACH
>until the destination calls SET_RUNNING(1).  The fast-fail condition checks
>whether device's backends are dropped, and if they're, the guest is
>considered to be not ready.
>
>However, there might be other reasons for backends to be nulled.  In
>particular, when QEMU is performing CPR (checkpoint-restore) migration,
>device ownership is being RESET and SET again, which leads to backends
>drop and reattach.  If we end up connecting during this window, an
>AF_VSOCK client gets -EHOSTUNREACH, which is wrong.
>
>Add an 'ever_started' flag which is set once in vhost_vsock_start() and is
>never cleared.  The behaviour changes to:
>
>  * When device was never started -> flag is unset -> no listener can
>    exist yet -> fast-fail;
>  * Once the device starts -> flag is set -> we don't fast-fail ->
>    we queue and preserve during any later stop / CPR pause.
>
>The VHOST_RESET_OWNER ioctl is implemented in a following patch, and
>without RESET_OWNER the problem we fix here isn't manifesting - thus
>this patch is a preparation to support RESET_OWNER.
>
>Important caveat: after the first start, a connect during any stopped
>window is queued instead of fast-failed.  That was the behaviour before
>the patch bb26ed5f3a8b, and we're restoring it now.  However we still
>keep the behaviour originally intended by that commit (i.e. fast-fail if
>there's no real listener yet) while fixing the CPR path.
>
>Suggested-by: Stefano Garzarella <sgarzare@redhat.com>
>Signed-off-by: Denis V. Lunev <den@openvz.org>
>Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
>Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
>---
> drivers/vhost/vsock.c | 22 ++++++++++++----------
> 1 file changed, 12 insertions(+), 10 deletions(-)

Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>


^ permalink raw reply

* Re: [PATCH RFC v3 0/6] Add Rust virtio bindings and sample device
From: Manos Pitsidianakis @ 2026-07-22  8:55 UTC (permalink / raw)
  To: Eugenio Perez Martin
  Cc: Michael S. Tsirkin, Manos Pitsidianakis, Peter Hilber,
	Stefano Garzarella, Stefan Hajnoczi, Viresh Kumar, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
	Daniel Almeida, rust-for-linux, Jason Wang, Xuan Zhuo,
	virtualization, linux-kernel
In-Reply-To: <CAJaqyWcSeXW_vdP03-oTXp5uO8vNBg224LDgyCn3QrXhuJ6tHw@mail.gmail.com>

Hi Eugenio,

On Wed, 22 Jul 2026 11:49, Eugenio Perez Martin <eperezma@redhat.com> wrote:
>On Tue, Jul 21, 2026 at 8:24 AM Manos Pitsidianakis
><manos@pitsidianak.is> wrote:
>>
>> Ping.
>>
>> I have a different version of the series WIP with a virtio-rng instead
>> of virtio-rtc, based on
>> https://lore.kernel.org/lkml/20260529-rust-hw_random-virtio-rng-v1-0-b3153dd90311@pitsidianak.is/
>> (which needs a v2 also)
>>
>> But since this series hasn't gotten any feedback on the virtio part, I'd
>> like to ask if there is any before respinning.
>>
>> Thanks!
>>
>
>I also think this will be a great addition, but I have very little
>knowledge of Rust. Is it easy to implement the simplest virtio-net
>driver using Rust, without CVQ or extra features, so I can test it and
>hopefully build features on top? Would it help?

I think so, however it would not be upstreamable right away since (I 
think) there are no netdev Rust bindings and abstractions yet. I will 
take a look when I have the time...

(This is something I am also interested in because I'm working on a 
different kind of network device)

You can definitely play with the sample driver included in this series 
however!

Manos


>
>Thanks!
>
>> On Sun, 10 May 2026 16:38, Manos Pitsidianakis <manos@pitsidianak.is> wrote:
>> >Hi all, this RFC series adds Rust bindings for Virtio drivers
>> >(frontends in virtio parlance).
>> >
>> >As a PoC, it also adds a sample virtio-rtc driver which performs
>> >capability discovery through the virtqueue without registering any clock.
>> >
>> >Before I send a cleaned-up non-RFC I would like some initial feedback
>> >(i.e. is it something the upstream wants?)
>> >
>> >This was tested with the rust-vmm vhost-device-rtc device backend that I
>> >wrote[^0]:
>> >
>> >[^0]: https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-rtc
>> >
>> >Instructions:
>> >
>> >  Run the daemon in a separate terminal:
>> >
>> >  $ cargo run --bin vhost-device-rtc -- -s /tmp/rtc.sock
>> >
>> >  Then run the VM:
>> >
>> >  $ qemu-system-aarch64 \
>> >    -machine type=virt,virtualization=off,acpi=on \
>> >    -cpu host \
>> >    -smp 8 \
>> >    -accel kvm \
>> >    -drive if=virtio,format=qcow2,file=./debian-13-nocloud-arm64-daily.qcow2 \
>> >    -device virtio-net-pci,netdev=unet \
>> >    -device virtio-scsi-pci \
>> >    -serial mon:stdio \
>> >    -m 8192 \
>> >    -object memory-backend-memfd,id=mem,size=8G,share=on \
>> >    -numa node,memdev=mem \
>> >    -display none \
>> >    -vga none \
>> >    -kernel /path/to/linux/build/arch/arm64/boot/Image \
>> >    -device vhost-user-test-device,chardev=rtc,id=rtc,virtio-id=17,num_vqs=2,vq_size=1024 \
>> >    -chardev socket,path=/tmp/rtc.sock,id=rtc \
>> >    ...
>> >
>> >  Example output:
>> >    [    1.105238] rust_virtio_rtc: Probe Rust virtio driver sample.
>> >    [    1.105645] rust_virtio_rtc: Found 1 vqs.
>> >    [    1.136050] rust_virtio_rtc: process_requestq got buf 16 bytes
>> >    [    1.136125] rust_virtio_rtc: Got response! Ok(RespCfg { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, num_clocks: Le16(3), reserved: [0, 0, 0, 0, 0, 0] })
>> >    [    1.136701] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 3, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] })
>> >    [    1.136724] rust_virtio_rtc virtio0: cannot expose clock 0 (type 3, variant 0, flags 0) to userspace
>> >    [    1.137259] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(1777890485031060388) })
>> >    [    1.137277] rust_virtio_rtc: #0 clock reading = 1777890485031060388
>> >    [    1.137749] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 1, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] })
>> >    [    1.137769] rust_virtio_rtc virtio0: cannot expose clock 1 (type 1, variant 0, flags 0) to userspace
>> >    [    1.138247] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(1777890485032086075) })
>> >    [    1.138264] rust_virtio_rtc: #1 clock reading = 1777890485032086075
>> >    [    1.138730] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 2, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] })
>> >    [    1.138751] rust_virtio_rtc virtio0: cannot expose clock 2 (type 2, variant 0, flags 0) to userspace
>> >    [    1.139253] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(338567896865557) })
>> >    [    1.139270] rust_virtio_rtc: #2 clock reading = 338567896865557
>> >
>> >Concerns - Notes - TODOs
>> >========================
>> >
>> >- Virtqueue lifetimes don't neatly apply to Rust as expected, so a lot
>> >  of times we have to go through unsafe pointer dereferences (though
>> >  which are guaranteed by Virtio subsystem to be valid, for example when
>> >  a callback is called with the vq argument). There's a potential for
>> >  misuse and definitely could use better thinking.
>> >- `struct virtio_device` is not reference-counted like other implemented
>> >  device types in rust/kernel. Maybe we need to change C API first to
>> >  make them reference counted, assuming this doesn't break anything?
>> >- The sample driver obviously conflicts with the C implementation, so
>> >  this would either need to move out of samples/ or figure out some way
>> >  to handle this in kbuild.
>> >- kernel::virtio module and its types need a few rustdoc examples that I
>> >  will add in followup series
>> >- Note that the registration of RTC clocks etc in the sample driver is
>> >  not done, I'm putting it off until I receive some feedback first. The
>> >  sample driver otherwise does send and receive data from the virtqueue
>> >  as a PoC.
>> >
>> >PS: No LLMs used so any mistakes and goofs are solely written by me.
>> >
>> >Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
>> >---
>> >Changes in v3:
>> >- Removed unused methods from virtio API
>> >- Clean up how scattergather lists are added to virtqueues by using
>> >  owned SGTables only, and make the API safe(r)
>> >- Add RAII cleanup for find_vqs return value that calls del_vqs
>> >- Reset device after remove callback
>> >- Significantly clean up sample driver as a result of the other cleanups
>> >- Link to v2: https://lore.kernel.org/r/20260509-rust-virtio-v2-0-c1e30ec2bd21@pitsidianak.is
>> >
>> >Changes in v2:
>> >- Move helper ifdefs to helper file (thanks Alice)
>> >- Changed CONFIG checks to IS_ENABLED to allow for CONFIG_VIRTIO=m
>> >- Split all use imports to one item per line according to style guide
>> >- Fixed wait_for_completion_interruptible*() rustdocs
>> >- Use Jiffy type alias in wait_for_completion_interruptible_timeout()
>> >- Pepper and salt #[inline]s wherever appropriate as per style guide
>> >- Split probe() into probe() and init() to allow cleaning up if init
>> >  fails
>> >- Remove unnecessary Send and Sync unsafe impls for
>> >  kernel::virtio::Device
>> >- Remove unnecessary LeSize and BeSize
>> >- Accept Option<_> for virtqueue callback when creating a VirtqueueInfo
>> >- Made all vq buffer adding operations unsafe
>> >- Use AtomicU16 instead of Cell<u16> for sample virtio driver
>> >- Fix RespHead field types in sample virtio driver
>> >- Fix response error checking in sample virtio driver
>> >- Change some device contexts in method signatures
>> >- Link to v1: https://lore.kernel.org/r/20260505-rust-virtio-v1-0-9563383909e4@pitsidianak.is
>> >
>> >---
>> >Manos Pitsidianakis (6):
>> >      rust/bindings: generate virtio bindings
>> >      rust/helpers: add virtio.c
>> >      rust/kernel/device: return parent at same context
>> >      rust: add virtio module
>> >      rust: impl interruptible waits for Completion
>> >      samples/rust: Add sample virtio-rtc driver [WIP]
>> >
>> > MAINTAINERS                     |   9 +
>> > rust/bindings/bindings_helper.h |   5 +
>> > rust/helpers/helpers.c          |   1 +
>> > rust/helpers/virtio.c           |  37 ++++
>> > rust/kernel/device.rs           |   2 +-
>> > rust/kernel/lib.rs              |   2 +
>> > rust/kernel/sync/completion.rs  |  42 +++-
>> > rust/kernel/virtio.rs           | 423 ++++++++++++++++++++++++++++++++++++++++
>> > rust/kernel/virtio/utils.rs     |  57 ++++++
>> > rust/kernel/virtio/virtqueue.rs | 314 +++++++++++++++++++++++++++++
>> > samples/rust/Kconfig            |  15 ++
>> > samples/rust/Makefile           |   1 +
>> > samples/rust/rust_virtio_rtc.rs | 403 ++++++++++++++++++++++++++++++++++++++
>> > 13 files changed, 1309 insertions(+), 2 deletions(-)
>> >---
>> >base-commit: 028ef9c96e96197026887c0f092424679298aae8
>> >change-id: 20260504-rust-virtio-8523b01dfdc2
>> >
>> >Best regards,
>> >--
>> >Manos Pitsidianakis <manos@pitsidianak.is>
>> >

^ permalink raw reply

* Re: [PATCH RFC v3 0/6] Add Rust virtio bindings and sample device
From: Eugenio Perez Martin @ 2026-07-22  8:49 UTC (permalink / raw)
  To: Manos Pitsidianakis
  Cc: Michael S. Tsirkin, Manos Pitsidianakis, Peter Hilber,
	Stefano Garzarella, Stefan Hajnoczi, Viresh Kumar, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
	Daniel Almeida, rust-for-linux, Jason Wang, Xuan Zhuo,
	virtualization, linux-kernel
In-Reply-To: <tiiht3.22qk83rct1pd@pitsidianak.is>

On Tue, Jul 21, 2026 at 8:24 AM Manos Pitsidianakis
<manos@pitsidianak.is> wrote:
>
> Ping.
>
> I have a different version of the series WIP with a virtio-rng instead
> of virtio-rtc, based on
> https://lore.kernel.org/lkml/20260529-rust-hw_random-virtio-rng-v1-0-b3153dd90311@pitsidianak.is/
> (which needs a v2 also)
>
> But since this series hasn't gotten any feedback on the virtio part, I'd
> like to ask if there is any before respinning.
>
> Thanks!
>

I also think this will be a great addition, but I have very little
knowledge of Rust. Is it easy to implement the simplest virtio-net
driver using Rust, without CVQ or extra features, so I can test it and
hopefully build features on top? Would it help?

Thanks!

> On Sun, 10 May 2026 16:38, Manos Pitsidianakis <manos@pitsidianak.is> wrote:
> >Hi all, this RFC series adds Rust bindings for Virtio drivers
> >(frontends in virtio parlance).
> >
> >As a PoC, it also adds a sample virtio-rtc driver which performs
> >capability discovery through the virtqueue without registering any clock.
> >
> >Before I send a cleaned-up non-RFC I would like some initial feedback
> >(i.e. is it something the upstream wants?)
> >
> >This was tested with the rust-vmm vhost-device-rtc device backend that I
> >wrote[^0]:
> >
> >[^0]: https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-rtc
> >
> >Instructions:
> >
> >  Run the daemon in a separate terminal:
> >
> >  $ cargo run --bin vhost-device-rtc -- -s /tmp/rtc.sock
> >
> >  Then run the VM:
> >
> >  $ qemu-system-aarch64 \
> >    -machine type=virt,virtualization=off,acpi=on \
> >    -cpu host \
> >    -smp 8 \
> >    -accel kvm \
> >    -drive if=virtio,format=qcow2,file=./debian-13-nocloud-arm64-daily.qcow2 \
> >    -device virtio-net-pci,netdev=unet \
> >    -device virtio-scsi-pci \
> >    -serial mon:stdio \
> >    -m 8192 \
> >    -object memory-backend-memfd,id=mem,size=8G,share=on \
> >    -numa node,memdev=mem \
> >    -display none \
> >    -vga none \
> >    -kernel /path/to/linux/build/arch/arm64/boot/Image \
> >    -device vhost-user-test-device,chardev=rtc,id=rtc,virtio-id=17,num_vqs=2,vq_size=1024 \
> >    -chardev socket,path=/tmp/rtc.sock,id=rtc \
> >    ...
> >
> >  Example output:
> >    [    1.105238] rust_virtio_rtc: Probe Rust virtio driver sample.
> >    [    1.105645] rust_virtio_rtc: Found 1 vqs.
> >    [    1.136050] rust_virtio_rtc: process_requestq got buf 16 bytes
> >    [    1.136125] rust_virtio_rtc: Got response! Ok(RespCfg { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, num_clocks: Le16(3), reserved: [0, 0, 0, 0, 0, 0] })
> >    [    1.136701] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 3, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] })
> >    [    1.136724] rust_virtio_rtc virtio0: cannot expose clock 0 (type 3, variant 0, flags 0) to userspace
> >    [    1.137259] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(1777890485031060388) })
> >    [    1.137277] rust_virtio_rtc: #0 clock reading = 1777890485031060388
> >    [    1.137749] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 1, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] })
> >    [    1.137769] rust_virtio_rtc virtio0: cannot expose clock 1 (type 1, variant 0, flags 0) to userspace
> >    [    1.138247] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(1777890485032086075) })
> >    [    1.138264] rust_virtio_rtc: #1 clock reading = 1777890485032086075
> >    [    1.138730] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 2, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] })
> >    [    1.138751] rust_virtio_rtc virtio0: cannot expose clock 2 (type 2, variant 0, flags 0) to userspace
> >    [    1.139253] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(338567896865557) })
> >    [    1.139270] rust_virtio_rtc: #2 clock reading = 338567896865557
> >
> >Concerns - Notes - TODOs
> >========================
> >
> >- Virtqueue lifetimes don't neatly apply to Rust as expected, so a lot
> >  of times we have to go through unsafe pointer dereferences (though
> >  which are guaranteed by Virtio subsystem to be valid, for example when
> >  a callback is called with the vq argument). There's a potential for
> >  misuse and definitely could use better thinking.
> >- `struct virtio_device` is not reference-counted like other implemented
> >  device types in rust/kernel. Maybe we need to change C API first to
> >  make them reference counted, assuming this doesn't break anything?
> >- The sample driver obviously conflicts with the C implementation, so
> >  this would either need to move out of samples/ or figure out some way
> >  to handle this in kbuild.
> >- kernel::virtio module and its types need a few rustdoc examples that I
> >  will add in followup series
> >- Note that the registration of RTC clocks etc in the sample driver is
> >  not done, I'm putting it off until I receive some feedback first. The
> >  sample driver otherwise does send and receive data from the virtqueue
> >  as a PoC.
> >
> >PS: No LLMs used so any mistakes and goofs are solely written by me.
> >
> >Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
> >---
> >Changes in v3:
> >- Removed unused methods from virtio API
> >- Clean up how scattergather lists are added to virtqueues by using
> >  owned SGTables only, and make the API safe(r)
> >- Add RAII cleanup for find_vqs return value that calls del_vqs
> >- Reset device after remove callback
> >- Significantly clean up sample driver as a result of the other cleanups
> >- Link to v2: https://lore.kernel.org/r/20260509-rust-virtio-v2-0-c1e30ec2bd21@pitsidianak.is
> >
> >Changes in v2:
> >- Move helper ifdefs to helper file (thanks Alice)
> >- Changed CONFIG checks to IS_ENABLED to allow for CONFIG_VIRTIO=m
> >- Split all use imports to one item per line according to style guide
> >- Fixed wait_for_completion_interruptible*() rustdocs
> >- Use Jiffy type alias in wait_for_completion_interruptible_timeout()
> >- Pepper and salt #[inline]s wherever appropriate as per style guide
> >- Split probe() into probe() and init() to allow cleaning up if init
> >  fails
> >- Remove unnecessary Send and Sync unsafe impls for
> >  kernel::virtio::Device
> >- Remove unnecessary LeSize and BeSize
> >- Accept Option<_> for virtqueue callback when creating a VirtqueueInfo
> >- Made all vq buffer adding operations unsafe
> >- Use AtomicU16 instead of Cell<u16> for sample virtio driver
> >- Fix RespHead field types in sample virtio driver
> >- Fix response error checking in sample virtio driver
> >- Change some device contexts in method signatures
> >- Link to v1: https://lore.kernel.org/r/20260505-rust-virtio-v1-0-9563383909e4@pitsidianak.is
> >
> >---
> >Manos Pitsidianakis (6):
> >      rust/bindings: generate virtio bindings
> >      rust/helpers: add virtio.c
> >      rust/kernel/device: return parent at same context
> >      rust: add virtio module
> >      rust: impl interruptible waits for Completion
> >      samples/rust: Add sample virtio-rtc driver [WIP]
> >
> > MAINTAINERS                     |   9 +
> > rust/bindings/bindings_helper.h |   5 +
> > rust/helpers/helpers.c          |   1 +
> > rust/helpers/virtio.c           |  37 ++++
> > rust/kernel/device.rs           |   2 +-
> > rust/kernel/lib.rs              |   2 +
> > rust/kernel/sync/completion.rs  |  42 +++-
> > rust/kernel/virtio.rs           | 423 ++++++++++++++++++++++++++++++++++++++++
> > rust/kernel/virtio/utils.rs     |  57 ++++++
> > rust/kernel/virtio/virtqueue.rs | 314 +++++++++++++++++++++++++++++
> > samples/rust/Kconfig            |  15 ++
> > samples/rust/Makefile           |   1 +
> > samples/rust/rust_virtio_rtc.rs | 403 ++++++++++++++++++++++++++++++++++++++
> > 13 files changed, 1309 insertions(+), 2 deletions(-)
> >---
> >base-commit: 028ef9c96e96197026887c0f092424679298aae8
> >change-id: 20260504-rust-virtio-8523b01dfdc2
> >
> >Best regards,
> >--
> >Manos Pitsidianakis <manos@pitsidianak.is>
> >
>
>
> --
>
> foo
>


^ permalink raw reply

* Re: [PATCH] vsock: use sock_error() to consume sk_err after connect timeout
From: Stefano Garzarella @ 2026-07-22  7:55 UTC (permalink / raw)
  To: Phi Nguyen
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, syzbot+1b2c9c4a0f8708082678, virtualization, netdev,
	linux-kernel
In-Reply-To: <78225425-1ca7-45fb-85cb-9e04f489e68f@gmail.com>

On Tue, Jul 21, 2026 at 01:34:03AM +0800, Phi Nguyen wrote:
>On 7/20/2026 4:17 PM, Stefano Garzarella wrote:
>>On Mon, Jul 20, 2026 at 05:57:47AM +0800, Nguyen Dinh Phi wrote:
>>>After vsock_connect() exits the wait loop due to sk->sk_err being
>>>set, the error was read but not cleared. This left sk->sk_err set
>>>for subsequent operations.
>>
>>So, is this a fix? If yes, we should put a Fixes tag.
>>
>>Also, can you describe how to trigger the issue?
>>
>>Because I see this in vsock_connect(), so I thought it was in some 
>>way already handled:
>>
>>         /* sk_err might have been set as a result of an earlier
>>          * (failed) connect attempt.
>>          */
>>         sk->sk_err = 0;
>>
>This only handles the case where the function following the failed 
>connect is another connect() call.

So, can we remove that with this patch, or better to leave as defensive
action?

>
>>>Switch to sock_error() which atomically reads and clears sk->sk_err,
>>>so the error is consumed when returned.
>>>
>>>Signed-off-by: Nguyen Dinh Phi <phind.uet@gmail.com>
>>>Reported-by: syzbot+1b2c9c4a0f8708082678@syzkaller.appspotmail.com
>>
>>Can you explain how this patch fixes that issue?
>>(this should be the first information to be put in the commit message IMHO)
>>
>>I'd like to understand better if this is a fix of real bug or just 
>>an improvement to the code (which is fine by me).
>>
>>Thanks,
>>Stefano
>>
>Here are the steps of the syzkaller reproducer:
>
>  r0 = socket(AF_VSOCK, SOCK_STREAM, 0)
>
>  bind(r0, {VMADDR_CID_ANY, PORT})
>
>  connect(r0, {VMADDR_CID_LOCAL, PORT})
>
>  listen(r0, backlog)
>
>  r1 = socket(AF_VSOCK, SOCK_STREAM, 0)
>
>  connect(r1, {VMADDR_CID_LOCAL, PORT})
>
>  connect(r0 -> self) -> -1, EPROTO
>
>  listen(r0)          -> 0
>
>  connect(r1 -> r0)   -> 0
>
>  accept(r0)          -> -1, EPROTO
>
>Basically, it creates a socket (r0) and triggers a self-connect after 
>binding it. This self-connect fails with EPROTO because it loops back 
>to r0 while the socket is still in the TCP_SYN_SENT state, causing it 
>to be incorrectly dispatched to the connecting-client path. The 
>unexpected packet type encountered there sets sk_err to EPROTO.
>
>After that, it invokes a listen() call on the same socket. This 
>listen() call succeeds because the kernel's listening path never 
>inspects or clears sk_err. Then, a new socket (r1) is created as a 
>normal client and connects to r0. However, vsock_accept() rejects this 
>incoming connection because the listener's sk_err still holds the 
>EPROTO error from the earlier failed self-connect.
>
>This rejection causes the child socket created for r1's connection to 
>never be freed on virtio or hyperv transports; only the VMCI transport 
>implements pending_work to revisit and clean up a rejected socket
>This patch will prevent the rejection branch to occur in this scenario.

Okay, get it now, thanks! Please include a summary of this in the commit 
description.

I understand that this resolves syzbot's specific test case, but it 
would be best to handle rejected sockets more effectively in af_vsock.c 
rather than in the transport layers (if possible). In any case, this can 
be done in another patch.

>
>I think we might schedule the cleanup worker to run in the rejection 
>path for these transports as well.

Yeah, we need to handle that part better, I think it's a leftover when 
we generalized AF_VSOCK to support more transport than vmci.

Indeed this part is a bit confusing:

		/* If the listener socket has received an error, then we should
		 * reject this socket and return.  Note that we simply mark the
		 * socket rejected, drop our reference, and let the cleanup
		 * function handle the cleanup; the fact that we found it in
		 * the listener's accept queue guarantees that the cleanup
		 * function hasn't run yet.
		 */
		if (err) {
			vconnected->rejected = true;
		} else {


Would be nice to handle everything in af_vsock.c in some way.

In conclusion, the patch LGTM, but please expand the commit description, 
add the Fixes tag, and target the net tree in the v2.

Thanks,
Stefano


^ permalink raw reply

* Re: [PATCH v8 10/11] virt/steal_governor: Implement steal_governor policy loop
From: Yury Norov @ 2026-07-22  7:39 UTC (permalink / raw)
  To: Shrikanth Hegde
  Cc: linux-kernel, mingo, peterz, juri.lelli, vincent.guittot,
	yury.norov, kprateek.nayak, iii, corbet, tglx, gregkh, pbonzini,
	seanjc, vschneid, huschle, rostedt, dietmar.eggemann, maddy,
	srikar, hdanton, chleroy, vineeth, frederic, arighi, pauld,
	christian.loehle, tj, tommaso.cucinotta, maz, rafael, rdunlap,
	kernellwp, linux-doc, jgross, virtualization
In-Reply-To: <c64ed18e-7863-44c3-9c7b-2f1efd1a805e@linux.ibm.com>

On Wed, Jul 22, 2026 at 12:44:03PM +0530, Shrikanth Hegde wrote:
> Hi Yury.

...

> > > +	schedule_delayed_work(&sg_core_ctx.work,
> > > +			      msecs_to_jiffies(sg_core_ctx.interval_ms));
> > 
> > If you need jiffies, why don't you have them in the structure, instead of
> > milliseconds?
> > 
> > 	schedule_delayed_work(&sg_core_ctx.work, sg_core_ctx.delay);
> > 
> 
> I would prefer milliseconds as jiffies is very difficult for users to understand.
> It depends on HZ value and one has to query from configs.
> 
> HZ can very from 100 to 1000 today. Again I will have to play tricks to schedule
> the governor at fixed intervals.
> 
> So i think it is better to use milliseconds here.
> Correct me if i am not making sense.


User provides milliseconds, then in init() you convert them into
jiffies and save in sg.delay. That's it.

^ permalink raw reply

* Re: [PATCH v8 10/11] virt/steal_governor: Implement steal_governor policy loop
From: Shrikanth Hegde @ 2026-07-22  7:14 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-kernel, mingo, peterz, juri.lelli, vincent.guittot,
	yury.norov, kprateek.nayak, iii, corbet, tglx, gregkh, pbonzini,
	seanjc, vschneid, huschle, rostedt, dietmar.eggemann, maddy,
	srikar, hdanton, chleroy, vineeth, frederic, arighi, pauld,
	christian.loehle, tj, tommaso.cucinotta, maz, rafael, rdunlap,
	kernellwp, linux-doc, jgross, virtualization
In-Reply-To: <al_IbeAa3sDrt9A7@yury>

Hi Yury.

On 7/22/26 12:58 AM, Yury Norov wrote:
> On Mon, Jul 20, 2026 at 10:52:49PM +0530, Shrikanth Hegde wrote:

[...]
    
>> +/*
>> + * Returns steal time of the full system.
>> + * Compute collective steal time across all possible CPUs.
>> + */
>> +static u64 get_system_steal_time(void)
>> +{
>> +	int cpu;
>> +	u64 total_steal = 0;
>> +
>> +	for_each_possible_cpu(cpu)
>> +		total_steal += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
>> +
>> +	return total_steal;
>> +}
> 
> There's another implementation of the same logic in
> hd_calculate_steal_percentage())
> 
> It means it should live in include/linux/kernel_stat.h as:
>          
>          u64 kcpustat_steal_time(struct cpumask *cpus);
> 
> Or possibly even more generic:
> 
>          u64 kcpustat_field_total(enum cpu_usage_stat usage, struct cpumask *cpus);

That's good idea. Below are the callsites i think can be
refactored in addition to this patch.
  
arch/s390/kernel/hiperdispatch.c: hd_calculate_steal_percentage
fs/proc/uptime.c: uptime_proc_show

I can pick up this refactoring post the series. I think it is better
not to club them together. is that ok?

> 
> Similarly to the existing kcpustat_field().
> 
> The other possible candidates are: fs/proc/stat.c:: show_stat()
> arch_cpu_idle_time(), but I think it's out of the scope of your
> series.

Yes.

drivers/leds/trigger/ledtrig-activity.c: led_activity_function
fs/proc/stat.c: show_stat

These two sum up multiple CPUTIME_ fields. Doing them in one loop is
likely better than getting each of them in a separate loop. No?


> 
> What's the relation between the arch/s390/kernel/hiperdispatch.c and
> your steal governor? Is that a similar concept?
> 

It is similar but independent idea. Ilya explained it in brief below.
https://youtu.be/adxUKFPlOp0?t=1846

Tobais, Ilya, Correct me if i am wrong.

- It samples steal time and decides on CPU_CAPACITY of a
   CPU (between 1024 and 126) periodically.
- Triggers sched domain rebuild.


But Using CPU_CAPACITY to ensure no task running has drawbacks as we had
explored it very early.
- It fails under high concurrency. Typical real life workloads spawns
   threads/tasks based on online CPUs. Scheduler chooses low capacity
   CPUs instead of running them on busy CPUs. So under high concurrency or
   high utilization it simply doesn't work.
- It takes a long time to get the running task out of it.
- It needs a sched domain rebuild. That is costly
   (One can play tricks to avoid it)
- There are PR/SM overheads.


Since S390 has explicit knowledge of which CPUs to take out, it will likely
want a arch specific mechanism in steal_governor to take out Vertical Low CPUs
first. That is being deferred for now, once s390 has that, my take is
hiperdispatch can be removed altogether.

>> +/*
>> + * Returns number of CPUs to consider for steal ratio.
>> + * Return possible CPUs.
>> + */
> 
> Can you rephrase the comment? It has 2 'return' sections with
> different meaning. If the 2nd one is the implementation detail,
> I'd put it inside the function scope, or drop entirely.
> 

Ok. Let me drop second statement there.

>> +static unsigned int get_num_cpus_steal_ratio(void)
>> +{
>> +	return num_possible_cpus();
>> +}
>> +
>> +/*
>> + * Take action to decrease preferred CPUs.
>> + *
> 
> Drop this 'Take action' wording please.

Ok.

> 
>> + * Decrease the preferred CPUs by 1 core.
>> + * Take out the last core in the active & preferred.
>> + *
>> + * Must ensure
>> + * - least one housekeeping core is always kept as preferred
> 
> s/least/at least/ ?

Yep.

> 
>> + * - preferred is always subset of active.
>> + */
>> +static void decrease_preferred_cpus(void)
>> +{
>> +	int tmp_cpu, first_hk_cpu, last_cpu;
>> +	const struct cpumask *first_hk_core;
>> +	int target_cpu = nr_cpu_ids;
>> +
>> +	guard(cpus_read_lock)();
>> +	first_hk_cpu = cpumask_first_and(housekeeping_cpumask(HK_TYPE_KERNEL_NOISE),
>> +					 cpu_preferred_mask);
>> +	if (first_hk_cpu >= nr_cpu_ids)
>> +		return;
>> +
>> +	last_cpu = cpumask_last(cpu_preferred_mask);
>> +
>> +	if (last_cpu >= nr_cpu_ids)
>> +		return;
>> +
>> +	/* Always leave first housekeeping core as preferred. */
>> +	first_hk_core = topology_sibling_cpumask(first_hk_cpu);
>> +
>> +	/* Find the last CPU which doesn't belong to that first hk_core. */
>> +	if (!cpumask_test_cpu(last_cpu, first_hk_core)) {
>> +		target_cpu = last_cpu;
>> +	} else {
>> +		for_each_cpu_andnot(tmp_cpu, cpu_preferred_mask, first_hk_core)
>> +			target_cpu = tmp_cpu;
>> +	}
> 
> Too much local variables. You can drop those tmp_cpu, last_cpu and
> target_cpu, and just use a single variable 'cpu'. That would also
> simplify your logic:
> 
>          cpu = cpumask_last(cpu_preferred_mask);
>          core = topology_sibling_cpumask(first_hk_cpu);
> 
>          if (cpumask_test_cpu(cpu, core)) {
>                  for_each_cpu_andnot(cpu, cpu_preferred_mask, core)
>                          /* nop */ ;
>          }
> 
>          if (cpu >= nr_cpu_ids)
>                  return;
> 
> And so on.

Ok. Just two would suffice i think. cpu, and target_cpu.
With a bit shuffling first_hk_cpu can also go away.


I need at least two so that this loop works.

         for_each_cpu_and(tmp_cpu, topology_sibling_cpumask(target_cpu),
                          cpu_preferred_mask)
                 set_cpu_preferred(tmp_cpu, false);

> 
>> +
>> +	/* Only the first housekeeping core remains */
>> +	if (target_cpu >= nr_cpu_ids)
>> +		return;
>> +
>> +	for_each_cpu_and(tmp_cpu, topology_sibling_cpumask(target_cpu),
>> +			 cpu_preferred_mask)
>> +		set_cpu_preferred(tmp_cpu, false);
>> +}
>> +
>> +/*
>> + * Take action to increase preferred CPUs.
>> + *
> 
> Again, drop this 'take action' thing.

Sure.

> 
>> + * Increase the preferred CPUs by 1 core.
>> + * Add the first core in active & !preferred
>> + *
>> + * Must ensure preferred is subset of active.
>> + */
>> +static void increase_preferred_cpus(void)
>> +{
>> +	int first_cpu, tmp_cpu;
>> +
>> +	guard(cpus_read_lock)();
>> +	first_cpu = cpumask_first_andnot(cpu_active_mask, cpu_preferred_mask);
>> +
>> +	/* All CPUs are preferred. Nothing to increase further */
>> +	if (first_cpu >= nr_cpu_ids)
>> +		return;
>> +
>> +	for_each_cpu_and(tmp_cpu, topology_sibling_cpumask(first_cpu),
>> +			 cpu_active_mask)
>> +		set_cpu_preferred(tmp_cpu, true);
>> +}
>> +
>> +static void compute_preferred_cpus_work(struct work_struct *work)
>> +{
>> +	u64 curr_steal, delta_steal, delta_ns, steal_ratio;
>> +	ktime_t now;
>> +
>> +	now = ktime_get();
>> +	delta_ns = ktime_to_ns(ktime_sub(now, sg_core_ctx.time));
>> +
>> +	if (unlikely(delta_ns < NSEC_PER_MSEC)) {
>> +		pr_err_ratelimited("steal_governor: work scheduled too soon delta_ns: %llu\n",
>> +				   delta_ns);
>> +		goto requeue_work;
>> +	}
>> +
>> +	curr_steal = get_system_steal_time();
>> +	delta_steal = curr_steal > sg_core_ctx.steal ?
>> +		      curr_steal - sg_core_ctx.steal : 0;
>> +
>> +	/* Update for next calculation */
>> +	sg_core_ctx.steal = curr_steal;
>> +	sg_core_ctx.time = now;
>> +
>> +	/*
>> +	 * steal_ratio = (delta_steal * 100*100)/(delta_ns * num_cpus())
>> +	 * To avoid possible overflow, divide the denominator early.
>> +	 * Note minimum interval is 100ms.
>> +	 */
>> +	delta_ns = max_t(u64, div_u64(delta_ns * get_num_cpus_steal_ratio(),
>> +				      100 * 100), 1);
>> +	steal_ratio = div64_u64(delta_steal, delta_ns);
>> +
>> +	if (steal_ratio > sg_core_ctx.high_threshold)
>> +		decrease_preferred_cpus();
>> +	if (steal_ratio <= sg_core_ctx.low_threshold)
>> +		increase_preferred_cpus();
> 
> If you neither increase, nor decrease, you don't need to check the mask
> because you know you don't modify it. Also, I'd wrap the below integrity
> checks into a helper function.
> 
> 	if (steal_ratio > sg_core_ctx.high_threshold)
> 		decrease_preferred_cpus();
> 	else if (steal_ratio <= sg_core_ctx.low_threshold)
> 		increase_preferred_cpus();
>          else
>                  goto requeue_work;
> 
>          if (check_integrity())
>                  return;
> 

Ack. Good catch. Will do.

>> +	/* maintain design constructs always */
>> +	if (cpumask_empty(cpu_preferred_mask)) {
>> +		pr_err("empty preferred mask. stop steal governor\n");
>> +		restore_preferred_to_active();
>> +		return;
>> +	}
>> +
>> +	if (!cpumask_subset(cpu_preferred_mask, cpu_active_mask)) {
>> +		pr_err("preferred: %*pbl is not subset of active: %*pbl, stop steal governor\n",
>> +		       cpumask_pr_args(cpu_preferred_mask),
>> +		       cpumask_pr_args(cpu_active_mask));
>> +		restore_preferred_to_active();
>> +		return;
>> +	}
>> +
>> +requeue_work:
>> +	/* Trigger for next sampling */
> 
> The lablel above is pretty explaining to me. The comment just
> duplicates it. Maybe drop the comment?

Ok.

> 
>> +	schedule_delayed_work(&sg_core_ctx.work,
>> +			      msecs_to_jiffies(sg_core_ctx.interval_ms));
> 
> If you need jiffies, why don't you have them in the structure, instead of
> milliseconds?
> 
> 	schedule_delayed_work(&sg_core_ctx.work, sg_core_ctx.delay);
> 

I would prefer milliseconds as jiffies is very difficult for users to understand.
It depends on HZ value and one has to query from configs.

HZ can very from 100 to 1000 today. Again I will have to play tricks to schedule
the governor at fixed intervals.

So i think it is better to use milliseconds here.
Correct me if i am not making sense.

>> +}
>> +
>>   static int __init steal_governor_init(void)
>>   {
>>   	if (sg_core_ctx.low_threshold >= sg_core_ctx.high_threshold) {
>> @@ -100,11 +252,19 @@ static int __init steal_governor_init(void)
>>   	pr_info("steal_governor is enabled. interval: %ums, high_threshold: %u, low_threshold: %u\n",
>>   		sg_core_ctx.interval_ms, sg_core_ctx.high_threshold, sg_core_ctx.low_threshold);
>>   
>> +	INIT_DELAYED_WORK(&sg_core_ctx.work, compute_preferred_cpus_work);
>> +	sg_core_ctx.steal = get_system_steal_time();
>> +	sg_core_ctx.time = ktime_get();
>> +
>> +	schedule_delayed_work(&sg_core_ctx.work,
>> +			      msecs_to_jiffies(sg_core_ctx.interval_ms));
>> +
>>   	return 0;
>>   }
>>   
>>   static void __exit steal_governor_exit(void)
>>   {
>> +	disable_delayed_work_sync(&sg_core_ctx.work);
>>   	restore_preferred_to_active();
>>   	pr_info("steal_governor is disabled\n");
>>   }
>> diff --git a/drivers/virt/steal_governor/core.h b/drivers/virt/steal_governor/core.h
>> index e27305284ac0..59329c1d7109 100644
>> --- a/drivers/virt/steal_governor/core.h
>> +++ b/drivers/virt/steal_governor/core.h
>> @@ -12,6 +12,11 @@
>>   #include <linux/workqueue.h>
>>   #include <linux/ktime.h>
>>   #include <linux/kconfig.h>
>> +#include <linux/kernel_stat.h>
>> +#include <linux/topology.h>
>> +#include <linux/sched/isolation.h>
>> +#include <linux/cleanup.h>
>> +#include <linux/math64.h>
>>   
>>   struct steal_governor {
>>   	struct delayed_work	work;
>> -- 
>> 2.47.3


^ permalink raw reply

* [PATCH] vhost-scsi: fix T10-PI lifecycle hard BUG after endpoint
From: Jia Jia @ 2026-07-22  6:36 UTC (permalink / raw)
  To: mst
  Cc: jasowangio, michael.christie, pbonzini, stefanha, eperezma,
	virtualization, linux-kernel, Jia Jia

vhost_scsi_setup_vq_cmds() runs only from VHOST_SCSI_SET_ENDPOINT and
allocates each command's protection scatterlist array (prot_sgl) only
when VIRTIO_SCSI_F_T10_PI is already set at that moment.  Command pools
are not rebuilt later.  vhost_scsi_set_features() may still flip that
bit after the endpoint is live: it updates acked_features and returns
success without reallocating prot_sgl.

That is a feature-versus-resource lifetime mismatch.  The broken order
is:

  VHOST_SET_FEATURES(0)
  VHOST_SCSI_SET_ENDPOINT
      setup_vq_cmds() sees no T10-PI -> prot_sgl stays NULL
  VHOST_SET_FEATURES(VIRTIO_SCSI_F_T10_PI)
      only acked_features changes; command resources stay as above
  submit a T10-PI WRITE with a 129-page protection payload

The I/O path then follows the new feature bit while using the old
command objects.  vhost_scsi_mapal() (static, inlined into
vhost_scsi_handle_vq() here) does:

  sg_alloc_table_chained(table, 129, first_chunk=NULL,
                         nents_first_chunk=inline_sg_cnt)

With first_chunk NULL, __sg_alloc_table() sets curr_max_ents from
nents_first_chunk and calls sg_pool_alloc(129).  sg_pool_index() then
hits:

  BUG_ON(nents > SG_CHUNK_SIZE);   /* 129 > 128 */

The kernel reported the following call trace and register state:

  Call Trace:
   <TASK>
   ? __sg_alloc_table+0x1d8/0x250
   ? __pfx_vhost_run_work_list+0x10/0x10 [vhost]
   sg_alloc_table_chained+0x59/0xf0
   ? __pfx_sg_pool_alloc+0x10/0x10
   ? vhost_scsi_calc_sgls.constprop.0+0x43/0x60 [vhost_scsi]
   vhost_scsi_handle_vq+0xf02/0x1700 [vhost_scsi]
   ? __pfx_vhost_scsi_handle_vq+0x10/0x10 [vhost_scsi]
   vhost_scsi_handle_kick+0x37/0x50 [vhost_scsi]
   vhost_run_work_list+0x8e/0xd0 [vhost]
   vhost_task_fn+0xe1/0x210
   ret_from_fork+0x348/0x540
   </TASK>

  RIP: 0010:0x4
  CR2: 0000000000000004
  RSP: 0018:ffffc90000dbf940 EFLAGS: 00010202
  RAX: ffffffff82396810 RBX: ffff88811dc28b80 RCX: 0000000000000000
  RDX: 0000000000000000 RSI: 0000000000000820 RDI: 0000000000000081

The host worker dies and the machine stops accepting network service
until reset.  The missing object is prot_sgl after a post-endpoint
T10-PI enable introduced by commit bf2d650391be ("vhost-scsi: Allocate
T10 PI structs only when enabled").

I also checked the other feature bits handled around endpoint setup.
Only T10-PI allocates this endpoint-time per-command resource and does
not rebuild it on a later SET_FEATURES.  LOG_ALL uses lazy tvc_log and
already tears log storage down when cleared; HOTPLUG does not allocate
prot_sgl.  So the chosen fix is to refuse T10-PI enable/disable while
an endpoint is active, rather than adding a second rebuild path in
set_features().

Return -EBUSY if vs->vs_tpg is set and the T10-PI bit would change.
Userspace must CLEAR_ENDPOINT, SET_FEATURES, then SET_ENDPOINT again so
setup_vq_cmds() can allocate protection SGLs when needed.  That matches
the existing "build command resources at endpoint" model.

Fixes: bf2d650391be ("vhost-scsi: Allocate T10 PI structs only when enabled")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
---
 drivers/vhost/scsi.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 9a1253b9d8c5..000000000000 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -2219,6 +2219,7 @@ static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
 {
 	struct vhost_virtqueue *vq;
 	bool is_log, was_log;
+	bool is_t10_pi, was_t10_pi;
 	int i;
 
 	if (features & ~VHOST_SCSI_FEATURES)
@@ -2234,6 +2235,13 @@ static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
 	if (!vs->dev.nvqs)
 		goto out;
 
+	is_t10_pi = features & (1ULL << VIRTIO_SCSI_F_T10_PI);
+	was_t10_pi = vhost_has_feature(&vs->vqs[0].vq, VIRTIO_SCSI_F_T10_PI);
+	if (vs->vs_tpg && is_t10_pi != was_t10_pi) {
+		mutex_unlock(&vs->dev.mutex);
+		return -EBUSY;
+	}
+
 	is_log = features & (1 << VHOST_F_LOG_ALL);
 	/*
 	 * All VQs should have same feature.
-- 
2.43.0

^ permalink raw reply related

* Re: [PATCH v8 08/11] virt: Introduce steal governor driver
From: Shrikanth Hegde @ 2026-07-22  5:38 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-kernel, mingo, peterz, juri.lelli, vincent.guittot,
	yury.norov, kprateek.nayak, iii, corbet, tglx, gregkh, pbonzini,
	seanjc, vschneid, huschle, rostedt, dietmar.eggemann, maddy,
	srikar, hdanton, chleroy, vineeth, frederic, arighi, pauld,
	christian.loehle, tj, tommaso.cucinotta, maz, rafael, rdunlap,
	kernellwp, linux-doc, jgross, virtualization
In-Reply-To: <al-n0iPGnlTr39P9@yury>

Hi Yury,
Thanks for taking a look at the series. Much appreciated _/\_

On 7/21/26 10:39 PM, Yury Norov wrote:
> On Mon, Jul 20, 2026 at 10:52:47PM +0530, Shrikanth Hegde wrote:
>> Introduce a new driver in virt named steal_governor. This driver
>> will compute the steal time and drive the policy decisions of preferred
>> CPU state.
>>
>> More on it can be found in the Documentation/driver-api/steal-governor.rst
>>
>> There is a new kconfig called STEAL_GOVERNOR which is introduced in
>> subsequent patches. That driver is going to select PREFERRED_CPU.
>> This makes configs driven by user preference.
>> When the driver is disabled, preferred CPUs is same as active CPUs.
>>
>> File layout of the driver is being kept simple.
>> - core.c - contains main driver code. This includes the periodic
>>    work function and take action on steal time which is introduced
>>    in subsequent patches.
>> - core.h - header file which includes data structure.
>>
>> Main structure of steal governor has,
>> - work: deferred periodic work function
>> - steal, time: To calculate the delta in periodic work.
>> - interval_ms, high_threshold, low_threshold: debug knobs of
>>    steal_governor.
>>
>> While there, Add MAINTAINERS entry for this new driver.
>>
>> Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
>> ---
>>   Documentation/driver-api/index.rst          |   1 +
>>   Documentation/driver-api/steal-governor.rst | 117 ++++++++++++++++++++
>>   MAINTAINERS                                 |   9 ++
>>   drivers/virt/steal_governor/core.c          |  48 ++++++++
>>   drivers/virt/steal_governor/core.h          |  25 +++++
> 
> Unless I missed something, you don't use struct steal_governor out of
> the driver. If so, you don't need this layout. Just put everything in
> drivers/virt/steal_governor.c.
>

Ok.

By that I assume you mean to move all those headers also into 
steal_governor.c, remove core.h and remove folder for steal_governor.


> Thanks,
> Yury


^ permalink raw reply

* Re: [PATCH] virtio_net: fix spelling of aggressively in comments
From: Jakub Kicinski @ 2026-07-21 22:22 UTC (permalink / raw)
  To: Weimin Xiong
  Cc: virtualization, netdev, mst, jasowangio, xuanzhuo, eperezma,
	andrew+netdev, davem, edumazet, pabeni, linux-kernel
In-Reply-To: <20260716011201.86688-1-xiongwm2026@163.com>

On Thu, 16 Jul 2026 09:12:01 +0800 Weimin Xiong wrote:
> -			/* Pre-fill rq agressively, to make sure we are ready to
> +			/* Pre-fill rq aggressively, to make sure we are ready to
>  			 * get packets immediately.

Move the "to" to the next line to avoid going over 80 chars
-- 
pw-bot: cr

^ permalink raw reply

* Re: [PATCH v8 10/11] virt/steal_governor: Implement steal_governor policy loop
From: Yury Norov @ 2026-07-21 19:28 UTC (permalink / raw)
  To: Shrikanth Hegde
  Cc: linux-kernel, mingo, peterz, juri.lelli, vincent.guittot,
	yury.norov, kprateek.nayak, iii, corbet, tglx, gregkh, pbonzini,
	seanjc, vschneid, huschle, rostedt, dietmar.eggemann, maddy,
	srikar, hdanton, chleroy, vineeth, frederic, arighi, pauld,
	christian.loehle, tj, tommaso.cucinotta, maz, rafael, rdunlap,
	kernellwp, linux-doc, jgross, virtualization
In-Reply-To: <20260720172250.2257582-11-sshegde@linux.ibm.com>

On Mon, Jul 20, 2026 at 10:52:49PM +0530, Shrikanth Hegde wrote:
> schedule work at regular intervals to implement the steal_governor
> policy of monitoring the steal time and take action on the state of
> preferred CPUs. The interval is determined by interval_ms parameter.
> schedule_delayed_work is used since interval_ms
> is in the order of milliseconds. Work need not happen instantly.
> 
> Periodic policy loop essentially does:
> - Gets the total/delta steal values and cpus to use steal_ratio.
>   (get_system_steal_time, get_num_cpus_steal_ratio)
> - Calculate the steal_ratio as below.
> 
>        steal_ratio = (delta_steal * 100*100)/(delta_ns * num_cpus())
> 
>   It is calculated to consider the fractional values of steal time.
>   I.e 10 means 0.1% steal time. A few tricks such as divide by 10,000
>   are used to avoid possible overflow.
> - If steal value is higher than high threshold, call the method to reduce
>   the preferred CPUs. (decrease_preferred_cpus)
> - If steal value is lower or equal to low threshold, call the method to
>   increase the preferred CPUs. (increase_preferred_cpus)
> - If the steal value is in between, no action is taken.
> - Save the values for next delta calculations.
> - Ensure design checks are met.
>   1. At least one core/CPU must be there in preferred mask.
>   2. preferred CPUs is subset of active CPUs.
> If not met, then restore preferred CPUs to active and stop
> requeue of the work. Driver is effectively non-functional after that.
> 
> In Order to help the above loop, a few helper functions have been added.
> 
> 1. get_system_steal_time()
> - steal governor takes global view of steal time instead of individual
>   vCPU. Collect the steal values across the vCPUs of interest.
> - Sum up steal time values across possible CPUs. This helps to keep it
>   a monotonically increasing number and avoids spikes due to CPU
>   hotplug.
> 
> 2. decrease_preferred_cpus()
> - Called when there is high steal time. It needs to decide which CPUs to
>   mark as non-preferred and set that state.
> - Get first housekeeping CPU and its core mask. Mark it as
>   protected core. This helps to keep at least one core as preferred.
>   kernel ensures at least one housekeeping CPU stays active.
> - Find the last CPU outside of this protected core mask. (target CPU)
> - Based on that target CPU, get its sibling and mark them as
>   non-preferred.
> 
> 3. increase_preferred_cpus()
> - Called when there is low steal time. It needs to decide which CPUs to
>   mark as preferred and set that state.
> - Get the first active non-preferred CPUs. This likely is the last
>   set of CPUs being marked as non-preferred.
> - get the siblings of that CPU and mark them as preferred.
> 
> 4. get_num_cpus_steal_ratio()
> - informs how many CPUs needs to be considered for steal_ratio
>   calculations.
> - Return number of possible CPUs as get_system_steal_time computes
>   steal values across possible CPUs.
> 
> Notes:
> 1. Using core instead of individual CPUs performs better as SMT is
>    quite common and some hypervisor such as powerVM does core scheduling.
> 
> 2. This doesn't do any NUMA splicing to keep the code simpler and
>    minimal overhead. Current code expects CPUs spread uniformly
>    across NUMA nodes.
> 
> Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
> ---
>  drivers/virt/steal_governor/core.c | 160 +++++++++++++++++++++++++++++
>  drivers/virt/steal_governor/core.h |   5 +
>  2 files changed, 165 insertions(+)
> 
> diff --git a/drivers/virt/steal_governor/core.c b/drivers/virt/steal_governor/core.c
> index 1cb766a8ce28..97f82d6df60f 100644
> --- a/drivers/virt/steal_governor/core.c
> +++ b/drivers/virt/steal_governor/core.c
> @@ -89,6 +89,158 @@ module_param_named(low_threshold, sg_core_ctx.low_threshold, uint, 0444);
>  MODULE_PARM_DESC(low_threshold,
>  		 "Low steal threshold. default: 200 i.e 2%. Must be < high_threshold");
>  
> +/*
> + * Returns steal time of the full system.
> + * Compute collective steal time across all possible CPUs.
> + */
> +static u64 get_system_steal_time(void)
> +{
> +	int cpu;
> +	u64 total_steal = 0;
> +
> +	for_each_possible_cpu(cpu)
> +		total_steal += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
> +
> +	return total_steal;
> +}

There's another implementation of the same logic in
hd_calculate_steal_percentage())

It means it should live in include/linux/kernel_stat.h as:
        
        u64 kcpustat_steal_time(struct cpumask *cpus);

Or possibly even more generic:

        u64 kcpustat_field_total(enum cpu_usage_stat usage, struct cpumask *cpus);

Similarly to the existing kcpustat_field().

The other possible candidates are: fs/proc/stat.c:: show_stat()
arch_cpu_idle_time(), but I think it's out of the scope of your
series. 

What's the relation between the arch/s390/kernel/hiperdispatch.c and
your steal governor? Is that a similar concept?

> +/*
> + * Returns number of CPUs to consider for steal ratio.
> + * Return possible CPUs.
> + */

Can you rephrase the comment? It has 2 'return' sections with
different meaning. If the 2nd one is the implementation detail,
I'd put it inside the function scope, or drop entirely.

> +static unsigned int get_num_cpus_steal_ratio(void)
> +{
> +	return num_possible_cpus();
> +}
> +
> +/*
> + * Take action to decrease preferred CPUs.
> + *

Drop this 'Take action' wording please.

> + * Decrease the preferred CPUs by 1 core.
> + * Take out the last core in the active & preferred.
> + *
> + * Must ensure
> + * - least one housekeeping core is always kept as preferred

s/least/at least/ ?

> + * - preferred is always subset of active.
> + */
> +static void decrease_preferred_cpus(void)
> +{
> +	int tmp_cpu, first_hk_cpu, last_cpu;
> +	const struct cpumask *first_hk_core;
> +	int target_cpu = nr_cpu_ids;
> +
> +	guard(cpus_read_lock)();
> +	first_hk_cpu = cpumask_first_and(housekeeping_cpumask(HK_TYPE_KERNEL_NOISE),
> +					 cpu_preferred_mask);
> +	if (first_hk_cpu >= nr_cpu_ids)
> +		return;
> +
> +	last_cpu = cpumask_last(cpu_preferred_mask);
> +
> +	if (last_cpu >= nr_cpu_ids)
> +		return;
> +
> +	/* Always leave first housekeeping core as preferred. */
> +	first_hk_core = topology_sibling_cpumask(first_hk_cpu);
> +
> +	/* Find the last CPU which doesn't belong to that first hk_core. */
> +	if (!cpumask_test_cpu(last_cpu, first_hk_core)) {
> +		target_cpu = last_cpu;
> +	} else {
> +		for_each_cpu_andnot(tmp_cpu, cpu_preferred_mask, first_hk_core)
> +			target_cpu = tmp_cpu;
> +	}

Too much local variables. You can drop those tmp_cpu, last_cpu and
target_cpu, and just use a single variable 'cpu'. That would also
simplify your logic:

        cpu = cpumask_last(cpu_preferred_mask);
        core = topology_sibling_cpumask(first_hk_cpu);

        if (cpumask_test_cpu(cpu, core)) {
                for_each_cpu_andnot(cpu, cpu_preferred_mask, core)
                        /* nop */ ;
        }

        if (cpu >= nr_cpu_ids)
                return;

And so on.

> +
> +	/* Only the first housekeeping core remains */
> +	if (target_cpu >= nr_cpu_ids)
> +		return;
> +
> +	for_each_cpu_and(tmp_cpu, topology_sibling_cpumask(target_cpu),
> +			 cpu_preferred_mask)
> +		set_cpu_preferred(tmp_cpu, false);
> +}
> +
> +/*
> + * Take action to increase preferred CPUs.
> + *

Again, drop this 'take action' thing.

> + * Increase the preferred CPUs by 1 core.
> + * Add the first core in active & !preferred
> + *
> + * Must ensure preferred is subset of active.
> + */
> +static void increase_preferred_cpus(void)
> +{
> +	int first_cpu, tmp_cpu;
> +
> +	guard(cpus_read_lock)();
> +	first_cpu = cpumask_first_andnot(cpu_active_mask, cpu_preferred_mask);
> +
> +	/* All CPUs are preferred. Nothing to increase further */
> +	if (first_cpu >= nr_cpu_ids)
> +		return;
> +
> +	for_each_cpu_and(tmp_cpu, topology_sibling_cpumask(first_cpu),
> +			 cpu_active_mask)
> +		set_cpu_preferred(tmp_cpu, true);
> +}
> +
> +static void compute_preferred_cpus_work(struct work_struct *work)
> +{
> +	u64 curr_steal, delta_steal, delta_ns, steal_ratio;
> +	ktime_t now;
> +
> +	now = ktime_get();
> +	delta_ns = ktime_to_ns(ktime_sub(now, sg_core_ctx.time));
> +
> +	if (unlikely(delta_ns < NSEC_PER_MSEC)) {
> +		pr_err_ratelimited("steal_governor: work scheduled too soon delta_ns: %llu\n",
> +				   delta_ns);
> +		goto requeue_work;
> +	}
> +
> +	curr_steal = get_system_steal_time();
> +	delta_steal = curr_steal > sg_core_ctx.steal ?
> +		      curr_steal - sg_core_ctx.steal : 0;
> +
> +	/* Update for next calculation */
> +	sg_core_ctx.steal = curr_steal;
> +	sg_core_ctx.time = now;
> +
> +	/*
> +	 * steal_ratio = (delta_steal * 100*100)/(delta_ns * num_cpus())
> +	 * To avoid possible overflow, divide the denominator early.
> +	 * Note minimum interval is 100ms.
> +	 */
> +	delta_ns = max_t(u64, div_u64(delta_ns * get_num_cpus_steal_ratio(),
> +				      100 * 100), 1);
> +	steal_ratio = div64_u64(delta_steal, delta_ns);
> +
> +	if (steal_ratio > sg_core_ctx.high_threshold)
> +		decrease_preferred_cpus();
> +	if (steal_ratio <= sg_core_ctx.low_threshold)
> +		increase_preferred_cpus();

If you neither increase, nor decrease, you don't need to check the mask
because you know you don't modify it. Also, I'd wrap the below integrity
checks into a helper function.

	if (steal_ratio > sg_core_ctx.high_threshold)
		decrease_preferred_cpus();
	else if (steal_ratio <= sg_core_ctx.low_threshold)
		increase_preferred_cpus();
        else
                goto requeue_work;

        if (check_integrity())
                return;

> +	/* maintain design constructs always */
> +	if (cpumask_empty(cpu_preferred_mask)) {
> +		pr_err("empty preferred mask. stop steal governor\n");
> +		restore_preferred_to_active();
> +		return;
> +	}
> +
> +	if (!cpumask_subset(cpu_preferred_mask, cpu_active_mask)) {
> +		pr_err("preferred: %*pbl is not subset of active: %*pbl, stop steal governor\n",
> +		       cpumask_pr_args(cpu_preferred_mask),
> +		       cpumask_pr_args(cpu_active_mask));
> +		restore_preferred_to_active();
> +		return;
> +	}
> +
> +requeue_work:
> +	/* Trigger for next sampling */

The lablel above is pretty explaining to me. The comment just
duplicates it. Maybe drop the comment?

> +	schedule_delayed_work(&sg_core_ctx.work,
> +			      msecs_to_jiffies(sg_core_ctx.interval_ms));

If you need jiffies, why don't you have them in the structure, instead of
milliseconds?

	schedule_delayed_work(&sg_core_ctx.work, sg_core_ctx.delay);

> +}
> +
>  static int __init steal_governor_init(void)
>  {
>  	if (sg_core_ctx.low_threshold >= sg_core_ctx.high_threshold) {
> @@ -100,11 +252,19 @@ static int __init steal_governor_init(void)
>  	pr_info("steal_governor is enabled. interval: %ums, high_threshold: %u, low_threshold: %u\n",
>  		sg_core_ctx.interval_ms, sg_core_ctx.high_threshold, sg_core_ctx.low_threshold);
>  
> +	INIT_DELAYED_WORK(&sg_core_ctx.work, compute_preferred_cpus_work);
> +	sg_core_ctx.steal = get_system_steal_time();
> +	sg_core_ctx.time = ktime_get();
> +
> +	schedule_delayed_work(&sg_core_ctx.work,
> +			      msecs_to_jiffies(sg_core_ctx.interval_ms));
> +
>  	return 0;
>  }
>  
>  static void __exit steal_governor_exit(void)
>  {
> +	disable_delayed_work_sync(&sg_core_ctx.work);
>  	restore_preferred_to_active();
>  	pr_info("steal_governor is disabled\n");
>  }
> diff --git a/drivers/virt/steal_governor/core.h b/drivers/virt/steal_governor/core.h
> index e27305284ac0..59329c1d7109 100644
> --- a/drivers/virt/steal_governor/core.h
> +++ b/drivers/virt/steal_governor/core.h
> @@ -12,6 +12,11 @@
>  #include <linux/workqueue.h>
>  #include <linux/ktime.h>
>  #include <linux/kconfig.h>
> +#include <linux/kernel_stat.h>
> +#include <linux/topology.h>
> +#include <linux/sched/isolation.h>
> +#include <linux/cleanup.h>
> +#include <linux/math64.h>
>  
>  struct steal_governor {
>  	struct delayed_work	work;
> -- 
> 2.47.3

^ permalink raw reply

* Re: [PATCH v8 08/11] virt: Introduce steal governor driver
From: Yury Norov @ 2026-07-21 17:09 UTC (permalink / raw)
  To: Shrikanth Hegde
  Cc: linux-kernel, mingo, peterz, juri.lelli, vincent.guittot,
	yury.norov, kprateek.nayak, iii, corbet, tglx, gregkh, pbonzini,
	seanjc, vschneid, huschle, rostedt, dietmar.eggemann, maddy,
	srikar, hdanton, chleroy, vineeth, frederic, arighi, pauld,
	christian.loehle, tj, tommaso.cucinotta, maz, rafael, rdunlap,
	kernellwp, linux-doc, jgross, virtualization
In-Reply-To: <20260720172250.2257582-9-sshegde@linux.ibm.com>

On Mon, Jul 20, 2026 at 10:52:47PM +0530, Shrikanth Hegde wrote:
> Introduce a new driver in virt named steal_governor. This driver
> will compute the steal time and drive the policy decisions of preferred
> CPU state.
> 
> More on it can be found in the Documentation/driver-api/steal-governor.rst
> 
> There is a new kconfig called STEAL_GOVERNOR which is introduced in
> subsequent patches. That driver is going to select PREFERRED_CPU.
> This makes configs driven by user preference.
> When the driver is disabled, preferred CPUs is same as active CPUs.
> 
> File layout of the driver is being kept simple.
> - core.c - contains main driver code. This includes the periodic
>   work function and take action on steal time which is introduced
>   in subsequent patches.
> - core.h - header file which includes data structure.
> 
> Main structure of steal governor has,
> - work: deferred periodic work function
> - steal, time: To calculate the delta in periodic work.
> - interval_ms, high_threshold, low_threshold: debug knobs of
>   steal_governor.
> 
> While there, Add MAINTAINERS entry for this new driver.
> 
> Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
> ---
>  Documentation/driver-api/index.rst          |   1 +
>  Documentation/driver-api/steal-governor.rst | 117 ++++++++++++++++++++
>  MAINTAINERS                                 |   9 ++
>  drivers/virt/steal_governor/core.c          |  48 ++++++++
>  drivers/virt/steal_governor/core.h          |  25 +++++

Unless I missed something, you don't use struct steal_governor out of
the driver. If so, you don't need this layout. Just put everything in 
drivers/virt/steal_governor.c.

Thanks,
Yury

^ permalink raw reply

* [PATCH] drm/virtio: Remove usage of drm_simple_encoder_init()
From: liutianyi2211 @ 2026-07-21 16:21 UTC (permalink / raw)
  To: David Airlie, Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh,
	Chia-I Wu, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Simona Vetter, open list:VIRTIO GPU DRIVER,
	open list:VIRTIO GPU DRIVER, open list
  Cc: Tianyi Liu

From: Tianyi Liu <liutianyi2211@gmail.com>

Remove the deprecated trivial helper drm_simple_encoder_init(). Inline
the call to drm_encoder_init and add instance of
drm_encoder_funcs.

Signed-off-by: Tianyi Liu <liutianyi2211@gmail.com>
---
 drivers/gpu/drm/virtio/virtgpu_display.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index 44ffffec550f..048c19543218 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -32,7 +32,7 @@
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
-#include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_encoder.h>
 #include <drm/drm_vblank.h>
 #include <drm/drm_vblank_helper.h>
 
@@ -67,6 +67,10 @@ static const struct drm_framebuffer_funcs virtio_gpu_fb_funcs = {
 	.dirty = drm_atomic_helper_dirtyfb,
 };
 
+static const struct drm_encoder_funcs virtio_gpu_encoder_funcs_cleanup = {
+	.destroy = drm_encoder_cleanup,
+};
+
 static int
 virtio_gpu_framebuffer_init(struct drm_device *dev,
 			    struct virtio_gpu_framebuffer *vgfb,
@@ -306,7 +310,8 @@ static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index)
 	if (vgdev->has_edid)
 		drm_connector_attach_edid_property(connector);
 
-	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_VIRTUAL);
+	drm_encoder_init(dev, encoder, &virtio_gpu_encoder_funcs_cleanup,
+				DRM_MODE_ENCODER_VIRTUAL, NULL);
 	drm_encoder_helper_add(encoder, &virtio_gpu_enc_helper_funcs);
 	encoder->possible_crtcs = 1 << index;
 
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH net] vhost-net: fix TX stall when vhost owns virtio-net header
From: patchwork-bot+netdevbpf @ 2026-07-21 13:20 UTC (permalink / raw)
  To: enrico.zanda
  Cc: jasowangio, virtualization, mst, netdev, kuba, kvm, linux-kernel,
	eperezma, nd
In-Reply-To: <20260708152242.2268848-1-enrico.zanda@arm.com>

Hello:

This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:

On Wed, 8 Jul 2026 16:22:42 +0100 you wrote:
> From: Enrico Zanda <enrico.zanda@arm.com>
> 
> When vhost owns the virtio-net header, i.e. when
> VHOST_NET_F_VIRTIO_NET_HDR is negotiated, sock_hlen is 0,
> meaning that no header will be forwarded to the TAP device.
> 
> In the current vhost_net_build_xdp() implementation,
> when sock_hlen == 0, the gso pointer can point at the start of the
> Ethernet frame instead of a virtio-net header.
> This results in a wrong interpretation of the destination MAC address
> bytes as struct virtio_net_hdr fields.
> 
> [...]

Here is the summary with links:
  - [net] vhost-net: fix TX stall when vhost owns virtio-net header
    https://git.kernel.org/netdev/net/c/3c0d10f233f1

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH net] vhost-net: fix TX stall when vhost owns virtio-net header
From: Paolo Abeni @ 2026-07-21 11:19 UTC (permalink / raw)
  To: Michael S. Tsirkin, enrico.zanda
  Cc: jasowangio, virtualization, netdev, kuba, kvm, linux-kernel,
	eperezma, nd
In-Reply-To: <20260708124901-mutt-send-email-mst@kernel.org>

On 7/8/26 6:50 PM, Michael S. Tsirkin wrote:
> On Wed, Jul 08, 2026 at 04:22:42PM +0100, enrico.zanda@arm.com wrote:
>> From: Enrico Zanda <enrico.zanda@arm.com>
>>
>> When vhost owns the virtio-net header, i.e. when
>> VHOST_NET_F_VIRTIO_NET_HDR is negotiated, sock_hlen is 0,
>> meaning that no header will be forwarded to the TAP device.
>>
>> In the current vhost_net_build_xdp() implementation,
>> when sock_hlen == 0, the gso pointer can point at the start of the
>> Ethernet frame instead of a virtio-net header.
>> This results in a wrong interpretation of the destination MAC address
>> bytes as struct virtio_net_hdr fields.
>>
>> This can, for some MAC addresses, trigger -EINVAL and return early
>> before the TX descriptor is completed, which can stall vhost-net TX.
>>
>> Before 97b2409f28e0, the gso pointer was set to the zeroed padding area,
>> using it as a synthetic virtio-net header. Restore that behavior.
>>
>> Fixes: 97b2409f28e0 ("vhost-net: reduce one userspace copy when building XDP buff")
>> Signed-off-by: Enrico Zanda <enrico.zanda@arm.com>
> 
> 
> The fix looks good:
> Acked-by: Michael S. Tsirkin <mst@redhat.com>
> 
> Sashiko thinks there's something something security here, but I think
> it is misguided. It's just guest hurting itself. driver breaks the
> device it gets to keep both pieces.
Out of sheer curiosity: which sashiko instance? AFAICS both gemini and
nipa are clean:

https://sashiko.dev/#/patchset/20260708152242.2268848-1-enrico.zanda%40arm.com
https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260708152242.2268848-1-enrico.zanda%40arm.com

/P


^ permalink raw reply

* Re: [PATCH net v2 0/2] vsock/virtio: collapse receive queue under memory pressure
From: patchwork-bot+netdevbpf @ 2026-07-21 10:20 UTC (permalink / raw)
  To: Stefano Garzarella
  Cc: netdev, jasowangio, xuanzhuo, edumazet, eperezma, horms, stefanha,
	davem, linux-kernel, mst, kvm, pabeni, virtualization, kuba,
	jasowang
In-Reply-To: <20260708102904.50732-1-sgarzare@redhat.com>

Hello:

This series was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:

On Wed,  8 Jul 2026 12:29:02 +0200 you wrote:
> This series contains a patch (the first one) that is part of work I'm
> doing to improve the tracking of memory used by AF_VSOCK sockets.
> The second patch is a test for our suite that highlights the issue.
> 
> Since Brien reported an issue with his environment (based on Linux 6.12.y)
> related to the work I’m doing, I extracted this patch and tried to make it
> as easy as possible to backport. Brien tested it by backporting it to
> 6.12.y, which now contains the backport of the 059b7dbd20a6
> ("vsock/virtio: fix potential unbounded skb queue").
> 
> [...]

Here is the summary with links:
  - [net,v2,1/2] vsock/virtio: collapse receive queue under memory pressure
    https://git.kernel.org/netdev/net/c/2a12c05aef21
  - [net,v2,2/2] vsock/test: add test for small packets under pressure
    https://git.kernel.org/netdev/net/c/30c82aa0a8b1

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox