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