From nobody Fri May 3 05:05:19 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1491233148906208.54481182262612; Mon, 3 Apr 2017 08:25:48 -0700 (PDT) Received: from localhost ([::1]:59763 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cv3rX-000488-I0 for importer@patchew.org; Mon, 03 Apr 2017 11:25:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55850) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cuxqI-0003J9-Sl for qemu-devel@nongnu.org; Mon, 03 Apr 2017 05:00:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cuxqE-00065u-3q for qemu-devel@nongnu.org; Mon, 03 Apr 2017 05:00:07 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37034) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cuxqD-00060f-Uy for qemu-devel@nongnu.org; Mon, 03 Apr 2017 05:00:02 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8AA3381229 for ; Mon, 3 Apr 2017 08:59:51 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-152.ams2.redhat.com [10.36.116.152]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3259477ED6; Mon, 3 Apr 2017 08:59:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8AA3381229 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=slp@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 8AA3381229 From: Sergio Lopez To: qemu-devel@nongnu.org Date: Mon, 3 Apr 2017 10:58:22 +0200 Message-Id: <20170403085822.13863-1-slp@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Mon, 03 Apr 2017 08:59:55 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 X-Mailman-Approved-At: Mon, 03 Apr 2017 11:23:36 -0400 Subject: [Qemu-devel] [PATCH] vfio: If DMA map returns ENOMEM wait and try again X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.williamson@redhat.com, Sergio Lopez Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 --- 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, hwa= ddr iova, map.flags |=3D VFIO_DMA_MAP_FLAG_WRITE; } =20 - /* - * 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) =3D=3D 0 || - (errno =3D=3D EBUSY && vfio_dma_unmap(container, iova, size) =3D= =3D 0 && - ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) =3D=3D 0)) { + if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) =3D=3D 0) { return 0; } =20 + if (errno =3D=3D 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) =3D=3D 0) { + return 0; + } + } else if (errno =3D=3D 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) =3D=3D 0 && + ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) =3D=3D 0) { + return 0; + } + } + error_report("VFIO_MAP_DMA: %d", -errno); return -errno; } --=20 2.9.3