From: Paolo Bonzini <pbonzini@redhat.com>
To: Fam Zheng <famz@redhat.com>, qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Max Reitz <mreitz@redhat.com>,
qemu-block@nongnu.org, eblake@redhat.com
Subject: Re: [Qemu-devel] [PATCH] file-posix: Incoporate max_segments in block limit
Date: Tue, 7 Mar 2017 11:58:35 +0100 [thread overview]
Message-ID: <453cf467-9b0c-efa8-a523-a3f35072e70d@redhat.com> (raw)
In-Reply-To: <20170307021748.7743-1-famz@redhat.com>
On 07/03/2017 03:17, Fam Zheng wrote:
> 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 <famz@redhat.com>
> ---
> 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(BlockDriverState *bs, int fd)
> #endif
> }
>
> +static int hdev_get_max_segments(BlockDriverState *bs)
> +{
> +#ifdef CONFIG_LINUX
> + char buf[32];
> + const char *end;
> + char *sysfspath, *fullpath;
> + int ret;
> + int fd = -1;
> + long max_segments;
> +
> + fullpath = realpath(bs->exact_filename, NULL);
> + if (!fullpath) {
> + return -errno;
> + }
> + if (strncmp(fullpath, "/dev/", 5) || !fullpath[5]) {
> + ret = -ENOTSUP;
> + goto out;
> + }
> + sysfspath = g_strdup_printf("/sys/block/%s/queue/max_segments",
> + &fullpath[5]);
I think you cannot rely on the /dev/... path. Luckily, there is an
alternative path to "queue" via /sys/dev/block/MAJOR:MINOR/queue, where
MAJOR:MINOR can be retrieved via fstat. This also avoids any possible
TOC-TOU races.
Thanks,
Paolo
> + fd = open(sysfspath, O_RDONLY);
> + if (fd == -1) {
> + ret = -errno;
> + goto out;
> + }
> + do {
> + ret = read(fd, buf, sizeof(buf));
> + } while (ret == -1 && errno == EINTR);
> + if (ret < 0) {
> + ret = -errno;
> + goto out;
> + } else if (ret == 0) {
> + ret = -EIO;
> + goto out;
> + }
> + buf[ret] = 0;
> + /* The file is ended with '\n', pass 'end' to accept that. */
> + ret = qemu_strtol(buf, &end, 10, &max_segments);
> + if (ret == 0 && end && *end == '\n') {
> + ret = max_segments;
> + }
> +
> +out:
> + if (fd >= 0) {
> + close(fd);
> + }
> + free(fullpath);
> + return ret;
> +#else
> + return -ENOTSUP;
> +#endif
> +}
> +
> static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
> {
> BDRVRawState *s = bs->opaque;
> @@ -679,6 +732,11 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
> if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
> bs->bl.max_transfer = pow2floor(ret);
> }
> + ret = hdev_get_max_segments(bs);
> + if (ret > 0) {
> + bs->bl.max_transfer = MIN(bs->bl.max_transfer,
> + ret * getpagesize());
> + }
> }
> }
>
>
next prev parent reply other threads:[~2017-03-07 10:58 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-07 2:17 [Qemu-devel] [PATCH] file-posix: Incoporate max_segments in block limit Fam Zheng
2017-03-07 10:58 ` Paolo Bonzini [this message]
2017-03-08 6:16 ` Fam Zheng
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=453cf467-9b0c-efa8-a523-a3f35072e70d@redhat.com \
--to=pbonzini@redhat.com \
--cc=eblake@redhat.com \
--cc=famz@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).