diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2011-10-10 19:25:21 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2011-10-10 19:25:21 -0400 |
commit | 980c85219653614ebc0f6bb072e97dc09e0ef90f (patch) | |
tree | 8f2a3dcad2466a0d90ce725158f8916e2ef0909d | |
parent | 77870ba296b06385088f02516b7346fa7a7756b4 (diff) | |
parent | cdf72c79a135a993f0ad464b8fbc61f8e71948eb (diff) |
Merge branch 'wip-mc' of ssh://cvs.cs.unc.edu/cvs/proj/litmus/repo/litmus2010 into wip-mc
Conflicts:
include/litmus/trace.h
-rw-r--r-- | include/litmus/litmus.h | 14 | ||||
-rw-r--r-- | include/litmus/rt_param.h | 3 | ||||
-rw-r--r-- | include/litmus/trace.h | 39 | ||||
-rw-r--r-- | litmus/ftdev.c | 68 | ||||
-rw-r--r-- | litmus/locking.c | 16 | ||||
-rw-r--r-- | litmus/sched_litmus.c | 5 | ||||
-rw-r--r-- | litmus/trace.c | 30 |
7 files changed, 129 insertions, 46 deletions
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h index 2112eecd1dc8..4322d59c0e8f 100644 --- a/include/litmus/litmus.h +++ b/include/litmus/litmus.h | |||
@@ -129,6 +129,16 @@ void srp_ceiling_block(void); | |||
129 | 129 | ||
130 | #define bheap2task(hn) ((struct task_struct*) hn->value) | 130 | #define bheap2task(hn) ((struct task_struct*) hn->value) |
131 | 131 | ||
132 | static inline struct control_page* get_control_page(struct task_struct *t) | ||
133 | { | ||
134 | return tsk_rt(t)->ctrl_page; | ||
135 | } | ||
136 | |||
137 | static inline int has_control_page(struct task_struct* t) | ||
138 | { | ||
139 | return tsk_rt(t)->ctrl_page != NULL; | ||
140 | } | ||
141 | |||
132 | #ifdef CONFIG_NP_SECTION | 142 | #ifdef CONFIG_NP_SECTION |
133 | 143 | ||
134 | static inline int is_kernel_np(struct task_struct *t) | 144 | static inline int is_kernel_np(struct task_struct *t) |
@@ -244,4 +254,8 @@ static inline quanta_t time2quanta(lt_t time, enum round round) | |||
244 | /* By how much is cpu staggered behind CPU 0? */ | 254 | /* By how much is cpu staggered behind CPU 0? */ |
245 | u64 cpu_stagger_offset(int cpu); | 255 | u64 cpu_stagger_offset(int cpu); |
246 | 256 | ||
257 | #define TS_SYSCALL_IN_START \ | ||
258 | if (has_control_page(current)) \ | ||
259 | __TS_SYSCALL_IN_START(&get_control_page(current)->ts_syscall_start); | ||
260 | |||
247 | #endif | 261 | #endif |
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index e6288e8807f0..221edad83d77 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h | |||
@@ -63,6 +63,9 @@ struct control_page { | |||
63 | * its non-preemptive section? */ | 63 | * its non-preemptive section? */ |
64 | int delayed_preemption; | 64 | int delayed_preemption; |
65 | 65 | ||
66 | /* locking overhead tracing: time stamp prior to system call */ | ||
67 | uint64_t ts_syscall_start; /* Feather-Trace cycles */ | ||
68 | |||
66 | /* to be extended */ | 69 | /* to be extended */ |
67 | }; | 70 | }; |
68 | 71 | ||
diff --git a/include/litmus/trace.h b/include/litmus/trace.h index 95e1ee647a8a..d6829c416912 100644 --- a/include/litmus/trace.h +++ b/include/litmus/trace.h | |||
@@ -28,7 +28,8 @@ feather_callback void save_timestamp(unsigned long event); | |||
28 | feather_callback void save_timestamp_def(unsigned long event, unsigned long type); | 28 | feather_callback void save_timestamp_def(unsigned long event, unsigned long type); |
29 | feather_callback void save_timestamp_task(unsigned long event, unsigned long t_ptr); | 29 | feather_callback void save_timestamp_task(unsigned long event, unsigned long t_ptr); |
30 | feather_callback void save_timestamp_cpu(unsigned long event, unsigned long cpu); | 30 | feather_callback void save_timestamp_cpu(unsigned long event, unsigned long cpu); |
31 | 31 | feather_callback void save_task_latency(unsigned long event, unsigned long when_ptr); | |
32 | feather_callback void save_timestamp_time(unsigned long event, unsigned long time_ptr); | ||
32 | 33 | ||
33 | #define TIMESTAMP(id) ft_event0(id, save_timestamp) | 34 | #define TIMESTAMP(id) ft_event0(id, save_timestamp) |
34 | 35 | ||
@@ -40,6 +41,14 @@ feather_callback void save_timestamp_cpu(unsigned long event, unsigned long cpu) | |||
40 | #define CTIMESTAMP(id, cpu) \ | 41 | #define CTIMESTAMP(id, cpu) \ |
41 | ft_event1(id, save_timestamp_cpu, (unsigned long) cpu) | 42 | ft_event1(id, save_timestamp_cpu, (unsigned long) cpu) |
42 | 43 | ||
44 | #define LTIMESTAMP(id, task) \ | ||
45 | ft_event1(id, save_task_latency, (unsigned long) task) | ||
46 | |||
47 | #define TIMESTAMP_TIME(id, time_ptr) \ | ||
48 | ft_event1(id, save_timestamp_time, (unsigned long) time_ptr) | ||
49 | |||
50 | #define TIMESTAMP_PID(id) ft_event0(id, save_timestamp_pid) | ||
51 | |||
43 | #else /* !CONFIG_SCHED_OVERHEAD_TRACE */ | 52 | #else /* !CONFIG_SCHED_OVERHEAD_TRACE */ |
44 | 53 | ||
45 | #define TIMESTAMP(id) /* no tracing */ | 54 | #define TIMESTAMP(id) /* no tracing */ |
@@ -50,6 +59,12 @@ feather_callback void save_timestamp_cpu(unsigned long event, unsigned long cpu) | |||
50 | 59 | ||
51 | #define CTIMESTAMP(id, cpu) /* no tracing */ | 60 | #define CTIMESTAMP(id, cpu) /* no tracing */ |
52 | 61 | ||
62 | #define LTIMESTAMP(id, when_ptr) /* no tracing */ | ||
63 | |||
64 | #define TIMESTAMP_TIME(id, time_ptr) /* no tracing */ | ||
65 | |||
66 | #define TIMESTAMP_PID(id) /* no tracing */ | ||
67 | |||
53 | #endif | 68 | #endif |
54 | 69 | ||
55 | 70 | ||
@@ -61,6 +76,21 @@ feather_callback void save_timestamp_cpu(unsigned long event, unsigned long cpu) | |||
61 | * always the next number after the start time event id. | 76 | * always the next number after the start time event id. |
62 | */ | 77 | */ |
63 | 78 | ||
79 | #define __TS_SYSCALL_IN_START(p) TIMESTAMP_TIME(10, p) | ||
80 | #define TS_SYSCALL_IN_END TIMESTAMP_PID(11) | ||
81 | |||
82 | #define TS_SYSCALL_OUT_START TIMESTAMP_PID(20) | ||
83 | #define TS_SYSCALL_OUT_END TIMESTAMP_PID(21) | ||
84 | |||
85 | #define TS_LOCK_START TIMESTAMP_PID(30) | ||
86 | #define TS_LOCK_END TIMESTAMP_PID(31) | ||
87 | |||
88 | #define TS_LOCK_SUSPEND TIMESTAMP_PID(38) | ||
89 | #define TS_LOCK_RESUME TIMESTAMP_PID(39) | ||
90 | |||
91 | #define TS_UNLOCK_START TIMESTAMP_PID(40) | ||
92 | #define TS_UNLOCK_END TIMESTAMP_PID(41) | ||
93 | |||
64 | #define TS_SCHED_START DTIMESTAMP(100, TSK_UNKNOWN) /* we only | 94 | #define TS_SCHED_START DTIMESTAMP(100, TSK_UNKNOWN) /* we only |
65 | * care | 95 | * care |
66 | * about | 96 | * about |
@@ -91,12 +121,9 @@ feather_callback void save_timestamp_cpu(unsigned long event, unsigned long cpu) | |||
91 | #define TS_EXIT_NP_START TIMESTAMP(150) | 121 | #define TS_EXIT_NP_START TIMESTAMP(150) |
92 | #define TS_EXIT_NP_END TIMESTAMP(151) | 122 | #define TS_EXIT_NP_END TIMESTAMP(151) |
93 | 123 | ||
94 | #define TS_LOCK_START TIMESTAMP(170) | ||
95 | #define TS_LOCK_END TIMESTAMP(171) | ||
96 | #define TS_UNLOCK_START TIMESTAMP(172) | ||
97 | #define TS_UNLOCK_END TIMESTAMP(173) | ||
98 | |||
99 | #define TS_SEND_RESCHED_START(c) CTIMESTAMP(190, c) | 124 | #define TS_SEND_RESCHED_START(c) CTIMESTAMP(190, c) |
100 | #define TS_SEND_RESCHED_END DTIMESTAMP(191, TSK_UNKNOWN) | 125 | #define TS_SEND_RESCHED_END DTIMESTAMP(191, TSK_UNKNOWN) |
101 | 126 | ||
127 | #define TS_RELEASE_LATENCY(when) LTIMESTAMP(208, &(when)) | ||
128 | |||
102 | #endif /* !_SYS_TRACE_H_ */ | 129 | #endif /* !_SYS_TRACE_H_ */ |
diff --git a/litmus/ftdev.c b/litmus/ftdev.c index 4a4b2e3e56c2..e282f8a9c067 100644 --- a/litmus/ftdev.c +++ b/litmus/ftdev.c | |||
@@ -229,13 +229,20 @@ static ssize_t ftdev_read(struct file *filp, | |||
229 | * here with copied data because that data would get | 229 | * here with copied data because that data would get |
230 | * lost if the task is interrupted (e.g., killed). | 230 | * lost if the task is interrupted (e.g., killed). |
231 | */ | 231 | */ |
232 | mutex_unlock(&ftdm->lock); | ||
232 | set_current_state(TASK_INTERRUPTIBLE); | 233 | set_current_state(TASK_INTERRUPTIBLE); |
234 | |||
233 | schedule_timeout(50); | 235 | schedule_timeout(50); |
236 | |||
234 | if (signal_pending(current)) { | 237 | if (signal_pending(current)) { |
235 | if (err == 0) | 238 | if (err == 0) |
236 | /* nothing read yet, signal problem */ | 239 | /* nothing read yet, signal problem */ |
237 | err = -ERESTARTSYS; | 240 | err = -ERESTARTSYS; |
238 | break; | 241 | goto out; |
242 | } | ||
243 | if (mutex_lock_interruptible(&ftdm->lock)) { | ||
244 | err = -ERESTARTSYS; | ||
245 | goto out; | ||
239 | } | 246 | } |
240 | } else if (copied < 0) { | 247 | } else if (copied < 0) { |
241 | /* page fault */ | 248 | /* page fault */ |
@@ -250,64 +257,47 @@ out: | |||
250 | return err; | 257 | return err; |
251 | } | 258 | } |
252 | 259 | ||
253 | typedef uint32_t cmd_t; | 260 | static long ftdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
254 | |||
255 | static ssize_t ftdev_write(struct file *filp, const char __user *from, | ||
256 | size_t len, loff_t *f_pos) | ||
257 | { | 261 | { |
262 | long err = -ENOIOCTLCMD; | ||
258 | struct ftdev_minor* ftdm = filp->private_data; | 263 | struct ftdev_minor* ftdm = filp->private_data; |
259 | ssize_t err = -EINVAL; | ||
260 | cmd_t cmd; | ||
261 | cmd_t id; | ||
262 | |||
263 | if (len % sizeof(cmd) || len < 2 * sizeof(cmd)) | ||
264 | goto out; | ||
265 | |||
266 | if (copy_from_user(&cmd, from, sizeof(cmd))) { | ||
267 | err = -EFAULT; | ||
268 | goto out; | ||
269 | } | ||
270 | len -= sizeof(cmd); | ||
271 | from += sizeof(cmd); | ||
272 | |||
273 | if (cmd != FTDEV_ENABLE_CMD && cmd != FTDEV_DISABLE_CMD) | ||
274 | goto out; | ||
275 | 264 | ||
276 | if (mutex_lock_interruptible(&ftdm->lock)) { | 265 | if (mutex_lock_interruptible(&ftdm->lock)) { |
277 | err = -ERESTARTSYS; | 266 | err = -ERESTARTSYS; |
278 | goto out; | 267 | goto out; |
279 | } | 268 | } |
280 | 269 | ||
281 | err = sizeof(cmd); | 270 | /* FIXME: check id against list of acceptable events */ |
282 | while (len) { | 271 | |
283 | if (copy_from_user(&id, from, sizeof(cmd))) { | 272 | switch (cmd) { |
284 | err = -EFAULT; | 273 | case FTDEV_ENABLE_CMD: |
285 | goto out_unlock; | 274 | if (activate(&ftdm->events, arg)) |
286 | } | ||
287 | /* FIXME: check id against list of acceptable events */ | ||
288 | len -= sizeof(cmd); | ||
289 | from += sizeof(cmd); | ||
290 | if (cmd == FTDEV_DISABLE_CMD) | ||
291 | deactivate(&ftdm->events, id); | ||
292 | else if (activate(&ftdm->events, id) != 0) { | ||
293 | err = -ENOMEM; | 275 | err = -ENOMEM; |
294 | goto out_unlock; | 276 | else |
295 | } | 277 | err = 0; |
296 | err += sizeof(cmd); | 278 | break; |
297 | } | 279 | |
280 | case FTDEV_DISABLE_CMD: | ||
281 | deactivate(&ftdm->events, arg); | ||
282 | err = 0; | ||
283 | break; | ||
284 | |||
285 | default: | ||
286 | printk(KERN_DEBUG "ftdev: strange ioctl (%u, %lu)\n", cmd, arg); | ||
287 | }; | ||
298 | 288 | ||
299 | out_unlock: | ||
300 | mutex_unlock(&ftdm->lock); | 289 | mutex_unlock(&ftdm->lock); |
301 | out: | 290 | out: |
302 | return err; | 291 | return err; |
303 | } | 292 | } |
304 | 293 | ||
294 | |||
305 | struct file_operations ftdev_fops = { | 295 | struct file_operations ftdev_fops = { |
306 | .owner = THIS_MODULE, | 296 | .owner = THIS_MODULE, |
307 | .open = ftdev_open, | 297 | .open = ftdev_open, |
308 | .release = ftdev_release, | 298 | .release = ftdev_release, |
309 | .write = ftdev_write, | ||
310 | .read = ftdev_read, | 299 | .read = ftdev_read, |
300 | .unlocked_ioctl = ftdev_ioctl, | ||
311 | }; | 301 | }; |
312 | 302 | ||
313 | int ftdev_init( struct ftdev* ftdev, struct module* owner, | 303 | int ftdev_init( struct ftdev* ftdev, struct module* owner, |
diff --git a/litmus/locking.c b/litmus/locking.c index 728b56835cf7..bc4150804250 100644 --- a/litmus/locking.c +++ b/litmus/locking.c | |||
@@ -1,3 +1,5 @@ | |||
1 | #include <linux/sched.h> | ||
2 | #include <litmus/litmus.h> | ||
1 | #include <litmus/fdso.h> | 3 | #include <litmus/fdso.h> |
2 | 4 | ||
3 | #ifdef CONFIG_LITMUS_LOCKING | 5 | #ifdef CONFIG_LITMUS_LOCKING |
@@ -69,6 +71,10 @@ asmlinkage long sys_litmus_lock(int lock_od) | |||
69 | struct od_table_entry* entry; | 71 | struct od_table_entry* entry; |
70 | struct litmus_lock* l; | 72 | struct litmus_lock* l; |
71 | 73 | ||
74 | TS_SYSCALL_IN_START; | ||
75 | |||
76 | TS_SYSCALL_IN_END; | ||
77 | |||
72 | TS_LOCK_START; | 78 | TS_LOCK_START; |
73 | 79 | ||
74 | entry = get_entry_for_od(lock_od); | 80 | entry = get_entry_for_od(lock_od); |
@@ -80,7 +86,9 @@ asmlinkage long sys_litmus_lock(int lock_od) | |||
80 | 86 | ||
81 | /* Note: task my have been suspended or preempted in between! Take | 87 | /* Note: task my have been suspended or preempted in between! Take |
82 | * this into account when computing overheads. */ | 88 | * this into account when computing overheads. */ |
83 | TS_UNLOCK_END; | 89 | TS_LOCK_END; |
90 | |||
91 | TS_SYSCALL_OUT_START; | ||
84 | 92 | ||
85 | return err; | 93 | return err; |
86 | } | 94 | } |
@@ -91,6 +99,10 @@ asmlinkage long sys_litmus_unlock(int lock_od) | |||
91 | struct od_table_entry* entry; | 99 | struct od_table_entry* entry; |
92 | struct litmus_lock* l; | 100 | struct litmus_lock* l; |
93 | 101 | ||
102 | TS_SYSCALL_IN_START; | ||
103 | |||
104 | TS_SYSCALL_IN_END; | ||
105 | |||
94 | TS_UNLOCK_START; | 106 | TS_UNLOCK_START; |
95 | 107 | ||
96 | entry = get_entry_for_od(lock_od); | 108 | entry = get_entry_for_od(lock_od); |
@@ -104,6 +116,8 @@ asmlinkage long sys_litmus_unlock(int lock_od) | |||
104 | * account when computing overheads. */ | 116 | * account when computing overheads. */ |
105 | TS_UNLOCK_END; | 117 | TS_UNLOCK_END; |
106 | 118 | ||
119 | TS_SYSCALL_OUT_START; | ||
120 | |||
107 | return err; | 121 | return err; |
108 | } | 122 | } |
109 | 123 | ||
diff --git a/litmus/sched_litmus.c b/litmus/sched_litmus.c index e6952896dc4b..0687be0c8a78 100644 --- a/litmus/sched_litmus.c +++ b/litmus/sched_litmus.c | |||
@@ -194,6 +194,9 @@ static void dequeue_task_litmus(struct rq *rq, struct task_struct *p, | |||
194 | 194 | ||
195 | static void yield_task_litmus(struct rq *rq) | 195 | static void yield_task_litmus(struct rq *rq) |
196 | { | 196 | { |
197 | TS_SYSCALL_IN_START; | ||
198 | |||
199 | TS_SYSCALL_OUT_END; | ||
197 | BUG_ON(rq->curr != current); | 200 | BUG_ON(rq->curr != current); |
198 | /* sched_yield() is called to trigger delayed preemptions. | 201 | /* sched_yield() is called to trigger delayed preemptions. |
199 | * Thus, mark the current task as needing to be rescheduled. | 202 | * Thus, mark the current task as needing to be rescheduled. |
@@ -202,6 +205,8 @@ static void yield_task_litmus(struct rq *rq) | |||
202 | */ | 205 | */ |
203 | clear_exit_np(current); | 206 | clear_exit_np(current); |
204 | litmus_reschedule_local(); | 207 | litmus_reschedule_local(); |
208 | |||
209 | TS_SYSCALL_OUT_START; | ||
205 | } | 210 | } |
206 | 211 | ||
207 | /* Plugins are responsible for this. | 212 | /* Plugins are responsible for this. |
diff --git a/litmus/trace.c b/litmus/trace.c index e7ea1c2ab3e4..49f8246cda50 100644 --- a/litmus/trace.c +++ b/litmus/trace.c | |||
@@ -37,6 +37,36 @@ static inline void __save_timestamp(unsigned long event, | |||
37 | __save_timestamp_cpu(event, type, raw_smp_processor_id()); | 37 | __save_timestamp_cpu(event, type, raw_smp_processor_id()); |
38 | } | 38 | } |
39 | 39 | ||
40 | /* hack: fake timestamp to user-reported time, and record parts of the PID */ | ||
41 | feather_callback void save_timestamp_time(unsigned long event, unsigned long ptr) | ||
42 | { | ||
43 | uint64_t* time = (uint64_t*) ptr; | ||
44 | unsigned int seq_no; | ||
45 | struct timestamp *ts; | ||
46 | seq_no = fetch_and_inc((int *) &ts_seq_no); | ||
47 | if (ft_buffer_start_write(trace_ts_buf, (void**) &ts)) { | ||
48 | ts->event = event; | ||
49 | ts->timestamp = *time; | ||
50 | ts->seq_no = seq_no; | ||
51 | /* type takes lowest byte of PID */ | ||
52 | ts->task_type = (uint8_t) current->pid; | ||
53 | /* cpu takes second-lowest byte of PID*/ | ||
54 | ts->cpu = (uint8_t) (current->pid >> 8); | ||
55 | |||
56 | ft_buffer_finish_write(trace_ts_buf, ts); | ||
57 | } | ||
58 | } | ||
59 | |||
60 | feather_callback void save_timestamp_pid(unsigned long event) | ||
61 | { | ||
62 | /* Abuse existing fields to partially export PID. */ | ||
63 | __save_timestamp_cpu(event, | ||
64 | /* type takes lowest byte of PID */ | ||
65 | (uint8_t) current->pid, | ||
66 | /* cpu takes second-lowest byte of PID*/ | ||
67 | (uint8_t) (current->pid >> 8)); | ||
68 | } | ||
69 | |||
40 | feather_callback void save_timestamp(unsigned long event) | 70 | feather_callback void save_timestamp(unsigned long event) |
41 | { | 71 | { |
42 | __save_timestamp(event, TSK_UNKNOWN); | 72 | __save_timestamp(event, TSK_UNKNOWN); |