lkml.org 
[lkml]   [2004]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
SubjectRe: [patch] Real-Time Preemption, -RT-2.6.9-mm1-V0
From
Date
On Wed, 2004-10-27 at 12:21 -0500, K.R. Foley wrote:
> >
> > Anyway I am generating a cleaned up version of the patch agaqinst
> > 2.6.9-mm1.
> >
> > Lee
> >
>
> Actually if you are cleaning it up anyway, could you fix it to work with
> Ingo's changes to rtc.c? If not I will be glad to do it. Up until one of
> the last couple of versions of RT PREEMPT it applied cleanly, but I just
> tried it and it failed.

Yup, here it is against 2.6.9-mm1-V0.4.1. Not yet tested (building now)
but should work. I took out the show_trace_smp part because that never
worked, I always get "Stack pointer is garbage". So now the patch is
smaller and only touches rtc.c.

--- linux-2.6.9-mm1/drivers/char/rtc.c 2004-10-27 13:19:04.000000000 -0400
+++ linux-2.6.9-mm1-V0.4.1/drivers/char/rtc.c 2004-10-27 12:55:23.000000000 -0400
@@ -86,6 +86,18 @@
#include <asm/hpet.h>
#endif

+static unsigned long long last_interrupt_time;
+
+#include <asm/timex.h>
+
+
+#define CPU_MHZ (cpu_khz / 1000)
+#define HISTSIZE 10000
+static int histogram[HISTSIZE];
+
+int rtc_debug;
+int rtc_running;
+
#ifdef __sparc__
#include <linux/pci.h>
#include <asm/ebus.h>
@@ -191,6 +203,14 @@
static const unsigned char days_in_mo[] =
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

+static int rtc_state;
+
+enum rtc_states {
+ S_IDLE, /* Waiting for an interrupt */
+ S_WAITING_FOR_READ, /* Signal delivered. waiting for rtc_read() */
+ S_READ_MISSED, /* Signal delivered, read() deadline missed */
+};
+
/*
* Returns true if a clock update is in progress
*/
@@ -259,7 +279,36 @@
spin_unlock_irqrestore(&rtc_task_lock, flags);
wake_up_interruptible(&rtc_wait);

- kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
+ if (!(rtc_status & RTC_IS_OPEN))
+ goto tata;
+
+ switch (rtc_state) {
+ case S_IDLE: /* Waiting for an interrupt */
+ rdtscll(last_interrupt_time);
+ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
+ rtc_state = S_WAITING_FOR_READ;
+ break;
+ case S_WAITING_FOR_READ: /* Signal has been delivered. waiting for rtc_read() */
+ /*
+ * Well foo. The usermode application didn't schedule and read in time.
+ */
+ rtc_state = S_READ_MISSED;
+ if (strcmp(current->comm, "amlat") != 0) {
+ printk("`%s'[%d] is being piggy. "
+ "need_resched=%d, cpu=%d\n",
+ current->comm, current->pid,
+ need_resched(), smp_processor_id());
+ /* show_trace_smp(); */
+ }
+ break;
+ case S_READ_MISSED: /* Signal has been delivered, read() deadline was missed */
+ /*
+ * Not much we can do here. We're waiting for the usermode
+ * application to read the rtc
+ */
+ break;
+ }
+tata:

return IRQ_HANDLED;
}
@@ -319,8 +368,74 @@
* Now all the various file operations that we export.
*/

-static ssize_t rtc_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t ll_rtc_read(struct file *file, char *buf,
+ size_t count, loff_t *ppos)
+{
+ ssize_t retval;
+ unsigned long long now;
+
+ rdtscll(now);
+
+ switch (rtc_state) {
+ case S_IDLE: /* Waiting for an interrupt */
+ /*
+ * err... This can't be happening
+ */
+ printk("ll_rtc_read(): called in state S_IDLE!\n");
+ break;
+ case S_WAITING_FOR_READ: /*
+ * Signal has been delivered.
+ * waiting for rtc_read()
+ */
+ /*
+ * Well done
+ */
+ case S_READ_MISSED: /*
+ * Signal has been delivered, read()
+ * deadline was missed
+ */
+ /*
+ * So, you finally got here.
+ */
+ if (last_interrupt_time == 0)
+ printk("ll_rtc_read(): we screwed up. "
+ "last_interrupt_time = 0\n");
+ rtc_state = S_IDLE;
+ {
+ unsigned long long latency = now - last_interrupt_time;
+ unsigned long delta; /* Nocroseconds */
+
+ delta = latency;
+ delta /= CPU_MHZ;
+ if (delta > 1000 * 1000) {
+ printk("rtc: eek\n");
+ } else {
+ unsigned long slot = delta;
+ if (slot >= HISTSIZE)
+ slot = HISTSIZE - 1;
+ histogram[slot]++;
+ if (delta > 2000)
+ printk("wow! That was a "
+ "%ld millisec bump\n",
+ delta / 1000);
+ }
+ }
+ rtc_state = S_IDLE;
+ break;
+ }
+
+ if (count < sizeof(last_interrupt_time))
+ return -EINVAL;
+
+ retval = -EIO;
+ if (copy_to_user(buf, &last_interrupt_time,
+ sizeof(last_interrupt_time)) == 0)
+ retval = sizeof(last_interrupt_time);
+ return retval;
+}
+
+static ssize_t orig_rtc_read(struct file *file, char *buf,
+ size_t count, loff_t *ppos)
{
#ifndef RTC_IRQ
return -EIO;
@@ -375,6 +490,19 @@
#endif
}

+/*
+ * If anyone reads this, please send me an email describing
+ * the superlative elegance of this conception
+ */
+static ssize_t rtc_read(struct file *file, char *buf,
+ size_t count, loff_t *ppos)
+{
+ if (strcmp(current->comm, "amlat") == 0)
+ return ll_rtc_read(file, buf, count, ppos);
+ else
+ return orig_rtc_read(file, buf, count, ppos);
+}
+
static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
{
struct rtc_time wtime;
@@ -692,6 +820,8 @@
* needed here. Or anywhere else in this driver. */
static int rtc_open(struct inode *inode, struct file *file)
{
+ int i;
+
spin_lock_irq (&rtc_lock);

if(rtc_status & RTC_IS_OPEN)
@@ -699,7 +829,16 @@

rtc_status |= RTC_IS_OPEN;

- rtc_irq_data = 0;
+ if (strcmp(current->comm, "amlat") == 0) {
+ last_interrupt_time = 0;
+ rtc_state = S_IDLE;
+ rtc_irq_data = 0;
+ }
+
+ rtc_running = 1;
+ for (i = 0; i < HISTSIZE; i++)
+ histogram[i] = 0;
+
spin_unlock_irq (&rtc_lock);
return 0;

@@ -753,6 +892,19 @@
rtc_irq_data = 0;
rtc_status &= ~RTC_IS_OPEN;
spin_unlock_irq (&rtc_lock);
+ {
+ int i = 0;
+ unsigned long total = 0;
+ printk("rtc histogram:\n");
+ for (i = 0; i < HISTSIZE; i++) {
+ if (histogram[i]) {
+ total += histogram[i];
+ printk("%d %d\n", i, histogram[i]);
+ }
+ }
+ printk("\nTotal samples: %lu\n", total);
+ rtc_running = 0;
+ }
return 0;
}

@@ -1127,6 +1279,7 @@
wake_up_interruptible(&rtc_wait);

kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
+ return;
}
#endif




-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:07    [W:0.457 / U:1.236 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site