From nobody Thu May 2 13:50:08 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 1488853134094268.8320842977181; Mon, 6 Mar 2017 18:18:54 -0800 (PST) Received: from localhost ([::1]:46958 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cl4iC-0003TD-Lf for importer@patchew.org; Mon, 06 Mar 2017 21:18:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35989) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cl4hM-0003Q0-H5 for qemu-devel@nongnu.org; Mon, 06 Mar 2017 21:18:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cl4hL-0003kf-FP for qemu-devel@nongnu.org; Mon, 06 Mar 2017 21:18:00 -0500 Received: from mx1.redhat.com ([209.132.183.28]:44820) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cl4hG-0003k2-5m; Mon, 06 Mar 2017 21:17:54 -0500 Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6B7087701; Tue, 7 Mar 2017 02:17:53 +0000 (UTC) Received: from lemon.redhat.com (ovpn-8-32.pek2.redhat.com [10.72.8.32]) by smtp.corp.redhat.com (Postfix) with ESMTP id D7107660C0; Tue, 7 Mar 2017 02:17:50 +0000 (UTC) From: Fam Zheng To: qemu-devel@nongnu.org Date: Tue, 7 Mar 2017 10:17:48 +0800 Message-Id: <20170307021748.7743-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.74 on 10.5.11.28 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Tue, 07 Mar 2017 02:17:53 +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 Subject: [Qemu-devel] [PATCH] file-posix: Incoporate max_segments in block limit 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: Kevin Wolf , pbonzini@redhat.com, qemu-block@nongnu.org, Max Reitz 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" Linux exposes a separate limit, /sys/block/.../queue/max_segments, which in the worst case can be more restrictive than BLKSECTGET (as they are two different things). Similar to the BLKSECTGET story, guests don't see this limit and send big requests will get -EINVAL error on SG_IO. Lean on the safer side to clamp max_transfer according to max_segments and page size, because in the end what host HBA gets is the mapped host pages rather than a guest buffer. Signed-off-by: Fam Zheng --- block/file-posix.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 58 insertions(+) diff --git a/block/file-posix.c b/block/file-posix.c index 4de1abd..b615262 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -668,6 +668,59 @@ static int hdev_get_max_transfer_length(BlockDriverSta= te *bs, int fd) #endif } =20 +static int hdev_get_max_segments(BlockDriverState *bs) +{ +#ifdef CONFIG_LINUX + char buf[32]; + const char *end; + char *sysfspath, *fullpath; + int ret; + int fd =3D -1; + long max_segments; + + fullpath =3D realpath(bs->exact_filename, NULL); + if (!fullpath) { + return -errno; + } + if (strncmp(fullpath, "/dev/", 5) || !fullpath[5]) { + ret =3D -ENOTSUP; + goto out; + } + sysfspath =3D g_strdup_printf("/sys/block/%s/queue/max_segments", + &fullpath[5]); + fd =3D open(sysfspath, O_RDONLY); + if (fd =3D=3D -1) { + ret =3D -errno; + goto out; + } + do { + ret =3D read(fd, buf, sizeof(buf)); + } while (ret =3D=3D -1 && errno =3D=3D EINTR); + if (ret < 0) { + ret =3D -errno; + goto out; + } else if (ret =3D=3D 0) { + ret =3D -EIO; + goto out; + } + buf[ret] =3D 0; + /* The file is ended with '\n', pass 'end' to accept that. */ + ret =3D qemu_strtol(buf, &end, 10, &max_segments); + if (ret =3D=3D 0 && end && *end =3D=3D '\n') { + ret =3D max_segments; + } + +out: + if (fd >=3D 0) { + close(fd); + } + free(fullpath); + return ret; +#else + return -ENOTSUP; +#endif +} + static void raw_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVRawState *s =3D bs->opaque; @@ -679,6 +732,11 @@ static void raw_refresh_limits(BlockDriverState *bs, E= rror **errp) if (ret > 0 && ret <=3D BDRV_REQUEST_MAX_BYTES) { bs->bl.max_transfer =3D pow2floor(ret); } + ret =3D hdev_get_max_segments(bs); + if (ret > 0) { + bs->bl.max_transfer =3D MIN(bs->bl.max_transfer, + ret * getpagesize()); + } } } =20 --=20 2.9.3