qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Isaku Yamahata <yamahata@valinux.co.jp>
To: Juan Quintela <quintela@redhat.com>
Cc: benoit.hudzia@gmail.com, aarcange@redhat.com,
	aliguori@us.ibm.com, kvm@vger.kernel.org,
	satoshi.itoh@aist.go.jp, stefanha@gmail.com,
	t.hirofuchi@aist.go.jp, dlaor@redhat.com, qemu-devel@nongnu.org,
	mdroth@linux.vnet.ibm.com, yoshikawa.takuya@oss.ntt.co.jp,
	owasserm@redhat.com, avi@redhat.com, pbonzini@redhat.com
Subject: Re: [Qemu-devel] [PATCH v2 35/41] postcopy: introduce helper functions for	postcopy
Date: Sat, 16 Jun 2012 18:48:27 +0900	[thread overview]
Message-ID: <20120616094827.GL23851@valinux.co.jp> (raw)
In-Reply-To: <87vcitshm6.fsf@elfo.mitica>

On Thu, Jun 14, 2012 at 11:34:09PM +0200, Juan Quintela wrote:
> Isaku Yamahata <yamahata@valinux.co.jp> wrote:
> > +//#define DEBUG_UMEM
> > +#ifdef DEBUG_UMEM
> > +#include <sys/syscall.h>
> > +#define DPRINTF(format, ...)                                            \
> > +    do {                                                                \
> > +        printf("%d:%ld %s:%d "format, getpid(), syscall(SYS_gettid),    \
> > +               __func__, __LINE__, ## __VA_ARGS__);                     \
> > +    } while (0)
> 
> This should be in a header file that is linux specific?  And (at least
> on my systems) gettid is already defined on glibc.

I'll remove getpid/gettid. It was just for debugging in early phase.
They are not necessary any more.


> > +#else
> > +#define DPRINTF(format, ...)    do { } while (0)
> > +#endif
> 
> 
> > +
> > +#define DEV_UMEM        "/dev/umem"
> > +
> > +UMem *umem_new(void *hostp, size_t size)
> > +{
> > +    struct umem_init uinit = {
> > +        .size = size,
> > +    };
> > +    UMem *umem;
> > +
> > +    assert((size % getpagesize()) == 0);
> > +    umem = g_new(UMem, 1);
> > +    umem->fd = open(DEV_UMEM, O_RDWR);
> > +    if (umem->fd < 0) {
> > +        perror("can't open "DEV_UMEM);
> > +        abort();
> 
> Can we return one error insntead of abort?  the same for the rest of the
> file aborts.

Ok.


> > +size_t umem_pages_size(uint64_t nr)
> > +{
> > +    return sizeof(struct umem_pages) + nr * sizeof(uint64_t);
> 
> Can we make sure that the pgoffs field is aligned?  I know that as it is
> now it is aligned, but better to be sure?

It is already done by gcc extension, zero length array.


> > +}
> > +
> > +static void umem_write_cmd(int fd, uint8_t cmd)
> > +{
> > +    DPRINTF("write cmd %c\n", cmd);
> > +
> > +    for (;;) {
> > +        ssize_t ret = write(fd, &cmd, 1);
> > +        if (ret == -1) {
> > +            if (errno == EINTR) {
> > +                continue;
> > +            } else if (errno == EPIPE) {
> > +                perror("pipe");
> > +                DPRINTF("write cmd %c %zd %d: pipe is closed\n",
> > +                        cmd, ret, errno);
> > +                break;
> > +            }
> 
> 
> Grr, we don't have a function that writes does a "safe_write".  The most
> similar thing in qemu looks to be send_all().

So we should introduce something like qemu_safe_write/read?


> > +
> > +            perror("pipe");
> 
> Can we make a different perror() message than previous error?
> 
> > +            DPRINTF("write cmd %c %zd %d\n", cmd, ret, errno);
> > +            abort();
> > +        }
> > +
> > +        break;
> > +    }
> > +}
> > +
> > +static void umem_read_cmd(int fd, uint8_t expect)
> > +{
> > +    uint8_t cmd;
> > +    for (;;) {
> > +        ssize_t ret = read(fd, &cmd, 1);
> > +        if (ret == -1) {
> > +            if (errno == EINTR) {
> > +                continue;
> > +            }
> > +            perror("pipe");
> > +            DPRINTF("read error cmd %c %zd %d\n", cmd, ret, errno);
> > +            abort();
> > +        }
> > +
> > +        if (ret == 0) {
> > +            DPRINTF("read cmd %c %zd: pipe is closed\n", cmd, ret);
> > +            abort();
> > +        }
> > +
> > +        break;
> > +    }
> > +
> > +    DPRINTF("read cmd %c\n", cmd);
> > +    if (cmd != expect) {
> > +        DPRINTF("cmd %c expect %d\n", cmd, expect);
> > +        abort();
> 
> Ouch.  If we receive garbage, we just exit?
> 
> I really think that we should implement error handling.
> 
> > +    }
> > +}
> > +
> > +struct umem_pages *umem_recv_pages(QEMUFile *f, int *offset)
> > +{
> > +    int ret;
> > +    uint64_t nr;
> > +    size_t size;
> > +    struct umem_pages *pages;
> > +
> > +    ret = qemu_peek_buffer(f, (uint8_t*)&nr, sizeof(nr), *offset);
> > +    *offset += sizeof(nr);
> > +    DPRINTF("ret %d nr %ld\n", ret, nr);
> > +    if (ret != sizeof(nr) || nr == 0) {
> > +        return NULL;
> > +    }
> > +
> > +    size = umem_pages_size(nr);
> > +    pages = g_malloc(size);
> 
> Just thinking about this.  Couldn't we just decide on a "big enough"
> buffer, and never send anything bigger than that?  That would remove the
> need to have to malloc()/free() a buffer for each reception?

Will try to address it.


> > +/* qemu side handler */
> > +struct umem_pages *umem_qemu_trigger_page_fault(QEMUFile *from_umemd,
> > +                                                int *offset)
> > +{
> > +    uint64_t i;
> > +    int page_shift = ffs(getpagesize()) - 1;
> > +    struct umem_pages *pages = umem_recv_pages(from_umemd, offset);
> > +    if (pages == NULL) {
> > +        return NULL;
> > +    }
> > +
> > +    for (i = 0; i < pages->nr; i++) {
> > +        ram_addr_t addr = pages->pgoffs[i] << page_shift;
> > +
> > +        /* make pages present by forcibly triggering page fault. */
> > +        volatile uint8_t *ram = qemu_get_ram_ptr(addr);
> > +        uint8_t dummy_read = ram[0];
> > +        (void)dummy_read;   /* suppress unused variable warning */
> > +    }
> > +
> > +    /*
> > +     * Very Linux implementation specific.
> > +     * Make it sure that other thread doesn't fault on the above virtual
> > +     * address. (More exactly other thread doesn't call fault handler with
> > +     * the offset.)
> > +     * the fault handler is called with mmap_sem read locked.
> > +     * madvise() does down/up_write(mmap_sem)
> > +     */
> > +    qemu_madvise(NULL, 0, MADV_NORMAL);
> 
> If it is linux specific, should be inside CONFIG_LINUX ifdef, or a
> function hided on some header.

Good idea.


> Talking about looking, what protects that no other thread enters this
> function before this one calls madvise?   Or I am losing something obvious?

It is assumed that only main thread calls this function via iohandler.


> > +
> > +struct umem_pages {
> > +    uint64_t nr;
> > +    uint64_t pgoffs[0];
> > +};
> > +
> 
> QEMU really likes typedefs for structs.
> 
> Later, Juan.
> 

-- 
yamahata

  reply	other threads:[~2012-06-16  9:48 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-04  9:57 [Qemu-devel] [PATCH v2 00/41] postcopy live migration Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 01/41] arch_init: export sort_ram_list() and ram_save_block() Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 02/41] arch_init: export RAM_SAVE_xxx flags for postcopy Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 03/41] arch_init/ram_save: introduce constant for ram save version = 4 Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 04/41] arch_init: refactor host_from_stream_offset() Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 05/41] arch_init/ram_save_live: factor out RAM_SAVE_FLAG_MEM_SIZE case Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 06/41] arch_init: refactor ram_save_block() Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 07/41] arch_init/ram_save_live: factor out ram_save_limit Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 08/41] arch_init/ram_load: refactor ram_load Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 09/41] arch_init: introduce helper function to find ram block with id string Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 10/41] arch_init: simplify a bit by ram_find_block() Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 11/41] arch_init: factor out counting transferred bytes Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 12/41] arch_init: factor out setting last_block, last_offset Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 13/41] exec.c: factor out qemu_get_ram_ptr() Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 14/41] exec.c: export last_ram_offset() Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 15/41] savevm: export qemu_peek_buffer, qemu_peek_byte, qemu_file_skip Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 16/41] savevm: qemu_pending_size() to return pending buffered size Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 17/41] savevm, buffered_file: introduce method to drain buffer of buffered file Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 18/41] QEMUFile: add qemu_file_fd() for later use Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 19/41] savevm/QEMUFile: drop qemu_stdio_fd Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 20/41] savevm/QEMUFileSocket: drop duplicated member fd Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 21/41] savevm: rename QEMUFileSocket to QEMUFileFD, socket_close to fd_close Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 22/41] savevm/QEMUFile: introduce qemu_fopen_fd Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 23/41] migration.c: remove redundant line in migrate_init() Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 24/41] migration: export migrate_fd_completed() and migrate_fd_cleanup() Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 25/41] migration: factor out parameters into MigrationParams Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 26/41] buffered_file: factor out buffer management logic Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 27/41] buffered_file: Introduce QEMUFileNonblock for nonblock write Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 28/41] buffered_file: add qemu_file to read/write to buffer in memory Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 29/41] umem.h: import Linux umem.h Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 30/41] update-linux-headers.sh: teach umem.h to update-linux-headers.sh Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 31/41] configure: add CONFIG_POSTCOPY option Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 32/41] savevm: add new section that is used by postcopy Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 33/41] postcopy: introduce -postcopy and -postcopy-flags option Isaku Yamahata
2012-06-08 10:52   ` Juan Quintela
2012-06-08 16:07     ` Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 34/41] postcopy outgoing: add -p and -n option to migrate command Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 35/41] postcopy: introduce helper functions for postcopy Isaku Yamahata
2012-06-14 21:34   ` Juan Quintela
2012-06-16  9:48     ` Isaku Yamahata [this message]
2012-06-16 13:19       ` Juan Quintela
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 36/41] postcopy: implement incoming part of postcopy live migration Isaku Yamahata
2012-06-14 21:56   ` Juan Quintela
2012-06-14 21:58   ` Juan Quintela
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 37/41] postcopy: implement outgoing " Isaku Yamahata
2012-06-14 22:12   ` Juan Quintela
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 38/41] postcopy/outgoing: add forward, backward option to specify the size of prefault Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 39/41] postcopy/outgoing: implement prefault Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 40/41] migrate: add -m (movebg) option to migrate command Isaku Yamahata
2012-06-04  9:57 ` [Qemu-devel] [PATCH v2 41/41] migration/postcopy: add movebg mode Isaku Yamahata
2012-06-04 12:37 ` [Qemu-devel] [PATCH v2 00/41] postcopy live migration Anthony Liguori
2012-06-04 13:38   ` Isaku Yamahata
2012-06-05 11:23     ` Dor Laor
2012-06-07  7:46   ` Orit Wasserman
2012-06-08 10:16   ` Juan Quintela
2012-06-08 10:23     ` Avi Kivity
2012-06-14 21:07       ` Juan Quintela
2012-06-14 22:18 ` Juan Quintela

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=20120616094827.GL23851@valinux.co.jp \
    --to=yamahata@valinux.co.jp \
    --cc=aarcange@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=avi@redhat.com \
    --cc=benoit.hudzia@gmail.com \
    --cc=dlaor@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=owasserm@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=satoshi.itoh@aist.go.jp \
    --cc=stefanha@gmail.com \
    --cc=t.hirofuchi@aist.go.jp \
    --cc=yoshikawa.takuya@oss.ntt.co.jp \
    /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).