[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH][RFC] post copy chardevice (was Re: [RFC] postco
From: |
Isaku Yamahata |
Subject: |
Re: [Qemu-devel] [PATCH][RFC] post copy chardevice (was Re: [RFC] postcopy livemigration proposal) |
Date: |
Fri, 12 Aug 2011 20:09:39 +0900 |
User-agent: |
Mutt/1.5.19 (2009-01-05) |
Sample user land program for testing the post copy chardevice.
===========================================================================
/*
* sample user land for post copy vmem
*
* Copyright (c) 2011,
* National Institute of Advanced Industrial Science and Technology
*
* https://sites.google.com/site/grivonhome/quick-kvm-migration
* Author: Isaku Yamahata <yamahata at valinux co jp>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*/
#include <err.h>
#include <inttypes.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//#include <linux/kvm.h>
#define __user
#include "my-kvm.h"
#if 1
#define DPRINTF(format, ...) \
printf("%s:%d "format, __func__, __LINE__, ## __VA_ARGS__)
#else
#define DPRINTF(format, ...) do { } while (0)
#endif
#define VMEM_NR_PAGES 8
void server(int vmem_fd, int shmem_fd, size_t size, size_t page_size)
{
int nr_pages = size / page_size;
void* shmem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
shmem_fd, 0);
if (shmem == MAP_FAILED) {
err(EXIT_FAILURE, "server: mmap(\"shmem\")");
}
close(shmem_fd);
DPRINTF("KVM_VMEM_READY\n");
if (ioctl(vmem_fd, KVM_VMEM_READY) < 0) {
err(EXIT_FAILURE, "server: KVM_VMEM_READY");
}
struct kvm_vmem_page_request page_request;
page_request.pgoffs = malloc(sizeof(*page_request.pgoffs) * nr_pages);
if (page_request.pgoffs == NULL) {
err(EXIT_FAILURE, "server: malloc(\"page_request.pgoffs\")");
}
struct kvm_vmem_page_cached page_cached;
page_cached.pgoffs = malloc(sizeof(*page_cached.pgoffs) * nr_pages);
if (page_cached.pgoffs == NULL) {
err(EXIT_FAILURE, "server: malloc(\"page_cached.pgoffs\")");
}
int fill = 0;
fill++;
memset(shmem, fill, page_size);
page_cached.nr = 1;
page_cached.pgoffs[0] = 0;
DPRINTF("KVM_VMEM_MARK_PAGE_CACHED\n");
if (ioctl(vmem_fd, KVM_VMEM_MARK_PAGE_CACHED, &page_cached)) {
err(EXIT_FAILURE, "server: KVM_VMEM_MARK_PAGE_CACHED");
}
struct kvm_vmem_page_range page_range = {
.pgoff = 0,
.nr_pages = 1,
};
struct kvm_vmem_make_pages_present pages_present = {
.nr = 1,
.ranges = &page_range,
};
DPRINTF("KVM_VMEM_MAKE_PAGES_PRESENT\n");
if (ioctl(vmem_fd, KVM_VMEM_MAKE_PAGES_PRESENT, &pages_present) < 0) {
err(EXIT_FAILURE, "server: KVM_VMEM_MAKE_PAGES_PRESENT");
}
int page_served = 1;
while (page_served < nr_pages) {
DPRINTF("KVM_VMEM_GET_PAGE_REQUEST\n");
page_request.nr = nr_pages;
if (ioctl(vmem_fd, KVM_VMEM_GET_PAGE_REQUEST, &page_request)) {
err(EXIT_FAILURE, "server: KVM_VMEM_GET_PAGE_REQUEST");
}
DPRINTF("request.nr %d\n", page_request.nr);
page_cached.nr = 0;
int i;
for (i = 0; i < page_request.nr; ++i) {
memset(shmem + page_size * page_request.pgoffs[i],
fill, page_size);
fill++;
page_cached.pgoffs[page_cached.nr] =
page_request.pgoffs[i];
page_cached.nr++;
DPRINTF("request[%d] %lx fill: %d\n",
i, (unsigned long)page_request.pgoffs[i],
fill - 1);
}
DPRINTF("KVM_VMEM_MARK_PAGE_CACHED\n");
if (ioctl(vmem_fd, KVM_VMEM_MARK_PAGE_CACHED,
&page_cached) < 0) {
err(EXIT_FAILURE, "server: KVM_VMEM_MARK_PAGE_CACHED");
}
page_served += page_cached.nr;
}
#if 0
DPRINTF("KVM_VMEM_MAKE_VMA_ANONYMOUS\n");
if (ioctl(vmem_fd, KVM_VMEM_MAKE_VMA_ANONYMOUS)) {
err(EXIT_FAILURE, "server: KVM_VMEM_MAKE_VMA_ANONYMOUS");
}
#endif
munmap(shmem, size);
close(vmem_fd);
}
void qemu(int vmem_fd, size_t size, size_t page_size)
{
DPRINTF("mmap\n");
void *ram = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
vmem_fd, 0);
if (ram == MAP_FAILED) {
err(EXIT_FAILURE, "qemu: mmap");
}
DPRINTF("KVM_VMEM_WAIT_READY\n");
if (ioctl(vmem_fd, KVM_VMEM_WAIT_READY) < 0) {
err(EXIT_FAILURE, "qemu: KVM_VMEM_WAIT_READY");
}
DPRINTF("close\n");
close(vmem_fd);
int pages[] = {7, 1, 6, 2, 0, 5, 3, 4};
int val[VMEM_NR_PAGES];
int i;
for (i = 0; i < VMEM_NR_PAGES; ++i) {
if (i == 2 || i == 6)
sleep(1);
DPRINTF("access to %d\n", pages[i]);
fflush(stdout);
val[i] = *(uint8_t*)(ram + page_size * pages[i]);
DPRINTF("page:%d val[i=%d]=%d\n", pages[i], i, val[i]);
}
munmap(ram, size);
}
int main(int argc, char **argv)
{
int kvm_fd = open("/dev/kvm", O_RDWR);
if (kvm_fd < 0) {
perror("can't open /dev/kvm");
exit(EXIT_FAILURE);
}
int vmem_dev_fd = ioctl(kvm_fd, KVM_CREATE_VMEM_DEV);
if (vmem_dev_fd < 0) {
err(EXIT_FAILURE, "can't create vmem_dev");
}
long page_size = sysconf(_SC_PAGESIZE);
struct kvm_vmem_create create = {
.size = VMEM_NR_PAGES * page_size,
};
if (ioctl(vmem_dev_fd, KVM_CREATE_VMEM, &create) < 0) {
err(EXIT_FAILURE, "KVM_CREATE_VMEM");
}
close(vmem_dev_fd);
int vmem_fd = create.vmem_fd;
int shmem_fd = create.shmem_fd;
size_t size = create.size;
if (ftruncate(shmem_fd, size) < 0) {
err(EXIT_FAILURE, "truncate(\"shmem_fd\")");
}
printf("vmem_fd %d shmem_fd %d\n", vmem_fd, shmem_fd);
fflush(stdout);
pid_t child = fork();
if (child < 0) {
err(EXIT_FAILURE, "fork");
}
if (child == 0) {
sleep(1);
printf("server pid: %d\n", getpid());
server(vmem_fd, shmem_fd, size, page_size);
return 0;
}
printf("qemu pid: %d server pid: %d\n", getpid(), child);
close(shmem_fd);
qemu(vmem_fd, size, page_size);
return 0;
}
===========================================================================
--
yamahata
- Re: [Qemu-devel] [RFC] postcopy livemigration proposal, (continued)
Re: [Qemu-devel] [RFC] postcopy livemigration proposal, Stefan Hajnoczi, 2011/08/08
Re: [Qemu-devel] [RFC] postcopy livemigration proposal, Avi Kivity, 2011/08/08
[Qemu-devel] [PATCH][RFC] post copy chardevice (was Re: [RFC] postcopy livemigration proposal), Isaku Yamahata, 2011/08/12