From owner-svn-src-stable-10@freebsd.org Sat Jan 9 17:06:22 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 8FF0EA6873B; Sat, 9 Jan 2016 17:06:22 +0000 (UTC) (envelope-from dchagin@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 67FCA13C9; Sat, 9 Jan 2016 17:06:22 +0000 (UTC) (envelope-from dchagin@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u09H6Lnq051480; Sat, 9 Jan 2016 17:06:21 GMT (envelope-from dchagin@FreeBSD.org) Received: (from dchagin@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u09H6LVl051478; Sat, 9 Jan 2016 17:06:21 GMT (envelope-from dchagin@FreeBSD.org) Message-Id: <201601091706.u09H6LVl051478@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dchagin set sender to dchagin@FreeBSD.org using -f From: Dmitry Chagin Date: Sat, 9 Jan 2016 17:06:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r293561 - stable/10/sys/compat/linux X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 09 Jan 2016 17:06:22 -0000 Author: dchagin Date: Sat Jan 9 17:06:21 2016 New Revision: 293561 URL: https://svnweb.freebsd.org/changeset/base/293561 Log: MFC r283459: Add some clock mappings used in glibc 2.20. Modified: stable/10/sys/compat/linux/linux_time.c stable/10/sys/compat/linux/linux_timer.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/compat/linux/linux_time.c ============================================================================== --- stable/10/sys/compat/linux/linux_time.c Sat Jan 9 17:05:00 2016 (r293560) +++ stable/10/sys/compat/linux/linux_time.c Sat Jan 9 17:06:21 2016 (r293561) @@ -40,8 +40,11 @@ __KERNEL_RCSID(0, "$NetBSD: linux_time.c #include #include +#include #include #include +#include +#include #include #include #include @@ -60,7 +63,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_time.c #endif #include -#include +#include /* DTrace init */ LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); @@ -158,6 +161,20 @@ linux_to_native_clockid(clockid_t *n, cl LIN_SDT_PROBE2(time, linux_to_native_clockid, entry, n, l); + if (l < 0) { + /* cpu-clock */ + if ((l & LINUX_CLOCKFD_MASK) == LINUX_CLOCKFD) + return (EINVAL); + if (LINUX_CPUCLOCK_WHICH(l) >= LINUX_CPUCLOCK_MAX) + return (EINVAL); + + if (LINUX_CPUCLOCK_PERTHREAD(l)) + *n = CLOCK_THREAD_CPUTIME_ID; + else + *n = CLOCK_PROCESS_CPUTIME_ID; + return (0); + } + switch (l) { case LINUX_CLOCK_REALTIME: *n = CLOCK_REALTIME; @@ -165,21 +182,27 @@ linux_to_native_clockid(clockid_t *n, cl case LINUX_CLOCK_MONOTONIC: *n = CLOCK_MONOTONIC; break; - case LINUX_CLOCK_PROCESS_CPUTIME_ID: - case LINUX_CLOCK_THREAD_CPUTIME_ID: - case LINUX_CLOCK_REALTIME_HR: - case LINUX_CLOCK_MONOTONIC_HR: + case LINUX_CLOCK_REALTIME_COARSE: + *n = CLOCK_REALTIME_FAST; + break; + case LINUX_CLOCK_MONOTONIC_COARSE: + *n = CLOCK_MONOTONIC_FAST; + break; + case LINUX_CLOCK_MONOTONIC_RAW: + case LINUX_CLOCK_BOOTTIME: + case LINUX_CLOCK_REALTIME_ALARM: + case LINUX_CLOCK_BOOTTIME_ALARM: + case LINUX_CLOCK_SGI_CYCLE: + case LINUX_CLOCK_TAI: LIN_SDT_PROBE1(time, linux_to_native_clockid, unsupported_clockid, l); LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL); return (EINVAL); - break; default: LIN_SDT_PROBE1(time, linux_to_native_clockid, unknown_clockid, l); LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL); return (EINVAL); - break; } LIN_SDT_PROBE1(time, linux_to_native_clockid, return, 0); @@ -190,9 +213,14 @@ int linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args) { struct l_timespec lts; - int error; - clockid_t nwhich = 0; /* XXX: GCC */ struct timespec tp; + struct rusage ru; + struct thread *targettd; + struct proc *p; + int error, clockwhich; + clockid_t nwhich = 0; /* XXX: GCC */ + pid_t pid; + lwpid_t tid; LIN_SDT_PROBE2(time, linux_clock_gettime, entry, args->which, args->tp); @@ -203,7 +231,100 @@ linux_clock_gettime(struct thread *td, s LIN_SDT_PROBE1(time, linux_clock_gettime, return, error); return (error); } - error = kern_clock_gettime(td, nwhich, &tp); + + switch (nwhich) { + case CLOCK_PROCESS_CPUTIME_ID: + clockwhich = LINUX_CPUCLOCK_WHICH(args->which); + pid = LINUX_CPUCLOCK_ID(args->which); + if (pid == 0) { + p = td->td_proc; + PROC_LOCK(p); + } else { + error = pget(pid, PGET_CANSEE, &p); + if (error != 0) + return (EINVAL); + } + switch (clockwhich) { + case LINUX_CPUCLOCK_PROF: + PROC_STATLOCK(p); + calcru(p, &ru.ru_utime, &ru.ru_stime); + PROC_STATUNLOCK(p); + PROC_UNLOCK(p); + timevaladd(&ru.ru_utime, &ru.ru_stime); + TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp); + break; + case LINUX_CPUCLOCK_VIRT: + PROC_STATLOCK(p); + calcru(p, &ru.ru_utime, &ru.ru_stime); + PROC_STATUNLOCK(p); + PROC_UNLOCK(p); + TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp); + break; + case LINUX_CPUCLOCK_SCHED: + PROC_UNLOCK(p); + error = kern_clock_getcpuclockid2(td, pid, + CPUCLOCK_WHICH_PID, &nwhich); + if (error != 0) + return (EINVAL); + error = kern_clock_gettime(td, nwhich, &tp); + break; + default: + PROC_UNLOCK(p); + return (EINVAL); + } + + break; + + case CLOCK_THREAD_CPUTIME_ID: + clockwhich = LINUX_CPUCLOCK_WHICH(args->which); + p = td->td_proc; + tid = LINUX_CPUCLOCK_ID(args->which); + if (tid == 0) { + targettd = td; + PROC_LOCK(p); + } else { + targettd = tdfind(tid, p->p_pid); + if (targettd == NULL) + return (EINVAL); + } + switch (clockwhich) { + case LINUX_CPUCLOCK_PROF: + PROC_STATLOCK(p); + thread_lock(targettd); + rufetchtd(targettd, &ru); + thread_unlock(targettd); + PROC_STATUNLOCK(p); + PROC_UNLOCK(p); + timevaladd(&ru.ru_utime, &ru.ru_stime); + TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp); + break; + case LINUX_CPUCLOCK_VIRT: + PROC_STATLOCK(p); + thread_lock(targettd); + rufetchtd(targettd, &ru); + thread_unlock(targettd); + PROC_STATUNLOCK(p); + PROC_UNLOCK(p); + TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp); + break; + case LINUX_CPUCLOCK_SCHED: + error = kern_clock_getcpuclockid2(td, tid, + CPUCLOCK_WHICH_TID, &nwhich); + PROC_UNLOCK(p); + if (error != 0) + return (EINVAL); + error = kern_clock_gettime(td, nwhich, &tp); + break; + default: + PROC_UNLOCK(p); + return (EINVAL); + } + break; + + default: + error = kern_clock_gettime(td, nwhich, &tp); + break; + } if (error != 0) { LIN_SDT_PROBE1(time, linux_clock_gettime, gettime_error, error); LIN_SDT_PROBE1(time, linux_clock_gettime, return, error); @@ -261,19 +382,16 @@ linux_clock_settime(struct thread *td, s int linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args) { + struct proc *p; struct timespec ts; struct l_timespec lts; - int error; + int error, clockwhich; clockid_t nwhich = 0; /* XXX: GCC */ + pid_t pid; + lwpid_t tid; LIN_SDT_PROBE2(time, linux_clock_getres, entry, args->which, args->tp); - if (args->tp == NULL) { - LIN_SDT_PROBE0(time, linux_clock_getres, nullcall); - LIN_SDT_PROBE1(time, linux_clock_getres, return, 0); - return (0); - } - error = linux_to_native_clockid(&nwhich, args->which); if (error != 0) { LIN_SDT_PROBE1(time, linux_clock_getres, conversion_error, @@ -281,6 +399,59 @@ linux_clock_getres(struct thread *td, st LIN_SDT_PROBE1(time, linux_clock_getres, return, error); return (error); } + + /* + * Check user supplied clock id in case of per-process + * or thread-specific cpu-time clock. + */ + switch (nwhich) { + case CLOCK_THREAD_CPUTIME_ID: + tid = LINUX_CPUCLOCK_ID(args->which); + if (tid != 0) { + p = td->td_proc; + if (tdfind(tid, p->p_pid) == NULL) + return (ESRCH); + PROC_UNLOCK(p); + } + break; + case CLOCK_PROCESS_CPUTIME_ID: + pid = LINUX_CPUCLOCK_ID(args->which); + if (pid != 0) { + error = pget(pid, PGET_CANSEE, &p); + if (error != 0) + return (EINVAL); + PROC_UNLOCK(p); + } + break; + } + + if (args->tp == NULL) { + LIN_SDT_PROBE0(time, linux_clock_getres, nullcall); + LIN_SDT_PROBE1(time, linux_clock_getres, return, 0); + return (0); + } + + switch (nwhich) { + case CLOCK_THREAD_CPUTIME_ID: + case CLOCK_PROCESS_CPUTIME_ID: + clockwhich = LINUX_CPUCLOCK_WHICH(args->which); + switch (clockwhich) { + case LINUX_CPUCLOCK_PROF: + nwhich = CLOCK_PROF; + break; + case LINUX_CPUCLOCK_VIRT: + nwhich = CLOCK_VIRTUAL; + break; + case LINUX_CPUCLOCK_SCHED: + break; + default: + return (EINVAL); + } + break; + + default: + break; + } error = kern_clock_getres(td, nwhich, &ts); if (error != 0) { LIN_SDT_PROBE1(time, linux_clock_getres, getres_error, error); Modified: stable/10/sys/compat/linux/linux_timer.h ============================================================================== --- stable/10/sys/compat/linux/linux_timer.h Sat Jan 9 17:05:00 2016 (r293560) +++ stable/10/sys/compat/linux/linux_timer.h Sat Jan 9 17:06:21 2016 (r293561) @@ -56,6 +56,23 @@ #define LINUX_CLOCK_SGI_CYCLE 10 #define LINUX_CLOCK_TAI 11 +#define LINUX_CPUCLOCK_PERTHREAD_MASK 4 +#define LINUX_CPUCLOCK_MASK 3 +#define LINUX_CPUCLOCK_WHICH(clock) \ + ((clock) & (clockid_t) LINUX_CPUCLOCK_MASK) +#define LINUX_CPUCLOCK_PROF 0 +#define LINUX_CPUCLOCK_VIRT 1 +#define LINUX_CPUCLOCK_SCHED 2 +#define LINUX_CPUCLOCK_MAX 3 +#define LINUX_CLOCKFD LINUX_CPUCLOCK_MAX +#define LINUX_CLOCKFD_MASK \ + (LINUX_CPUCLOCK_PERTHREAD_MASK|LINUX_CPUCLOCK_MASK) + +#define LINUX_CPUCLOCK_ID(clock) ((pid_t) ~((clock) >> 3)) +#define LINUX_CPUCLOCK_PERTHREAD(clock) \ + (((clock) & (clockid_t) LINUX_CPUCLOCK_PERTHREAD_MASK) != 0) + + #define L_SIGEV_SIGNAL 0 #define L_SIGEV_NONE 1 #define L_SIGEV_THREAD 2