Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Feb 2020 12:23:33 -0800
From:      Conrad Meyer <cem@freebsd.org>
To:        Dmitry Chagin <dchagin@freebsd.org>
Cc:        src-committers <src-committers@freebsd.org>, svn-src-all <svn-src-all@freebsd.org>,  svn-src-head <svn-src-head@freebsd.org>
Subject:   Re: svn commit: r357492 - in head/sys: kern sys
Message-ID:  <CAG6CVpVkdw5t=FYozt7-Q8trRd_0gK7tn0VXdUn-O4t28786fw@mail.gmail.com>
In-Reply-To: <202002040525.0145Pppn034466@repo.freebsd.org>
References:  <202002040525.0145Pppn034466@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi Dmitry,

This seems to trigger some panics via clock_gettime syscalls (native
and 32-bit, reported by Syzkaller):

panic: mutex process lock not owned at
/syzkaller/managers/main/kernel/sys/kern/kern_time.c:261
cpuid = 0
time = 1580841963
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x47/frame 0xfffffe00244778c0
vpanic() at vpanic+0x1ce/frame 0xfffffe0024477930
panic() at panic+0x43/frame 0xfffffe0024477990
__mtx_assert() at __mtx_assert+0x196/frame 0xfffffe00244779d0
kern_thread_cputime() at kern_thread_cputime+0xaa/frame 0xfffffe0024477a20
kern_clock_gettime() at kern_clock_gettime+0x277/frame 0xfffffe0024477a80
sys_clock_gettime() at sys_clock_gettime+0x25/frame 0xfffffe0024477ab0
amd64_syscall() at amd64_syscall+0x499/frame 0xfffffe0024477bf0

panic: mutex process lock not owned at
/syzkaller/managers/i386/kernel/sys/kern/kern_time.c:261
cpuid = 0
time = 1580847200
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x47/frame 0xfffffe00244a68b0
vpanic() at vpanic+0x1ce/frame 0xfffffe00244a6920
panic() at panic+0x43/frame 0xfffffe00244a6980
__mtx_assert() at __mtx_assert+0x196/frame 0xfffffe00244a69c0
kern_thread_cputime() at kern_thread_cputime+0xaa/frame 0xfffffe00244a6a10
kern_clock_gettime() at kern_clock_gettime+0x277/frame 0xfffffe00244a6a70
freebsd32_clock_gettime() at freebsd32_clock_gettime+0x25/frame
0xfffffe00244a6ab0
ia32_syscall() at ia32_syscall+0x48c/frame 0xfffffe00244a6bf0

Best,
Conrad

On Mon, Feb 3, 2020 at 9:25 PM Dmitry Chagin <dchagin@freebsd.org> wrote:
>
> Author: dchagin
> Date: Tue Feb  4 05:25:51 2020
> New Revision: 357492
> URL: https://svnweb.freebsd.org/changeset/base/357492
>
> Log:
>   For code reuse in Linuxulator rename get_proccess_cputime()
>   and get_thread_cputime() and add prototypes for it to <sys/syscallsubr.h>.
>
>   As both functions become a public interface add process lock assert
>   to ensure that the process is not exiting under it.
>
>   Fix whitespace nit while here.
>
>   Reviewed by:          kib
>   Differential Revision:        https://reviews.freebsd.org/D23340
>   MFC after             2 weeks
>
> Modified:
>   head/sys/kern/kern_time.c
>   head/sys/sys/syscallsubr.h
>
> Modified: head/sys/kern/kern_time.c
> ==============================================================================
> --- head/sys/kern/kern_time.c   Tue Feb  4 05:23:34 2020        (r357491)
> +++ head/sys/kern/kern_time.c   Tue Feb  4 05:25:51 2020        (r357492)
> @@ -242,7 +242,7 @@ sys_clock_gettime(struct thread *td, struct clock_gett
>         return (error);
>  }
>
> -static inline void
> +static inline void
>  cputick2timespec(uint64_t runtime, struct timespec *ats)
>  {
>         runtime = cputick2usec(runtime);
> @@ -250,12 +250,15 @@ cputick2timespec(uint64_t runtime, struct timespec *at
>         ats->tv_nsec = runtime % 1000000 * 1000;
>  }
>
> -static void
> -get_thread_cputime(struct thread *targettd, struct timespec *ats)
> +void
> +kern_thread_cputime(struct thread *targettd, struct timespec *ats)
>  {
>         uint64_t runtime, curtime, switchtime;
> +       struct proc *p;
>
>         if (targettd == NULL) { /* current thread */
> +               p = curthread->td_proc;
> +               PROC_LOCK_ASSERT(p, MA_OWNED);
>                 critical_enter();
>                 switchtime = PCPU_GET(switchtime);
>                 curtime = cpu_ticks();
> @@ -263,6 +266,8 @@ get_thread_cputime(struct thread *targettd, struct tim
>                 critical_exit();
>                 runtime += curtime - switchtime;
>         } else {
> +               p = targettd->td_proc;
> +               PROC_LOCK_ASSERT(p, MA_OWNED);
>                 thread_lock(targettd);
>                 runtime = targettd->td_runtime;
>                 thread_unlock(targettd);
> @@ -270,12 +275,13 @@ get_thread_cputime(struct thread *targettd, struct tim
>         cputick2timespec(runtime, ats);
>  }
>
> -static void
> -get_process_cputime(struct proc *targetp, struct timespec *ats)
> +void
> +kern_process_cputime(struct proc *targetp, struct timespec *ats)
>  {
>         uint64_t runtime;
>         struct rusage ru;
>
> +       PROC_LOCK_ASSERT(targetp, MA_OWNED);
>         PROC_STATLOCK(targetp);
>         rufetch(targetp, &ru);
>         runtime = targetp->p_rux.rux_runtime;
> @@ -300,14 +306,14 @@ get_cputime(struct thread *td, clockid_t clock_id, str
>                 td2 = tdfind(tid, p->p_pid);
>                 if (td2 == NULL)
>                         return (EINVAL);
> -               get_thread_cputime(td2, ats);
> +               kern_thread_cputime(td2, ats);
>                 PROC_UNLOCK(td2->td_proc);
>         } else {
>                 pid = clock_id & CPUCLOCK_ID_MASK;
>                 error = pget(pid, PGET_CANSEE, &p2);
>                 if (error != 0)
>                         return (EINVAL);
> -               get_process_cputime(p2, ats);
> +               kern_process_cputime(p2, ats);
>                 PROC_UNLOCK(p2);
>         }
>         return (0);
> @@ -360,11 +366,11 @@ kern_clock_gettime(struct thread *td, clockid_t clock_
>                 ats->tv_nsec = 0;
>                 break;
>         case CLOCK_THREAD_CPUTIME_ID:
> -               get_thread_cputime(NULL, ats);
> +               kern_thread_cputime(NULL, ats);
>                 break;
>         case CLOCK_PROCESS_CPUTIME_ID:
>                 PROC_LOCK(p);
> -               get_process_cputime(p, ats);
> +               kern_process_cputime(p, ats);
>                 PROC_UNLOCK(p);
>                 break;
>         default:
>
> Modified: head/sys/sys/syscallsubr.h
> ==============================================================================
> --- head/sys/sys/syscallsubr.h  Tue Feb  4 05:23:34 2020        (r357491)
> +++ head/sys/sys/syscallsubr.h  Tue Feb  4 05:25:51 2020        (r357492)
> @@ -91,6 +91,8 @@ int   kern_clock_nanosleep(struct thread *td, clockid_t
>             const struct timespec *rqtp, struct timespec *rmtp);
>  int    kern_clock_settime(struct thread *td, clockid_t clock_id,
>             struct timespec *ats);
> +void   kern_thread_cputime(struct thread *targettd, struct timespec *ats);
> +void   kern_process_cputime(struct proc *targetp, struct timespec *ats);
>  int    kern_close(struct thread *td, int fd);
>  int    kern_connectat(struct thread *td, int dirfd, int fd,
>             struct sockaddr *sa);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAG6CVpVkdw5t=FYozt7-Q8trRd_0gK7tn0VXdUn-O4t28786fw>