aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2011-10-10 19:25:21 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2011-10-10 19:25:21 -0400
commit980c85219653614ebc0f6bb072e97dc09e0ef90f (patch)
tree8f2a3dcad2466a0d90ce725158f8916e2ef0909d
parent77870ba296b06385088f02516b7346fa7a7756b4 (diff)
parentcdf72c79a135a993f0ad464b8fbc61f8e71948eb (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.h14
-rw-r--r--include/litmus/rt_param.h3
-rw-r--r--include/litmus/trace.h39
-rw-r--r--litmus/ftdev.c68
-rw-r--r--litmus/locking.c16
-rw-r--r--litmus/sched_litmus.c5
-rw-r--r--litmus/trace.c30
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
132static inline struct control_page* get_control_page(struct task_struct *t)
133{
134 return tsk_rt(t)->ctrl_page;
135}
136
137static 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
134static inline int is_kernel_np(struct task_struct *t) 144static 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? */
245u64 cpu_stagger_offset(int cpu); 255u64 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);
28feather_callback void save_timestamp_def(unsigned long event, unsigned long type); 28feather_callback void save_timestamp_def(unsigned long event, unsigned long type);
29feather_callback void save_timestamp_task(unsigned long event, unsigned long t_ptr); 29feather_callback void save_timestamp_task(unsigned long event, unsigned long t_ptr);
30feather_callback void save_timestamp_cpu(unsigned long event, unsigned long cpu); 30feather_callback void save_timestamp_cpu(unsigned long event, unsigned long cpu);
31 31feather_callback void save_task_latency(unsigned long event, unsigned long when_ptr);
32feather_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
253typedef uint32_t cmd_t; 260static long ftdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
254
255static 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
299out_unlock:
300 mutex_unlock(&ftdm->lock); 289 mutex_unlock(&ftdm->lock);
301out: 290out:
302 return err; 291 return err;
303} 292}
304 293
294
305struct file_operations ftdev_fops = { 295struct 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
313int ftdev_init( struct ftdev* ftdev, struct module* owner, 303int 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
195static void yield_task_litmus(struct rq *rq) 195static 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 */
41feather_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
60feather_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
40feather_callback void save_timestamp(unsigned long event) 70feather_callback void save_timestamp(unsigned long event)
41{ 71{
42 __save_timestamp(event, TSK_UNKNOWN); 72 __save_timestamp(event, TSK_UNKNOWN);