From 00b4b17dc1f65a1e5de4648200c826cc2eef37f4 Mon Sep 17 00:00:00 2001 From: Bjoern Brandenburg Date: Mon, 3 Sep 2012 14:51:31 +0200 Subject: Use user-provided irq count for TS_SYSCALL_IN_END To detect interrupts that interfered after the initial time stamp was recorded, this patch changes sched_trace to also record the IRQ count as observed by userspace. --- include/litmus/litmus.h | 19 +++++++++++++++++++ include/litmus/trace.h | 8 +++++++- litmus/trace.c | 21 +++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h index f7893ef18162..1cb3eaf25740 100644 --- a/include/litmus/litmus.h +++ b/include/litmus/litmus.h @@ -270,9 +270,28 @@ static inline int has_control_page(struct task_struct* t) } +#ifdef CONFIG_SCHED_OVERHEAD_TRACE + #define TS_SYSCALL_IN_START \ if (has_control_page(current)) { \ __TS_SYSCALL_IN_START(&get_control_page(current)->ts_syscall_start); \ } +#define TS_SYSCALL_IN_END \ + if (has_control_page(current)) { \ + uint64_t irqs; \ + local_irq_disable(); \ + irqs = get_control_page(current)->irq_count - \ + get_control_page(current)->irq_syscall_start; \ + __TS_SYSCALL_IN_END(&irqs); \ + local_irq_enable(); \ + } + +#else + +#define TS_SYSCALL_IN_START +#define TS_SYSCALL_IN_END + +#endif + #endif diff --git a/include/litmus/trace.h b/include/litmus/trace.h index ee55c2eca482..635dd8986bd4 100644 --- a/include/litmus/trace.h +++ b/include/litmus/trace.h @@ -34,6 +34,7 @@ feather_callback void save_timestamp_task(unsigned long event, unsigned long t_p feather_callback void save_timestamp_cpu(unsigned long event, unsigned long cpu); feather_callback void save_task_latency(unsigned long event, unsigned long when_ptr); feather_callback void save_timestamp_time(unsigned long event, unsigned long time_ptr); +feather_callback void save_timestamp_irq(unsigned long event, unsigned long irq_count_ptr); #define TIMESTAMP(id) ft_event0(id, save_timestamp) @@ -53,6 +54,9 @@ feather_callback void save_timestamp_time(unsigned long event, unsigned long tim #define TIMESTAMP_TIME(id, time_ptr) \ ft_event1(id, save_timestamp_time, (unsigned long) time_ptr) +#define TIMESTAMP_IRQ(id, irq_count_ptr) \ + ft_event1(id, save_timestamp_irq, (unsigned long) irq_count_ptr) + #else /* !CONFIG_SCHED_OVERHEAD_TRACE */ #define TIMESTAMP(id) /* no tracing */ @@ -69,6 +73,8 @@ feather_callback void save_timestamp_time(unsigned long event, unsigned long tim #define TIMESTAMP_TIME(id, time_ptr) /* no tracing */ +#define TIMESTAMP_IRQ(id, irq_count_ptr) /* no tracing */ + #endif @@ -81,7 +87,7 @@ feather_callback void save_timestamp_time(unsigned long event, unsigned long tim */ #define __TS_SYSCALL_IN_START(p) TIMESTAMP_TIME(10, p) -#define TS_SYSCALL_IN_END TIMESTAMP_CUR(11) +#define __TS_SYSCALL_IN_END(p) TIMESTAMP_IRQ(11, p) #define TS_SYSCALL_OUT_START TIMESTAMP_CUR(20) #define TS_SYSCALL_OUT_END TIMESTAMP_CUR(21) diff --git a/litmus/trace.c b/litmus/trace.c index c511003ea911..45cd662c021d 100644 --- a/litmus/trace.c +++ b/litmus/trace.c @@ -166,6 +166,27 @@ void save_timestamp_time(unsigned long event, } } +/* Record user-reported IRQ count */ +void save_timestamp_irq(unsigned long event, + unsigned long irq_counter_ptr) +{ + uint64_t* irqs = (uint64_t*) irq_counter_ptr; + unsigned int seq_no; + struct timestamp *ts; + seq_no = fetch_and_inc((int *) &ts_seq_no); + if (ft_buffer_start_write(trace_ts_buf, (void**) &ts)) { + ts->event = event; + ts->seq_no = seq_no; + ts->pid = current->pid; + ts->cpu = raw_smp_processor_id(); + ts->task_type = is_realtime(current) ? TSK_RT : TSK_BE; + ts->irq_count = *irqs; + ts->irq_flag = *irqs > 0; + ts->timestamp = ft_timestamp(); + ft_buffer_finish_write(trace_ts_buf, ts); + } +} + /******************************************************************************/ /* DEVICE FILE DRIVER */ /******************************************************************************/ -- cgit v1.2.2