Thread: Need help with the numa migration code

  1. #1
    Registered User
    Join Date
    Mar 2011
    Posts
    45

    Need help with the numa migration code

    Hi ,
    here is the code I am trying to get running on my linux system. I emulated NUMA on my laptop using the numa=fake=2 boot time option. The source code is from the documentation I found in the website for numactl.
    Heres is link

    numactl 2.0.5, mbind__mig__pages_8c-source.html

    the code is

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <numa.h>
    #include <numaif.h>
    #include <unistd.h>
    #include <asm/unistd.h>
    
    unsigned int pagesize;
    unsigned int page_count = 32;
    
    char *page_base;
    char *pages;
    
    void **addr;
    int *status;
    int *nodes;
    int errors;
    int nr_nodes;
    
    struct bitmask *old_nodes;
    struct bitmask *new_nodes;
    
    int main(int argc, char **argv)
    {
          int i, rc;
    
          pagesize = getpagesize();
    
          nr_nodes = numa_max_node()+1;
    
          old_nodes = numa_bitmask_alloc(nr_nodes);
          new_nodes = numa_bitmask_alloc(nr_nodes);
          numa_bitmask_setbit(old_nodes, 0);
          numa_bitmask_setbit(new_nodes, 1);
    
          if (nr_nodes < 2) {
                printf("A minimum of 2 nodes is required for this test.\n");
                exit(1);
          }
    
          setbuf(stdout, NULL);
          printf("mbind migration test ......\n");
          if (argc > 1)
                sscanf(argv[1], "%d", &page_count);
    
          page_base = malloc((pagesize + 1) * page_count);
          addr = malloc(sizeof(char *) * page_count);
          status = malloc(sizeof(int *) * page_count);
          nodes = malloc(sizeof(int *) * page_count);
          if (!page_base || !addr || !status || !nodes) {
                printf("Unable to allocate memory\n");
                exit(1);
          }
    
          pages = (void *) ((((long)page_base) & ~((long)(pagesize - 1))) + pagesize);
    
          for (i = 0; i < page_count; i++) {
                if (i != 2)
                      /* We leave page 2 unallocated */
                      pages[ i * pagesize ] = (char) i;
                addr[i] = pages + i * pagesize;
                nodes[i] = 0;
                status[i] = -123;
          }
    
          /* Move pages toi node zero */
          numa_move_pages(0, page_count, addr, nodes, status, 0);
    
          printf("\nPage status before page migration\n");
          printf("---------------------------------\n");
          rc = numa_move_pages(0, page_count, addr, NULL, status, 0);
          if (rc < 0) {
                perror("move_pages");
                exit(1);
          }
    
          for (i = 0; i < page_count; i++) {
                printf("Page %d vaddr=%p node=%d\n", i, pages + i * pagesize, status[i]);
                if (i != 2 && status[i]) {
                      printf("Bad page state. Page %d status %d\n",i, status[i]);
                      exit(1);
                }
          }
    
          /* Move to node zero */
          printf("\nMoving pages via mbind to node 0 ...\n");
          rc = mbind(pages, page_count * pagesize, MPOL_BIND, old_nodes->maskp,
                old_nodes->size + 1, MPOL_MF_MOVE | MPOL_MF_STRICT);
          if (rc < 0) {
                perror("mbind");
                errors++;
          }
    
    
          printf("\nMoving pages via mbind from node 0 to 1 ...\n");
          rc = mbind(pages, page_count * pagesize, MPOL_BIND, new_nodes->maskp,
                new_nodes->size + 1, MPOL_MF_MOVE | MPOL_MF_STRICT);
          if (rc < 0) {
                perror("mbind");
                errors++;
          }
    
          numa_move_pages(0, page_count, addr, NULL, status, 0);
          for (i = 0; i < page_count; i++) {
                printf("Page %d vaddr=%lx node=%d\n", i,
                      (unsigned long)(pages + i * pagesize), status[i]);
                if (i != 2) {
                      if (pages[ i* pagesize ] != (char) i) {
                            printf("*** Page content corrupted.\n");
                            errors++;
                      } else if (status[i] != 1) {
                            printf("*** Page on wrong node.\n");
                            errors++;
                      }
                }
          }
    
          if (!errors)
                printf("Test successful.\n");
          else
                printf("%d errors.\n", errors);
    
          return errors > 0 ? 1 : 0;
    }

    The problem is that different runs of the program give me different outcomes. it fails and runs successfully at its own will. Since the behaviour is not constant, I am having a real trouble debugging the code. Is there some obvious initialization mistake somewhere in the code? I tried all error checks and none of the function actually gives any error. I am really lost.

    I also want to add that the source node is always found to be sucessfully set to 0 even in runs that are unsuccessful. That means up until line 83 the code is fine..something goes wrong after that point.



    Thanks in advance.
    Last edited by livin; 08-27-2012 at 03:56 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. AIX To Linux Migration
    By Testing in forum C++ Programming
    Replies: 9
    Last Post: 11-10-2011, 09:26 AM
  2. Upcoming server migration
    By webmaster in forum General Discussions
    Replies: 2
    Last Post: 04-14-2011, 06:00 AM
  3. a question about NUMA
    By ZeroMemory in forum Windows Programming
    Replies: 2
    Last Post: 10-11-2009, 11:23 PM
  4. NUMA - WinApi
    By bazz-dee in forum Windows Programming
    Replies: 2
    Last Post: 06-12-2008, 11:24 AM
  5. Numa Numa!
    By jverkoey in forum A Brief History of Cprogramming.com
    Replies: 12
    Last Post: 02-28-2005, 09:06 AM