/* * Migration test program * * (C) 2007 Silicon Graphics, Inc. Christoph Lameter * */ #include #include #include "numa.h" #include "numaif.h" #include #include #include #include #include "util.h" char *memory; unsigned long pages = 1000; unsigned long pagesize; const char *optstr = "hvp:"; char *cmd; int verbose; struct timespec start,end; void usage(void) { printf("usage %s [-p pages] [-h] [-v] from-nodes to-nodes\n", cmd); printf(" from and to nodes may specified in form N or N-N\n"); printf(" -p pages number of pages to try (defaults to %ld)\n", pages); printf(" -v verbose\n"); printf(" -h usage\n"); exit(1); } void displaymap(void) { FILE *f = fopen("/proc/self/numa_maps","r"); if (!f) { printf("/proc/self/numa_maps not accessible.\n"); exit(1); } while (!feof(f)) { char buffer[2000]; if (!fgets(buffer, sizeof(buffer), f)) break; if (!strstr(buffer, "bind")) continue ; printf("%s", buffer); } fclose(f); } int main(int argc, char *argv[]) { char *p; int option; struct timespec result; unsigned long bytes; double duration, mbytes; struct bitmask *from; struct bitmask *to; pagesize = getpagesize(); /* Command line processing */ opterr = 1; cmd = argv[0]; while ((option = getopt(argc, argv, optstr)) != EOF) switch (option) { case 'h' : case '?' : usage(); case 'v' : verbose++; break; case 'p' : pages = strtoul(optarg, &p, 0); if (p == optarg || *p) usage(); break; } if (!argv[optind]) usage(); if (verbose > 1) printf("numa_max_node = %d\n", numa_max_node()); numa_exit_on_error = 1; from = numa_parse_nodestring(argv[optind]); if (!from) { printf ("<%s> is invalid\n", argv[optind]); exit(1); } if (errno) { perror("from mask"); exit(1); } if (verbose) printmask("From", from); if (!argv[optind+1]) usage(); to = numa_parse_nodestring(argv[optind+1]); if (!to) { printf ("<%s> is invalid\n", argv[optind+1]); exit(1); } if (errno) { perror("to mask"); exit(1); } if (verbose) printmask("To", to); bytes = pages * pagesize; if (verbose) printf("Allocating %lu pages of %lu bytes of memory\n", pages, pagesize); memory = memalign(pagesize, bytes); if (!memory) { printf("Out of Memory\n"); exit(2); } if (mbind(memory, bytes, MPOL_BIND, from->maskp, from->size, 0) < 0) numa_error("mbind"); if (verbose) printf("Dirtying memory....\n"); for (p = memory; p <= memory + bytes; p += pagesize) *p = 1; if (verbose) printf("Starting test\n"); displaymap(); clock_gettime(CLOCK_REALTIME, &start); if (mbind(memory, bytes, MPOL_BIND, to->maskp, to->size, MPOL_MF_MOVE) <0) numa_error("memory move"); clock_gettime(CLOCK_REALTIME, &end); displaymap(); result.tv_sec = end.tv_sec - start.tv_sec; result.tv_nsec = end.tv_nsec - start.tv_nsec; if (result.tv_nsec < 0) { result.tv_sec--; result.tv_nsec += 1000000000; } if (result.tv_nsec >= 1000000000) { result.tv_sec++; result.tv_nsec -= 1000000000; } duration = result.tv_sec + result.tv_nsec / 1000000000.0; mbytes = bytes / (1024*1024.0); printf("%1.1f Mbyte migrated in %1.2f secs. %3.1f Mbytes/second\n", mbytes, duration, mbytes / duration); return 0; }