mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: tglx@linutronix.de
To: linux-kernel@vger.kernel.org
Cc: akpm@osdl.org, rostedt@goodmis.org, johnstul@us.ibm.com,
	zippel@linux-m86k.org, mingo@elte.hu
Subject: [patch 17/21] Switch itimers to hrtimer
Date: Tue, 06 Dec 2005 01:01:43 +0100	[thread overview]
Message-ID: <20051206000155.185937000@tglx.tec.linutronix.de> (raw)
In-Reply-To: <20051206000126.589223000@tglx.tec.linutronix.de>

[-- Attachment #1: hrtimer-convert-itimer.patch --]
[-- Type: text/plain, Size: 9316 bytes --]


- switch itimers to a hrtimers-based implementation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

 fs/exec.c             |    6 +-
 fs/proc/array.c       |    6 +-
 include/linux/sched.h |    5 +-
 include/linux/timer.h |    2 
 kernel/exit.c         |    2 
 kernel/fork.c         |    6 +-
 kernel/itimer.c       |  108 ++++++++++++++++++++++++--------------------------
 7 files changed, 66 insertions(+), 69 deletions(-)

Index: linux-2.6.15-rc5/fs/exec.c
===================================================================
--- linux-2.6.15-rc5.orig/fs/exec.c
+++ linux-2.6.15-rc5/fs/exec.c
@@ -632,10 +632,10 @@ static inline int de_thread(struct task_
 		 * synchronize with any firing (by calling del_timer_sync)
 		 * before we can safely let the old group leader die.
 		 */
-		sig->real_timer.data = (unsigned long)current;
+		sig->real_timer.data = current;
 		spin_unlock_irq(lock);
-		if (del_timer_sync(&sig->real_timer))
-			add_timer(&sig->real_timer);
+		if (hrtimer_cancel(&sig->real_timer))
+			hrtimer_restart(&sig->real_timer);
 		spin_lock_irq(lock);
 	}
 	while (atomic_read(&sig->count) > count) {
Index: linux-2.6.15-rc5/fs/proc/array.c
===================================================================
--- linux-2.6.15-rc5.orig/fs/proc/array.c
+++ linux-2.6.15-rc5/fs/proc/array.c
@@ -330,7 +330,7 @@ static int do_task_stat(struct task_stru
 	unsigned long  min_flt = 0,  maj_flt = 0;
 	cputime_t cutime, cstime, utime, stime;
 	unsigned long rsslim = 0;
-	unsigned long it_real_value = 0;
+	DEFINE_KTIME(it_real_value);
 	struct task_struct *t;
 	char tcomm[sizeof(task->comm)];
 
@@ -386,7 +386,7 @@ static int do_task_stat(struct task_stru
 			utime = cputime_add(utime, task->signal->utime);
 			stime = cputime_add(stime, task->signal->stime);
 		}
-		it_real_value = task->signal->it_real_value;
+		it_real_value = task->signal->real_timer.expires;
 	}
 	ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
 	read_unlock(&tasklist_lock);
@@ -435,7 +435,7 @@ static int do_task_stat(struct task_stru
 		priority,
 		nice,
 		num_threads,
-		jiffies_to_clock_t(it_real_value),
+		(long) ktime_to_clock_t(it_real_value),
 		start_time,
 		vsize,
 		mm ? get_mm_rss(mm) : 0,
Index: linux-2.6.15-rc5/include/linux/sched.h
===================================================================
--- linux-2.6.15-rc5.orig/include/linux/sched.h
+++ linux-2.6.15-rc5/include/linux/sched.h
@@ -104,6 +104,7 @@ extern unsigned long nr_iowait(void);
 #include <linux/param.h>
 #include <linux/resource.h>
 #include <linux/timer.h>
+#include <linux/hrtimer.h>
 
 #include <asm/processor.h>
 
@@ -402,8 +403,8 @@ struct signal_struct {
 	struct list_head posix_timers;
 
 	/* ITIMER_REAL timer for the process */
-	struct timer_list real_timer;
-	unsigned long it_real_value, it_real_incr;
+	struct hrtimer real_timer;
+	ktime_t it_real_incr;
 
 	/* ITIMER_PROF and ITIMER_VIRTUAL timers for the process */
 	cputime_t it_prof_expires, it_virt_expires;
Index: linux-2.6.15-rc5/include/linux/timer.h
===================================================================
--- linux-2.6.15-rc5.orig/include/linux/timer.h
+++ linux-2.6.15-rc5/include/linux/timer.h
@@ -96,6 +96,6 @@ static inline void add_timer(struct time
 
 extern void init_timers(void);
 extern void run_local_timers(void);
-extern void it_real_fn(unsigned long);
+extern int it_real_fn(void *);
 
 #endif
Index: linux-2.6.15-rc5/kernel/exit.c
===================================================================
--- linux-2.6.15-rc5.orig/kernel/exit.c
+++ linux-2.6.15-rc5/kernel/exit.c
@@ -842,7 +842,7 @@ fastcall NORET_TYPE void do_exit(long co
 	}
 	group_dead = atomic_dec_and_test(&tsk->signal->live);
 	if (group_dead) {
- 		del_timer_sync(&tsk->signal->real_timer);
+ 		hrtimer_cancel(&tsk->signal->real_timer);
 		exit_itimers(tsk->signal);
 		acct_process(code);
 	}
Index: linux-2.6.15-rc5/kernel/fork.c
===================================================================
--- linux-2.6.15-rc5.orig/kernel/fork.c
+++ linux-2.6.15-rc5/kernel/fork.c
@@ -793,10 +793,10 @@ static inline int copy_signal(unsigned l
 	init_sigpending(&sig->shared_pending);
 	INIT_LIST_HEAD(&sig->posix_timers);
 
-	sig->it_real_value = sig->it_real_incr = 0;
+	hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC);
+	sig->it_real_incr.tv64 = 0;
 	sig->real_timer.function = it_real_fn;
-	sig->real_timer.data = (unsigned long) tsk;
-	init_timer(&sig->real_timer);
+	sig->real_timer.data = tsk;
 
 	sig->it_virt_expires = cputime_zero;
 	sig->it_virt_incr = cputime_zero;
Index: linux-2.6.15-rc5/kernel/itimer.c
===================================================================
--- linux-2.6.15-rc5.orig/kernel/itimer.c
+++ linux-2.6.15-rc5/kernel/itimer.c
@@ -12,36 +12,46 @@
 #include <linux/syscalls.h>
 #include <linux/time.h>
 #include <linux/posix-timers.h>
+#include <linux/hrtimer.h>
 
 #include <asm/uaccess.h>
 
-static unsigned long it_real_value(struct signal_struct *sig)
+/**
+ * itimer_get_remtime - get remaining time for the timer
+ *
+ * @timer: the timer to read
+ *
+ * Returns the delta between the expiry time and now, which can be
+ * less than zero or 1usec for an pending expired timer
+ */
+static struct timeval itimer_get_remtime(struct hrtimer *timer)
 {
-	unsigned long val = 0;
-	if (timer_pending(&sig->real_timer)) {
-		val = sig->real_timer.expires - jiffies;
-
-		/* look out for negative/zero itimer.. */
-		if ((long) val <= 0)
-			val = 1;
-	}
-	return val;
+	ktime_t rem = hrtimer_get_remaining(timer);
+
+	/*
+	 * Racy but safe: if the itimer expires after the above
+	 * hrtimer_get_remtime() call but before this condition
+	 * then we return 0 - which is correct.
+	 */
+	if (hrtimer_active(timer)) {
+		if (rem.tv64 <= 0)
+			rem.tv64 = NSEC_PER_USEC;
+	} else
+		rem.tv64 = 0;
+
+	return ktime_to_timeval(rem);
 }
 
 int do_getitimer(int which, struct itimerval *value)
 {
 	struct task_struct *tsk = current;
-	unsigned long interval, val;
 	cputime_t cinterval, cval;
 
 	switch (which) {
 	case ITIMER_REAL:
-		spin_lock_irq(&tsk->sighand->siglock);
-		interval = tsk->signal->it_real_incr;
-		val = it_real_value(tsk->signal);
-		spin_unlock_irq(&tsk->sighand->siglock);
-		jiffies_to_timeval(val, &value->it_value);
-		jiffies_to_timeval(interval, &value->it_interval);
+		value->it_value = itimer_get_remtime(&tsk->signal->real_timer);
+		value->it_interval =
+			ktime_to_timeval(tsk->signal->it_real_incr);
 		break;
 	case ITIMER_VIRTUAL:
 		read_lock(&tasklist_lock);
@@ -113,59 +123,45 @@ asmlinkage long sys_getitimer(int which,
 }
 
 
-void it_real_fn(unsigned long __data)
+/*
+ * The timer is automagically restarted, when interval != 0
+ */
+int it_real_fn(void *data)
 {
-	struct task_struct * p = (struct task_struct *) __data;
-	unsigned long inc = p->signal->it_real_incr;
+	struct task_struct *tsk = (struct task_struct *) data;
 
-	send_group_sig_info(SIGALRM, SEND_SIG_PRIV, p);
+	send_group_sig_info(SIGALRM, SEND_SIG_PRIV, tsk);
 
-	/*
-	 * Now restart the timer if necessary.  We don't need any locking
-	 * here because do_setitimer makes sure we have finished running
-	 * before it touches anything.
-	 * Note, we KNOW we are (or should be) at a jiffie edge here so
-	 * we don't need the +1 stuff.  Also, we want to use the prior
-	 * expire value so as to not "slip" a jiffie if we are late.
-	 * Deal with requesting a time prior to "now" here rather than
-	 * in add_timer.
-	 */
-	if (!inc)
-		return;
-	while (time_before_eq(p->signal->real_timer.expires, jiffies))
-		p->signal->real_timer.expires += inc;
-	add_timer(&p->signal->real_timer);
+	if (tsk->signal->it_real_incr.tv64 != 0) {
+		hrtimer_forward(&tsk->signal->real_timer,
+			       tsk->signal->it_real_incr);
+
+		return HRTIMER_RESTART;
+	}
+	return HRTIMER_NORESTART;
 }
 
 int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
 {
 	struct task_struct *tsk = current;
- 	unsigned long val, interval, expires;
+	struct hrtimer *timer;
+	ktime_t expires;
 	cputime_t cval, cinterval, nval, ninterval;
 
 	switch (which) {
 	case ITIMER_REAL:
-again:
-		spin_lock_irq(&tsk->sighand->siglock);
-		interval = tsk->signal->it_real_incr;
-		val = it_real_value(tsk->signal);
-		/* We are sharing ->siglock with it_real_fn() */
-		if (try_to_del_timer_sync(&tsk->signal->real_timer) < 0) {
-			spin_unlock_irq(&tsk->sighand->siglock);
-			goto again;
-		}
-		tsk->signal->it_real_incr =
-			timeval_to_jiffies(&value->it_interval);
-		expires = timeval_to_jiffies(&value->it_value);
-		if (expires)
-			mod_timer(&tsk->signal->real_timer,
-				  jiffies + 1 + expires);
-		spin_unlock_irq(&tsk->sighand->siglock);
+		timer = &tsk->signal->real_timer;
+		hrtimer_cancel(timer);
 		if (ovalue) {
-			jiffies_to_timeval(val, &ovalue->it_value);
-			jiffies_to_timeval(interval,
-					   &ovalue->it_interval);
+			ovalue->it_value = itimer_get_remtime(timer);
+			ovalue->it_interval
+				= ktime_to_timeval(tsk->signal->it_real_incr);
 		}
+		tsk->signal->it_real_incr =
+			timeval_to_ktime(value->it_interval);
+		expires = timeval_to_ktime(value->it_value);
+		if (expires.tv64 != 0)
+			hrtimer_start(timer, expires, HRTIMER_REL);
 		break;
 	case ITIMER_VIRTUAL:
 		nval = timeval_to_cputime(&value->it_value);

--


  parent reply	other threads:[~2005-12-06  0:40 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-12-06  0:01 [patch 00/21] hrtimer - High-resolution timer subsystem tglx
2005-12-06  0:01 ` [patch 01/21] Move div_long_long_rem out of jiffies.h tglx
2005-12-06  0:01 ` [patch 02/21] Remove duplicate div_long_long_rem implementation tglx
2005-12-06  0:01 ` [patch 03/21] Deinline mktime and set_normalized_timespec tglx
2005-12-06  0:01 ` [patch 04/21] Clean up mktime and make arguments const tglx
2005-12-06  0:01 ` [patch 05/21] Export deinlined mktime tglx
2005-12-06  0:01 ` [patch 06/21] Remove unused clock constants tglx
2005-12-06  0:01 ` [patch 07/21] Coding style clean up of " tglx
2005-12-06  0:01 ` [patch 08/21] Coding style and white space cleanup tglx
2005-12-06  0:01 ` [patch 09/21] Make clockid_t arguments const tglx
2005-12-06  0:01 ` [patch 10/21] Coding style and white space cleanup tglx
2005-12-06  0:01 ` [patch 11/21] Create and use timespec_valid macro tglx
2005-12-06  0:01 ` [patch 12/21] Validate timespec of do_sys_settimeofday tglx
2005-12-06  0:01 ` [patch 13/21] Introduce nsec_t type and conversion functions tglx
2005-12-06  0:01 ` [patch 14/21] Introduce ktime_t time format tglx
2005-12-06  0:01 ` [patch 15/21] hrtimer core code tglx
2005-12-15  3:43   ` Matt Helsley
2005-12-06  0:01 ` [patch 16/21] hrtimer documentation tglx
2005-12-06  0:01 ` tglx [this message]
2005-12-06  0:01 ` [patch 18/21] Create hrtimer nanosleep API tglx
2005-12-06  0:01 ` [patch 19/21] Switch sys_nanosleep to hrtimer tglx
2005-12-06  0:01 ` [patch 20/21] Switch clock_nanosleep to hrtimer nanosleep API tglx
2005-12-06  0:01 ` [patch 21/21] Convert posix timers completely tglx
2005-12-06 17:32 ` [patch 00/21] hrtimer - High-resolution timer subsystem Roman Zippel
2005-12-06 19:07   ` Ingo Molnar
2005-12-07  3:05     ` Roman Zippel
2005-12-08  5:18       ` Paul Jackson
2005-12-08  8:12         ` Ingo Molnar
2005-12-08  9:26       ` Ingo Molnar
2005-12-08 13:08         ` Roman Zippel
2005-12-08 15:36           ` Steven Rostedt
2005-12-06 22:10   ` Thomas Gleixner
2005-12-07  3:11     ` Roman Zippel
2005-12-06 22:28   ` Thomas Gleixner
2005-12-07  9:31     ` Andrew Morton
2005-12-07 10:11       ` Ingo Molnar
2005-12-07 10:20         ` Ingo Molnar
2005-12-07 10:23         ` Nick Piggin
2005-12-07 10:49           ` Ingo Molnar
2005-12-07 11:09             ` Nick Piggin
2005-12-07 11:33               ` Ingo Molnar
2005-12-07 11:40                 ` Nick Piggin
2005-12-07 13:06                 ` Roman Zippel
2005-12-07 12:40               ` Roman Zippel
2005-12-07 23:12                 ` Nick Piggin
2005-12-07 12:18     ` Roman Zippel
2005-12-07 16:55       ` Ingo Molnar
2005-12-07 17:17         ` Roman Zippel
2005-12-07 17:57           ` Ingo Molnar
2005-12-07 18:18             ` Roman Zippel
2005-12-07 18:02           ` Paul Baxter
2005-12-09 17:23       ` Thomas Gleixner
2005-12-12 13:39         ` Roman Zippel
2005-12-12 16:42           ` Thomas Gleixner
2005-12-12 18:37             ` Thomas Gleixner
2005-12-13  1:25             ` George Anzinger
2005-12-13  9:18               ` Thomas Gleixner
2005-12-15  1:35               ` Roman Zippel
2005-12-15  2:29                 ` George Anzinger
2005-12-19 14:56                   ` Roman Zippel
2005-12-19 20:54                     ` George Anzinger
2005-12-21 23:03                       ` Roman Zippel
2005-12-22  4:30                         ` George Anzinger
2005-12-14 20:48             ` Roman Zippel
2005-12-14 22:30               ` Thomas Gleixner
2005-12-15  0:55                 ` George Anzinger
2005-12-15 14:18                 ` Steven Rostedt
2005-12-19 14:50                 ` Roman Zippel
2005-12-19 22:05                   ` Thomas Gleixner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20051206000155.185937000@tglx.tec.linutronix.de \
    --to=tglx@linutronix.de \
    --cc=akpm@osdl.org \
    --cc=johnstul@us.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=rostedt@goodmis.org \
    --cc=zippel@linux-m86k.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®