[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device
From: |
Isaku Yamahata |
Subject: |
Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy |
Date: |
Thu, 29 Dec 2011 10:31:43 +0900 |
User-agent: |
Mutt/1.5.19 (2009-01-05) |
On Thu, Dec 29, 2011 at 10:26:16AM +0900, Isaku Yamahata wrote:
> UMEM_DEV_LIST: list created umem devices
> UMEM_DEV_REATTACH: re-attach the created umem device
> UMEM_DEV_LIST and UMEM_DEV_REATTACH are used when
> the process that services page fault disappears or get stack.
> Then, administrator can list the umem devices and unblock
> the process which is waiting for page.
Here is a simple utility which cleans up umem devices.
---------------------------------------------------------------------------
/*
* simple clean up utility of for umem devices
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include <err.h>
#include <errno.h>
#include <inttypes.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/umem.h>
void mark_all_pages_cached(int umem_dev_fd, const char *id, const char *name)
{
struct umem_create create;
memset(&create, 0, sizeof(create));
strncpy(create.name.id, id, sizeof(create.name.id));
strncpy(create.name.name, name, sizeof(create.name.name));
if (ioctl(umem_dev_fd, UMEM_DEV_REATTACH, &create) < 0) {
err(EXIT_FAILURE, "UMEM_DEV_REATTACH");
}
close(create.shmem_fd);
long page_size = sysconf(_SC_PAGESIZE);
int page_shift = ffs(page_size) - 1;
int umem_fd = create.umem_fd;
printf("umem_fd %d size %"PRId64"\n", umem_fd, (uint64_t)create.size);
__u64 i;
__u64 e_pgoff = (create.size + page_size - 1) >> page_shift;
#define UMEM_CACHED_MAX 512
__u64 pgoffs[UMEM_CACHED_MAX];
struct umem_page_cached page_cached = {
.nr = 0,
.pgoffs = pgoffs,
};
for (i = 0; i < e_pgoff; i++) {
page_cached.pgoffs[page_cached.nr] = i;
page_cached.nr++;
if (page_cached.nr == UMEM_CACHED_MAX) {
if (ioctl(umem_fd, UMEM_MARK_PAGE_CACHED,
&page_cached) < 0) {
err(EXIT_FAILURE, "UMEM_MARK_PAGE_CACHED");
}
page_cached.nr = 0;
}
}
if (page_cached.nr > 0) {
if (ioctl(umem_fd, UMEM_MARK_PAGE_CACHED, &page_cached) < 0) {
err(EXIT_FAILURE, "UMEM_MARK_PAGE_CACHED");
}
}
close(umem_fd);
}
#define DEV_UMEM "/dev/umem"
int main(int argc, char **argv)
{
const char *id = NULL;
const char *name = NULL;
if (argc >= 2) {
id = argv[1];
}
if (argc >= 3) {
name = argv[2];
}
int umem_dev_fd = open(DEV_UMEM, O_RDWR);
if (umem_dev_fd < 0) {
perror("can't open "DEV_UMEM);
exit(EXIT_FAILURE);
}
struct umem_list tmp_ulist = {
.nr = 0,
};
if (ioctl(umem_dev_fd, UMEM_DEV_LIST, &tmp_ulist) < 0) {
err(EXIT_FAILURE, "UMEM_DEV_LIST");
}
if (tmp_ulist.nr == 0) {
printf("no umem files\n");
exit(EXIT_SUCCESS);
}
struct umem_list *ulist = malloc(
sizeof(*ulist) + sizeof(ulist->names[0]) * tmp_ulist.nr);
ulist->nr = tmp_ulist.nr;
if (ioctl(umem_dev_fd, UMEM_DEV_LIST, ulist) < 0) {
err(EXIT_FAILURE, "UMEM_DEV_LIST");
}
uint32_t i;
for (i = 0; i < ulist->nr; ++i) {
char *u_id = ulist->names[i].id;
char *u_name = ulist->names[i].name;
char tmp_id_c = u_id[UMEM_ID_MAX - 1];
char tmp_name_c = u_name[UMEM_NAME_MAX - 1];
u_id[UMEM_ID_MAX - 1] = '\0';
u_name[UMEM_NAME_MAX - 1] = '\0';
printf("%d: id: %s name: %s\n", i, u_id, u_name);
if ((id != NULL || name != NULL) &&
(id == NULL || strncmp(id, u_id, UMEM_ID_MAX) == 0) &&
(name == NULL ||
strncmp(name, u_name, UMEM_NAME_MAX) == 0)) {
printf("marking cached: %d: id: %s name: %s\n",
i, u_id, u_name);
u_id[UMEM_ID_MAX - 1] = tmp_id_c;
u_name[UMEM_NAME_MAX - 1] = tmp_name_c;
mark_all_pages_cached(umem_dev_fd, u_id, u_name);
}
}
close(umem_dev_fd);
return 0;
}
- [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy, Isaku Yamahata, 2011/12/28
- Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy,
Isaku Yamahata <=
- [Qemu-devel] [PATCH 1/2] export necessary symbols, Isaku Yamahata, 2011/12/28
- Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy, Avi Kivity, 2011/12/29
- Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy, Isaku Yamahata, 2011/12/29
- Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy, Avi Kivity, 2011/12/29
- Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy, Isaku Yamahata, 2011/12/29
- Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy, Avi Kivity, 2011/12/29
- Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy, Isaku Yamahata, 2011/12/29
- Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy, Avi Kivity, 2011/12/29
- Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy, Isaku Yamahata, 2011/12/29
- Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy, Avi Kivity, 2011/12/29