On Thu, Apr 05, 2018 at 12:30:27AM +0000, Wang, Wei W wrote:
> On Wednesday, April 4, 2018 10:08 PM, Michael S. Tsirkin wrote:
> > On Wed, Apr 04, 2018 at 10:07:51AM +0800, Wei Wang wrote:
> > > On 04/04/2018 02:47 AM, Michael S. Tsirkin wrote:
> > > > On Wed, Apr 04, 2018 at 12:10:03AM +0800, Wei Wang wrote:
> > > > > +static int add_one_sg(struct virtqueue *vq, unsigned long pfn,
> > > > > +uint32_t len) {
> > > > > + struct scatterlist sg;
> > > > > + unsigned int unused;
> > > > > +
> > > > > + sg_init_table(&sg, 1);
> > > > > + sg_set_page(&sg, pfn_to_page(pfn), len, 0);
> > > > > +
> > > > > + /* Detach all the used buffers from the vq */
> > > > > + while (virtqueue_get_buf(vq, &unused))
> > > > > + ;
> > > > > +
> > > > > + /*
> > > > > + * Since this is an optimization feature, losing a couple of
> > > > > free
> > > > > + * pages to report isn't important. We simply return without
> > > > > adding
> > > > > + * the page hint if the vq is full.
> > > > why not stop scanning of following pages though?
> > >
> > > Because continuing to send hints is a way to deliver the maximum
> > > possible hints to host. For example, host may have a delay in taking
> > > hints at some point, and then it resumes to take hints soon. If the
> > > driver does not stop when the vq is full, it will be able to put more
> > > hints to the vq once the vq has available entries to add.
> >
> > What this appears to be is just lack of coordination between host and guest.
> >
> > But meanwhile you are spending cycles walking the list uselessly.
> > Instead of trying nilly-willy, the standard thing to do is to wait for host
> > to
> > consume an entry and proceed.
> >
> > Coding it up might be tricky, so it's probably acceptable as is for now, but
> > please replace the justification about with a TODO entry that we should
> > synchronize with the host.
>
> Thanks. I plan to add
>
> TODO: The current implementation could be further improved by stopping the
> reporting when the vq is full and continuing the reporting when host notifies
> that there are available entries for the driver to add.
... that entries have been used.
>
> >
> >
> > >
> > > >
> > > > > + * We are adding one entry each time, which essentially results
> > > > > in no
> > > > > + * memory allocation, so the GFP_KERNEL flag below can be
> > > > > ignored.
> > > > > + * Host works by polling the free page vq for hints after
> > > > > sending the
> > > > > + * starting cmd id, so the driver doesn't need to kick after
> > > > > filling
> > > > > + * the vq.
> > > > > + * Lastly, there is always one entry reserved for the cmd id to
> > > > > use.
> > > > > + */
> > > > > + if (vq->num_free > 1)
> > > > > + return virtqueue_add_inbuf(vq, &sg, 1, vq, GFP_KERNEL);
> > > > > +
> > > > > + return 0;
> > > > > +}
> > > > > +
> > > > > +static int virtio_balloon_send_free_pages(void *opaque, unsigned long
> > pfn,
> > > > > + unsigned long nr_pages)
> > > > > +{
> > > > > + struct virtio_balloon *vb = (struct virtio_balloon *)opaque;
> > > > > + uint32_t len = nr_pages << PAGE_SHIFT;
> > > > > +
> > > > > + /*
> > > > > + * If a stop id or a new cmd id was just received from host,
> > > > > stop
> > > > > + * the reporting, and return 1 to indicate an active stop.
> > > > > + */
> > > > > + if (virtio32_to_cpu(vb->vdev, vb->cmd_id_use) != vb-
> > >cmd_id_received)
> > > > > + return 1;
> >
> > functions returning int should return 0 or -errno on failure, positive
> > return
> > code should indicate progress.
> >
> > If you want a boolean, use bool pls.
>
> OK. I plan to change 1 to -EBUSY to indicate the case that host actively
> asks the driver to stop reporting (This makes the callback return value type
> consistent with walk_free_mem_block).
>
something like EINTR might be a better fit.
>
> >
> >
> > > > > +
> > > > this access to cmd_id_use and cmd_id_received without locks bothers
> > > > me. Pls document why it's safe.
> > >
> > > OK. Probably we could add below to the above comments:
> > >
> > > cmd_id_use and cmd_id_received don't need to be accessed under locks
> > > because the reporting does not have to stop immediately before
> > > cmd_id_received is changed (i.e. when host requests to stop). That is,
> > > reporting more hints after host requests to stop isn't an issue for
> > > this optimization feature, because host will simply drop the stale
> > > hints next time when it needs a new reporting.
> >
> > What about the other direction? Can this observe a stale value and exit
> > erroneously?
>
> I'm afraid the driver couldn't be aware if the added hints are stale or not,
No - I mean that driver has code that compares two values
and stops reporting. Can one of the values be stale?
> because host and guest actions happen asynchronously. That is, host side
> iothread stops taking hints as soon as the migration thread asks to stop, it
> doesn't wait for any ACK from the driver to stop (as we discussed before,
> host couldn't always assume that the driver is in a responsive state).
>
> Btw, we also don't need to worry about any memory left in the vq, since only
> addresses are added to the vq, there is no real memory allocations.
>
> Best,
> Wei
When we support DMA API we will have to unmap things there.