All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sergio Lopez <slp@redhat.com>
To: qemu-devel@nongnu.org
Cc: alex.williamson@redhat.com, Sergio Lopez <slp@redhat.com>
Subject: [Qemu-devel] [PATCH] vfio: If DMA map returns ENOMEM wait and try again
Date: Mon,  3 Apr 2017 10:58:22 +0200	[thread overview]
Message-ID: <20170403085822.13863-1-slp@redhat.com> (raw)

When quickly unmapping and mapping memory regions (as may happen in
address_space_update_topology), if running with a non-unlimited
RLIMIT_MEMLOCK, the kernel may return ENOMEM for a map request
because the previous unmap has been processed, but accounted yet.

Probably this should be fixed in the kernel ensuring a deterministic
behavior for VFIO map and unmap operations. Until then, this works
around the issue, waiting 10ms and trying again.

Signed-off-by: Sergio Lopez <slp@redhat.com>
---
 hw/vfio/common.c | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index f3ba9b9..db41fa5 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -228,17 +228,32 @@ static int vfio_dma_map(VFIOContainer *container, hwaddr iova,
         map.flags |= VFIO_DMA_MAP_FLAG_WRITE;
     }
 
-    /*
-     * Try the mapping, if it fails with EBUSY, unmap the region and try
-     * again.  This shouldn't be necessary, but we sometimes see it in
-     * the VGA ROM space.
-     */
-    if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0 ||
-        (errno == EBUSY && vfio_dma_unmap(container, iova, size) == 0 &&
-         ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0)) {
+    if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0) {
         return 0;
     }
 
+    if (errno == ENOMEM) {
+        /*
+         * When quickly unmapping and mapping ranges, the kernel may
+         * return ENOMEM for a map request because the previous unmap
+         * has not been accounted yet. Wait a bit and try again.
+         */
+        usleep(10 * 1000);
+        if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0) {
+            return 0;
+        }
+    } else if (errno == EBUSY) {
+        /*
+         * If mapping fails with EBUSY, unmap the region and try again.
+         * This shouldn't be necessary, but we sometimes see it in the
+         * VGA ROM space.
+         */
+        if (vfio_dma_unmap(container, iova, size) == 0 &&
+            ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0) {
+            return 0;
+        }
+    }
+
     error_report("VFIO_MAP_DMA: %d", -errno);
     return -errno;
 }
-- 
2.9.3

             reply	other threads:[~2017-04-03  9:00 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-03  8:58 Sergio Lopez [this message]
2017-04-03 15:40 ` [Qemu-devel] [PATCH] vfio: If DMA map returns ENOMEM wait and try again Alex Williamson
2017-04-03 16:07   ` Sergio Lopez Pascual

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=20170403085822.13863-1-slp@redhat.com \
    --to=slp@redhat.com \
    --cc=alex.williamson@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.