Commit 9ca7d8e6834c40a99622bbe4a88aaf64313ae43c

Authored by Carsten Emde
Committed by Thomas Gleixner
1 parent 351b3f7a21

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>

Showing 1 changed file with 25 additions and 49 deletions Side-by-side Diff

... ... @@ -428,7 +428,7 @@
428 428 * sr: SEND or RECV
429 429 */
430 430 static int wq_sleep(struct mqueue_inode_info *info, int sr,
431   - long timeout, struct ext_wait_queue *ewp)
  431 + ktime_t *timeout, struct ext_wait_queue *ewp)
432 432 {
433 433 int retval;
434 434 signed long time;
... ... @@ -439,7 +439,8 @@
439 439 set_current_state(TASK_INTERRUPTIBLE);
440 440  
441 441 spin_unlock(&info->lock);
442   - time = schedule_timeout(timeout);
  442 + time = schedule_hrtimeout_range_clock(timeout,
  443 + HRTIMER_MODE_ABS, 0, CLOCK_REALTIME);
443 444  
444 445 while (ewp->state == STATE_PENDING)
445 446 cpu_relax();
446 447  
447 448  
... ... @@ -551,31 +552,16 @@
551 552 wake_up(&info->wait_q);
552 553 }
553 554  
554   -static long prepare_timeout(struct timespec *p)
  555 +static int prepare_timeout(const struct timespec __user *u_abs_timeout,
  556 + ktime_t *expires, struct timespec *ts)
555 557 {
556   - struct timespec nowts;
557   - long timeout;
  558 + if (copy_from_user(ts, u_abs_timeout, sizeof(struct timespec)))
  559 + return -EFAULT;
  560 + if (!timespec_valid(ts))
  561 + return -EINVAL;
558 562  
559   - if (p) {
560   - if (unlikely(p->tv_nsec < 0 || p->tv_sec < 0
561   - || p->tv_nsec >= NSEC_PER_SEC))
562   - return -EINVAL;
563   - nowts = CURRENT_TIME;
564   - /* first subtract as jiffies can't be too big */
565   - p->tv_sec -= nowts.tv_sec;
566   - if (p->tv_nsec < nowts.tv_nsec) {
567   - p->tv_nsec += NSEC_PER_SEC;
568   - p->tv_sec--;
569   - }
570   - p->tv_nsec -= nowts.tv_nsec;
571   - if (p->tv_sec < 0)
572   - return 0;
573   -
574   - timeout = timespec_to_jiffies(p) + 1;
575   - } else
576   - return MAX_SCHEDULE_TIMEOUT;
577   -
578   - return timeout;
  563 + *expires = timespec_to_ktime(*ts);
  564 + return 0;
579 565 }
580 566  
581 567 static void remove_notification(struct mqueue_inode_info *info)
582 568  
583 569  
... ... @@ -861,22 +847,21 @@
861 847 struct ext_wait_queue *receiver;
862 848 struct msg_msg *msg_ptr;
863 849 struct mqueue_inode_info *info;
864   - struct timespec ts, *p = NULL;
865   - long timeout;
  850 + ktime_t expires, *timeout = NULL;
  851 + struct timespec ts;
866 852 int ret;
867 853  
868 854 if (u_abs_timeout) {
869   - if (copy_from_user(&ts, u_abs_timeout,
870   - sizeof(struct timespec)))
871   - return -EFAULT;
872   - p = &ts;
  855 + int res = prepare_timeout(u_abs_timeout, &expires, &ts);
  856 + if (res)
  857 + return res;
  858 + timeout = &expires;
873 859 }
874 860  
875 861 if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX))
876 862 return -EINVAL;
877 863  
878   - audit_mq_sendrecv(mqdes, msg_len, msg_prio, p);
879   - timeout = prepare_timeout(p);
  864 + audit_mq_sendrecv(mqdes, msg_len, msg_prio, timeout ? &ts : NULL);
880 865  
881 866 filp = fget(mqdes);
882 867 if (unlikely(!filp)) {
... ... @@ -918,9 +903,6 @@
918 903 if (filp->f_flags & O_NONBLOCK) {
919 904 spin_unlock(&info->lock);
920 905 ret = -EAGAIN;
921   - } else if (unlikely(timeout < 0)) {
922   - spin_unlock(&info->lock);
923   - ret = timeout;
924 906 } else {
925 907 wait.task = current;
926 908 wait.msg = (void *) msg_ptr;
927 909  
928 910  
929 911  
... ... @@ -953,24 +935,23 @@
953 935 size_t, msg_len, unsigned int __user *, u_msg_prio,
954 936 const struct timespec __user *, u_abs_timeout)
955 937 {
956   - long timeout;
957 938 ssize_t ret;
958 939 struct msg_msg *msg_ptr;
959 940 struct file *filp;
960 941 struct inode *inode;
961 942 struct mqueue_inode_info *info;
962 943 struct ext_wait_queue wait;
963   - struct timespec ts, *p = NULL;
  944 + ktime_t expires, *timeout = NULL;
  945 + struct timespec ts;
964 946  
965 947 if (u_abs_timeout) {
966   - if (copy_from_user(&ts, u_abs_timeout,
967   - sizeof(struct timespec)))
968   - return -EFAULT;
969   - p = &ts;
  948 + int res = prepare_timeout(u_abs_timeout, &expires, &ts);
  949 + if (res)
  950 + return res;
  951 + timeout = &expires;
970 952 }
971 953  
972   - audit_mq_sendrecv(mqdes, msg_len, 0, p);
973   - timeout = prepare_timeout(p);
  954 + audit_mq_sendrecv(mqdes, msg_len, 0, timeout ? &ts : NULL);
974 955  
975 956 filp = fget(mqdes);
976 957 if (unlikely(!filp)) {
... ... @@ -1002,11 +983,6 @@
1002 983 if (filp->f_flags & O_NONBLOCK) {
1003 984 spin_unlock(&info->lock);
1004 985 ret = -EAGAIN;
1005   - msg_ptr = NULL;
1006   - } else if (unlikely(timeout < 0)) {
1007   - spin_unlock(&info->lock);
1008   - ret = timeout;
1009   - msg_ptr = NULL;
1010 986 } else {
1011 987 wait.task = current;
1012 988 wait.state = STATE_NONE;