* [PATCH 0/2] Convert message queue timeouts to hrtimer @ 2010-04-02 20:40 Carsten Emde 2010-04-02 20:40 ` [PATCH 1/2] provide-schedule_hrtimeout-for-wallclock.patch Carsten Emde 2010-04-02 20:40 ` [PATCH 2/2] let-message-queue-timeout-use-hrtimer.patch Carsten Emde 0 siblings, 2 replies; 5+ messages in thread From: Carsten Emde @ 2010-04-02 20:40 UTC (permalink / raw) To: Andrew Morton Cc: Arjan van de Veen, Thomas Gleixner, Pradyumna Sampath, LKML, RT-users, Carsten Emde The message queue system calls that may timeout, mq_timedsend() and mq_timedreceive(), still use the old jiffie-based timer interface. Convert them to hrtimer. The first patch provides the hrtimer infrastructure, the second patch does the actual conversion to hrtimer. Carsten. ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] provide-schedule_hrtimeout-for-wallclock.patch 2010-04-02 20:40 [PATCH 0/2] Convert message queue timeouts to hrtimer Carsten Emde @ 2010-04-02 20:40 ` Carsten Emde 2010-04-06 19:54 ` [tip:timers/core] hrtimers: Provide schedule_hrtimeout for CLOCK_REALTIME tip-bot for Carsten Emde 2010-04-02 20:40 ` [PATCH 2/2] let-message-queue-timeout-use-hrtimer.patch Carsten Emde 1 sibling, 1 reply; 5+ messages in thread From: Carsten Emde @ 2010-04-02 20:40 UTC (permalink / raw) To: Andrew Morton Cc: Arjan van de Veen, Thomas Gleixner, Pradyumna Sampath, LKML, RT-users, Carsten Emde [-- Attachment #1: provide-schedule_hrtimeout-for-wallclock.patch --] [-- Type: text/plain, Size: 4836 bytes --] The current version of schedule_hrtimeout() always uses the monotonic clock. Some system calls such as mq_timedsend() and mq_timedreceive(), however, require the use of the wall clock due to the definition of the system call. This patch provides the infrastructure to use schedule_hrtimeout() with a wallclock timer. CC: Andrew Morton <akpm@linux-foundation.org> CC: Arjan van de Veen <arjan@infradead.org> CC: Thomas Gleixner <tglx@linutronix.de> Tested-by: Pradyumna Sampath <pradysam@gmail.com> Signed-off-by: Carsten Emde <C.Emde@osadl.org> --- include/linux/hrtimer.h | 2 + kernel/hrtimer.c | 66 +++++++++++++++++++++++++++++------------------- 2 files changed, 42 insertions(+), 26 deletions(-) Index: head/include/linux/hrtimer.h =================================================================== --- head.orig/include/linux/hrtimer.h +++ head/include/linux/hrtimer.h @@ -422,6 +422,8 @@ extern void hrtimer_init_sleeper(struct extern int schedule_hrtimeout_range(ktime_t *expires, unsigned long delta, const enum hrtimer_mode mode); +extern int schedule_hrtimeout_range_clock(ktime_t *expires, + unsigned long delta, const enum hrtimer_mode mode, int clock); extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode); /* Soft interrupt function to run the hrtimer queues: */ Index: head/kernel/hrtimer.c =================================================================== --- head.orig/kernel/hrtimer.c +++ head/kernel/hrtimer.c @@ -1749,35 +1749,14 @@ void __init hrtimers_init(void) } /** - * schedule_hrtimeout_range - sleep until timeout + * schedule_hrtimeout_range_clock - sleep until timeout * @expires: timeout value (ktime_t) * @delta: slack in expires timeout (ktime_t) * @mode: timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL - * - * Make the current task sleep until the given expiry time has - * elapsed. The routine will return immediately unless - * the current task state has been set (see set_current_state()). - * - * The @delta argument gives the kernel the freedom to schedule the - * actual wakeup to a time that is both power and performance friendly. - * The kernel give the normal best effort behavior for "@expires+@delta", - * but may decide to fire the timer earlier, but no earlier than @expires. - * - * You can set the task state as follows - - * - * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to - * pass before the routine returns. - * - * %TASK_INTERRUPTIBLE - the routine may return early if a signal is - * delivered to the current task. - * - * The current task state is guaranteed to be TASK_RUNNING when this - * routine returns. - * - * Returns 0 when the timer has expired otherwise -EINTR + * @clock: timer clock, CLOCK_MONOTONIC or CLOCK_REALTIME */ -int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta, - const enum hrtimer_mode mode) +int __sched schedule_hrtimeout_range_clock(ktime_t *expires, + unsigned long delta, const enum hrtimer_mode mode, int clock) { struct hrtimer_sleeper t; @@ -1799,7 +1778,7 @@ int __sched schedule_hrtimeout_range(kti return -EINTR; } - hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, mode); + hrtimer_init_on_stack(&t.timer, clock, mode); hrtimer_set_expires_range_ns(&t.timer, *expires, delta); hrtimer_init_sleeper(&t, current); @@ -1818,6 +1797,41 @@ int __sched schedule_hrtimeout_range(kti return !t.task ? 0 : -EINTR; } + +/** + * schedule_hrtimeout_range - sleep until timeout + * @expires: timeout value (ktime_t) + * @delta: slack in expires timeout (ktime_t) + * @mode: timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL + * + * Make the current task sleep until the given expiry time has + * elapsed. The routine will return immediately unless + * the current task state has been set (see set_current_state()). + * + * The @delta argument gives the kernel the freedom to schedule the + * actual wakeup to a time that is both power and performance friendly. + * The kernel give the normal best effort behavior for "@expires+@delta", + * but may decide to fire the timer earlier, but no earlier than @expires. + * + * You can set the task state as follows - + * + * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to + * pass before the routine returns. + * + * %TASK_INTERRUPTIBLE - the routine may return early if a signal is + * delivered to the current task. + * + * The current task state is guaranteed to be TASK_RUNNING when this + * routine returns. + * + * Returns 0 when the timer has expired otherwise -EINTR + */ +int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta, + const enum hrtimer_mode mode) +{ + return schedule_hrtimeout_range_clock(expires, delta, mode, + CLOCK_MONOTONIC); +} EXPORT_SYMBOL_GPL(schedule_hrtimeout_range); /** ^ permalink raw reply [flat|nested] 5+ messages in thread
* [tip:timers/core] hrtimers: Provide schedule_hrtimeout for CLOCK_REALTIME 2010-04-02 20:40 ` [PATCH 1/2] provide-schedule_hrtimeout-for-wallclock.patch Carsten Emde @ 2010-04-06 19:54 ` tip-bot for Carsten Emde 0 siblings, 0 replies; 5+ messages in thread From: tip-bot for Carsten Emde @ 2010-04-06 19:54 UTC (permalink / raw) To: linux-tip-commits Cc: linux-kernel, hpa, mingo, pradysam, arjan, akpm, tglx, C.Emde Commit-ID: 351b3f7a21e413a9b14d0393171497d2373bd702 Gitweb: http://git.kernel.org/tip/351b3f7a21e413a9b14d0393171497d2373bd702 Author: Carsten Emde <C.Emde@osadl.org> AuthorDate: Fri, 2 Apr 2010 22:40:19 +0200 Committer: Thomas Gleixner <tglx@linutronix.de> CommitDate: Tue, 6 Apr 2010 21:50:03 +0200 hrtimers: Provide schedule_hrtimeout for CLOCK_REALTIME The current version of schedule_hrtimeout() always uses the monotonic clock. Some system calls such as mq_timedsend() and mq_timedreceive(), however, require the use of the wall clock due to the definition of the system call. This patch provides the infrastructure to use schedule_hrtimeout() with a CLOCK_REALTIME timer. Signed-off-by: Carsten Emde <C.Emde@osadl.org> Tested-by: Pradyumna Sampath <pradysam@gmail.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Arjan van de Veen <arjan@infradead.org> LKML-Reference: <20100402204331.167439615@osadl.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- include/linux/hrtimer.h | 2 + kernel/hrtimer.c | 67 ++++++++++++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 5d86fb2..fd0c1b8 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -422,6 +422,8 @@ extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, extern int schedule_hrtimeout_range(ktime_t *expires, unsigned long delta, const enum hrtimer_mode mode); +extern int schedule_hrtimeout_range_clock(ktime_t *expires, + unsigned long delta, const enum hrtimer_mode mode, int clock); extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode); /* Soft interrupt function to run the hrtimer queues: */ diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 0086628..b9b134b 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -1749,35 +1749,15 @@ void __init hrtimers_init(void) } /** - * schedule_hrtimeout_range - sleep until timeout + * schedule_hrtimeout_range_clock - sleep until timeout * @expires: timeout value (ktime_t) * @delta: slack in expires timeout (ktime_t) * @mode: timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL - * - * Make the current task sleep until the given expiry time has - * elapsed. The routine will return immediately unless - * the current task state has been set (see set_current_state()). - * - * The @delta argument gives the kernel the freedom to schedule the - * actual wakeup to a time that is both power and performance friendly. - * The kernel give the normal best effort behavior for "@expires+@delta", - * but may decide to fire the timer earlier, but no earlier than @expires. - * - * You can set the task state as follows - - * - * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to - * pass before the routine returns. - * - * %TASK_INTERRUPTIBLE - the routine may return early if a signal is - * delivered to the current task. - * - * The current task state is guaranteed to be TASK_RUNNING when this - * routine returns. - * - * Returns 0 when the timer has expired otherwise -EINTR + * @clock: timer clock, CLOCK_MONOTONIC or CLOCK_REALTIME */ -int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta, - const enum hrtimer_mode mode) +int __sched +schedule_hrtimeout_range_clock(ktime_t *expires, unsigned long delta, + const enum hrtimer_mode mode, int clock) { struct hrtimer_sleeper t; @@ -1799,7 +1779,7 @@ int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta, return -EINTR; } - hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, mode); + hrtimer_init_on_stack(&t.timer, clock, mode); hrtimer_set_expires_range_ns(&t.timer, *expires, delta); hrtimer_init_sleeper(&t, current); @@ -1818,6 +1798,41 @@ int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta, return !t.task ? 0 : -EINTR; } + +/** + * schedule_hrtimeout_range - sleep until timeout + * @expires: timeout value (ktime_t) + * @delta: slack in expires timeout (ktime_t) + * @mode: timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL + * + * Make the current task sleep until the given expiry time has + * elapsed. The routine will return immediately unless + * the current task state has been set (see set_current_state()). + * + * The @delta argument gives the kernel the freedom to schedule the + * actual wakeup to a time that is both power and performance friendly. + * The kernel give the normal best effort behavior for "@expires+@delta", + * but may decide to fire the timer earlier, but no earlier than @expires. + * + * You can set the task state as follows - + * + * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to + * pass before the routine returns. + * + * %TASK_INTERRUPTIBLE - the routine may return early if a signal is + * delivered to the current task. + * + * The current task state is guaranteed to be TASK_RUNNING when this + * routine returns. + * + * Returns 0 when the timer has expired otherwise -EINTR + */ +int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta, + const enum hrtimer_mode mode) +{ + return schedule_hrtimeout_range_clock(expires, delta, mode, + CLOCK_MONOTONIC); +} EXPORT_SYMBOL_GPL(schedule_hrtimeout_range); /** ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] let-message-queue-timeout-use-hrtimer.patch 2010-04-02 20:40 [PATCH 0/2] Convert message queue timeouts to hrtimer Carsten Emde 2010-04-02 20:40 ` [PATCH 1/2] provide-schedule_hrtimeout-for-wallclock.patch Carsten Emde @ 2010-04-02 20:40 ` Carsten Emde 2010-04-06 19:55 ` [tip:timers/core] mqueue: Convert message queue timeout to use hrtimers tip-bot for Carsten Emde 1 sibling, 1 reply; 5+ messages in thread From: Carsten Emde @ 2010-04-02 20:40 UTC (permalink / raw) To: Andrew Morton Cc: Arjan van de Veen, Thomas Gleixner, Pradyumna Sampath, LKML, RT-users, Carsten Emde [-- Attachment #1: let-message-queue-timeout-use-hrtimer.patch --] [-- Type: text/plain, Size: 4760 bytes --] The message queue functions mq_timedsend() and mq_timedreceive() have not yet been converted to use the hrtimer interface. This patch replaces the call to schedule_timeout() by a call to schedule_hrtimeout() and transforms the expiration time from timespec to ktime as required. CC: Andrew Morton <akpm@linux-foundation.org> CC: Arjan van de Veen <arjan@infradead.org> CC: Thomas Gleixner <tglx@linutronix.de> Tested-by: Pradyumna Sampath <pradysam@gmail.com> Signed-off-by: Carsten Emde <C.Emde@osadl.org> --- ipc/mqueue.c | 74 +++++++++++++++++++---------------------------------------- 1 file changed, 25 insertions(+), 49 deletions(-) Index: head/ipc/mqueue.c =================================================================== --- head.orig/ipc/mqueue.c +++ head/ipc/mqueue.c @@ -428,7 +428,7 @@ static void wq_add(struct mqueue_inode_i * sr: SEND or RECV */ static int wq_sleep(struct mqueue_inode_info *info, int sr, - long timeout, struct ext_wait_queue *ewp) + ktime_t *timeout, struct ext_wait_queue *ewp) { int retval; signed long time; @@ -439,7 +439,8 @@ static int wq_sleep(struct mqueue_inode_ set_current_state(TASK_INTERRUPTIBLE); spin_unlock(&info->lock); - time = schedule_timeout(timeout); + time = schedule_hrtimeout_range_clock(timeout, + HRTIMER_MODE_ABS, 0, CLOCK_REALTIME); while (ewp->state == STATE_PENDING) cpu_relax(); @@ -551,31 +552,16 @@ static void __do_notify(struct mqueue_in wake_up(&info->wait_q); } -static long prepare_timeout(struct timespec *p) +static int prepare_timeout(const struct timespec __user *u_abs_timeout, + ktime_t *expires, struct timespec *ts) { - struct timespec nowts; - long timeout; - - if (p) { - if (unlikely(p->tv_nsec < 0 || p->tv_sec < 0 - || p->tv_nsec >= NSEC_PER_SEC)) - return -EINVAL; - nowts = CURRENT_TIME; - /* first subtract as jiffies can't be too big */ - p->tv_sec -= nowts.tv_sec; - if (p->tv_nsec < nowts.tv_nsec) { - p->tv_nsec += NSEC_PER_SEC; - p->tv_sec--; - } - p->tv_nsec -= nowts.tv_nsec; - if (p->tv_sec < 0) - return 0; - - timeout = timespec_to_jiffies(p) + 1; - } else - return MAX_SCHEDULE_TIMEOUT; + if (copy_from_user(ts, u_abs_timeout, sizeof(struct timespec))) + return -EFAULT; + if (!timespec_valid(ts)) + return -EINVAL; - return timeout; + *expires = timespec_to_ktime(*ts); + return 0; } static void remove_notification(struct mqueue_inode_info *info) @@ -861,22 +847,21 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqd struct ext_wait_queue *receiver; struct msg_msg *msg_ptr; struct mqueue_inode_info *info; - struct timespec ts, *p = NULL; - long timeout; + ktime_t expires, *timeout = NULL; + struct timespec ts; int ret; if (u_abs_timeout) { - if (copy_from_user(&ts, u_abs_timeout, - sizeof(struct timespec))) - return -EFAULT; - p = &ts; + int res = prepare_timeout(u_abs_timeout, &expires, &ts); + if (res) + return res; + timeout = &expires; } if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX)) return -EINVAL; - audit_mq_sendrecv(mqdes, msg_len, msg_prio, p); - timeout = prepare_timeout(p); + audit_mq_sendrecv(mqdes, msg_len, msg_prio, timeout ? &ts : NULL); filp = fget(mqdes); if (unlikely(!filp)) { @@ -918,9 +903,6 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqd if (filp->f_flags & O_NONBLOCK) { spin_unlock(&info->lock); ret = -EAGAIN; - } else if (unlikely(timeout < 0)) { - spin_unlock(&info->lock); - ret = timeout; } else { wait.task = current; wait.msg = (void *) msg_ptr; @@ -953,24 +935,23 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, size_t, msg_len, unsigned int __user *, u_msg_prio, const struct timespec __user *, u_abs_timeout) { - long timeout; ssize_t ret; struct msg_msg *msg_ptr; struct file *filp; struct inode *inode; struct mqueue_inode_info *info; struct ext_wait_queue wait; - struct timespec ts, *p = NULL; + ktime_t expires, *timeout = NULL; + struct timespec ts; if (u_abs_timeout) { - if (copy_from_user(&ts, u_abs_timeout, - sizeof(struct timespec))) - return -EFAULT; - p = &ts; + int res = prepare_timeout(u_abs_timeout, &expires, &ts); + if (res) + return res; + timeout = &expires; } - audit_mq_sendrecv(mqdes, msg_len, 0, p); - timeout = prepare_timeout(p); + audit_mq_sendrecv(mqdes, msg_len, 0, timeout ? &ts : NULL); filp = fget(mqdes); if (unlikely(!filp)) { @@ -1002,11 +983,6 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, if (filp->f_flags & O_NONBLOCK) { spin_unlock(&info->lock); ret = -EAGAIN; - msg_ptr = NULL; - } else if (unlikely(timeout < 0)) { - spin_unlock(&info->lock); - ret = timeout; - msg_ptr = NULL; } else { wait.task = current; wait.state = STATE_NONE; ^ permalink raw reply [flat|nested] 5+ messages in thread
* [tip:timers/core] mqueue: Convert message queue timeout to use hrtimers 2010-04-02 20:40 ` [PATCH 2/2] let-message-queue-timeout-use-hrtimer.patch Carsten Emde @ 2010-04-06 19:55 ` tip-bot for Carsten Emde 0 siblings, 0 replies; 5+ messages in thread From: tip-bot for Carsten Emde @ 2010-04-06 19:55 UTC (permalink / raw) To: linux-tip-commits Cc: linux-kernel, hpa, mingo, pradysam, arjan, akpm, tglx, C.Emde Commit-ID: 9ca7d8e6834c40a99622bbe4a88aaf64313ae43c Gitweb: http://git.kernel.org/tip/9ca7d8e6834c40a99622bbe4a88aaf64313ae43c Author: Carsten Emde <C.Emde@osadl.org> AuthorDate: Fri, 2 Apr 2010 22:40:20 +0200 Committer: Thomas Gleixner <tglx@linutronix.de> CommitDate: Tue, 6 Apr 2010 21:50:03 +0200 mqueue: Convert message queue timeout to use hrtimers The message queue functions mq_timedsend() and mq_timedreceive() have not yet been converted to use the hrtimer interface. This patch replaces the call to schedule_timeout() by a call to schedule_hrtimeout() and transforms the expiration time from timespec to ktime as required. [ tglx: Fixed whitespace wreckage ] Signed-off-by: Carsten Emde <C.Emde@osadl.org> Tested-by: Pradyumna Sampath <pradysam@gmail.com> Cc: Arjan van de Veen <arjan@infradead.org> Cc: Andrew Morton <akpm@linux-foundation.org> LKML-Reference: <20100402204331.715783034@osadl.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- ipc/mqueue.c | 74 +++++++++++++++++++-------------------------------------- 1 files changed, 25 insertions(+), 49 deletions(-) diff --git a/ipc/mqueue.c b/ipc/mqueue.c index e4e3f04..a9d8b0c 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -428,7 +428,7 @@ static void wq_add(struct mqueue_inode_info *info, int sr, * sr: SEND or RECV */ static int wq_sleep(struct mqueue_inode_info *info, int sr, - long timeout, struct ext_wait_queue *ewp) + ktime_t *timeout, struct ext_wait_queue *ewp) { int retval; signed long time; @@ -439,7 +439,8 @@ static int wq_sleep(struct mqueue_inode_info *info, int sr, set_current_state(TASK_INTERRUPTIBLE); spin_unlock(&info->lock); - time = schedule_timeout(timeout); + time = schedule_hrtimeout_range_clock(timeout, + HRTIMER_MODE_ABS, 0, CLOCK_REALTIME); while (ewp->state == STATE_PENDING) cpu_relax(); @@ -551,31 +552,16 @@ static void __do_notify(struct mqueue_inode_info *info) wake_up(&info->wait_q); } -static long prepare_timeout(struct timespec *p) +static int prepare_timeout(const struct timespec __user *u_abs_timeout, + ktime_t *expires, struct timespec *ts) { - struct timespec nowts; - long timeout; - - if (p) { - if (unlikely(p->tv_nsec < 0 || p->tv_sec < 0 - || p->tv_nsec >= NSEC_PER_SEC)) - return -EINVAL; - nowts = CURRENT_TIME; - /* first subtract as jiffies can't be too big */ - p->tv_sec -= nowts.tv_sec; - if (p->tv_nsec < nowts.tv_nsec) { - p->tv_nsec += NSEC_PER_SEC; - p->tv_sec--; - } - p->tv_nsec -= nowts.tv_nsec; - if (p->tv_sec < 0) - return 0; - - timeout = timespec_to_jiffies(p) + 1; - } else - return MAX_SCHEDULE_TIMEOUT; + if (copy_from_user(ts, u_abs_timeout, sizeof(struct timespec))) + return -EFAULT; + if (!timespec_valid(ts)) + return -EINVAL; - return timeout; + *expires = timespec_to_ktime(*ts); + return 0; } static void remove_notification(struct mqueue_inode_info *info) @@ -861,22 +847,21 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, struct ext_wait_queue *receiver; struct msg_msg *msg_ptr; struct mqueue_inode_info *info; - struct timespec ts, *p = NULL; - long timeout; + ktime_t expires, *timeout = NULL; + struct timespec ts; int ret; if (u_abs_timeout) { - if (copy_from_user(&ts, u_abs_timeout, - sizeof(struct timespec))) - return -EFAULT; - p = &ts; + int res = prepare_timeout(u_abs_timeout, &expires, &ts); + if (res) + return res; + timeout = &expires; } if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX)) return -EINVAL; - audit_mq_sendrecv(mqdes, msg_len, msg_prio, p); - timeout = prepare_timeout(p); + audit_mq_sendrecv(mqdes, msg_len, msg_prio, timeout ? &ts : NULL); filp = fget(mqdes); if (unlikely(!filp)) { @@ -918,9 +903,6 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, if (filp->f_flags & O_NONBLOCK) { spin_unlock(&info->lock); ret = -EAGAIN; - } else if (unlikely(timeout < 0)) { - spin_unlock(&info->lock); - ret = timeout; } else { wait.task = current; wait.msg = (void *) msg_ptr; @@ -953,24 +935,23 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, size_t, msg_len, unsigned int __user *, u_msg_prio, const struct timespec __user *, u_abs_timeout) { - long timeout; ssize_t ret; struct msg_msg *msg_ptr; struct file *filp; struct inode *inode; struct mqueue_inode_info *info; struct ext_wait_queue wait; - struct timespec ts, *p = NULL; + ktime_t expires, *timeout = NULL; + struct timespec ts; if (u_abs_timeout) { - if (copy_from_user(&ts, u_abs_timeout, - sizeof(struct timespec))) - return -EFAULT; - p = &ts; + int res = prepare_timeout(u_abs_timeout, &expires, &ts); + if (res) + return res; + timeout = &expires; } - audit_mq_sendrecv(mqdes, msg_len, 0, p); - timeout = prepare_timeout(p); + audit_mq_sendrecv(mqdes, msg_len, 0, timeout ? &ts : NULL); filp = fget(mqdes); if (unlikely(!filp)) { @@ -1002,11 +983,6 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, if (filp->f_flags & O_NONBLOCK) { spin_unlock(&info->lock); ret = -EAGAIN; - msg_ptr = NULL; - } else if (unlikely(timeout < 0)) { - spin_unlock(&info->lock); - ret = timeout; - msg_ptr = NULL; } else { wait.task = current; wait.state = STATE_NONE; ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-04-06 19:56 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-04-02 20:40 [PATCH 0/2] Convert message queue timeouts to hrtimer Carsten Emde 2010-04-02 20:40 ` [PATCH 1/2] provide-schedule_hrtimeout-for-wallclock.patch Carsten Emde 2010-04-06 19:54 ` [tip:timers/core] hrtimers: Provide schedule_hrtimeout for CLOCK_REALTIME tip-bot for Carsten Emde 2010-04-02 20:40 ` [PATCH 2/2] let-message-queue-timeout-use-hrtimer.patch Carsten Emde 2010-04-06 19:55 ` [tip:timers/core] mqueue: Convert message queue timeout to use hrtimers tip-bot for Carsten Emde
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
Powered by JetHome