Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


minor numa interface cleanup, and make sure initialization occurs
[palacios.git] / linux_module / main.c
index 425e08f..8162172 100644 (file)
@@ -3,7 +3,7 @@
    (c) Jack Lange, 2010
  */
 
-
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/errno.h>
 #include "palacios.h"
 #include "mm.h"
 #include "vm.h"
+#include "numa.h"
 #include "allow_devmem.h"
 #include "memcheck.h"
 #include "lockcheck.h"
 
 #include "linux-exts.h"
 
-
 MODULE_LICENSE("GPL");
 
 // Module parameter
@@ -222,9 +222,13 @@ out_err:
         case V3_RESET_MEMORY: {
            DEBUG("Resetting memory\n");
             if (palacios_deinit_mm() == -1) {
-                ERROR("Error resetting Palacios memory\n");
+                ERROR("Error deiniting the Palacios memory manager\n");
                 return -EFAULT;
             }
+           if (palacios_init_mm()) { 
+               ERROR("Error initing the Palacios memory manager\n");
+               return -EFAULT;
+           }
             break;  
         }
 
@@ -445,6 +449,7 @@ static int guests_full_proc_open(struct inode * inode, struct file * filp)
 
 
 
+
 static struct file_operations guest_full_proc_ops = {
     .owner = THIS_MODULE,
     .open = guests_full_proc_open, 
@@ -461,6 +466,78 @@ static struct file_operations guest_short_proc_ops = {
     .release = single_release,
 };
 
+// Supply basic information that the user-space tools need
+// to manipulate Palacios.   The current use case here is to 
+// convey memory information
+static int read_info(struct seq_file *s, void *v)
+{
+    uint64_t mem_block_size;
+    int i,j;
+    int max_node=-1;
+    seq_printf(s,"kernel MAX_ORDER:\t%d\n",MAX_ORDER);
+    seq_printf(s,"number of nodes:\t%d\n", numa_num_nodes());
+    seq_printf(s,"number of cpus: \t%d\n", num_online_cpus());
+    seq_printf(s,"\npalacios compiled mem_block_size:\t%d\n", V3_CONFIG_MEM_BLOCK_SIZE);
+    if (!v3_lookup_option("mem_block_size")) { 
+       mem_block_size = V3_CONFIG_MEM_BLOCK_SIZE;
+    } else {
+       if (strict_strtoull(v3_lookup_option("mem_block_size"), 0, &mem_block_size)) {
+           // huh?
+           mem_block_size=-1;
+       }
+    }
+    seq_printf(s,"palacios run-time mem_block_size:\t%llu\n", mem_block_size);
+    
+    seq_printf(s,"\nCPU to node mappings\n");
+    for (i=0;i<num_online_cpus();i++) { 
+       seq_printf(s,"cpu %d -> node %d\n", i, numa_cpu_to_node(i));
+       if (numa_cpu_to_node(i)>max_node) { 
+           max_node=numa_cpu_to_node(i);
+       }
+    }
+    seq_printf(s,"\nNode to node distances\n");
+    for (j=0;j<=max_node;j++) { 
+       seq_printf(s,"   \t%2d", j);
+    }
+    seq_printf(s,"\n");
+    for (i=0;i<=max_node;i++) { 
+       seq_printf(s,"%2d ",i);
+       for (j=0;j<=max_node;j++) { 
+           seq_printf(s,"\t%2d", numa_get_distance(i,j));
+       }
+       seq_printf(s,"\n");
+    }
+    seq_printf(s,"\nCPU to CPU distances\n");
+    for (j=0;j<num_online_cpus();j++) { 
+       seq_printf(s,"   \t%2d", j);
+    }
+    seq_printf(s,"\n");
+    for (i=0;i<num_online_cpus();i++) { 
+       seq_printf(s,"%2d ",i);
+       for (j=0;j<num_online_cpus();j++) { 
+           seq_printf(s,"\t%2d", numa_get_distance(numa_cpu_to_node(i),numa_cpu_to_node(j)));
+       }
+       seq_printf(s,"\n");
+    }
+    return 0;
+}
+
+static int info_proc_open(struct inode * inode, struct file * filp) 
+{
+    struct proc_dir_entry * proc_entry = PDE(inode);
+    return single_open(filp, read_info, proc_entry->data);
+}
+
+
+
+static struct file_operations info_proc_ops = {
+    .owner = THIS_MODULE,
+    .open = info_proc_open, 
+    .read = seq_read,
+    .llseek = seq_lseek, 
+    .release = single_release,
+};
+
 
 static int __init v3_init(void) {
 
@@ -486,6 +563,10 @@ static int __init v3_init(void) {
       palacios_allow_devmem();
     }
 
+    // numa is now a required interface and we need it
+    // up before primary initiatilization
+    palacios_init_numa();
+
     // Initialize Palacios
     palacios_vmm_init(options);
 
@@ -546,14 +627,27 @@ static int __init v3_init(void) {
            ERROR("Could not create proc entry\n");
            goto failure7;
        }
+
+       entry = create_proc_entry("v3-info", 0444, palacios_proc_dir);
+        if (entry) {
+           entry->proc_fops = &info_proc_ops;
+           INFO("/proc/v3vee/v3-info successfully created\n");
+       } else {
+           ERROR("Could not create proc entry\n");
+           goto failure8;
+       }
+
+
     }
        
     return 0;
 
- failure7:
+ failure8:
     remove_proc_entry("v3-guests-details", palacios_proc_dir);
- failure6:
+ failure7:
     remove_proc_entry("v3-guests", palacios_proc_dir);
+ failure6:
+    device_destroy(v3_class, dev);
  failure5:
     unregister_chrdev_region(MKDEV(v3_major_num, 0), MAX_VMS + 1);
  failure4:
@@ -605,6 +699,8 @@ static void __exit v3_exit(void) {
 
     palacios_vmm_exit();
 
+    palacios_deinit_numa();
+
     DEBUG("Palacios Mallocs = %d, Frees = %d\n", mallocs, frees);
     DEBUG("Palacios Vmallocs = %d, Vfrees = %d\n", vmallocs, vfrees);
     DEBUG("Palacios Page Allocs = %d, Page Frees = %d\n", pg_allocs, pg_frees);
@@ -625,6 +721,7 @@ static void __exit v3_exit(void) {
 
     palacios_deinit_mm();
 
+    remove_proc_entry("v3-info", palacios_proc_dir);
     remove_proc_entry("v3-guests-details", palacios_proc_dir);
     remove_proc_entry("v3-guests", palacios_proc_dir);
     remove_proc_entry("v3vee", NULL);