(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
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;
}
seq_printf(s, "\nMemory Regions\n");
for (j=0;j<mem->num_regions;j++) {
- seq_printf(s," region %u has HPAs 0x%p-0x%p\n",
- j, mem->region[j].host_paddr, mem->region[j].host_paddr+mem->region[j].size);
+ seq_printf(s," region %u has HPAs 0x%p-0x%p (node %d)\n",
+ j, mem->region[j].host_paddr, mem->region[j].host_paddr+mem->region[j].size,
+ numa_addr_to_node((uintptr_t)(mem->region[j].host_paddr)));
}
}
seq_printf(s,
+
static struct file_operations guest_full_proc_ops = {
.owner = THIS_MODULE,
.open = guests_full_proc_open,
.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) {
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);
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:
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);
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);