mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: linux-kernel@vger.kernel.org
Cc: akpm@osdl.org, mingo@elte.hu, zippel@linux-m68k.org,
	george@mvista.com, johnstul@us.ibm.com
Subject: [patch 21/43] Switch clock_nanosleep to ktimer nanosleep API
Date: Thu, 01 Dec 2005 01:03:38 +0100	[thread overview]
Message-ID: <1133395418.32542.464.camel@tglx.tec.linutronix.de> (raw)
In-Reply-To: <20051130231140.164337000@tglx.tec.linutronix.de>

plain text document attachment
(ktimer-convert-posix-clock-nanosleep.patch)
- Switch clock_nanosleep to use the new nanosleep functions
  in ktimer.c

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

 include/linux/posix-timers.h |    7 +-
 kernel/posix-cpu-timers.c    |   23 ++++--
 kernel/posix-timers.c        |  150 +++++++------------------------------------
 3 files changed, 44 insertions(+), 136 deletions(-)

Index: linux-2.6.15-rc2-rework/include/linux/posix-timers.h
===================================================================
--- linux-2.6.15-rc2-rework.orig/include/linux/posix-timers.h
+++ linux-2.6.15-rc2-rework/include/linux/posix-timers.h
@@ -81,7 +81,7 @@ struct k_clock {
 	int (*clock_get) (const clockid_t which_clock, struct timespec * tp);
 	int (*timer_create) (struct k_itimer *timer);
 	int (*nsleep) (const clockid_t which_clock, int flags,
-		       struct timespec *);
+		       struct timespec *, struct timespec __user *);
 	int (*timer_set) (struct k_itimer * timr, int flags,
 			  struct itimerspec * new_setting,
 			  struct itimerspec * old_setting);
@@ -95,7 +95,8 @@ void register_posix_clock(const clockid_
 
 /* error handlers for timer_create, nanosleep and settime */
 int do_posix_clock_notimer_create(struct k_itimer *timer);
-int do_posix_clock_nonanosleep(const clockid_t, int flags, struct timespec *);
+int do_posix_clock_nonanosleep(const clockid_t, int flags, struct timespec *,
+			       struct timespec __user *);
 int do_posix_clock_nosettime(const clockid_t, struct timespec *tp);
 
 /* function to call to trigger timer event */
@@ -129,7 +130,7 @@ int posix_cpu_clock_get(const clockid_t 
 int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *ts);
 int posix_cpu_timer_create(struct k_itimer *timer);
 int posix_cpu_nsleep(const clockid_t which_clock, int flags,
-		     struct timespec *ts);
+		     struct timespec *rqtp, struct timespec __user *rmtp);
 int posix_cpu_timer_set(struct k_itimer *timer, int flags,
 			struct itimerspec *new, struct itimerspec *old);
 int posix_cpu_timer_del(struct k_itimer *timer);
Index: linux-2.6.15-rc2-rework/kernel/posix-cpu-timers.c
===================================================================
--- linux-2.6.15-rc2-rework.orig/kernel/posix-cpu-timers.c
+++ linux-2.6.15-rc2-rework/kernel/posix-cpu-timers.c
@@ -1411,7 +1411,7 @@ void set_process_cpu_timer(struct task_s
 static long posix_cpu_clock_nanosleep_restart(struct restart_block *);
 
 int posix_cpu_nsleep(const clockid_t which_clock, int flags,
-		     struct timespec *rqtp)
+		     struct timespec *rqtp, struct timespec __user *rmtp)
 {
 	struct restart_block *restart_block =
 	    &current_thread_info()->restart_block;
@@ -1436,7 +1436,6 @@ int posix_cpu_nsleep(const clockid_t whi
 	error = posix_cpu_timer_create(&timer);
 	timer.it_process = current;
 	if (!error) {
-		struct timespec __user *rmtp;
 		static struct itimerspec zero_it;
 		struct itimerspec it = { .it_value = *rqtp,
 					 .it_interval = {} };
@@ -1483,7 +1482,6 @@ int posix_cpu_nsleep(const clockid_t whi
 		/*
 		 * Report back to the user the time still remaining.
 		 */
-		rmtp = (struct timespec __user *) restart_block->arg1;
 		if (rmtp != NULL && !(flags & TIMER_ABSTIME) &&
 		    copy_to_user(rmtp, &it.it_value, sizeof *rmtp))
 			return -EFAULT;
@@ -1491,6 +1489,7 @@ int posix_cpu_nsleep(const clockid_t whi
 		restart_block->fn = posix_cpu_clock_nanosleep_restart;
 		/* Caller already set restart_block->arg1 */
 		restart_block->arg0 = which_clock;
+		restart_block->arg1 = (unsigned long) rmtp;
 		restart_block->arg2 = rqtp->tv_sec;
 		restart_block->arg3 = rqtp->tv_nsec;
 
@@ -1504,10 +1503,15 @@ static long
 posix_cpu_clock_nanosleep_restart(struct restart_block *restart_block)
 {
 	clockid_t which_clock = restart_block->arg0;
-	struct timespec t = { .tv_sec = restart_block->arg2,
-			      .tv_nsec = restart_block->arg3 };
+	struct timespec __user *rmtp;
+	struct timespec t;
+
+	rmtp = (struct timespec __user *) restart_block->arg1;
+	t.tv_sec = restart_block->arg2;
+	t.tv_nsec = restart_block->arg3;
+
 	restart_block->fn = do_no_restart_syscall;
-	return posix_cpu_nsleep(which_clock, TIMER_ABSTIME, &t);
+	return posix_cpu_nsleep(which_clock, TIMER_ABSTIME, &t, rmtp);
 }
 

@@ -1530,9 +1534,10 @@ static int process_cpu_timer_create(stru
 	return posix_cpu_timer_create(timer);
 }
 static int process_cpu_nsleep(const clockid_t which_clock, int flags,
-			      struct timespec *rqtp)
+			      struct timespec *rqtp,
+			      struct timespec __user *rmtp)
 {
-	return posix_cpu_nsleep(PROCESS_CLOCK, flags, rqtp);
+	return posix_cpu_nsleep(PROCESS_CLOCK, flags, rqtp, rmtp);
 }
 static int thread_cpu_clock_getres(const clockid_t which_clock,
 				   struct timespec *tp)
@@ -1550,7 +1555,7 @@ static int thread_cpu_timer_create(struc
 	return posix_cpu_timer_create(timer);
 }
 static int thread_cpu_nsleep(const clockid_t which_clock, int flags,
-			      struct timespec *rqtp)
+			      struct timespec *rqtp, struct timespec __user *rmtp)
 {
 	return -EINVAL;
 }
Index: linux-2.6.15-rc2-rework/kernel/posix-timers.c
===================================================================
--- linux-2.6.15-rc2-rework.orig/kernel/posix-timers.c
+++ linux-2.6.15-rc2-rework/kernel/posix-timers.c
@@ -209,7 +209,8 @@ static inline int common_timer_create(st
 /*
  * These ones are defined below.
  */
-static int common_nsleep(const clockid_t, int flags, struct timespec *t);
+static int common_nsleep(const clockid_t, int flags, struct timespec *t,
+			 struct timespec __user *rmtp);
 static void common_timer_get(struct k_itimer *, struct itimerspec *);
 static int common_timer_set(struct k_itimer *, int,
 			    struct itimerspec *, struct itimerspec *);
@@ -1227,7 +1228,7 @@ int do_posix_clock_notimer_create(struct
 EXPORT_SYMBOL_GPL(do_posix_clock_notimer_create);
 
 int do_posix_clock_nonanosleep(const clockid_t clock, int flags,
-			       struct timespec *t)
+			       struct timespec *t, struct timespec __user *r)
 {
 #ifndef ENOTSUP
 	return -EOPNOTSUPP;	/* aka ENOTSUP in userland for POSIX */
@@ -1387,7 +1388,27 @@ void clock_was_set(void)
 	up(&clock_was_set_lock);
 }
 
-long clock_nanosleep_restart(struct restart_block *restart_block);
+/*
+ * nanosleep for monotonic and realtime clocks
+ */
+static int common_nsleep(const clockid_t which_clock, int flags,
+			 struct timespec *tsave, struct timespec __user *rmtp)
+{
+	int mode = flags & TIMER_ABSTIME ? KTIMER_ABS : KTIMER_REL;
+
+	switch (which_clock) {
+	case CLOCK_REALTIME:
+		/* Posix madness. Only absolute timers on clock realtime
+		   are affected by clock set. */
+		if (mode == KTIMER_ABS)
+			return ktimer_nanosleep_real(tsave, rmtp, mode);
+	case CLOCK_MONOTONIC:
+		return ktimer_nanosleep(tsave, rmtp, mode);
+	default:
+		break;
+	}
+	return -EINVAL;
+}
 
 asmlinkage long
 sys_clock_nanosleep(const clockid_t which_clock, int flags,
@@ -1395,9 +1416,6 @@ sys_clock_nanosleep(const clockid_t whic
 		    struct timespec __user *rmtp)
 {
 	struct timespec t;
-	struct restart_block *restart_block =
-	    &(current_thread_info()->restart_block);
-	int ret;
 
 	if (invalid_clockid(which_clock))
 		return -EINVAL;
@@ -1408,122 +1426,6 @@ sys_clock_nanosleep(const clockid_t whic
 	if (!timespec_valid(&t))
 		return -EINVAL;
 
-	/*
-	 * Do this here as nsleep function does not have the real address.
-	 */
-	restart_block->arg1 = (unsigned long)rmtp;
-
-	ret = CLOCK_DISPATCH(which_clock, nsleep, (which_clock, flags, &t));
-
-	if ((ret == -ERESTART_RESTARTBLOCK) && rmtp &&
-					copy_to_user(rmtp, &t, sizeof (t)))
-		return -EFAULT;
-	return ret;
-}
-
-
-static int common_nsleep(const clockid_t which_clock,
-			 int flags, struct timespec *tsave)
-{
-	struct timespec t, dum;
-	DECLARE_WAITQUEUE(abs_wqueue, current);
-	u64 rq_time = (u64)0;
-	s64 left;
-	int abs;
-	struct restart_block *restart_block =
-	    &current_thread_info()->restart_block;
-
-	abs_wqueue.flags = 0;
-	abs = flags & TIMER_ABSTIME;
-
-	if (restart_block->fn == clock_nanosleep_restart) {
-		/*
-		 * Interrupted by a non-delivered signal, pick up remaining
-		 * time and continue.  Remaining time is in arg2 & 3.
-		 */
-		restart_block->fn = do_no_restart_syscall;
-
-		rq_time = restart_block->arg3;
-		rq_time = (rq_time << 32) + restart_block->arg2;
-		if (!rq_time)
-			return -EINTR;
-		left = rq_time - get_jiffies_64();
-		if (left <= (s64)0)
-			return 0;	/* Already passed */
-	}
-
-	if (abs && (posix_clocks[which_clock].clock_get !=
-			    posix_clocks[CLOCK_MONOTONIC].clock_get))
-		add_wait_queue(&nanosleep_abs_wqueue, &abs_wqueue);
-
-	do {
-		t = *tsave;
-		if (abs || !rq_time) {
-			adjust_abs_time(&posix_clocks[which_clock], &t, abs,
-					&rq_time, &dum);
-		}
-
-		left = rq_time - get_jiffies_64();
-		if (left >= (s64)MAX_JIFFY_OFFSET)
-			left = (s64)MAX_JIFFY_OFFSET;
-		if (left < (s64)0)
-			break;
-
-		schedule_timeout_interruptible(left);
-
-		left = rq_time - get_jiffies_64();
-	} while (left > (s64)0 && !test_thread_flag(TIF_SIGPENDING));
-
-	if (abs_wqueue.task_list.next)
-		finish_wait(&nanosleep_abs_wqueue, &abs_wqueue);
-
-	if (left > (s64)0) {
-
-		/*
-		 * Always restart abs calls from scratch to pick up any
-		 * clock shifting that happened while we are away.
-		 */
-		if (abs)
-			return -ERESTARTNOHAND;
-
-		left *= TICK_NSEC;
-		tsave->tv_sec = div_long_long_rem(left, 
-						  NSEC_PER_SEC, 
-						  &tsave->tv_nsec);
-		/*
-		 * Restart works by saving the time remaing in 
-		 * arg2 & 3 (it is 64-bits of jiffies).  The other
-		 * info we need is the clock_id (saved in arg0). 
-		 * The sys_call interface needs the users 
-		 * timespec return address which _it_ saves in arg1.
-		 * Since we have cast the nanosleep call to a clock_nanosleep
-		 * both can be restarted with the same code.
-		 */
-		restart_block->fn = clock_nanosleep_restart;
-		restart_block->arg0 = which_clock;
-		/*
-		 * Caller sets arg1
-		 */
-		restart_block->arg2 = rq_time & 0xffffffffLL;
-		restart_block->arg3 = rq_time >> 32;
-
-		return -ERESTART_RESTARTBLOCK;
-	}
-
-	return 0;
-}
-/*
- * This will restart clock_nanosleep.
- */
-long
-clock_nanosleep_restart(struct restart_block *restart_block)
-{
-	struct timespec t;
-	int ret = common_nsleep(restart_block->arg0, 0, &t);
-
-	if ((ret == -ERESTART_RESTARTBLOCK) && restart_block->arg1 &&
-	    copy_to_user((struct timespec __user *)(restart_block->arg1), &t,
-			 sizeof (t)))
-		return -EFAULT;
-	return ret;
+	return CLOCK_DISPATCH(which_clock, nsleep,
+			      (which_clock, flags, &t, rmtp));
 }

--


  parent reply	other threads:[~2005-12-01  0:11 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20051130231140.164337000@tglx.tec.linutronix.de>
2005-12-01  0:00 ` [patch 01/43] Move div_long_long_rem out of jiffies.h Thomas Gleixner
2005-12-01  2:06   ` Adrian Bunk
2005-12-01 11:38   ` Christoph Hellwig
2005-12-01  0:02 ` [patch 02/43] Remove duplicate div_long_long_rem implementation Thomas Gleixner
2005-12-01  0:02 ` [patch 03/43] Deinline mktime and set_normalized_timespec Thomas Gleixner
2005-12-01  0:02 ` [patch 04/43] Clean up mktime and add const modifiers Thomas Gleixner
2005-12-01  0:02 ` [patch 05/43] Export deinlined mktime Thomas Gleixner
2005-12-01  0:02 ` [patch 06/43] Remove unused clock constants Thomas Gleixner
2005-12-01  0:02 ` [patch 07/43] Cleanup clock constants coding style Thomas Gleixner
2005-12-01  0:03 ` [patch 08/43] Coding style and whitespace cleanup time.h Thomas Gleixner
2005-12-01  0:03 ` [patch 09/43] Make clock selectors in posix-timers const Thomas Gleixner
2005-12-01  0:03 ` [patch 10/43] Coding style and white space cleanup posix-timer.h Thomas Gleixner
2005-12-01  0:03 ` [patch 11/43] Create timespec_valid macro Thomas Gleixner
2005-12-01  0:03 ` [patch 12/43] Check user space timespec in do_sys_settimeofday Thomas Gleixner
2005-12-01  0:03 ` [patch 13/43] Introduce nsec_t type and conversion functions Thomas Gleixner
2005-12-01  0:03 ` [patch 14/43] Introduce ktime_t time format Thomas Gleixner
2005-12-01  0:03 ` [patch 15/43] ktimer core code Thomas Gleixner
2005-12-01  0:03 ` [patch 16/43] ktimer documentation Thomas Gleixner
2005-12-01  0:03 ` [patch 17/43] Switch itimers to ktimer Thomas Gleixner
2005-12-01  0:03 ` [patch 18/43] Remove now unnecessary includes Thomas Gleixner
2005-12-01  0:03 ` [patch 19/43] Introduce ktimer_nanosleep APIs Thomas Gleixner
2005-12-01  0:03 ` [patch 20/43] Convert sys_nanosleep to ktimer_nanosleep Thomas Gleixner
2005-12-01  0:03 ` Thomas Gleixner [this message]
2005-12-01  0:03 ` [patch 22/43] Convert posix interval timers to use ktimers Thomas Gleixner
2005-12-01  0:03 ` [patch 23/43] Simplify ktimers rearm code Thomas Gleixner
2005-12-01  0:03 ` [patch 24/43] Split timeout code into kernel/ktimeout.c Thomas Gleixner
2005-12-01  0:03 ` [patch 25/43] Create ktimeout.h and move timer.h code into it Thomas Gleixner
2005-12-01  2:36   ` Adrian Bunk
2005-12-01  2:51     ` Ingo Molnar
2005-12-01  0:03 ` [patch 26/43] Rename struct timer_list to struct ktimeout Thomas Gleixner
2005-12-01  0:03 ` [patch 27/43] Convert timer_list users to ktimeout Thomas Gleixner
2005-12-01  0:03 ` [patch 28/43] Convert ktimeout.h and create wrappers Thomas Gleixner
2005-12-01  0:03 ` [patch 29/43] Convert ktimeout.c to ktimeout struct and APIs Thomas Gleixner
2005-12-01  0:04 ` [patch 30/43] ktimeout documentation Thomas Gleixner
2005-12-01  0:04 ` [patch 31/43] rename init_ktimeout() to ktimeout_init() Thomas Gleixner
2005-12-01  0:04 ` [patch 32/43] rename setup_ktimeout() to ktimeout_setup() Thomas Gleixner
2005-12-01  0:04 ` [patch 33/43] rename add_ktimeout_on() to ktimeout_add_on() Thomas Gleixner
2005-12-01  0:04 ` [patch 34/43] rename del_ktimeout() to ktimeout_del() Thomas Gleixner
2005-12-01  0:04 ` [patch 35/43] rename __mod_ktimeout() to __mod_ktimeout() Thomas Gleixner
2005-12-01  0:04 ` [patch 36/43] rename mod_ktimeout() to ktimeout_mod() Thomas Gleixner
2005-12-01  0:04 ` [patch 37/43] rename next_ktimeout_interrupt() to ktimeout_next_interrupt() Thomas Gleixner
2005-12-01  0:04 ` [patch 38/43] rename add_ktimeout() to ktimeout_add() Thomas Gleixner
2005-12-01  0:04 ` [patch 39/43] rename try_to_del_ktimeout_sync() to ktimeout_try_to_del_sync() Thomas Gleixner
2005-12-01  0:04 ` [patch 40/43] rename del_ktimeout_sync() to del_ktimeout_sync() Thomas Gleixner
2005-12-01  0:04 ` [patch 41/43] rename del_singleshot_ktimeout_sync() to ktimeout_del_singleshot_sync() Thomas Gleixner
2005-12-01  0:04 ` [patch 42/43] rename TIMER_SOFTIRQ to TIMEOUT_SOFTIRQ Thomas Gleixner
2005-12-01  0:04 ` [patch 43/43] ktimeout code style cleanups 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=1133395418.32542.464.camel@tglx.tec.linutronix.de \
    --to=tglx@linutronix.de \
    --cc=akpm@osdl.org \
    --cc=george@mvista.com \
    --cc=johnstul@us.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=zippel@linux-m68k.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®