qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paul Brook <paul@codesourcery.com>
To: qemu-devel@nongnu.org
Cc: Amit Shah <amit.shah@redhat.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	Juan Quintela <quintela@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v8 7/7] virtio-console: Enable port throttling when chardev is slow to consume data
Date: Mon, 6 Dec 2010 09:35:10 +0000	[thread overview]
Message-ID: <201012060935.10382.paul@codesourcery.com> (raw)
In-Reply-To: <20101206065506.GD11457@amit-x200.redhat.com>

> On (Thu) Dec 02 2010 [17:31:36], Paul Brook wrote:
> > > > > when there's a partial write, it tries to do a write again, which
> > > > > will fail with -EAGAIN.
> > > > 
> > > > Doesn't that cause the first partial chunk to be incorrectly
> > > > transmitted twice? You may only return EAGAIN if no data was
> > > > transmitted.
> > > 
> > > Except for the fact that no caller of qemu_chr_write() resubmits (or
> > > even checks) partial writes.
> > 
> > I don't buy this argument. The current implementation of qemu_chr_write
> > never generates transient failures, so they don't need to.
> 
> And applying this patch won't change the situation.

Sure it will. The whole point of the patch is to allow transient failures 
(i.e. avoid blocking) when writing to char backends.  You should expect to 
have to modify the device code to cope with this.

As with the DMA interface added a while ago, I believe it's important to get 
these APIs right.  Quick hacks to support limited use-cases just end up 
needing a complete rewrite (or even worse multiple concurrent 
APIs/implementations) once we actually start using them seriously.

I'm extremely reluctant to add a new layer of buffering that is not visible to 
ether the kernel or the device.  In practice we still need to be able to split 
oversize requests, so handling small split requests should be pretty much 
free.

> What I proposed in the earlier mail was to buffer only the data that has
> to be re-submitted in case the caller is capable of stopping further
> output till the char layer indicates it's free to start again.

That's case (b) below.

> > Once data has been transmitted, we have three options:
> > 
> > a) Block until the write completes. This makes the whole patch fairly
> > pointless as host and guest block boundaries are unlikely to align.
> 
> This is what currently happens and will remain so for callers of
> qemu_chr_write() which don't have a .write_unblocked() pointer assigned
> in the char dev struct.

Obviously if the device doesn't supply an unbocked() hook then the behavior is 
unchanged.  That's trivially uninteresting.  I'm talking about devices that do 
provide the unblocked() hook.

> > b) Store the data on the side somewhere. Tell the device all data has
> > been sent, and arrange for this data to be flushed before accepting any
> > more data. This is bad because it allows the guest to allocate
> > arbitrarily large[1] buffers on the host. i.e. a fairly easily
> > exploitable DoS attack.
> 
> With virtio-serial, this is what's in use.  The buffer is limited to the
> length of the vq (which is a compile-time constant) and there also is
> the virtio_serial_throttle_port() call that tells the guest to not send
> any more data to the host till the char layer indicates it's OK to send
> more data.

No.

Firstly you're assuming all users are virtio based. That may be all you care 
about, but is not acceptable if you want to get this code merged.

Secondly, the virtqueue only restricts the number of direct ring buffer 
entries. It does not restrict the quantity of data each ring entry points to.

As a side note, I notice that the virtio-serial-buf code is already allocating 
buffers and calling iov_to_buf on arbitrary sized requests. This is wrong for 
the same reason. Don't do it.

> > c) Return a partial write to the guest. The guest already has to handle
> > retries due to EAGAIN, and DMA capable devices already have to handle
> > partial mappings, so this doesn't seem too onerous a requirement. This
> > is not a new concept, it's the same as the unix write(2)/send(2)
> > functions.
> 
> This isn't possible with the current vq design.

You need to fix that then.  I'm fairly sure it must be possible as virtio-blk 
has to handle similar problems.

Paul

  reply	other threads:[~2010-12-06  9:35 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-01  9:54 [Qemu-devel] [PATCH v8 0/7] char: non-blocking writes, virtio-console flow control Amit Shah
2010-12-01  9:54 ` [Qemu-devel] [PATCH v8 1/7] virtio-console: Factor out common init between console and generic ports Amit Shah
2010-12-01  9:54 ` [Qemu-devel] [PATCH v8 2/7] char: Add a QemuChrHandlers struct to initialise chardev handlers Amit Shah
2010-12-01  9:54 ` [Qemu-devel] [PATCH v8 3/7] char: Introduce char_set/remove_fd_handlers() Amit Shah
2010-12-01  9:54 ` [Qemu-devel] [PATCH v8 4/7] char: Add framework for a 'write unblocked' callback Amit Shah
2010-12-01  9:54 ` [Qemu-devel] [PATCH v8 5/7] char: Update send_all() to handle nonblocking chardev write requests Amit Shah
2010-12-01  9:54 ` [Qemu-devel] [PATCH v8 6/7] char: Equip the unix/tcp backend to handle nonblocking writes Amit Shah
2010-12-01  9:54 ` [Qemu-devel] [PATCH v8 7/7] virtio-console: Enable port throttling when chardev is slow to consume data Amit Shah
2010-12-01 11:30   ` Paul Brook
2010-12-01 11:48     ` Amit Shah
2010-12-01 11:59       ` Paul Brook
2010-12-01 12:12         ` Amit Shah
2010-12-01 13:08           ` Paul Brook
2010-12-02  9:21             ` Amit Shah
2010-12-02 17:31               ` Paul Brook
2010-12-06  6:55                 ` Amit Shah
2010-12-06  9:35                   ` Paul Brook [this message]
2010-12-06 10:11                     ` Amit Shah
2010-12-06 13:23                       ` Paul Brook
2010-12-07  7:11                         ` Amit Shah
2010-12-08 12:56                           ` Paul Brook
2010-12-08 14:25                             ` Amit Shah
2010-12-08 16:54                               ` Paul Brook

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=201012060935.10382.paul@codesourcery.com \
    --to=paul@codesourcery.com \
    --cc=amit.shah@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.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;
as well as URLs for NNTP newsgroup(s).