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; } -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html