aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-04-15 19:29:09 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2012-04-15 19:29:09 -0400
commit0b865246946a97dc03a81ccf55bf84acce923c4b (patch)
treebc8f16cd18e6b6a759f701508a23b698771299fa
parentbb4922c968aa1a30fddd6ad9d0f750706c7b3b29 (diff)
Infrastructure for affinity-aware k-exclusion
-rw-r--r--include/litmus/fdso.h5
-rw-r--r--include/litmus/kexclu_affinity.h31
-rw-r--r--include/litmus/rt_param.h5
-rw-r--r--include/litmus/sched_plugin.h14
-rw-r--r--litmus/Kconfig24
-rw-r--r--litmus/Makefile2
-rw-r--r--litmus/fdso.c6
-rw-r--r--litmus/kexclu_affinity.c84
-rw-r--r--litmus/sched_gsn_edf.c1
-rw-r--r--litmus/sched_plugin.c15
10 files changed, 183 insertions, 4 deletions
diff --git a/include/litmus/fdso.h b/include/litmus/fdso.h
index 2bff9cc3909d..baf28c47e95d 100644
--- a/include/litmus/fdso.h
+++ b/include/litmus/fdso.h
@@ -24,7 +24,10 @@ typedef enum {
24 IKGLP_SEM = 3, 24 IKGLP_SEM = 3,
25 KFMLP_SEM = 4, 25 KFMLP_SEM = 4,
26 26
27 MAX_OBJ_TYPE = 4 27 IKGLP_AFF_OBS = 5,
28 KFMLP_AFF_OBS = 6,
29
30 MAX_OBJ_TYPE = 6
28} obj_type_t; 31} obj_type_t;
29 32
30struct inode_obj_id { 33struct inode_obj_id {
diff --git a/include/litmus/kexclu_affinity.h b/include/litmus/kexclu_affinity.h
new file mode 100644
index 000000000000..f5b5e7b1f359
--- /dev/null
+++ b/include/litmus/kexclu_affinity.h
@@ -0,0 +1,31 @@
1#ifndef LITMUS_AFF_OBS_H
2#define LITMUS_AFF_OBS_H
3
4#include <litmus/locking.h>
5
6struct affinity_observer_ops;
7
8struct affinity_observer
9{
10 struct affinity_observer_ops* ops;
11 int type;
12 int ident;
13
14 struct litmus_lock* lock; // the lock under observation
15};
16
17typedef int (*aff_obs_open_t)(struct affinity_observer* aff_obs,
18 void* __user arg);
19typedef int (*aff_obs_close_t)(struct affinity_observer* aff_obs);
20typedef void (*aff_obs_free_t)(struct affinity_observer* aff_obs);
21
22struct affinity_observer_ops
23{
24 aff_obs_open_t open;
25 aff_obs_close_t close;
26 aff_obs_free_t deallocate;
27};
28
29struct litmus_lock* get_lock_from_od(int od);
30
31#endif
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h
index b4eb8ee95687..cc638e9c55d1 100644
--- a/include/litmus/rt_param.h
+++ b/include/litmus/rt_param.h
@@ -52,6 +52,11 @@ union np_flag {
52 } np; 52 } np;
53}; 53};
54 54
55struct affinity_observer_args
56{
57 int lock_od;
58};
59
55/* The definition of the data that is shared between the kernel and real-time 60/* The definition of the data that is shared between the kernel and real-time
56 * tasks via a shared page (see litmus/ctrldev.c). 61 * tasks via a shared page (see litmus/ctrldev.c).
57 * 62 *
diff --git a/include/litmus/sched_plugin.h b/include/litmus/sched_plugin.h
index 8e65555d9b7f..d14f705ef414 100644
--- a/include/litmus/sched_plugin.h
+++ b/include/litmus/sched_plugin.h
@@ -11,6 +11,10 @@
11#include <litmus/locking.h> 11#include <litmus/locking.h>
12#endif 12#endif
13 13
14#ifdef CONFIG_LITMUS_AFFINITY_LOCKING
15#include <litmus/kexclu_affinity.h>
16#endif
17
14#include <linux/interrupt.h> 18#include <linux/interrupt.h>
15 19
16/************************ setup/tear down ********************/ 20/************************ setup/tear down ********************/
@@ -59,6 +63,10 @@ typedef void (*task_exit_t) (struct task_struct *);
59typedef long (*allocate_lock_t) (struct litmus_lock **lock, int type, 63typedef long (*allocate_lock_t) (struct litmus_lock **lock, int type,
60 void* __user config); 64 void* __user config);
61 65
66typedef long (*allocate_affinity_observer_t) (
67 struct affinity_observer **aff_obs, int type,
68 void* __user config);
69
62typedef void (*increase_prio_t)(struct task_struct* t, struct task_struct* prio_inh); 70typedef void (*increase_prio_t)(struct task_struct* t, struct task_struct* prio_inh);
63typedef void (*decrease_prio_t)(struct task_struct* t, struct task_struct* prio_inh); 71typedef void (*decrease_prio_t)(struct task_struct* t, struct task_struct* prio_inh);
64typedef void (*nested_increase_prio_t)(struct task_struct* t, struct task_struct* prio_inh, 72typedef void (*nested_increase_prio_t)(struct task_struct* t, struct task_struct* prio_inh,
@@ -146,7 +154,11 @@ struct sched_plugin {
146#ifdef CONFIG_LITMUS_DGL_SUPPORT 154#ifdef CONFIG_LITMUS_DGL_SUPPORT
147 get_dgl_spinlock_t get_dgl_spinlock; 155 get_dgl_spinlock_t get_dgl_spinlock;
148#endif 156#endif
149 157
158#ifdef CONFIG_LITMUS_AFFINITY_LOCKING
159 allocate_affinity_observer_t allocate_aff_obs;
160#endif
161
150#ifdef CONFIG_LITMUS_SOFTIRQD 162#ifdef CONFIG_LITMUS_SOFTIRQD
151 increase_prio_klitirq_t increase_prio_klitirqd; 163 increase_prio_klitirq_t increase_prio_klitirqd;
152 decrease_prio_klitirqd_t decrease_prio_klitirqd; 164 decrease_prio_klitirqd_t decrease_prio_klitirqd;
diff --git a/litmus/Kconfig b/litmus/Kconfig
index 6cf4d7eaa96f..263c3ee49c15 100644
--- a/litmus/Kconfig
+++ b/litmus/Kconfig
@@ -60,6 +60,16 @@ config LITMUS_LOCKING
60 Say Yes if you want to include locking protocols such as the FMLP and 60 Say Yes if you want to include locking protocols such as the FMLP and
61 Baker's SRP. 61 Baker's SRP.
62 62
63config LITMUS_AFFINITY_LOCKING
64 bool "Enable affinity infrastructure in k-exclusion locking protocols."
65 depends on LITMUS_LOCKING
66 default n
67 help
68 Enable affinity tracking infrastructure in k-exclusion locking protocols.
69 This only enabled the *infrastructure* not actual affinity algorithms.
70
71 If unsure, say No.
72
63config LITMUS_NESTED_LOCKING 73config LITMUS_NESTED_LOCKING
64 bool "Support for nested inheritance in locking protocols" 74 bool "Support for nested inheritance in locking protocols"
65 depends on LITMUS_LOCKING 75 depends on LITMUS_LOCKING
@@ -291,7 +301,19 @@ config LITMUS_NVIDIA
291 depends on LITMUS_SOFTIRQD || LITMUS_PAI_SOFTIRQD 301 depends on LITMUS_SOFTIRQD || LITMUS_PAI_SOFTIRQD
292 default n 302 default n
293 help 303 help
294 Direct tasklets from NVIDIA devices to Litmus's klitirqd. 304 Direct tasklets from NVIDIA devices to Litmus's klitirqd
305 or PAI interrupt handling routines.
306
307 If unsure, say No.
308
309config LITMUS_AFFINITY_AWARE_GPU_ASSINGMENT
310 bool "Enable affinity-aware heuristics to improve GPU assignment."
311 depends on LITMUS_NVIDIA && LITMUS_AFFINITY_LOCKING
312 default n
313 help
314 Enable several heuristics to improve the assignment
315 of GPUs to real-time tasks to reduce the overheads
316 of memory migrations.
295 317
296 If unsure, say No. 318 If unsure, say No.
297 319
diff --git a/litmus/Makefile b/litmus/Makefile
index 91fd32cb979d..1698afb75ec4 100644
--- a/litmus/Makefile
+++ b/litmus/Makefile
@@ -34,3 +34,5 @@ obj-$(CONFIG_LITMUS_NESTED_LOCKING) += rsm_lock.o ikglp_lock.o
34obj-$(CONFIG_LITMUS_SOFTIRQD) += litmus_softirq.o 34obj-$(CONFIG_LITMUS_SOFTIRQD) += litmus_softirq.o
35obj-$(CONFIG_LITMUS_PAI_SOFTIRQD) += litmus_pai_softirq.o 35obj-$(CONFIG_LITMUS_PAI_SOFTIRQD) += litmus_pai_softirq.o
36obj-$(CONFIG_LITMUS_NVIDIA) += nvidia_info.o sched_trace_external.o 36obj-$(CONFIG_LITMUS_NVIDIA) += nvidia_info.o sched_trace_external.o
37
38obj-$(CONFIG_LITMUS_AFFINITY_LOCKING) += kexclu_affinity.o
diff --git a/litmus/fdso.c b/litmus/fdso.c
index 5ef858e59ab0..0bacea179660 100644
--- a/litmus/fdso.c
+++ b/litmus/fdso.c
@@ -20,12 +20,16 @@
20 20
21extern struct fdso_ops generic_lock_ops; 21extern struct fdso_ops generic_lock_ops;
22 22
23extern struct fdso_ops generic_affinity_ops;
24
23static const struct fdso_ops* fdso_ops[] = { 25static const struct fdso_ops* fdso_ops[] = {
24 &generic_lock_ops, /* FMLP_SEM */ 26 &generic_lock_ops, /* FMLP_SEM */
25 &generic_lock_ops, /* KFMLP_SEM */
26 &generic_lock_ops, /* SRP_SEM */ 27 &generic_lock_ops, /* SRP_SEM */
27 &generic_lock_ops, /* RSM_MUTEX */ 28 &generic_lock_ops, /* RSM_MUTEX */
28 &generic_lock_ops, /* IKGLP_SEM */ 29 &generic_lock_ops, /* IKGLP_SEM */
30 &generic_lock_ops, /* KFMLP_SEM */
31 &generic_affinity_ops, /* IKGLP_AFF_OBS */
32 &generic_affinity_ops, /* KFMLP_AFF_OBS */
29}; 33};
30 34
31static int fdso_create(void** obj_ref, obj_type_t type, void* __user config) 35static int fdso_create(void** obj_ref, obj_type_t type, void* __user config)
diff --git a/litmus/kexclu_affinity.c b/litmus/kexclu_affinity.c
new file mode 100644
index 000000000000..a06df3e1acbd
--- /dev/null
+++ b/litmus/kexclu_affinity.c
@@ -0,0 +1,84 @@
1#include <litmus/fdso.h>
2#include <litmus/sched_plugin.h>
3#include <litmus/trace.h>
4#include <litmus/litmus.h>
5#include <litmus/locking.h>
6
7#include <litmus/kexclu_affinity.h>
8
9static int create_generic_aff_obs(void** obj_ref, obj_type_t type, void* __user arg);
10static int open_generic_aff_obs(struct od_table_entry* entry, void* __user arg);
11static int close_generic_aff_obs(struct od_table_entry* entry);
12static void destroy_generic_aff_obs(obj_type_t type, void* sem);
13
14struct fdso_ops generic_affinity_ops = {
15 .create = create_generic_aff_obs,
16 .open = open_generic_aff_obs,
17 .close = close_generic_aff_obs,
18 .destroy = destroy_generic_aff_obs
19};
20
21static atomic_t aff_obs_id_gen = ATOMIC_INIT(0);
22
23static inline bool is_affinity_observer(struct od_table_entry *entry)
24{
25 return (entry->class == &generic_affinity_ops);
26}
27
28static inline struct affinity_observer* get_affinity_observer(struct od_table_entry* entry)
29{
30 BUG_ON(!is_affinity_observer(entry));
31 return (struct affinity_observer*) entry->obj->obj;
32}
33
34static int create_generic_aff_obs(void** obj_ref, obj_type_t type, void* __user arg)
35{
36 struct affinity_observer* aff_obs;
37 int err;
38
39 err = litmus->allocate_aff_obs(&aff_obs, type, arg);
40 if (err == 0) {
41 BUG_ON(!aff_obs->lock);
42 aff_obs->ident = atomic_inc_return(&aff_obs_id_gen);
43 *obj_ref = aff_obs;
44 }
45 return err;
46}
47
48static int open_generic_aff_obs(struct od_table_entry* entry, void* __user arg)
49{
50 struct affinity_observer* aff_obs = get_affinity_observer(entry);
51 if (aff_obs->ops->open)
52 return aff_obs->ops->open(aff_obs, arg);
53 else
54 return 0; /* default: any task can open it */
55}
56
57static int close_generic_aff_obs(struct od_table_entry* entry)
58{
59 struct affinity_observer* aff_obs = get_affinity_observer(entry);
60 if (aff_obs->ops->close)
61 return aff_obs->ops->close(aff_obs);
62 else
63 return 0; /* default: closing succeeds */
64}
65
66static void destroy_generic_aff_obs(obj_type_t type, void* obj)
67{
68 struct affinity_observer* aff_obs = (struct affinity_observer*) obj;
69 aff_obs->ops->deallocate(aff_obs);
70}
71
72
73struct litmus_lock* get_lock_from_od(int od)
74{
75 extern struct fdso_ops generic_lock_ops;
76
77 struct od_table_entry *entry = get_entry_for_od(od);
78
79 if(entry && entry->class == &generic_lock_ops) {
80 return (struct litmus_lock*) entry->obj->obj;
81 }
82 return NULL;
83}
84
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c
index 37294111bb0c..1440372227c6 100644
--- a/litmus/sched_gsn_edf.c
+++ b/litmus/sched_gsn_edf.c
@@ -1042,6 +1042,7 @@ static void __increase_priority_inheritance(struct task_struct* t,
1042 1042
1043#ifdef CONFIG_LITMUS_NESTED_LOCKING 1043#ifdef CONFIG_LITMUS_NESTED_LOCKING
1044 /* this sanity check allows for weaker locking in protocols */ 1044 /* this sanity check allows for weaker locking in protocols */
1045 /* TODO (klitirqd): Skip this check if 't' is a proxy thread (???) */
1045 if(__edf_higher_prio(prio_inh, BASE, t, EFFECTIVE)) { 1046 if(__edf_higher_prio(prio_inh, BASE, t, EFFECTIVE)) {
1046#endif 1047#endif
1047 TRACE_TASK(t, "inherits priority from %s/%d\n", 1048 TRACE_TASK(t, "inherits priority from %s/%d\n",
diff --git a/litmus/sched_plugin.c b/litmus/sched_plugin.c
index 24326ce4657e..de15e80743a8 100644
--- a/litmus/sched_plugin.c
+++ b/litmus/sched_plugin.c
@@ -188,6 +188,14 @@ static raw_spinlock_t* litmus_dummy_get_dgl_spinlock(struct task_struct *t)
188} 188}
189#endif 189#endif
190 190
191#ifdef CONFIG_LITMUS_AFFINITY_LOCKING
192static long litmus_dummy_allocate_aff_obs(struct affinity_observer **aff_obs,
193 int type,
194 void* __user config)
195{
196 return -ENXIO;
197}
198#endif
191 199
192 200
193/* The default scheduler plugin. It doesn't do anything and lets Linux do its 201/* The default scheduler plugin. It doesn't do anything and lets Linux do its
@@ -228,6 +236,10 @@ struct sched_plugin linux_sched_plugin = {
228#ifdef CONFIG_LITMUS_DGL_SUPPORT 236#ifdef CONFIG_LITMUS_DGL_SUPPORT
229 .get_dgl_spinlock = litmus_dummy_get_dgl_spinlock, 237 .get_dgl_spinlock = litmus_dummy_get_dgl_spinlock,
230#endif 238#endif
239#ifdef CONFIG_LITMUS_AFFINITY_LOCKING
240 .allocate_aff_obs = litmus_dummy_allocate_aff_obs,
241#endif
242
231 .admit_task = litmus_dummy_admit_task 243 .admit_task = litmus_dummy_admit_task
232}; 244};
233 245
@@ -286,6 +298,9 @@ int register_sched_plugin(struct sched_plugin* plugin)
286#ifdef CONFIG_LITMUS_DGL_SUPPORT 298#ifdef CONFIG_LITMUS_DGL_SUPPORT
287 CHECK(get_dgl_spinlock); 299 CHECK(get_dgl_spinlock);
288#endif 300#endif
301#ifdef CONFIG_LITMUS_AFFINITY_LOCKING
302 CHECK(allocate_aff_obs);
303#endif
289 CHECK(admit_task); 304 CHECK(admit_task);
290 305
291 if (!plugin->release_at) 306 if (!plugin->release_at)