Every devmem dmabuf binding hands the page_pool PAGE_SIZE niovs today.
On NICs that consume one descriptor per netmem, this caps a single RX
descriptor at PAGE_SIZE and burns CPU on buffer churn.
In this series, we add a bind-time netlink attribute,
NETDEV_A_DMABUF_RX_BUF_SIZE, that lets userspace request a larger niov
size (power of two >= PAGE_SIZE). Drivers must opt in via
queue_mgmt_ops.QCFG_RX_PAGE_SIZE.
Measurements:
Setup: kperf devmem RX/TX cuda, 4 flows, 64 MB messages, 60s, dctcp,
num-rx-queues=4, dmabuf-rx/tx-size-mb=2048, 10 runs per niov size,
mlx5.
niov RX dev Gbps RX flow avg Gbps app sys %
----- ---------------- ----------------- ----------------
4K 300.63 +/- 53.21 75.16 +/- 13.30 54.15 +/- 10.23
16K 321.35 +/- 28.20 80.34 +/- 7.05 41.05 +/- 8.87
32K 347.63 +/- 2.20 86.91 +/- 0.55 44.54 +/- 3.51
64K 332.11 +/- 14.26 83.03 +/- 3.56 35.47 +/- 3.11
RX app sys % drops ~19% from 4K to 64K.
kperf support (not yet merged):
https://github.com/facebookexperimental/kperf/commit/8837577f920876bce6986e…
Signed-off-by: Bobby Eshleman <bobbyeshleman(a)meta.com>
---
Changes in v5:
- removed unnecessary change from ssize_t to size_t (Mina)
- removed '--------' lines in the commit message (Paolo)
- removed commit msg about CONFIG_HUGETLB since that change was already
merged
- Link to v4: https://lore.kernel.org/r/20260701-tcpdm-large-niovs-v4-0-ca4654f37570@meta…
Changes in v4:
- ncdevmem: fix the possible overflow in ncdevmem (Sashiko)
- drop the udmabuf patch because the fix is now already in net-next
- silenced two pylint complaints in devmem_lib.py
- Link to v3: https://lore.kernel.org/r/20260612-tcpdm-large-niovs-v3-0-a3b693e76fcb@meta…
Changes in v3:
- fix a bunch of non-reverse christmas tree declarations (Stan)
- remove extra uint32 cast for getpagesize() (Stan)
- remove overzealous strtoul checking (Stan)
- remove value checks that the kernel already performs on rx_buf_size
(Stan)
- Link to v2: https://lore.kernel.org/r/20260611-tcpdm-large-niovs-v2-0-ee2bf15e7523@meta…
Changes in v2:
- Use NL_SET_ERR_MSG_FMT for sg alignment failure details (Stan)
- Keep -E2BIG (not a direct ask, but seemed preferred, Stan)
- Update udmabuf commit message and comments explaining why
"one sg ent per folio" is useful (Christian)
- Set/restore nr_hugepages in py harness (Stan)
- Link to v1: https://lore.kernel.org/r/20260603-tcpdm-large-niovs-v1-0-f37a4ac6726c@meta…
---
Bobby Eshleman (3):
net: devmem: allow rx-buf-size > PAGE_SIZE per dmabuf binding
selftests/net: ncdevmem: add -b option to set rx-buf-size on bind
selftests/net: devmem.py: add check_rx_large_niov
Documentation/netlink/specs/netdev.yaml | 8 +++
include/uapi/linux/netdev.h | 1 +
net/core/devmem.c | 51 +++++++++++--------
net/core/devmem.h | 13 +++--
net/core/netdev-genl-gen.c | 5 +-
net/core/netdev-genl.c | 19 ++++++-
tools/include/uapi/linux/netdev.h | 1 +
tools/testing/selftests/drivers/net/hw/devmem.py | 12 ++++-
.../testing/selftests/drivers/net/hw/devmem_lib.py | 59 +++++++++++++++++++++-
tools/testing/selftests/drivers/net/hw/ncdevmem.c | 36 +++++++++++--
.../testing/selftests/drivers/net/hw/nk_devmem.py | 11 +++-
11 files changed, 178 insertions(+), 38 deletions(-)
---
base-commit: 474cff6868129755cf889edf40d7f491729fc588
change-id: 20260602-tcpdm-large-niovs-56523a3a1077
Best regards,
--
Bobby Eshleman <bobbyeshleman(a)meta.com>
7.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tvrtko Ursulin <tvrtko.ursulin(a)igalia.com>
[ Upstream commit e94b9f01543cc6a83538c2c2cc645a424d3015ca ]
Trace_dma_fence_signaled, trace_dma_fence_wait_end and
trace_dma_fence_destroy can all currently dereference a null fence->ops
pointer after it has been reset on fence signalling.
Lets use the safe string getters for most tracepoints to avoid this class
of a problem, while for the signal tracepoint we move it to before ops are
cleared to avoid losing the driver and timeline name information. Apart
from moving it we also need to add a new tracepoint class to bypass the
safe name getters since the signaled bit is already set.
For dma_fence_init we also need to use the new tracepoint class since the
rcu read lock is not held there, and we can do the same for the enable
signaling since there we are certain the fence cannot be signaled while
we are holding the lock and have even validated the fence->ops.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin(a)igalia.com>
Fixes: 541c8f2468b9 ("dma-buf: detach fence ops on signal v3")
Cc: Christian König <christian.koenig(a)amd.com>
Cc: Philipp Stanner <phasta(a)kernel.org>
Cc: Boris Brezillon <boris.brezillon(a)collabora.com>
Cc: linux-media(a)vger.kernel.org
Cc: linaro-mm-sig(a)lists.linaro.org
Reviewed-by: Christian König <christian.koenig(a)amd.com>
Signed-off-by: Tvrtko Ursulin <tursulin(a)ursulin.net>
Link: https://lore.kernel.org/r/20260415083207.40513-2-tvrtko.ursulin@igalia.com
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
drivers/dma-buf/dma-fence.c | 3 ++-
include/trace/events/dma_fence.h | 40 +++++++++++++++++++++++++++-----
2 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index a2aa82f4eedd49..b3bfa6943a8e13 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -363,6 +363,8 @@ void dma_fence_signal_timestamp_locked(struct dma_fence *fence,
&fence->flags)))
return;
+ trace_dma_fence_signaled(fence);
+
/*
* When neither a release nor a wait operation is specified set the ops
* pointer to NULL to allow the fence structure to become independent
@@ -377,7 +379,6 @@ void dma_fence_signal_timestamp_locked(struct dma_fence *fence,
fence->timestamp = timestamp;
set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);
- trace_dma_fence_signaled(fence);
list_for_each_entry_safe(cur, tmp, &cb_list, node) {
INIT_LIST_HEAD(&cur->node);
diff --git a/include/trace/events/dma_fence.h b/include/trace/events/dma_fence.h
index 3abba45c0601a4..5b10a9e06fb4ec 100644
--- a/include/trace/events/dma_fence.h
+++ b/include/trace/events/dma_fence.h
@@ -9,12 +9,40 @@
struct dma_fence;
+DECLARE_EVENT_CLASS(dma_fence,
+
+ TP_PROTO(struct dma_fence *fence),
+
+ TP_ARGS(fence),
+
+ TP_STRUCT__entry(
+ __string(driver, dma_fence_driver_name(fence))
+ __string(timeline, dma_fence_timeline_name(fence))
+ __field(unsigned int, context)
+ __field(unsigned int, seqno)
+ ),
+
+ TP_fast_assign(
+ __assign_str(driver);
+ __assign_str(timeline);
+ __entry->context = fence->context;
+ __entry->seqno = fence->seqno;
+ ),
+
+ TP_printk("driver=%s timeline=%s context=%u seqno=%u",
+ __get_str(driver), __get_str(timeline), __entry->context,
+ __entry->seqno)
+);
+
/*
* Safe only for call sites which are guaranteed to not race with fence
- * signaling,holding the fence->lock and having checked for not signaled, or the
- * signaling path itself.
+ * signaling, holding the fence->lock and having checked for not signaled, or
+ * the signaling path itself.
+ *
+ * TODO: Remove the need for this event class when drivers switch to independent
+ * fences.
*/
-DECLARE_EVENT_CLASS(dma_fence,
+DECLARE_EVENT_CLASS(dma_fence_ops,
TP_PROTO(struct dma_fence *fence),
@@ -46,7 +74,7 @@ DEFINE_EVENT(dma_fence, dma_fence_emit,
TP_ARGS(fence)
);
-DEFINE_EVENT(dma_fence, dma_fence_init,
+DEFINE_EVENT(dma_fence_ops, dma_fence_init,
TP_PROTO(struct dma_fence *fence),
@@ -60,14 +88,14 @@ DEFINE_EVENT(dma_fence, dma_fence_destroy,
TP_ARGS(fence)
);
-DEFINE_EVENT(dma_fence, dma_fence_enable_signal,
+DEFINE_EVENT(dma_fence_ops, dma_fence_enable_signal,
TP_PROTO(struct dma_fence *fence),
TP_ARGS(fence)
);
-DEFINE_EVENT(dma_fence, dma_fence_signaled,
+DEFINE_EVENT(dma_fence_ops, dma_fence_signaled,
TP_PROTO(struct dma_fence *fence),
--
2.53.0
On Fri, 2026-07-17 at 14:14 -0300, Daniel Almeida wrote:
> >
> > > > + try_pin_init!(Self {
> > > > + // SAFETY: `dma_fence_context_alloc()` merely works on a global atomic.
> > > > + // Parameter `1` is the number of contexts we want to allocate.
> > > > + nr: unsafe { bindings::dma_fence_context_alloc(1) },
> > > > + seqno: AtomicU64::new(0),
> > >
> > > Do we really need to force a 0 here? i.e.: can’t we take the initial seqno
> > > as an argument?
> >
> > We could. What would that be useful for?
>
>
> On Mali, the hardware syncobj starts at 0. If you see a 0, is this the default
> state, or should you signal seqno 0?
>
> This problem goes away if we can have seqnos starting at a custom value, like
> 1. It seems like the C machinery also special-cases 0 in a few other places too.
ACK.
>
> >
> > Hm, no, we don't.
> >
> > For the most part that's irrelevant, since all critical components then
> > only get set in new_fence(). Correct typization is enforced through T.
> >
> > The notable exception is the fence_ctx reference itself.
> >
> > What should we do about it?
> >
> > We could keep the fctx field as a MaybeUninit and set it later. Or we
> > check through the fctx identifier number whether it's the correct one
> > in new_fence(), but then new_fence() could fail with some error, and
> > it's probably better to have it be completely fail-free.
>
> Agree about the fail-free part.
>
> The problem I see here is that new_fence() will use "seqno" and "nr" from
> whatever context called new_fence(), but DriverFenceAllocation has some other
> (possibly unrelated) context as its DriverFenceData::fctx.
>
> The lifetimes are apparently broken too, because 'a is the lifetime of the
> context where new_fence_allocation was called, meaning that the context that
> actually called new_fence() can drop, even though it provided the state for
> dma_fence_init().
>
> I guess this can be solved by moving new_fence() to impl DriverFenceAllocation?
> That already has a context, and most importantly, the right context.
Yes that is / was broken. Having the wrong fctx would cause wrong
container_of() calls and therefore explode.
Fixed it locally following your suggestion of creating fences on the
allocation object.
> >
[…]
> > > > +
> > > > +/// The receiving counterpart of a [`DriverFence`], designed to register callbacks
> > > > +/// on, check the signalled state etc. A [`Fence`] cannot be signalled.
> > > > +/// A [`Fence`] is always refcounted.
> > >
> > > I would explain this a tad better.
> >
> > What exactly? The refcounting? The dualism between DriverFence and
> > Fence? :)
>
> For example, you say “a Fence cannot be signaled”. A person seeing this
> code for the first time might ask why. Specially if they start by reading the
> docs for Fence first.
>
> I think explaining a bit more about the DriverFence/Fence/refcounting as you
> said is already enough to settle it.
OK, I flesh that out a bit.
> > >
[…]
> > > > + let ret = unsafe { bindings::dma_fence_is_signaled(fence) };
> > > > +
> > > > + // To guarantee that an API caller can 100% rely on the signalling being
> > > > + // completed (i.e., all fence callbacks ran), we have to take the lock.
> > > > + //
> > > > + // The reason is that the C dma_fence backend currently does not carefully
> > > > + // synchronize the `dma_fence_is_signaled()` function with the proper
> > > > + // spinlock. This can lead to the function returning `true` while fence
> > > > + // callbacks are still being executed. This can be mitigated by guarding
> > > > + // the entire function with the spinlock.
> > > > + //
> > > > + // See commit c8a5d5ea3ba6a.
> > > > +
> > > > + // SAFETY: `fence` is valid because `self` is valid. `flag_ptr` is
> > > > + // merely a pointer to an integer, which lives as long as this function.
> > > > + unsafe { bindings::dma_fence_lock_irqsave(fence, flag_ptr) };
> > >
> > > Shouldn’t this be before the “is_signaled” ffi call? Or is this
> > > only about ensuring all callbacks have run? i.e.: is “ret” valid even
> > > though it was computed before taking the lock?
> >
> > OK, this is where it gets ugly.
> >
> > So during the last weeks I've been struggling to get the C backend into
> > better shape. One issue from my POV is that the C dma_fence spinlock
> > does not protect the fence state; there is insistence that the lock
> > shall only protect the callback list.
> >
> > The function dma_fence_is_signaled() has an unlocked fast path check:
> >
> > https://elixir.bootlin.com/linux/v7.2-rc3/source/include/linux/dma-fence.h#…
> >
> > whereas setting of that bit is done under lock-protection:
> >
> > https://elixir.bootlin.com/linux/v7.2-rc3/source/drivers/dma-buf/dma-fence.…
> >
> >
> > This can lead to funny races like in the commit mentioned in the
> > comment block above (c8a5d5ea3ba6a).
> >
> > And it also leads to weird hacks like this:
> >
> > https://elixir.bootlin.com/linux/v7.2-rc3/source/drivers/gpu/drm/amd/amdgpu…
> >
> >
> > Now, in principle I agree with you that a pattern like this:
> >
> > dma_fence_lock_irqsave(…);
> > let signaled = dma_fence_is_signaled_locked(…);
> > dma_fence_unlock_irqrestore(…);
> >
> > would be better.
> >
> > However, lengthy discussions with Christian seem to settle at the point
> > where Christian sees the very strict requirement of never calling fence
> > callbacks under lock protection, and where he views
> > dma_fence_is_signaled_locked() as a broken function that should be
> > removed.
> >
> > He's currently working on removing all bits where fence callbacks are
> > invoked under lock protection:
> >
> > https://lore.kernel.org/dri-devel/20260624122917.2483-1-christian.koenig@am…
> >
> > There's been a ton of discussions and proposals about that in recent
> > weeks
> >
> > https://lore.kernel.org/dri-devel/20260608142436.265820-2-phasta@kernel.org/
> > https://lore.kernel.org/dri-devel/20260612104251.2264707-2-phasta@kernel.or…
> >
> >
> > So tl;dr: The weird code you're commenting on above ensures that
> >
> > a) the fence->ops->is_signaled() callback is not called under lock
> > protection and
> > b) taking and releasing the lock guarantees that all callbacks are
> > really finished, i.e. they have run.
> >
> >
> > (I continue to believe that setting the bit under lock protection and
> > reading it without lock is fundamentally broken and needs to be fixed,
> > but fixes are being rejected because of claimed performance regressions
> > years ago when this was tried, because checking the bit is some sort of
> > fast path check for.. parties that spin on dma_fence_is_signaled() ??)
>
> I see, there is a lot more context on this then. Can you merely add a comment
> saying it’s ok to call dma_fence_is_signaled() without the locks? Otherwise
> people might try to “fix” this down the line...
I tried to make it clear with the comment above:
// To guarantee that an API caller can 100% rely on the signalling being
// completed (i.e., all fence callbacks ran), we have to take the lock.
//
// The reason is that the C dma_fence backend currently does not carefully
// synchronize the `dma_fence_is_signaled()` function with the proper
// spinlock. This can lead to the function returning `true` while fence
// callbacks are still being executed. This can be mitigated by guarding
// the entire function with the spinlock.
//
// See commit c8a5d5ea3ba6a.
I can try to make it more explicit.
Actually, I suppose with our design in Rust we would not actually need
this lock-unlock, because we ensure that it does not matter whether a
callback already ran.
But since we don't know who will be working on this in 5 years, adding
this or that exotic callback, or maybe registering callbacks on his own
fence, I put this sequence there for robustness.
So if the function returns true, you really know that all callbacks are
gone forever.
>
> >
> > >
> > > >
> >
> > […]
> > >
> > >
> > > > + /// The API user's data. This must either not need drop, or must delay its
> > > > + /// drop by a grace period. It is essential that the data only performs
> > > > + /// operations legal in atomic context in its [`Drop`] implementation.
> > > > + #[pin]
> > > > + data: T::FenceDataType,
> > > > +}
> > > > +
> > > >
> >
> > […]
> >
> > > > +
> > > > + // DriverFenceData is repr(C) and a Fence is its first member.
> > >
> > > > + let fence_data_ptr = fence_ptr as *mut DriverFenceData<'a, T>;
> > >
> > > Without a “CAST:” keyword, I think this will trigger the linter?
> > >
> >
> > Didn't see a complaint from clippy nor compiler.
>
> I recommend the CAST thing anyways. It’s being adopted in other parts of the kernel
> crate.
I can write a CAST comment, no problem.
Thx
P.
On Mon, Jul 20, 2026 at 10:05:33PM +0200, Natalie Vock wrote:
> On 7/19/26 19:58, Taehee Yoo wrote:
> > Add the AMD GCN (gfx9/gfx10) instruction encoder used to build the GPU
> > shaders that knod dispatches, plus a matching disassembler used for
> > debugging the generated code.
>
> Is it really necessary to have a full-on compiler and disassembler in the
> kernel driver? This patch is massive and I'm wondering how much benefit it
> really provides. Is there really no way to move GPU compilation out of the
> kernel, one way or another? Could you get acceptable perf with a static
> shader that interprets BPF programs at runtime? Such a shader can be
> compiled beforehand and just embedded into the kernel - there's prior art
> there with the CWSR trap handler in amdkfd.
>
> In case you really, really need to compile the BPF to native ISA, could you
> still have userspace take care of that in one way or another?
There was a long and painful discussion about P4, and offloading it to
hardware. The proponents of that wanted to do the compilation stage in
user space to produce a binary blob, but it was hard to prove that the
P4 passed to the kernel for software processing, and the binary blob
passed to the hardware actually where the same. It opened up the path
for closed source P4 where the kernel never got to see the actual P4
code. So it was not really offload, but kernel bypass.
So having a compiler in the kernel is probably the correct way to go,
if you want to be friendly to open source.
The other option is to get the GPU to do the compilation itself, so
you pass BPF byte codes to the GPU and it generates its own native
code. I've no idea if that is possible, but clang can target OpenMP,
so maybe it is possible to move this compiler into the GPU?
Andrew
Hi,
These patches fix two issues in the drm/drm_crtc driver. Initially I
was hitting the BUG_ON() in a scenario as explained in the commit
message of what is now the second patch in this series. For the reasons
outlines there, the BUG_ON() should just be removed.
After posting, sashiko.dev noticed another issue, that was previously
masked by the now-removed BUG_ON(). Since we can't have a loud BUG() be
replaced with silent data corruption or worse, I've also added a patch
to address this issue highlighted by sashiko.dev. I believe its
observation and analysis to be correct.
Cheers,
Andre'
Signed-off-by: André Draszik <andre.draszik(a)linaro.org>
---
Changes in v2:
- add new patch 1 to address sashiko observation
- original patch 1 becomes patch 2
- patch 2:
- don't turn fence_to_crtc() into macro (Jani, Philipp)
- update commit message to include reference to deprecated use of BUG
- Link to v1: https://lore.kernel.org/r/20260618-linux-drm_crtc_fix2-v1-1-c03e77b36f34@li…
---
André Draszik (2):
drm/drm_crtc: ensure dma_fence_ops remain valid during device unbind
drm/drm_crtc: fix race with dma_fence_signal() in ::get_driver_name()
drivers/gpu/drm/drm_crtc.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
---
base-commit: b9810cd75b9fb56a3425d391cba3f608502bd474
change-id: 20260618-linux-drm_crtc_fix2-23a7c354a412
Best regards,
--
André Draszik <andre.draszik(a)linaro.org>
The protagonist of the game is a conventional dinosaur known as a Tyrannosaurus rex. This is the species of dinosaur that is typically depicted in films and books that are about dinosaurs. https://dinogameonline.io
Hi David,
On 16/07/2026 22:23, David Matlack wrote:
> On 2026-07-16 03:51 PM, Matt Evans wrote:
>> Hi David,
>>
>> On 15/07/2026 19:12, David Matlack wrote:
>>> On Wed, Jul 15, 2026 at 10:47 AM Matt Evans <matt(a)ozlabs.org> wrote:
>>>
>>>> This is based on v7.2-rc3.
>>>>
>>>> These commits are on GitHub for easier browsing, along with
>>>> "[RFC ONLY] selftests: vfio: Add standalone vfio_dmabuf_mmap_test":
>>>>
>>>> https://github.com/metamev/linux/compare/v7.2-rc3...dev/mev/vfio-dmabuf-mma…
>>>
>>> It'd be great to have this test upstream. I'm happy to review it when
>>> you're ready. Looks like it just needs to be redone to use the VFIO
>>> selftests library and kselftests harness. AI could probably do the
>>> conversion pretty quick :)
>>
>> For sure, I'd intended to catch up with you on best approach here. :)
>>
>> Aside from the organic structure of the test (the open-coded VFIO
>> device/group setup/init needs to go), the main issue is that it relies
>> on a hacked/out of tree QEMU "EDU++" device with a second larger BAR
>> (containing freely read-writable memory). A subset of tests run with
>> the in-tree EDU device, but coverage is too low.
>>
>> The desirable properties are:
>>
>> - Having a BAR that is pure memory (all locations present, writable
>> without disruptive side-effects) so that mapping aliases can be
>> constructed and detected. This is good to test things like non-zero
>> vm_pgoffs and VA space presentation of physically-discontiguous DMABUFs.
>>
>> - BAR >> hugepage size so we can eyeball huge mappings work (or better,
>> mechanically test for them). At least 32MB would tick this box for 4K,
>> 16K page systems.
>>
>> - Something QEMU supports*, so one can run the test in a VM/TCG system.
>>
>> There were some real device models in QEMU that could be used this way,
>> but needed a fair bit of setup; I didn't want to rathole
>> vfio_dmabuf_mmap_test on including a ton of device-specific code for
>> some video card or similar.
>>
>> I'll dig more for a simple target that provides these properties --
>> obviously it would be better to point this test at an off-the-shelf
>> device (including silicon!). And, proposing EDU extensions to the QEMU
>> folks may be useful (there're uses for a better EDU in other contexts too).
>>
>> Since this test uses MMIO for a specific [class of] function, my first
>> thought is it should be another VFIO driver-type test sibling of
>> vfio_pci_driver_test. For example, we could extend the driver-type
>> tests' backend struct vfio_pci_driver_ops for functions capable of
>> providing a Big Memory BAR, like QEMU EDU++. EDU can also memcpy, so
>> could also support vfio_pci_driver_test.
>>
>> The spirit of the device backends hiding setup of a complex device is
>> handy, and it's plausible that several backends could provide this "big
>> memory BAR" service. What do you think, any concerns with extending
>> vfio_pci_driver_ops like that?
>
> I wouldn't recommend leveraging the driver framework unless absolutely
> necessary. It makes the test harder to run.
>
> The biggest issue I see with the proposed properties is being able to
> treat the BAR as memory. That obviously will depend on the device and
> may require device-specific setup. If we decide that treating the BAR as
> memory is truly required then using the driver framework is the way to
> go. But I'm hoping we can avoid that requirement.
>
> Instead, I think you can get pretty far by inspecting /proc/pid/pagemap
> to determine if the mmap() set things up correctly, without actually
> accessing the BAR. You can use /proc/pid/pagemap to look up the PFN and
> PAGEMAP_SCAN to detect huge pages.
Hmm, possible, although that's quite a different test at that point. I
agree never touching the device has advantages, but it's harder to test
certain things if we _never_ do MMIO. The mitigation effort to get
coverage may not be the right tradeoff vs easier running. I can think
of some "easy" VFIO bugs that would be challenging to properly verify in
userspace (e.g. PFNs all having some undesired offset). The current
test method is harder to fool per unit effort in writing it.
Though, I will have a think about this no-touch flavour of test.
What were you picturing regarding populating the VMA PTEs in order to
inspect the result via /proc/pid/pagemap, whilst still upholding the
principle of not touching the device? For example,
madvise(MADV_POPULATE_WRITE) won't work on the VFIO BAR regions because
they're VM_PFNMAP/VM_IO.
> With that requirement gone, then all you really need is a device with a
> large enough BAR. And even that it not a hard requirement. I'm sure
> there are plenty of test cases that could work with smaller BARs. The
> few tests that want to exercise huge mappings can inspect the device BAR
> sizes first, and if they're all too small, SKIP() the test.
>
> If you structure the test this way, then it's easy for the test to be
> used. It can be run against any device for the basic functional
> coverage, and can be run against a device with a larger BAR for full
> coverage of huge mappings.
>
> Does QEMU emulate any devices that have 32MB or larger BARs?
Yep, looks like `-device pci-testdev,membar=64M,membar-backed=on` or
even `-device bochs-display,vgamem=64M` would be suitable.
So I'll also try moving the existing test over to one of these to at
least remove the EDU++ device dependency. (bochs-display has >1 BAR,
and some MMIO regs which are nice for a quick kick-the-tyres access test.)
Cheers,
Matt
On Thu, 16 Jul 2026 21:23:22 +0000
David Matlack <dmatlack(a)google.com> wrote:
> On 2026-07-16 03:51 PM, Matt Evans wrote:
> > Hi David,
> >
> > On 15/07/2026 19:12, David Matlack wrote:
> > > On Wed, Jul 15, 2026 at 10:47 AM Matt Evans <matt(a)ozlabs.org> wrote:
> > >
> > >> This is based on v7.2-rc3.
> > >>
> > >> These commits are on GitHub for easier browsing, along with
> > >> "[RFC ONLY] selftests: vfio: Add standalone vfio_dmabuf_mmap_test":
> > >>
> > >> https://github.com/metamev/linux/compare/v7.2-rc3...dev/mev/vfio-dmabuf-mma…
> > >
> > > It'd be great to have this test upstream. I'm happy to review it when
> > > you're ready. Looks like it just needs to be redone to use the VFIO
> > > selftests library and kselftests harness. AI could probably do the
> > > conversion pretty quick :)
> >
> > For sure, I'd intended to catch up with you on best approach here. :)
> >
> > Aside from the organic structure of the test (the open-coded VFIO
> > device/group setup/init needs to go), the main issue is that it relies
> > on a hacked/out of tree QEMU "EDU++" device with a second larger BAR
> > (containing freely read-writable memory). A subset of tests run with
> > the in-tree EDU device, but coverage is too low.
> >
> > The desirable properties are:
> >
> > - Having a BAR that is pure memory (all locations present, writable
> > without disruptive side-effects) so that mapping aliases can be
> > constructed and detected. This is good to test things like non-zero
> > vm_pgoffs and VA space presentation of physically-discontiguous DMABUFs.
> >
> > - BAR >> hugepage size so we can eyeball huge mappings work (or better,
> > mechanically test for them). At least 32MB would tick this box for 4K,
> > 16K page systems.
> >
> > - Something QEMU supports*, so one can run the test in a VM/TCG system.
> >
> > There were some real device models in QEMU that could be used this way,
> > but needed a fair bit of setup; I didn't want to rathole
> > vfio_dmabuf_mmap_test on including a ton of device-specific code for
> > some video card or similar.
> >
> > I'll dig more for a simple target that provides these properties --
> > obviously it would be better to point this test at an off-the-shelf
> > device (including silicon!). And, proposing EDU extensions to the QEMU
> > folks may be useful (there're uses for a better EDU in other contexts too).
> >
> > Since this test uses MMIO for a specific [class of] function, my first
> > thought is it should be another VFIO driver-type test sibling of
> > vfio_pci_driver_test. For example, we could extend the driver-type
> > tests' backend struct vfio_pci_driver_ops for functions capable of
> > providing a Big Memory BAR, like QEMU EDU++. EDU can also memcpy, so
> > could also support vfio_pci_driver_test.
> >
> > The spirit of the device backends hiding setup of a complex device is
> > handy, and it's plausible that several backends could provide this "big
> > memory BAR" service. What do you think, any concerns with extending
> > vfio_pci_driver_ops like that?
>
> I wouldn't recommend leveraging the driver framework unless absolutely
> necessary. It makes the test harder to run.
>
> The biggest issue I see with the proposed properties is being able to
> treat the BAR as memory. That obviously will depend on the device and
> may require device-specific setup. If we decide that treating the BAR as
> memory is truly required then using the driver framework is the way to
> go. But I'm hoping we can avoid that requirement.
Could you run a test where only a known part of the BAR can be treated
as memory?
A large BAR is likely to have some areas that can be accessed as memory.
David
>
> Instead, I think you can get pretty far by inspecting /proc/pid/pagemap
> to determine if the mmap() set things up correctly, without actually
> accessing the BAR. You can use /proc/pid/pagemap to look up the PFN and
> PAGEMAP_SCAN to detect huge pages.
>
> With that requirement gone, then all you really need is a device with a
> large enough BAR. And even that it not a hard requirement. I'm sure
> there are plenty of test cases that could work with smaller BARs. The
> few tests that want to exercise huge mappings can inspect the device BAR
> sizes first, and if they're all too small, SKIP() the test.
>
> If you structure the test this way, then it's easy for the test to be
> used. It can be run against any device for the basic functional
> coverage, and can be run against a device with a larger BAR for full
> coverage of huge mappings.
>
> Does QEMU emulate any devices that have 32MB or larger BARs?
>
Both Tvrtko [1] and I [2] have recently proposed some improvals for
drm_sched.
While taking Tvrtko's feedback into account for my patch, I realized
that both his and my patch can be fully replaced with a bigger and far
more beautiful series.
If I am not mistaken, it turns out that the entire entity->entity_idle
completion is also nothing but a workaround around the grave mistake of
not using the greatest helper with parallel programming that exists in
computer science: Locking.
This series adds locking to the last_scheduled field and all checks
related to detect the idleness of the entity. As before, the
job_scheduled event queue causes the periodic checks.
This way, we can get rid of memory barriers, RCU, a few lines of code,
make things more readable, understandable...
Tested with drm-sched-unit tests. I'm a bit busy right now, but wanted
to show you guys the idea. Before merging I'd test it more exhaustively
with Nouveau.
Greetings,
Philipp
[1] https://lore.kernel.org/dri-devel/20260611123423.39819-1-tvrtko.ursulin@iga…
[2] https://lore.kernel.org/dri-devel/20260626081942.2122144-2-phasta@kernel.or…
Philipp Stanner (5):
drm/sched: Protect entity->last_scheduled with spinlock
drm/sched: Lock spsc_queue in drm_sched_entity_pop_job()
drm/sched: Avoid lock cycle for sched_entity
drm/sched: Lock drm_sched_entity_is_idle()
drm/sched: Remove entity->entity_idle
drivers/gpu/drm/scheduler/sched_entity.c | 75 +++++++++++-------------
drivers/gpu/drm/scheduler/sched_main.c | 2 -
drivers/gpu/drm/scheduler/sched_rq.c | 5 +-
include/drm/gpu_scheduler.h | 16 ++---
4 files changed, 41 insertions(+), 57 deletions(-)
base-commit: be4f10d44757211fd656fa57f37034657f26c883
--
2.54.0
Several drivers call dma_buf_fd() — which internally calls fd_install()
— before copy_to_user() returns the fd number to userspace. If
copy_to_user() fails, the fd is already published in the caller's fd
table but the ioctl returns an error, so userspace never learns the fd
number. Worse, the window between fd_install() and copy_to_user()
allows other threads to observe and manipulate the fd (dup, close,
SCM_RIGHTS), making any "close it on the failure path" fix unsafe.
The fix is to split the allocation into three steps: reserve an fd with
get_unused_fd_flags() (not yet visible to other threads), do
copy_to_user(), and only then publish the fd with fd_install() via the
new dma_buf_fd_install() helper. On copy_to_user() failure,
put_unused_fd() + dma_buf_put() cleanly unwind with no user-visible
side effects.
Patch 1 introduces dma_buf_fd_install() in dma-buf.c (wrapping
fd_install() together with the DMA_BUF_TRACE call to preserve export
tracing) and applies the fix to dma-heap.
Patch 2 applies the same fix to fastrpc, which even had a comment
acknowledging the problem could not be fixed before.
v1: https://lore.kernel.org/dri-devel/20260703080922.1838362-1-shoubaineng@gmai…
v2: https://lore.kernel.org/dri-devel/20260710105430.3059661-1-shoubaineng@gmai…
Changes in v3:
- Split into two patches (dma-heap + fastrpc separately)
- Add dma_buf_fd_install() to preserve trace_dma_buf_fd tracepoint
(spotted by T.J. Mercier and sashiko-bot on v2)
- Add fastrpc fix using the new helper (suggested by T.J. Mercier)
Baineng Shou (2):
dma-buf: dma-heap: don't publish fd before copy_to_user() succeeds
misc: fastrpc: don't publish fd before copy_to_user() succeeds
drivers/dma-buf/dma-buf.c | 20 ++++++++++
drivers/dma-buf/dma-heap.c | 80 +++++++++++++++++++-------------------
drivers/misc/fastrpc.c | 16 +++-----
include/linux/dma-buf.h | 1 +
4 files changed, 67 insertions(+), 50 deletions(-)
--
2.34.1