int main(int argc, char **argv) { int fd; char *p; char buf[256]; signal(SIGUSR1, sighandler); fd = open_check(argv[1], O_RDWR, 0644); p = mmap_check((void *)0x700000000000, 0x202*PS, PROTECTION, MAP_SHARED, fd, 0); buf[0] = p[0]; buf[1] = p[PS]; buf[2] = p[PS*0x10]; buf[3] = p[PS*0x11]; buf[4] = p[PS*0x200]; buf[5] = p[PS*0x201]; pause(); return 0; }
static int stress_mremap_child( const args_t *args, const size_t sz, size_t new_sz, const size_t page_size, const size_t mremap_bytes, int *flags) { do { uint8_t *buf = NULL; size_t old_sz; if (!g_keep_stressing_flag) break; buf = mmap(NULL, new_sz, PROT_READ | PROT_WRITE, *flags, -1, 0); if (buf == MAP_FAILED) { /* Force MAP_POPULATE off, just in case */ #if defined(MAP_POPULATE) *flags &= ~MAP_POPULATE; #endif continue; /* Try again */ } (void)madvise_random(buf, new_sz); (void)mincore_touch_pages(buf, mremap_bytes); /* Ensure we can write to the mapped pages */ if (g_opt_flags & OPT_FLAGS_VERIFY) { mmap_set(buf, new_sz, page_size); if (mmap_check(buf, sz, page_size) < 0) { pr_fail("%s: mmap'd region of %zu " "bytes does not contain expected data\n", args->name, sz); (void)munmap(buf, new_sz); return EXIT_FAILURE; } } old_sz = new_sz; new_sz >>= 1; while (new_sz > page_size) { if (try_remap(args, &buf, old_sz, new_sz) < 0) { (void)munmap(buf, old_sz); return EXIT_FAILURE; } (void)madvise_random(buf, new_sz); if (g_opt_flags & OPT_FLAGS_VERIFY) { if (mmap_check(buf, new_sz, page_size) < 0) { pr_fail("%s: mremap'd region " "of %zu bytes does " "not contain expected data\n", args->name, sz); (void)munmap(buf, new_sz); return EXIT_FAILURE; } } old_sz = new_sz; new_sz >>= 1; } new_sz <<= 1; while (new_sz < mremap_bytes) { if (try_remap(args, &buf, old_sz, new_sz) < 0) { (void)munmap(buf, old_sz); return EXIT_FAILURE; } (void)madvise_random(buf, new_sz); old_sz = new_sz; new_sz <<= 1; } (void)munmap(buf, old_sz); inc_counter(args); } while (keep_stressing()); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { int fd; int sem; int nrpages = 1; int ret = 0; int tmp = 0; int offset = 0; char c; char *filename; char *actype; char *onerror; char *p; pid_t pid; int wait_status; uint64_t pflag; struct sembuf sembuf; struct pagestat pgstat; if (argc != 5) { printf("Usage: %s filename nrpages accesstype onerror\n", argv[0]); exit(EXIT_FAILURE); } filename = argv[1]; nrpages = strtol(argv[2], NULL, 10); actype = argv[3]; onerror = argv[4]; DEB("filename = %s, nrpages = %d, actype = %s, onerror = %s\n", filename, nrpages, actype, onerror); if (strcmp(onerror, "onerror") == 0) offset = 0; else offset = PS; sem = create_and_init_semaphore(); fd = open_check(filename, O_RDWR, 0); tmp = pread(fd, rbuf, nrpages*PS, 0); DEB("parent first read %d [%c,%c]\n", tmp, rbuf[0], rbuf[PS]); get_semaphore(sem, &sembuf); if ((pid = fork()) == 0) { get_semaphore(sem, &sembuf); /* wait parent to dirty page */ p = mmap_check((void *)REFADDR, nrpages * PS, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (p != (void *)REFADDR) err("mmap"); if (nrpages == 1) { DEB("child read (after dirty) [%c]\n", p[0]); #ifdef DEBUG get_pagestat(p, &pgstat); #endif } else { DEB("child read (after dirty) [%c,%c]\n", p[0], p[PS]); #ifdef DEBUG get_pagestat(p, &pgstat); get_pagestat(p+PS, &pgstat); #endif } DEB("child hwpoison to vaddr %p\n", p); madvise(&p[0], PS, 100); /* hwpoison */ put_semaphore(sem, &sembuf); get_semaphore(sem, &sembuf); DEB("child terminated\n"); put_semaphore(sem, &sembuf); get_pflags(pgstat.pfn, &pflag, 1); exit(EXIT_SUCCESS); } else { DEB("parent dirty\n"); usleep(1000); memset(wbuf, 49, nrpages * PS); pwrite(fd, wbuf, nrpages * PS, 0); tmp = pread(fd, rbuf, nrpages * PS, 0); DEB("parent second read (after dirty) %d [%c,%c]\n", tmp, rbuf[0], rbuf[PS]); put_semaphore(sem, &sembuf); /* kick child to inject error */ get_semaphore(sem, &sembuf); /* pagecache should be hwpoison */ DEB("parent check\n"); if (strcmp(actype, "read") == 0) { tmp = pread(fd, rbuf, PS, offset); if (tmp < 0) DEB("parent first read failed.\n"); tmp = pread(fd, rbuf, PS, offset); DEB("parent read after hwpoison %d [%c,%c]\n", tmp, rbuf[0], rbuf[PS]); if (tmp < 0) { ret = -1; perror("read"); } else { ret = 0; } } else if (strcmp(actype, "writefull") == 0) { memset(wbuf, 50, nrpages * PS); tmp = pwrite(fd, wbuf, PS, offset); tmp = pwrite(fd, wbuf, PS, offset); DEB("parent write after hwpoison %d\n", tmp); if (tmp < 0) { ret = -1; perror("writefull"); } else { ret = 0; } } else if (strcmp(actype, "writepart") == 0) { memset(wbuf, 50, nrpages * PS); tmp = pwrite(fd, wbuf, PS / 2, offset); tmp = pwrite(fd, wbuf, PS / 2, offset); DEB("parent write after hwpoison %d\n", tmp); if (tmp < 0) { ret = -1; perror("writefull"); } else { ret = 0; } } else if (strcmp(actype, "fsync") == 0) { ret = fsync(fd); ret = fsync(fd); DEB("parent fsync after hwpoison [ret %d]\n", ret); if (ret) perror("fsync"); } else if (strcmp(actype, "sync_range_write") == 0) { ret = sync_file_range(fd, offset, PS, SYNC_FILE_RANGE_WRITE); ret = sync_file_range(fd, offset, PS, SYNC_FILE_RANGE_WRITE); if (ret) perror("sync_range_write"); } else if (strcmp(actype, "sync_range_wait") == 0) { ret = sync_file_range(fd, offset, PS, SYNC_FILE_RANGE_WAIT_BEFORE); ret = sync_file_range(fd, offset, PS, SYNC_FILE_RANGE_WAIT_BEFORE); if (ret) perror("sync_range_wait"); } else if (strcmp(actype, "mmapread") == 0) { /* * If mmap access failed, this program should be * terminated by segmentation fault with non-zero * returned value. So we don't set ret here. */ p = mmap_check((void *)REFADDR, nrpages * PS, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (p != (void *)REFADDR) err("mmap"); c = p[offset]; DEB("parent mmap() read after hwpoison [%c]\n", p[offset]); } else if (strcmp(actype, "mmapwrite") == 0) { p = mmap_check((void *)REFADDR, nrpages * PS, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (p != (void *)REFADDR) err("mmap"); memset(&p[offset], 50, PS); DEB("parent mmap() write after hwpoison [%c]\n", p[offset]); } } put_semaphore(sem, &sembuf); waitpid(pid, &wait_status, 0); if (!WIFEXITED(wait_status)) err("waitpid"); delete_semaphore(sem); DEB("parent exit %d.\n", ret); return ret; }
int main(int argc, char **argv) { char *p; int c; int len = HPS; int inject = 0; int collapse = 0; int mremap_flag = 0; int pfn_get = 0; int split = 0; int verbose = 0; char buf[256]; uint64_t pfn_buf[10]; while ((c = getopt(argc, argv, "m:w:crpsiv")) != -1) { switch (c) { case 'm': len = strtol(optarg, NULL, 10) * HPS; break; case 'c': collapse = 1; break; case 'r': mremap_flag = 1; break; case 'p': pfn_get = 1; break; case 's': split = 1; break; case 'i': inject = 1; break; case 'v': verbose = 1; break; default: usage(argv[0]); } } signal(SIGUSR1, sighandler); p = mmap_check((void *)0x7f0000000000, len, PROTECTION, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); Dprintf(verbose, "p = %p\n", p); madvise(p, len, MADV_HUGEPAGE); /* directly allocate thp in page fault. */ write_bytes(p, len); pause(); if (inject) madvise(p, 1, MADV_SOFT_OFFLINE); if (split) { mlock(p, 4096); munlock(p, 4096); } if (mremap_flag) { Dprintf(verbose, "mremap old p is %p!\n", p); p = mremap(p, len, len + HPS, 0, MREMAP_FIXED); /* p = mremap(p, len, len + HPS, 0, NULL); */ if (p == (void *)-1) err("mremap"); Dprintf(verbose, "mremap new p is %p!\n", p); } /* splitted thp will be collapsed again in the next khugepaged scan */ if (split && collapse) { /* split thp */ write_bytes(p, len); } pause(); munmap(p, len); return 0; }