Author: dchagin
Date: Sun May 24 17:29:18 2015
New Revision: 283463
URL: https://svnweb.freebsd.org/changeset/base/283463

Log:
  Do not use struct l_timespec without conversion. While here move
  args->timeout handling before acquiring the futex key at FUTEX_WAIT path.
  
  Differential Revision:        https://reviews.freebsd.org/D1520
  Reviewed by:  trasz

Modified:
  head/sys/compat/linux/linux_futex.c
  head/sys/compat/linux/linux_misc.c
  head/sys/compat/linux/linux_time.c
  head/sys/compat/linux/linux_timer.h

Modified: head/sys/compat/linux/linux_futex.c
==============================================================================
--- head/sys/compat/linux/linux_futex.c Sun May 24 17:27:59 2015        
(r283462)
+++ head/sys/compat/linux/linux_futex.c Sun May 24 17:29:18 2015        
(r283463)
@@ -65,6 +65,7 @@ __KERNEL_RCSID(1, "$NetBSD: linux_futex.
 #include <compat/linux/linux_dtrace.h>
 #include <compat/linux/linux_emul.h>
 #include <compat/linux/linux_futex.h>
+#include <compat/linux/linux_timer.h>
 #include <compat/linux/linux_util.h>
 
 /* DTrace init */
@@ -669,7 +670,8 @@ linux_sys_futex(struct thread *td, struc
        struct linux_pemuldata *pem;
        struct waiting_proc *wp;
        struct futex *f, *f2;
-       struct l_timespec timeout;
+       struct l_timespec ltimeout;
+       struct timespec timeout;
        struct timeval utv, ctv;
        int timeout_hz;
        int error;
@@ -713,6 +715,38 @@ linux_sys_futex(struct thread *td, struc
                LINUX_CTR3(sys_futex, "WAIT uaddr %p val 0x%x bitset 0x%x",
                    args->uaddr, args->val, args->val3);
 
+               if (args->timeout != NULL) {
+                       error = copyin(args->timeout, &ltimeout, 
sizeof(ltimeout));
+                       if (error) {
+                               LIN_SDT_PROBE1(futex, linux_sys_futex, 
copyin_error,
+                                   error);
+                               LIN_SDT_PROBE1(futex, linux_sys_futex, return, 
error);
+                               return (error);
+                       }
+                       error = linux_to_native_timespec(&timeout, &ltimeout);
+                       if (error)
+                               return (error);
+                       TIMESPEC_TO_TIMEVAL(&utv, &timeout);
+                       error = itimerfix(&utv);
+                       if (error) {
+                               LIN_SDT_PROBE1(futex, linux_sys_futex, 
itimerfix_error,
+                                   error);
+                               LIN_SDT_PROBE1(futex, linux_sys_futex, return, 
error);
+                               return (error);
+                       }
+                       if (clockrt) {
+                               microtime(&ctv);
+                               timevalsub(&utv, &ctv);
+                       } else if (args->op == LINUX_FUTEX_WAIT_BITSET) {
+                               microuptime(&ctv);
+                               timevalsub(&utv, &ctv);
+                       }
+                       if (utv.tv_sec < 0)
+                               timevalclear(&utv);
+                       timeout_hz = tvtohz(&utv);
+               } else
+                       timeout_hz = 0;
+
                error = futex_get(args->uaddr, &wp, &f,
                    flags | FUTEX_CREATE_WP);
                if (error) {
@@ -745,37 +779,6 @@ linux_sys_futex(struct thread *td, struc
                        return (EWOULDBLOCK);
                }
 
-               if (args->timeout != NULL) {
-                       error = copyin(args->timeout, &timeout, 
sizeof(timeout));
-                       if (error) {
-                               LIN_SDT_PROBE1(futex, linux_sys_futex, 
copyin_error,
-                                   error);
-                               LIN_SDT_PROBE1(futex, linux_sys_futex, return, 
error);
-                               futex_put(f, wp);
-                               return (error);
-                       }
-                       TIMESPEC_TO_TIMEVAL(&utv, &timeout);
-                       error = itimerfix(&utv);
-                       if (error) {
-                               LIN_SDT_PROBE1(futex, linux_sys_futex, 
itimerfix_error,
-                                   error);
-                               LIN_SDT_PROBE1(futex, linux_sys_futex, return, 
error);
-                               futex_put(f, wp);
-                               return (error);
-                       }
-                       if (clockrt) {
-                               microtime(&ctv);
-                               timevalsub(&utv, &ctv);
-                       } else if (args->op == LINUX_FUTEX_WAIT_BITSET) {
-                               microuptime(&ctv);
-                               timevalsub(&utv, &ctv);
-                       }
-                       if (utv.tv_sec < 0)
-                               timevalclear(&utv);
-                       timeout_hz = tvtohz(&utv);
-               } else
-                       timeout_hz = 0;
-
                error = futex_wait(f, wp, timeout_hz, args->val3);
                break;
 

Modified: head/sys/compat/linux/linux_misc.c
==============================================================================
--- head/sys/compat/linux/linux_misc.c  Sun May 24 17:27:59 2015        
(r283462)
+++ head/sys/compat/linux/linux_misc.c  Sun May 24 17:29:18 2015        
(r283463)
@@ -88,6 +88,7 @@ __FBSDID("$FreeBSD$");
 #include <compat/linux/linux_file.h>
 #include <compat/linux/linux_mib.h>
 #include <compat/linux/linux_signal.h>
+#include <compat/linux/linux_timer.h>
 #include <compat/linux/linux_util.h>
 #include <compat/linux/linux_sysproto.h>
 #include <compat/linux/linux_emul.h>
@@ -2168,8 +2169,9 @@ linux_pselect6(struct thread *td, struct
                error = copyin(args->tsp, &lts, sizeof(lts));
                if (error != 0)
                        return (error);
-               uts.tv_sec = lts.tv_sec;
-               uts.tv_nsec = lts.tv_nsec;
+               error = linux_to_native_timespec(&uts, &lts);
+               if (error != 0)
+                       return (error);
 
                TIMESPEC_TO_TIMEVAL(&utv, &uts);
                if (itimerfix(&utv))
@@ -2201,8 +2203,8 @@ linux_pselect6(struct thread *td, struct
                        timevalclear(&utv);
 
                TIMEVAL_TO_TIMESPEC(&utv, &uts);
-               lts.tv_sec = uts.tv_sec;
-               lts.tv_nsec = uts.tv_nsec;
+
+               native_to_linux_timespec(&lts, &uts);
                error = copyout(&lts, args->tsp, sizeof(lts));
        }
 
@@ -2234,8 +2236,9 @@ linux_ppoll(struct thread *td, struct li
                error = copyin(args->tsp, &lts, sizeof(lts));
                if (error)
                        return (error);
-               uts.tv_sec = lts.tv_sec;
-               uts.tv_nsec = lts.tv_nsec;
+               error = linux_to_native_timespec(&uts, &lts);
+               if (error != 0)
+                       return (error);
 
                nanotime(&ts0);
                tsp = &uts;
@@ -2254,8 +2257,7 @@ linux_ppoll(struct thread *td, struct li
                } else
                        timespecclear(&uts);
 
-               lts.tv_sec = uts.tv_sec;
-               lts.tv_nsec = uts.tv_nsec;
+               native_to_linux_timespec(&lts, &uts);
                error = copyout(&lts, args->tsp, sizeof(lts));
        }
 
@@ -2343,8 +2345,7 @@ linux_sched_rr_get_interval(struct threa
        PROC_UNLOCK(tdt->td_proc);
        if (error != 0)
                return (error);
-       lts.tv_sec = ts.tv_sec;
-       lts.tv_nsec = ts.tv_nsec;
+       native_to_linux_timespec(&lts, &ts);
        return (copyout(&lts, uap->interval, sizeof(lts)));
 }
 

Modified: head/sys/compat/linux/linux_time.c
==============================================================================
--- head/sys/compat/linux/linux_time.c  Sun May 24 17:27:59 2015        
(r283462)
+++ head/sys/compat/linux/linux_time.c  Sun May 24 17:29:18 2015        
(r283463)
@@ -119,13 +119,10 @@ LIN_SDT_PROBE_DEFINE1(time, linux_clock_
 LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_clockid, "int");
 LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, return, "int");
 
-static void native_to_linux_timespec(struct l_timespec *,
-                                    struct timespec *);
-static int linux_to_native_timespec(struct timespec *,
-                                    struct l_timespec *);
 static int linux_to_native_clockid(clockid_t *, clockid_t);
 
-static void
+
+void
 native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp)
 {
 
@@ -137,7 +134,7 @@ native_to_linux_timespec(struct l_timesp
        LIN_SDT_PROBE0(time, native_to_linux_timespec, return);
 }
 
-static int
+int
 linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp)
 {
 

Modified: head/sys/compat/linux/linux_timer.h
==============================================================================
--- head/sys/compat/linux/linux_timer.h Sun May 24 17:27:59 2015        
(r283462)
+++ head/sys/compat/linux/linux_timer.h Sun May 24 17:29:18 2015        
(r283463)
@@ -111,4 +111,9 @@ struct l_itimerspec {
        struct l_timespec it_value;
 };
 
+void native_to_linux_timespec(struct l_timespec *,
+                                    struct timespec *);
+int linux_to_native_timespec(struct timespec *,
+                                    struct l_timespec *);
+
 #endif /* _LINUX_TIMER_H */
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to