test on fb_eth
[ana-net.git] / src / sd_single.c
blob6013a6b0635c91c47d1429095126ce064d769e36
1 /*
2 * Lightweight Autonomic Network Architecture
4 * Single CPU scheduler.
6 * Copyright 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,
7 * Swiss federal institute of technology (ETH Zurich)
8 * Subject to the GPL.
9 */
11 #include <linux/module.h>
12 #include <linux/kernel.h>
13 #include <linux/cache.h>
14 #include <linux/cpumask.h>
15 #include <linux/spinlock.h>
17 #include "xt_sched.h"
18 #include "xt_engine.h"
20 extern struct proc_dir_entry *sched_proc_dir;
21 static struct proc_dir_entry *ppesched_cpu_proc;
22 static volatile unsigned long __read_mostly cpu = 0;
24 static int ppe_single_sched(struct sk_buff *skb, enum path_type dir)
26 #ifdef __MIGRATE
27 if (cpu != USERSPACECPU)
28 enqueue_on_engine(skb, cpu, dir);
29 else
30 kfree_skb(skb);
31 #else
32 enqueue_on_engine(skb, cpu, dir);
33 #endif /* __MIGRATE */
34 return PPE_SUCCESS;
37 static struct ppesched_discipline_ops ppe_single_ops __read_mostly = {
38 .discipline_sched = ppe_single_sched,
41 static struct ppesched_discipline ppe_single __read_mostly = {
42 .name = "singlecpu",
43 .ops = &ppe_single_ops,
44 .owner = THIS_MODULE,
47 static int ppe_single_procfs_read(char *page, char **start, off_t offset,
48 int count, int *eof, void *data)
50 off_t len = 0;
51 len += sprintf(page + len, "%lu\n", cpu);
52 *eof = 1;
53 return len;
56 static int ppe_single_procfs_write(struct file *file, const char __user *buffer,
57 unsigned long count, void *data)
59 int ret = count, res;
60 size_t len;
61 char *dst_cpu;
63 if (count > 64)
64 return -EINVAL;
65 len = count;
66 dst_cpu = kmalloc(len, GFP_KERNEL);
67 if (!dst_cpu)
68 return -ENOMEM;
69 memset(dst_cpu, 0, len);
70 if (copy_from_user(dst_cpu, buffer, len)) {
71 ret = -EFAULT;
72 goto out;
74 dst_cpu[len - 1] = 0;
75 res = simple_strtol(dst_cpu, NULL, 10);
76 if (res >= num_online_cpus() || res < 0) {
77 ret = -EINVAL;
78 goto out;
80 cpu = res;
81 barrier();
82 ret = len;
83 out:
84 kfree(dst_cpu);
85 return ret;
88 static int __init init_ppe_single_module(void)
90 int ret;
91 ret = ppesched_discipline_register(&ppe_single);
92 if (ret != 0)
93 return ret;
94 ppesched_cpu_proc = create_proc_entry("sched_cpu", 0666,
95 sched_proc_dir);
96 if (!ppesched_cpu_proc) {
97 ppesched_discipline_unregister(&ppe_single);
98 return -ENOMEM;
100 ppesched_cpu_proc->read_proc = ppe_single_procfs_read;
101 ppesched_cpu_proc->write_proc = ppe_single_procfs_write;
102 ppesched_cpu_proc->data = NULL;
103 return 0;
106 static void __exit cleanup_ppe_single_module(void)
108 remove_proc_entry("sched_cpu", sched_proc_dir);
109 ppesched_discipline_unregister(&ppe_single);
112 module_init(init_ppe_single_module);
113 module_exit(cleanup_ppe_single_module);
115 MODULE_LICENSE("GPL");
116 MODULE_AUTHOR("Daniel Borkmann <dborkma@tik.ee.ethz.ch>");
117 MODULE_DESCRIPTION("LANA single CPU scheduler");