qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH RFC 4/4] Curling: the receiver


From: junqing . wang
Subject: Re: [Qemu-devel] [PATCH RFC 4/4] Curling: the receiver
Date: Wed, 11 Sep 2013 16:25:08 +0800 (CST)

hi,

At 2013-09-10 22:19:48,"Juan Quintela" <address@hidden> wrote: >> @@ -112,13 +113,24 @@ static void process_incoming_migration_co(void *opaque) >>  { >>      QEMUFile *f = opaque; >>      int ret; >> +    int count = 0; >>   >> -    ret = qemu_loadvm_state(f); >> -    qemu_fclose(f); >> -    if (ret < 0) { >> -        fprintf(stderr, "load of migration failed\n"); >> -        exit(EXIT_FAILURE); >> +    if (ft_enabled()) { >> +        while (qemu_loadvm_state_ft(f) >= 0) { >> +            count++; >> +            DPRINTF("incoming count %d\r", count); >> +        } >> +        qemu_fclose(f); >> +        fprintf(stderr, "ft connection lost, launching self..\n"); > >Obviously,  here we are needing something more that an fprintf,,  right? >
>We are not checking either if it is one error.

Agree.

>> +    } else { >> +        ret = qemu_loadvm_state(f); >> +        qemu_fclose(f); >> +        if (ret < 0) { >> +            fprintf(stderr, "load of migration failed\n"); >> +            exit(EXIT_FAILURE); >> +        } >>      } >> +    cpu_synchronize_all_post_init(); >>      qemu_announce_self(); >>      DPRINTF("successfully loaded vm state\n"); >>   >> diff --git a/savevm.c b/savevm.c >> index 6daf690..d5bf153 100644 >> --- a/savevm.c >> +++ b/savevm.c >> @@ -52,6 +52,8 @@ >>  #define ARP_PTYPE_IP 0x0800 >>  #define ARP_OP_REQUEST_REV 0x3 >>   >> +#define PFB_SIZE 0x010000 >> + >>  static int announce_self_create(uint8_t *buf, >>   uint8_t *mac_addr) >>  { >> @@ -135,6 +137,10 @@ struct QEMUFile { >>      unsigned int iovcnt; >>   >>      int last_error; >> + >> +    uint8_t *pfb;   /* pfb -> PerFetch Buffer */ > >s/PreFetch/Prefetcth/ > >prefetch_buffer as name?  not used in so many places,  makes things >clearer or more convoluted?  Other comments? >

Agree.

>> +static int socket_get_prefetch_buffer(void *opaque, uint8_t *buf, >> +                                      int64_t pos, int size) >> +{ >> +    QEMUFile *f = opaque; >> + >> +    if (f->pfb_size - pos <= 0) { >> +        return 0; >> +    } >> + >> +    if (f->pfb_size - pos < size) { >> +        size = f->pfb_size - pos; >> +    } >> + >> +    memcpy(buf, f->pfb+pos, size); >> + >> +    return size; >> +} >> + >> + >>  static int socket_close(void *opaque) >>  { >>      QEMUFileSocket *s = opaque; >> @@ -440,6 +465,7 @@ QEMUFile *qemu_fdopen(int fd, const char *mode) >>  static const QEMUFileOps socket_read_ops = { >>      .get_fd =     socket_get_fd, >>      .get_buffer = socket_get_buffer, >> +    .get_prefetch_buffer = socket_get_prefetch_buffer, >>      .close =      socket_close >>  }; >>   > >>      if (f->last_error) { >>          ret = f->last_error; >>      } >> + >> +    if (f->pfb) { >> +        g_free(f->pfb); > >g_free(f->pfb); >It already checks for NULL.
Got it.
>> +    } >> + >>      g_free(f); >>      return ret; >>  } >> @@ -822,6 +853,14 @@ void qemu_put_byte(QEMUFile *f, int v) >>   >>  static void qemu_file_skip(QEMUFile *f, int size) >>  { >> +    if (f->pfb_index + size <= f->pfb_size) { >> +        f->pfb_index += size; >> +        return; >> +    } else { >> +        size -= f->pfb_size - f->pfb_index; >> +        f->pfb_index = f->pfb_size; >> +    } >> + >>      if (f->buf_index + size <= f->buf_size) { >>          f->buf_index += size; >>      } >> @@ -831,6 +870,21 @@ static int qemu_peek_buffer(QEMUFile *f, uint8_t *buf, int size, size_t offset) >>  { >>      int pending; >>      int index; >> +    int done; >> + >> +    if (f->ops->get_prefetch_buffer) { >> +        if (f->pfb_index + offset < f->pfb_size) { >> +            done = f->ops->get_prefetch_buffer(f, buf, f->pfb_index + offset, >> +                                               size); >> +            if (done == size) { >> +                return size; >> +            } >> +            size -= done; >> +            buf  += done; >> +        } else { >> +            offset -= f->pfb_size - f->pfb_index; >> +        } >> +    } >>   >>      assert(!qemu_file_is_writable(f)); >>   >> @@ -875,7 +929,15 @@ int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size) >>   >>  static int qemu_peek_byte(QEMUFile *f, int offset) >>  { >> -    int index = f->buf_index + offset; >> +    int index; >> + >> +    if (f->pfb_index + offset < f->pfb_size) { >> +        return f->pfb[f->pfb_index + offset]; >> +    } else { >> +        offset -= f->pfb_size - f->pfb_index; >> +    } >> + >> +    index = f->buf_index + offset; >>   >>      assert(!qemu_file_is_writable(f)); >>   >> @@ -1851,7 +1913,7 @@ void qemu_savevm_state_begin(QEMUFile *f, >>          } >>          se->ops->set_params(params, se->opaque); >>      } >> -     >> + >>      qemu_put_be32(f, QEMU_VM_FILE_MAGIC); >>      qemu_put_be32(f, QEMU_VM_FILE_VERSION); >>   >> @@ -2294,8 +2356,6 @@ int qemu_loadvm_state(QEMUFile *f) >>          } >>      } >>   >> -    cpu_synchronize_all_post_init(); >> - >>      ret = 0; >>   >>  out: >> @@ -2311,6 +2371,89 @@ out: >>      return ret; >>  } >>   >> +int qemu_loadvm_state_ft(QEMUFile *f) >> +{ >> +    int ret = 0; >> +    int i   = 0; >> +    int j   = 0; >> +    int done = 0; >> +    uint64_t size = 0; >> +    uint64_t count = 0; >> +    uint8_t *pfb = NULL; >> +    uint8_t *buf = NULL; >> + >> +    uint64_t max_mem = last_ram_offset() * 1.5; >> + >> +    if (!f->ops->get_prefetch_buffer) { >> +        fprintf(stderr, "Fault tolerant is not supported by this protocol.\n"); >> +        return EINVAL; >> +    } >> + >> +    size = PFB_SIZE; >> +    pfb = g_malloc(size); >> + >> +    while (true) { >> +        if (count + TARGET_PAGE_SIZE >= size) { >> +            if (size*2 > max_mem) { >> +                fprintf(stderr, "qemu_loadvm_state_ft: warning:" \ >> +                       "Prefetch buffer becomes too large.\n" \ >> +                       "Fault tolerant is unstable when you see this,\n" \ >> +                       "please increase the bandwidth or increase " \ >> +                       "the max down time.\n"); >> +                break; >> +            } >> +            size = size * 2; >> +            buf = g_try_realloc(pfb, size); >> +            if (!buf) { >> +                error_report("qemu_loadvm_state_ft: out of memory.\n"); >> +                g_free(pfb); >> +                return ENOMEM; > >You are not handling this error in the caller.  Notice that qemu >normally 
I am not sure what you mean.
I find my mistake that it should return -ENOMEM and -EINVAL.
>> +            } >> + >> +            pfb = buf; >> +        } >> + >> +        done = qemu_get_buffer(f, pfb + count, TARGET_PAGE_SIZE); >> + >> +        ret = qemu_file_get_error(f); >> +        if (ret != 0) { >> +            g_free(pfb); >> +            return ret; >> +        } >> + >> +        buf = pfb + count; >> +        count += done; >> +        for (i = 0; i < done; i++) { >> +            if (buf[i] != 0xfe) { >> +                continue; >> +            } >> +            if (buf[i-1] != 0xCa) { >> +                continue; >> +            } >> +            if (buf[i-2] != 0xed) { >> +                continue; >> +            } >> +            if (buf[i-3] == 0xFe) { >> +                goto out; >> +            } > >Using consistent capitalation here? >Better way to look for the signature? 

This code looks ugly, but runs fast. :)
And as we are looking for a better solution, this piece of code shall not
be kept in the final version of curling.

> Or,  what happens if it just >happens that the data contains that magic constant?

THAT IS THE PROBLEM, ft will fail if that happens. I expect better and fast solutions. Any suggestions?
Besides, I have tried the checksum solution which is slow. :(




reply via email to

[Prev in Thread] Current Thread [Next in Thread]