farmem_main.c 1.81 KB
Newer Older
1
2
3
#include<linux/module.h>
#include<linux/kernel.h>
#include <linux/memory_hotplug.h>
4
#include <linux/vmalloc.h>
5
6
7
8
9
10
11
12
13
14

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antoine Kaufmann");
MODULE_DESCRIPTION("Manually exposes specified memory region in the specified "
    "numa node.");
MODULE_VERSION("0.1");

static unsigned long base_addr = 0;
static unsigned long size = 0;
static int nnid = 1;
15
static bool drain_node = false;
16
17
18
19

module_param(base_addr, ulong, 0);
module_param(size, ulong, 0);
module_param(nnid, int, 0);
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
module_param(drain_node, bool, 0);

/**
 * drains all available memory from the specified numa node by allocating (and
 * leaking) it
 */
static void do_drain_node(int nid)
{
  unsigned long eaten;
  struct page *p;

  printk(KERN_INFO "draining node %d\n", nid);
  if (nid == 0) {
    printk(KERN_ALERT "draining node 0 is probably a bad idea\n");
  }

  /* start with large chunks and move to smaller ones */
  eaten = 0;
  do {
    p = alloc_pages_node(nid,
      GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY | GFP_NOWAIT | __GFP_THISNODE,
      0);
    if (p)
      eaten += PAGE_SIZE;
  } while (p);

  printk(KERN_INFO "drained %lu bytes\n", eaten);
}
48
49
50
51
52
53
54
55
56
57
58
59
60
61

static int __init farmem_mod_init(void)
{
  int rc;

  printk(KERN_ALERT "Loading farmem driver\n");
  if (!base_addr || !size) {
    panic("base address and length must be set");
  }

  if (!node_possible(nnid)) {
    panic("invalid numa node spcified");
  }

62
63
64
  if (drain_node)
    do_drain_node(nnid);

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  rc = add_memory_driver_managed(nnid, base_addr, size,
      "System RAM (farmem)", MHP_NONE);
  if (rc) {
    printk(KERN_ALERT "adding memory failed: %d\n", rc);
  }
  node_set_online(nnid);

  return 0;
}

static void __exit farmem_mod_exit(void)
{
  printk(KERN_ALERT "Unloading farmem driver, this is broken\n");
}

module_init(farmem_mod_init);
module_exit(farmem_mod_exit);