From: Alex Williamson <alex@shazbot.org>
To: Matt Evans <matt@ozlabs.org>
Cc: "Kevin Tian" <kevin.tian@intel.com>,
"Pranjal Shrivastava" <praan@google.com>,
"Leon Romanovsky" <leon@kernel.org>,
"Jason Gunthorpe" <jgg@nvidia.com>,
"Alex Mastro" <amastro@fb.com>,
"Christian König" <christian.koenig@amd.com>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Logan Gunthorpe" <logang@deltatee.com>,
"Longfang Liu" <liulongfang@huawei.com>,
"Mahmoud Adam" <mngyadam@amazon.de>,
"David Matlack" <dmatlack@google.com>,
"Björn Töpel" <bjorn@kernel.org>,
"Sumit Semwal" <sumit.semwal@linaro.org>,
"Ankit Agrawal" <ankita@nvidia.com>,
"Alistair Popple" <apopple@nvidia.com>,
"Vivek Kasireddy" <vivek.kasireddy@intel.com>,
linux-kernel@vger.kernel.org, linux-media@vger.kernel.org,
dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org,
kvm@vger.kernel.org, linux-pci@vger.kernel.org, alex@shazbot.org
Subject: Re: [PATCH v5 4/9] vfio/pci: Add a helper to create a DMABUF for a BAR-map VMA
Date: Thu, 13 Aug 2026 16:48:58 -0600 [thread overview]
Message-ID: <20260813164858.2459c660@shazbot.org> (raw)
In-Reply-To: <9a615f22-c0d4-46ae-9654-db11e94e5fec@ozlabs.org>
On Wed, 12 Aug 2026 23:39:37 +0100
Matt Evans <matt@ozlabs.org> wrote:
> Hi Alex, Leon, Kevin, Praan,
>
> On 15/07/2026 18:47, Matt Evans wrote:
> > This helper, vfio_pci_core_mmap_prep_dmabuf(), creates a single-range
> > DMABUF for the purpose of mapping a PCI BAR. This is used in a future
> > commit by VFIO's ordinary mmap() path.
> >
> > This function transfers ownership of the VFIO device fd to the
> > DMABUF, which fput()s when it's released.
> >
> > Refactor the existing vfio_pci_core_feature_dma_buf() to split out
> > export code common to the two paths, VFIO_DEVICE_FEATURE_DMA_BUF and
> > this new VFIO_BAR mmap().
> >
> > Signed-off-by: Matt Evans <matt@ozlabs.org>
> > Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> > Reviewed-by: Pranjal Shrivastava <praan@google.com>
> > ---
> > drivers/vfio/pci/vfio_pci_dmabuf.c | 142 +++++++++++++++++++++++------
> > drivers/vfio/pci/vfio_pci_priv.h | 5 +
> > 2 files changed, 117 insertions(+), 30 deletions(-)
> >
> > diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci_dmabuf.c
> > index 7c047400dfd1..74c02794bfe2 100644
> > --- a/drivers/vfio/pci/vfio_pci_dmabuf.c
> > +++ b/drivers/vfio/pci/vfio_pci_dmabuf.c
> > @@ -82,6 +82,8 @@ static void vfio_pci_dma_buf_release(struct dma_buf *dmabuf)
> > up_write(&priv->vdev->memory_lock);
> > vfio_device_put_registration(&priv->vdev->vdev);
> > }
> > + if (priv->vfile)
> > + fput(priv->vfile);
> > kfree(priv->phys_vec);
> > kfree(priv);
> > }
> > @@ -233,6 +235,45 @@ int vfio_pci_dma_buf_find_pfn(struct vfio_pci_dma_buf *priv,
> > return ret;
> > }
> >
> > +/*
> > + * Create a DMABUF corresponding to priv, add it to vdev->dmabufs list
> > + * for tracking (meaning cleanup or revocation will zap it), and take
> > + * a vfio_device registration.
> > + */
> > +static int vfio_pci_dmabuf_export(struct vfio_pci_core_device *vdev,
> > + struct vfio_pci_dma_buf *priv, u32 flags)
> > +{
> > + DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
> > +
> > + if (!vfio_device_try_get_registration(&vdev->vdev))
> > + return -ENODEV;
> > +
> > + exp_info.ops = &vfio_pci_dmabuf_ops;
> > + exp_info.size = priv->size;
> > + exp_info.flags = flags;
> > + exp_info.priv = priv;
> > +
> > + priv->dmabuf = dma_buf_export(&exp_info);
> > + if (IS_ERR(priv->dmabuf)) {
> > + vfio_device_put_registration(&vdev->vdev);
> > + return PTR_ERR(priv->dmabuf);
> > + }
> > +
> > + kref_init(&priv->kref);
> > + init_completion(&priv->comp);
> > +
> > + /* dma_buf_put() now frees priv */
> > + INIT_LIST_HEAD(&priv->dmabufs_elm);
> > + down_write(&vdev->memory_lock);
> > + dma_resv_lock(priv->dmabuf->resv, NULL);
> > + priv->revoked = !__vfio_pci_memory_enabled(vdev);
> > + list_add_tail(&priv->dmabufs_elm, &vdev->dmabufs);
> > + dma_resv_unlock(priv->dmabuf->resv);
> > + up_write(&vdev->memory_lock);
>
> It looks like a local Claude review (kreview) genuinely found a problem
> here. There seems to be a new deadlock scenario because vfio-pci's
> mmap() now does the DMABUF export and now takes vdev->memory_lock:
>
> nvgrace-gpu forwards mmap() of regular BARs on to vfio_pci_core_mmap(),
> so it takes vdev->memory_lock for write here with mm->mmap_lock held for
> write.
>
> But the nvgrace-gpu driver's MMIO accessors,
> nvgrace_gpu_{read,write}_mem(), rely on holding vdev->memory_lock for
> read across the device readiness check and the device access, e.g.:
>
> nvgrace_gpu_read_mem():
> takes memory_lock(R)
> nvgrace_gpu_check_device_ready()
> nvgrace_gpu_map_and_read():
> // The copy accesses the device
> copy_to_user(...) <-- could fault
>
> That fault hits lock_mm_and_find_vma() and tries to take
> mm->mmap_lock for read. That waits on another thread that's already
> started an mmap() and holds mm->mmap_lock for write but has blocked on
> the faulting thread's vdev->memory_lock. ABBA and boom.
>
> Yuck. I'm glad this was found now, at least. :|
>
> A possible way forward:
>
> Please can I have some expert advice on whether the DMABUF export really
> must hold vdev->memory_lock for _write_ or could relax to hold it for
> _read_ in the function above:
>
> - It's protecting the __vfio_pci_memory_enabled() test vs adding the
> buffer to the list (could be read)
> - It's upholding the invariant of priv->revoked not changing without
> holding both memory_lock & resv, but no one can see the DMABUF yet
> - It's protecting the list-add against a concurrent revoke/cleanup
> - It's protecting the list-add against another concurrent export
>
> If vfio_pci_dmabuf_export() could instead hold memory_lock for read,
> then nvgrace-gpu (or other future vfio-pci variant drivers!) can also
> hold it for read, and the deadlock is avoided.
>
> The revoke/cleanup paths hold vdev->memory_lock for write, so wouldn't
> run concurrently, but there'd be a new problem of protecting against
> another concurrent export. Perhaps a new vdev->export_lock held (only)
> in this function around vdev->memory_lock could address that.
>
> The other variant drivers seem to be OK in this regard. Solving this in
> the core seems the right approach; at any rate, I don't think the
> nvgrace-gpu side can be relaxed.
>
> There'd still be the strong constraint that the drivers must avoid
> taking vdev->memory_lock for write. How to enforce this?
>
> What are your thoughts on this problem/solution? Am I missing any nuances?
My read is that the vfio dmabuf code is using memory_lock write-lock to
serialize the dmabufs list as a matter of convenience since it needs to
be held across all the revokes anyway. It's an overloaded use of
memory_lock.
I agree with your analysis how we could use read-lock, but I don't
particularly like the idea of a separate lock just to serialize between
exports while legitimate write-lock paths continue to rely on
memory_lock for serialization. I'd rather see a dmabufs_lock mutex
added and used consistently for serializing the dmabufs list.
I think the touch points are:
- vfio_pci_dma_buf_release(): list protection only, dmabufs_lock
- vfio_pci_core_feature_dma_buf(): memory_lock(R) for memory enabled,
enclosing dmabufs_lock for list
- vfio_pci_dma_buf_move(): add dmabufs_lock guard
- vfio_pci_dma_buf_cleanup(): up_write memory_lock after move, add
dmabufs_lock guard around list walk
The cleanup call is on the close_device path, so while it's a bit
clunky that we drop and re-aquire dmabufs_lock between move and list
pruning, no dmabufs can be added in that gap since the device is
closed, ie. no dmabuf feature ioctl access. At least aiui.
For enforcement that a variant driver doesn't take the write-lock, I
think in part it's that there really shouldn't be a need for serializing
on memory_lock through mmap if we're using the lock correctly, but also
lockdep to find it. Thanks,
Alex
next prev parent reply other threads:[~2026-08-13 22:49 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-15 17:47 [PATCH v5 0/9] vfio/pci: Add mmap() for DMABUFs Matt Evans
2026-07-15 17:47 ` [PATCH v5 1/9] PCI/P2PDMA: Split pool-related cleanup out of pci_p2pdma_release() Matt Evans
2026-07-17 8:02 ` Tian, Kevin
2026-07-28 22:33 ` Alex Williamson
2026-07-29 10:08 ` Leon Romanovsky
2026-08-05 0:31 ` Jason Gunthorpe
2026-07-30 16:45 ` Pranjal Shrivastava
2026-07-15 17:47 ` [PATCH v5 2/9] PCI/P2PDMA: Add CONFIG_PCI_P2PDMA_CORE Matt Evans
2026-07-17 8:02 ` Tian, Kevin
2026-07-30 19:37 ` Pranjal Shrivastava
2026-08-04 15:42 ` Matt Evans
2026-08-04 16:19 ` Logan Gunthorpe
2026-08-05 0:39 ` Jason Gunthorpe
2026-08-05 16:28 ` Matt Evans
2026-08-05 16:40 ` Jason Gunthorpe
2026-08-05 20:50 ` Logan Gunthorpe
2026-08-11 13:45 ` Matt Evans
2026-08-11 14:01 ` Jason Gunthorpe
2026-07-15 17:47 ` [PATCH v5 3/9] vfio/pci: Add a helper to look up PFNs for DMABUFs Matt Evans
2026-07-17 8:02 ` Tian, Kevin
2026-07-29 17:52 ` Alex Williamson
2026-07-30 17:34 ` Matt Evans
2026-07-30 22:55 ` Pranjal Shrivastava
2026-07-31 17:43 ` Matt Evans
2026-08-03 18:22 ` Matt Evans
2026-08-04 19:01 ` Pranjal Shrivastava
2026-08-05 0:41 ` Jason Gunthorpe
2026-07-15 17:47 ` [PATCH v5 4/9] vfio/pci: Add a helper to create a DMABUF for a BAR-map VMA Matt Evans
2026-08-12 22:39 ` Matt Evans
2026-08-13 22:48 ` Alex Williamson [this message]
2026-07-15 17:47 ` [PATCH v5 5/9] vfio/pci: Convert BAR mmap() to use a DMABUF Matt Evans
2026-07-15 17:47 ` [PATCH v5 6/9] vfio/pci: Provide a user-facing name for BAR mappings Matt Evans
2026-07-17 8:03 ` Tian, Kevin
2026-07-29 17:52 ` Alex Williamson
2026-07-30 14:37 ` Matt Evans
2026-07-15 17:47 ` [PATCH v5 7/9] vfio/pci: Clean up BAR zap and revocation Matt Evans
2026-07-17 8:03 ` Tian, Kevin
2026-07-29 17:52 ` Alex Williamson
2026-07-30 14:47 ` Matt Evans
2026-08-04 20:10 ` Alex Williamson
2026-08-05 13:58 ` Matt Evans
2026-08-11 15:58 ` Matt Evans
2026-08-12 20:06 ` Alex Williamson
2026-08-13 15:49 ` Matt Evans
2026-07-30 23:20 ` Pranjal Shrivastava
2026-07-15 17:47 ` [PATCH v5 8/9] vfio/pci: Support mmap() of a VFIO DMABUF Matt Evans
2026-07-17 8:03 ` Tian, Kevin
2026-07-30 23:33 ` Pranjal Shrivastava
2026-07-15 17:47 ` [PATCH v5 9/9] vfio/pci: Permanently revoke a DMABUF on request Matt Evans
2026-07-17 8:03 ` Tian, Kevin
2026-07-30 23:43 ` Pranjal Shrivastava
2026-07-15 18:12 ` [PATCH v5 0/9] vfio/pci: Add mmap() for DMABUFs David Matlack
2026-07-16 14:51 ` Matt Evans
2026-07-16 21:23 ` David Matlack
2026-07-17 8:42 ` David Laight
2026-07-17 16:30 ` David Matlack
2026-07-17 17:12 ` Matt Evans
2026-07-20 21:50 ` David Matlack
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260813164858.2459c660@shazbot.org \
--to=alex@shazbot.org \
--cc=amastro@fb.com \
--cc=ankita@nvidia.com \
--cc=apopple@nvidia.com \
--cc=bhelgaas@google.com \
--cc=bjorn@kernel.org \
--cc=christian.koenig@amd.com \
--cc=dmatlack@google.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jgg@nvidia.com \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=leon@kernel.org \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=liulongfang@huawei.com \
--cc=logang@deltatee.com \
--cc=matt@ozlabs.org \
--cc=mngyadam@amazon.de \
--cc=praan@google.com \
--cc=sumit.semwal@linaro.org \
--cc=vivek.kasireddy@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®