* + sgi-altix-ia64-mmtimer-eliminate-long-interval-timer-holdoffs.patch added to -mm tree
@ 2010-10-07 22:43 akpm
0 siblings, 0 replies; only message in thread
From: akpm @ 2010-10-07 22:43 UTC (permalink / raw)
To: mm-commits; +Cc: sivanich, tony.luck
The patch titled
SGI Altix IA64 mmtimer: eliminate long interval timer holdoffs
has been added to the -mm tree. Its filename is
sgi-altix-ia64-mmtimer-eliminate-long-interval-timer-holdoffs.patch
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/SubmitChecklist when testing your code ***
See http://userweb.kernel.org/~akpm/stuff/added-to-mm.txt to find
out what to do about this
The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/
------------------------------------------------------
Subject: SGI Altix IA64 mmtimer: eliminate long interval timer holdoffs
From: Dimitri Sivanich <sivanich@sgi.com>
This patch for SGI Altix/IA64 eliminates interval long timer holdoffs in
cases where we don't start an interval timer before the expiration time.
This sometimes happens when a number of interval timers on the same shub
with the same interval run simultaneously.
Signed-off-by: Dimitri Sivanich <sivanich@sgi.com>
Cc: "Luck, Tony" <tony.luck@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
drivers/char/mmtimer.c | 55 +++++++++++++++++++--------------------
1 file changed, 27 insertions(+), 28 deletions(-)
diff -puN drivers/char/mmtimer.c~sgi-altix-ia64-mmtimer-eliminate-long-interval-timer-holdoffs drivers/char/mmtimer.c
--- a/drivers/char/mmtimer.c~sgi-altix-ia64-mmtimer-eliminate-long-interval-timer-holdoffs
+++ a/drivers/char/mmtimer.c
@@ -176,9 +176,8 @@ static void mmtimer_setup_int_2(int cpu,
* in order to insure that the setup succeeds in a deterministic time frame.
* It will check if the interrupt setup succeeded.
*/
-static int mmtimer_setup(int cpu, int comparator, unsigned long expires)
+static int mmtimer_setup(int cpu, int comparator, unsigned long expires, u64 *r)
{
-
switch (comparator) {
case 0:
mmtimer_setup_int_0(cpu, expires);
@@ -191,7 +190,8 @@ static int mmtimer_setup(int cpu, int co
break;
}
/* We might've missed our expiration time */
- if (rtc_time() <= expires)
+ *r = rtc_time();
+ if (*r <= expires)
return 1;
/*
@@ -227,6 +227,8 @@ static int mmtimer_disable_int(long nasi
#define TIMER_OFF 0xbadcabLL /* Timer is not setup */
#define TIMER_SET 0 /* Comparator is set for this timer */
+#define MMTIMER_INTRVL_RETRY_INCR_DEFAULT 40
+
/* There is one of these for each timer */
struct mmtimer {
struct rb_node list;
@@ -242,6 +244,10 @@ struct mmtimer_node {
};
static struct mmtimer_node *timers;
+static unsigned mmtimer_intrvl_retry_incr = MMTIMER_INTRVL_RETRY_INCR_DEFAULT;
+module_param(mmtimer_intrvl_retry_incr, uint, 0644);
+MODULE_PARM_DESC(mmtimer_intrvl_retry_incr,
+ "RTC ticks to add to expiration on interval retry (default 40)");
/*
* Add a new mmtimer struct to the node's mmtimer list.
@@ -289,7 +295,8 @@ static void mmtimer_set_next_timer(int n
struct mmtimer_node *n = &timers[nodeid];
struct mmtimer *x;
struct k_itimer *t;
- int o;
+ u64 expires, exp, r;
+ int i;
restart:
if (n->next == NULL)
@@ -300,7 +307,7 @@ restart:
if (!t->it.mmtimer.incr) {
/* Not an interval timer */
if (!mmtimer_setup(x->cpu, COMPARATOR,
- t->it.mmtimer.expires)) {
+ t->it.mmtimer.expires, &r)) {
/* Late setup, fire now */
tasklet_schedule(&n->tasklet);
}
@@ -308,14 +315,21 @@ restart:
}
/* Interval timer */
- o = 0;
- while (!mmtimer_setup(x->cpu, COMPARATOR, t->it.mmtimer.expires)) {
- unsigned long e, e1;
- struct rb_node *next;
- t->it.mmtimer.expires += t->it.mmtimer.incr << o;
- t->it_overrun += 1 << o;
- o++;
- if (o > 20) {
+ i = 0;
+ expires = exp = t->it.mmtimer.expires;
+ while (!mmtimer_setup(x->cpu, COMPARATOR, expires, &r)) {
+ int to;
+
+ i++;
+ expires = r + mmtimer_intrvl_retry_incr + (1 << i);
+ /* Calculate overruns as we go. */
+ to = ((u64)(expires - exp) / t->it.mmtimer.incr);
+ if (to) {
+ t->it_overrun += to;
+ t->it.mmtimer.expires += t->it.mmtimer.incr * to;
+ exp = t->it.mmtimer.expires;
+ }
+ if (i > 20) {
printk(KERN_ALERT "mmtimer: cannot reschedule timer\n");
t->it.mmtimer.clock = TIMER_OFF;
n->next = rb_next(&x->list);
@@ -323,21 +337,6 @@ restart:
kfree(x);
goto restart;
}
-
- e = t->it.mmtimer.expires;
- next = rb_next(&x->list);
-
- if (next == NULL)
- continue;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-10-07 22:43 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-07 22:43 + sgi-altix-ia64-mmtimer-eliminate-long-interval-timer-holdoffs.patch added to -mm tree akpm
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.