https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=218571
Bug ID: 218571 Summary: umtx compat6 regression affecting 'jar' command Product: Base System Version: 11.0-RELEASE Hardware: amd64 OS: Any Status: New Severity: Affects Some People Priority: --- Component: kern Assignee: freebsd-bugs@FreeBSD.org Reporter: nicholas.hardi...@gmail.com Hello, I'm in the process of upgrading about a hundred 8.2-RELEASE systems to 11.0-RELEASE (maybe 11.1 by the time I'm finished), and hit a snag with one of my regression tests. It involves running 'jar' from jdk1.5.0 (originally built on 6.3-RELEASE I believe), which goes into a loop and hangs. Replicating it is very simple - just run 'jar' and instead of displaying the usage message, it starts spinning. I ran it under truss, and after some normal-looking things (like a bunch of compat6 syscalls) saw a bunch of this at the end: _umtx_op(0x641c10,UMTX_OP_RESERVED0,0x18947,0x0,0x0) ERR#45 'Operation not supported' Looking through the svn history, it appears that two umtx syscalls were removed in https://svnweb.freebsd.org/base?view=revision&revision=263318 and https://svnweb.freebsd.org/base?view=revision&revision=304525. I don't consider myself a kernel developer, but I managed to cobble together a patch that got them working again for my use case. There is currently a TODO regarding the error handling - I just wanted to prove this would work and fix the jar issue. Looking through the rest of the code, it feels to me like the correct thing to do is put this stuff back in under #ifdef COMPAT_FREEBSD6. I have attached a patch that resolves my issue with jar. If the above approach sounds reasonable, I can work on cleaning it up into an actual, acceptable, form. Thanks, -Nicholas diff -u -r src.fbsd11.stock/lib/libc/sys/Symbol.map src.oldumtx/lib/libc/sys/Symbol.map --- src.fbsd11.stock/lib/libc/sys/Symbol.map 2016-09-28 19:25:57.000000000 -0400 +++ src.oldumtx/lib/libc/sys/Symbol.map 2017-04-05 13:54:37.026112000 -0400 @@ -34,7 +34,9 @@ __setugid; __syscall; __sysctl; + _umtx_lock; _umtx_op; + _umtx_unlock; abort2; accept; access; @@ -453,8 +455,12 @@ __sys___syscall; ___sysctl; __sys___sysctl; + __umtx_lock; + __sys__umtx_lock; __umtx_op; __sys__umtx_op; + __umtx_unlock; + __sys__umtx_unlock; _abort2; __sys_abort2; _accept; diff -u -r src.fbsd11.stock/sys/compat/freebsd32/freebsd32_proto.h src.oldumtx/sys/compat/freebsd32/freebsd32_proto.h --- src.fbsd11.stock/sys/compat/freebsd32/freebsd32_proto.h 2016-09-28 19:24:55.000000000 -0400 +++ src.oldumtx/sys/compat/freebsd32/freebsd32_proto.h 2017-04-05 15:48:00.638984000 -0400 @@ -2,8 +2,8 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: releng/11.0/sys/compat/freebsd32/freebsd32_proto.h 303858 2016-08-08 21:19:57Z bdrewery $ - * created from FreeBSD: stable/11/sys/compat/freebsd32/syscalls.master 302094 2016-06-22 21:15:59Z brooks + * $FreeBSD$ + * created from FreeBSD: releng/11.0/sys/compat/freebsd32/syscalls.master 302094 2016-06-22 21:15:59Z brooks */ #ifndef _FREEBSD32_SYSPROTO_H_ @@ -359,6 +359,12 @@ char oucp_l_[PADL_(struct freebsd32_ucontext *)]; struct freebsd32_ucontext * oucp; char oucp_r_[PADR_(struct freebsd32_ucontext *)]; char ucp_l_[PADL_(const struct freebsd32_ucontext *)]; const struct freebsd32_ucontext * ucp; char ucp_r_[PADR_(const struct freebsd32_ucontext *)]; }; +struct freebsd32_umtx_lock_args { + char umtx_l_[PADL_(struct umtx *)]; struct umtx * umtx; char umtx_r_[PADR_(struct umtx *)]; +}; +struct freebsd32_umtx_unlock_args { + char umtx_l_[PADL_(struct umtx *)]; struct umtx * umtx; char umtx_r_[PADR_(struct umtx *)]; +}; struct freebsd32_ksem_timedwait_args { char id_l_[PADL_(semid_t)]; semid_t id; char id_r_[PADR_(semid_t)]; char abstime_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * abstime; char abstime_r_[PADR_(const struct timespec32 *)]; @@ -757,6 +763,8 @@ int freebsd32_getcontext(struct thread *, struct freebsd32_getcontext_args *); int freebsd32_setcontext(struct thread *, struct freebsd32_setcontext_args *); int freebsd32_swapcontext(struct thread *, struct freebsd32_swapcontext_args *); +int freebsd32_umtx_lock(struct thread *, struct freebsd32_umtx_lock_args *); +int freebsd32_umtx_unlock(struct thread *, struct freebsd32_umtx_unlock_args *); int freebsd32_ksem_timedwait(struct thread *, struct freebsd32_ksem_timedwait_args *); int freebsd32_thr_suspend(struct thread *, struct freebsd32_thr_suspend_args *); int freebsd32_umtx_op(struct thread *, struct freebsd32_umtx_op_args *); @@ -1223,6 +1231,8 @@ #define FREEBSD32_SYS_AUE_freebsd32_getcontext AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_setcontext AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_swapcontext AUE_NULL +#define FREEBSD32_SYS_AUE_freebsd32_umtx_lock AUE_NULL +#define FREEBSD32_SYS_AUE_freebsd32_umtx_unlock AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_ksem_timedwait AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_thr_suspend AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_umtx_op AUE_NULL diff -u -r src.fbsd11.stock/sys/compat/freebsd32/freebsd32_syscall.h src.oldumtx/sys/compat/freebsd32/freebsd32_syscall.h --- src.fbsd11.stock/sys/compat/freebsd32/freebsd32_syscall.h 2016-09-28 19:24:55.000000000 -0400 +++ src.oldumtx/sys/compat/freebsd32/freebsd32_syscall.h 2017-04-05 15:48:00.635260000 -0400 @@ -2,8 +2,8 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: releng/11.0/sys/compat/freebsd32/freebsd32_syscall.h 303858 2016-08-08 21:19:57Z bdrewery $ - * created from FreeBSD: stable/11/sys/compat/freebsd32/syscalls.master 302094 2016-06-22 21:15:59Z brooks + * $FreeBSD$ + * created from FreeBSD: releng/11.0/sys/compat/freebsd32/syscalls.master 302094 2016-06-22 21:15:59Z brooks */ #define FREEBSD32_SYS_syscall 0 @@ -339,6 +339,8 @@ #define FREEBSD32_SYS_thr_exit 431 #define FREEBSD32_SYS_thr_self 432 #define FREEBSD32_SYS_thr_kill 433 +#define FREEBSD32_SYS_freebsd32_umtx_lock 434 +#define FREEBSD32_SYS_freebsd32_umtx_unlock 435 #define FREEBSD32_SYS_jail_attach 436 #define FREEBSD32_SYS_extattr_list_fd 437 #define FREEBSD32_SYS_extattr_list_file 438 diff -u -r src.fbsd11.stock/sys/compat/freebsd32/freebsd32_syscalls.c src.oldumtx/sys/compat/freebsd32/freebsd32_syscalls.c --- src.fbsd11.stock/sys/compat/freebsd32/freebsd32_syscalls.c 2016-09-28 19:24:55.000000000 -0400 +++ src.oldumtx/sys/compat/freebsd32/freebsd32_syscalls.c 2017-04-05 15:48:00.635249000 -0400 @@ -2,8 +2,8 @@ * System call names. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: releng/11.0/sys/compat/freebsd32/freebsd32_syscalls.c 303858 2016-08-08 21:19:57Z bdrewery $ - * created from FreeBSD: stable/11/sys/compat/freebsd32/syscalls.master 302094 2016-06-22 21:15:59Z brooks + * $FreeBSD$ + * created from FreeBSD: releng/11.0/sys/compat/freebsd32/syscalls.master 302094 2016-06-22 21:15:59Z brooks */ const char *freebsd32_syscallnames[] = { @@ -444,8 +444,8 @@ "thr_exit", /* 431 = thr_exit */ "thr_self", /* 432 = thr_self */ "thr_kill", /* 433 = thr_kill */ - "#434", /* 434 = nosys */ - "#435", /* 435 = nosys */ + "freebsd32_umtx_lock", /* 434 = freebsd32_umtx_lock */ + "freebsd32_umtx_unlock", /* 435 = freebsd32_umtx_unlock */ "jail_attach", /* 436 = jail_attach */ "extattr_list_fd", /* 437 = extattr_list_fd */ "extattr_list_file", /* 438 = extattr_list_file */ diff -u -r src.fbsd11.stock/sys/compat/freebsd32/freebsd32_sysent.c src.oldumtx/sys/compat/freebsd32/freebsd32_sysent.c --- src.fbsd11.stock/sys/compat/freebsd32/freebsd32_sysent.c 2016-09-28 19:24:55.000000000 -0400 +++ src.oldumtx/sys/compat/freebsd32/freebsd32_sysent.c 2017-04-05 15:48:00.637117000 -0400 @@ -2,8 +2,8 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: releng/11.0/sys/compat/freebsd32/freebsd32_sysent.c 303858 2016-08-08 21:19:57Z bdrewery $ - * created from FreeBSD: stable/11/sys/compat/freebsd32/syscalls.master 302094 2016-06-22 21:15:59Z brooks + * $FreeBSD$ + * created from FreeBSD: releng/11.0/sys/compat/freebsd32/syscalls.master 302094 2016-06-22 21:15:59Z brooks */ #include "opt_compat.h" @@ -487,8 +487,8 @@ { AS(thr_exit_args), (sy_call_t *)sys_thr_exit, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 431 = thr_exit */ { AS(thr_self_args), (sy_call_t *)sys_thr_self, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 432 = thr_self */ { AS(thr_kill_args), (sy_call_t *)sys_thr_kill, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 433 = thr_kill */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 434 = nosys */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 435 = nosys */ + { AS(freebsd32_umtx_lock_args), (sy_call_t *)freebsd32_umtx_lock, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 434 = freebsd32_umtx_lock */ + { AS(freebsd32_umtx_unlock_args), (sy_call_t *)freebsd32_umtx_unlock, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 435 = freebsd32_umtx_unlock */ { AS(jail_attach_args), (sy_call_t *)sys_jail_attach, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 436 = jail_attach */ { AS(extattr_list_fd_args), (sy_call_t *)sys_extattr_list_fd, AUE_EXTATTR_LIST_FD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 437 = extattr_list_fd */ { AS(extattr_list_file_args), (sy_call_t *)sys_extattr_list_file, AUE_EXTATTR_LIST_FILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 438 = extattr_list_file */ diff -u -r src.fbsd11.stock/sys/compat/freebsd32/freebsd32_systrace_args.c src.oldumtx/sys/compat/freebsd32/freebsd32_systrace_args.c --- src.fbsd11.stock/sys/compat/freebsd32/freebsd32_systrace_args.c 2016-09-28 19:24:55.000000000 -0400 +++ src.oldumtx/sys/compat/freebsd32/freebsd32_systrace_args.c 2017-04-05 15:48:00.641174000 -0400 @@ -2,7 +2,7 @@ * System call argument to DTrace register array converstion. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: releng/11.0/sys/compat/freebsd32/freebsd32_systrace_args.c 302095 2016-06-22 21:18:19Z brooks $ + * $FreeBSD$ * This file is part of the DTrace syscall provider. */ @@ -2200,6 +2200,20 @@ *n_args = 2; break; } + /* freebsd32_umtx_lock */ + case 434: { + struct freebsd32_umtx_lock_args *p = params; + uarg[0] = (intptr_t) p->umtx; /* struct umtx * */ + *n_args = 1; + break; + } + /* freebsd32_umtx_unlock */ + case 435: { + struct freebsd32_umtx_unlock_args *p = params; + uarg[0] = (intptr_t) p->umtx; /* struct umtx * */ + *n_args = 1; + break; + } /* jail_attach */ case 436: { struct jail_attach_args *p = params; @@ -6866,6 +6880,26 @@ break; }; break; + /* freebsd32_umtx_lock */ + case 434: + switch(ndx) { + case 0: + p = "struct umtx *"; + break; + default: + break; + }; + break; + /* freebsd32_umtx_unlock */ + case 435: + switch(ndx) { + case 0: + p = "struct umtx *"; + break; + default: + break; + }; + break; /* jail_attach */ case 436: switch(ndx) { @@ -10189,6 +10223,16 @@ if (ndx == 0 || ndx == 1) p = "int"; break; + /* freebsd32_umtx_lock */ + case 434: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* freebsd32_umtx_unlock */ + case 435: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* jail_attach */ case 436: if (ndx == 0 || ndx == 1) diff -u -r src.fbsd11.stock/sys/compat/freebsd32/syscalls.master src.oldumtx/sys/compat/freebsd32/syscalls.master --- src.fbsd11.stock/sys/compat/freebsd32/syscalls.master 2016-09-28 19:24:55.000000000 -0400 +++ src.oldumtx/sys/compat/freebsd32/syscalls.master 2017-04-04 14:06:39.408900000 -0400 @@ -777,8 +777,8 @@ 431 AUE_NULL NOPROTO { void thr_exit(long *state); } 432 AUE_NULL NOPROTO { int thr_self(long *id); } 433 AUE_NULL NOPROTO { int thr_kill(long id, int sig); } -434 AUE_NULL UNIMPL nosys -435 AUE_NULL UNIMPL nosys +434 AUE_NULL STD { int freebsd32_umtx_lock(struct umtx *umtx); } +435 AUE_NULL STD { int freebsd32_umtx_unlock(struct umtx *umtx); } 436 AUE_NULL NOPROTO { int jail_attach(int jid); } 437 AUE_EXTATTR_LIST_FD NOPROTO { ssize_t extattr_list_fd(int fd, \ int attrnamespace, void *data, \ diff -u -r src.fbsd11.stock/sys/kern/capabilities.conf src.oldumtx/sys/kern/capabilities.conf --- src.fbsd11.stock/sys/kern/capabilities.conf 2016-09-28 19:24:40.000000000 -0400 +++ src.oldumtx/sys/kern/capabilities.conf 2017-04-05 14:17:10.920476000 -0400 @@ -64,7 +64,9 @@ ## ## XXRW: Need to check this very carefully. ## +_umtx_lock _umtx_op +_umtx_unlock ## ## Allow process termination using abort2(2). diff -u -r src.fbsd11.stock/sys/kern/init_sysent.c src.oldumtx/sys/kern/init_sysent.c --- src.fbsd11.stock/sys/kern/init_sysent.c 2016-09-28 19:24:40.000000000 -0400 +++ src.oldumtx/sys/kern/init_sysent.c 2017-04-05 15:44:29.739973000 -0400 @@ -2,8 +2,8 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: releng/11.0/sys/kern/init_sysent.c 303858 2016-08-08 21:19:57Z bdrewery $ - * created from FreeBSD: stable/11/sys/kern/syscalls.master 303854 2016-08-08 20:23:11Z bdrewery + * $FreeBSD$ + * created from FreeBSD: releng/11.0/sys/kern/syscalls.master 303854 2016-08-08 20:23:11Z bdrewery */ #include "opt_compat.h" @@ -480,8 +480,8 @@ { AS(thr_exit_args), (sy_call_t *)sys_thr_exit, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 431 = thr_exit */ { AS(thr_self_args), (sy_call_t *)sys_thr_self, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 432 = thr_self */ { AS(thr_kill_args), (sy_call_t *)sys_thr_kill, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 433 = thr_kill */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 434 = nosys */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 435 = nosys */ + { AS(_umtx_lock_args), (sy_call_t *)sys__umtx_lock, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 434 = _umtx_lock */ + { AS(_umtx_unlock_args), (sy_call_t *)sys__umtx_unlock, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 435 = _umtx_unlock */ { AS(jail_attach_args), (sy_call_t *)sys_jail_attach, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 436 = jail_attach */ { AS(extattr_list_fd_args), (sy_call_t *)sys_extattr_list_fd, AUE_EXTATTR_LIST_FD, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 437 = extattr_list_fd */ { AS(extattr_list_file_args), (sy_call_t *)sys_extattr_list_file, AUE_EXTATTR_LIST_FILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 438 = extattr_list_file */ diff -u -r src.fbsd11.stock/sys/kern/kern_umtx.c src.oldumtx/sys/kern/kern_umtx.c --- src.fbsd11.stock/sys/kern/kern_umtx.c 2016-09-28 19:24:40.000000000 -0400 +++ src.oldumtx/sys/kern/kern_umtx.c 2017-04-05 15:52:53.900304000 -0400 @@ -909,6 +909,367 @@ } /* + * Lock a umtx object. + */ +static int +do_lock_umtx(struct thread *td, struct umtx *umtx, u_long id, + const struct timespec *timeout) +{ + struct abs_timeout timo; + struct umtx_q *uq; + u_long owner; + u_long old; + int error = 0; + + uq = td->td_umtxq; + if (timeout != NULL) + abs_timeout_init(&timo, CLOCK_REALTIME, 0, timeout); + + /* + * Care must be exercised when dealing with umtx structure. It + * can fault on any access. + */ + for (;;) { + /* + * Try the uncontested case. This should be done in userland. + */ + owner = casuword(&umtx->u_owner, UMTX_UNOWNED, id); + + /* The acquire succeeded. */ + if (owner == UMTX_UNOWNED) + return (0); + + /* The address was invalid. */ + if (owner == -1) + return (EFAULT); + + /* If no one owns it but it is contested try to acquire it. */ + if (owner == UMTX_CONTESTED) { + owner = casuword(&umtx->u_owner, + UMTX_CONTESTED, id | UMTX_CONTESTED); + + if (owner == UMTX_CONTESTED) + return (0); + + /* The address was invalid. */ + if (owner == -1) + return (EFAULT); + + error = umtxq_check_susp(td); + if (error != 0) + break; + + /* If this failed the lock has changed, restart. */ + continue; + } + + /* + * If we caught a signal, we have retried and now + * exit immediately. + */ + if (error != 0) + break; + + if ((error = umtx_key_get(umtx, TYPE_SIMPLE_LOCK, + AUTO_SHARE, &uq->uq_key)) != 0) + return (error); + + umtxq_lock(&uq->uq_key); + umtxq_busy(&uq->uq_key); + umtxq_insert(uq); + umtxq_unbusy(&uq->uq_key); + umtxq_unlock(&uq->uq_key); + + /* + * Set the contested bit so that a release in user space + * knows to use the system call for unlock. If this fails + * either some one else has acquired the lock or it has been + * released. + */ + old = casuword(&umtx->u_owner, owner, owner | UMTX_CONTESTED); + + /* The address was invalid. */ + if (old == -1) { + umtxq_lock(&uq->uq_key); + umtxq_remove(uq); + umtxq_unlock(&uq->uq_key); + umtx_key_release(&uq->uq_key); + return (EFAULT); + } + + /* + * We set the contested bit, sleep. Otherwise the lock changed + * and we need to retry or we lost a race to the thread + * unlocking the umtx. + */ + umtxq_lock(&uq->uq_key); + if (old == owner) + error = umtxq_sleep(uq, "umtx", timeout == NULL ? NULL : + &timo); + umtxq_remove(uq); + umtxq_unlock(&uq->uq_key); + umtx_key_release(&uq->uq_key); + + if (error == 0) + error = umtxq_check_susp(td); + } + + if (timeout == NULL) { + /* Mutex locking is restarted if it is interrupted. */ + if (error == EINTR) + error = ERESTART; + } else { + /* Timed-locking is not restarted. */ + if (error == ERESTART) + error = EINTR; + } + return (error); +} + +/* + * Unlock a umtx object. + */ +static int +do_unlock_umtx(struct thread *td, struct umtx *umtx, u_long id) +{ + struct umtx_key key; + u_long owner; + u_long old; + int error; + int count; + + /* + * Make sure we own this mtx. + */ + owner = fuword(__DEVOLATILE(u_long *, &umtx->u_owner)); + if (owner == -1) + return (EFAULT); + + if ((owner & ~UMTX_CONTESTED) != id) + return (EPERM); + + /* This should be done in userland */ + if ((owner & UMTX_CONTESTED) == 0) { + old = casuword(&umtx->u_owner, owner, UMTX_UNOWNED); + if (old == -1) + return (EFAULT); + if (old == owner) + return (0); + owner = old; + } + + /* We should only ever be in here for contested locks */ + if ((error = umtx_key_get(umtx, TYPE_SIMPLE_LOCK, AUTO_SHARE, + &key)) != 0) + return (error); + + umtxq_lock(&key); + umtxq_busy(&key); + count = umtxq_count(&key); + umtxq_unlock(&key); + + /* + * When unlocking the umtx, it must be marked as unowned if + * there is zero or one thread only waiting for it. + * Otherwise, it must be marked as contested. + */ + old = casuword(&umtx->u_owner, owner, + count <= 1 ? UMTX_UNOWNED : UMTX_CONTESTED); + umtxq_lock(&key); + umtxq_signal(&key,1); + umtxq_unbusy(&key); + umtxq_unlock(&key); + umtx_key_release(&key); + if (old == -1) + return (EFAULT); + if (old != owner) + return (EINVAL); + return (0); +} + +#ifdef COMPAT_FREEBSD32 + +/* + * Lock a umtx object. + */ +static int +do_lock_umtx32(struct thread *td, uint32_t *m, uint32_t id, + const struct timespec *timeout) +{ + struct abs_timeout timo; + struct umtx_q *uq; + uint32_t owner; + uint32_t old; + int error = 0; + + uq = td->td_umtxq; + + if (timeout != NULL) + abs_timeout_init(&timo, CLOCK_REALTIME, 0, timeout); + + /* + * Care must be exercised when dealing with umtx structure. It + * can fault on any access. + */ + for (;;) { + /* + * Try the uncontested case. This should be done in userland. + */ + owner = casuword32(m, UMUTEX_UNOWNED, id); + + /* The acquire succeeded. */ + if (owner == UMUTEX_UNOWNED) + return (0); + + /* The address was invalid. */ + if (owner == -1) + return (EFAULT); + + /* If no one owns it but it is contested try to acquire it. */ + if (owner == UMUTEX_CONTESTED) { + owner = casuword32(m, + UMUTEX_CONTESTED, id | UMUTEX_CONTESTED); + if (owner == UMUTEX_CONTESTED) + return (0); + + /* The address was invalid. */ + if (owner == -1) + return (EFAULT); + + error = umtxq_check_susp(td); + if (error != 0) + break; + + /* If this failed the lock has changed, restart. */ + continue; + } + + /* + * If we caught a signal, we have retried and now + * exit immediately. + */ + if (error != 0) + return (error); + + if ((error = umtx_key_get(m, TYPE_SIMPLE_LOCK, + AUTO_SHARE, &uq->uq_key)) != 0) + return (error); + + umtxq_lock(&uq->uq_key); + umtxq_busy(&uq->uq_key); + umtxq_insert(uq); + umtxq_unbusy(&uq->uq_key); + umtxq_unlock(&uq->uq_key); + + /* + * Set the contested bit so that a release in user space + * knows to use the system call for unlock. If this fails + * either some one else has acquired the lock or it has been + * released. + */ + old = casuword32(m, owner, owner | UMUTEX_CONTESTED); + + /* The address was invalid. */ + if (old == -1) { + umtxq_lock(&uq->uq_key); + umtxq_remove(uq); + umtxq_unlock(&uq->uq_key); + umtx_key_release(&uq->uq_key); + return (EFAULT); + } + + /* + * We set the contested bit, sleep. Otherwise the lock changed + * and we need to retry or we lost a race to the thread + * unlocking the umtx. + */ + umtxq_lock(&uq->uq_key); + if (old == owner) + error = umtxq_sleep(uq, "umtx", timeout == NULL ? + NULL : &timo); + umtxq_remove(uq); + umtxq_unlock(&uq->uq_key); + umtx_key_release(&uq->uq_key); + + if (error == 0) + error = umtxq_check_susp(td); + } + + if (timeout == NULL) { + /* Mutex locking is restarted if it is interrupted. */ + if (error == EINTR) + error = ERESTART; + } else { + /* Timed-locking is not restarted. */ + if (error == ERESTART) + error = EINTR; + } + return (error); +} + +/* + * Unlock a umtx object. + */ +static int +do_unlock_umtx32(struct thread *td, uint32_t *m, uint32_t id) +{ + struct umtx_key key; + uint32_t owner; + uint32_t old; + int error; + int count; + + /* + * Make sure we own this mtx. + */ + owner = fuword32(m); + if (owner == -1) + return (EFAULT); + + if ((owner & ~UMUTEX_CONTESTED) != id) + return (EPERM); + + /* This should be done in userland */ + if ((owner & UMUTEX_CONTESTED) == 0) { + old = casuword32(m, owner, UMUTEX_UNOWNED); + if (old == -1) + return (EFAULT); + if (old == owner) + return (0); + owner = old; + } + + /* We should only ever be in here for contested locks */ + if ((error = umtx_key_get(m, TYPE_SIMPLE_LOCK, AUTO_SHARE, + &key)) != 0) + return (error); + + umtxq_lock(&key); + umtxq_busy(&key); + count = umtxq_count(&key); + umtxq_unlock(&key); + + /* + * When unlocking the umtx, it must be marked as unowned if + * there is zero or one thread only waiting for it. + * Otherwise, it must be marked as contested. + */ + old = casuword32(m, owner, + count <= 1 ? UMUTEX_UNOWNED : UMUTEX_CONTESTED); + umtxq_lock(&key); + umtxq_signal(&key,1); + umtxq_unbusy(&key); + umtxq_unlock(&key); + umtx_key_release(&key); + if (old == -1) + return (EFAULT); + if (old != owner) + return (EINVAL); + return (0); +} +#endif + +/* * Fetch and compare value, sleep on the address if value is not changed. */ static int @@ -1078,6 +1439,10 @@ } } + if ((flags & UMUTEX_ERROR_CHECK) != 0 && + (owner & ~UMUTEX_CONTESTED) == id) + return (EDEADLK); + if (mode == _UMUTEX_TRY) return (EBUSY); @@ -1880,6 +2245,12 @@ break; } + if ((flags & UMUTEX_ERROR_CHECK) != 0 && + (owner & ~UMUTEX_CONTESTED) == id) { + error = EDEADLK; + break; + } + if (try != 0) { error = EBUSY; break; @@ -2149,6 +2520,12 @@ break; } + if ((flags & UMUTEX_ERROR_CHECK) != 0 && + (owner & ~UMUTEX_CONTESTED) == id) { + error = EDEADLK; + break; + } + if (try != 0) { error = EBUSY; break; @@ -3258,6 +3635,20 @@ return (error); } +int +sys__umtx_lock(struct thread *td, struct _umtx_lock_args *uap) + /* struct umtx *umtx */ +{ + return do_lock_umtx(td, uap->umtx, td->td_tid, 0); +} + +int +sys__umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap) + /* struct umtx *umtx */ +{ + return do_unlock_umtx(td, uap->umtx, td->td_tid); +} + inline int umtx_copyin_timeout(const void *addr, struct timespec *tsp) { @@ -3293,10 +3684,27 @@ } static int -__umtx_op_unimpl(struct thread *td, struct _umtx_op_args *uap) +__umtx_op_lock_umtx(struct thread *td, struct _umtx_op_args *uap) { + struct timespec *ts, timeout; + int error; + + /* Allow a null timespec (wait forever). */ + if (uap->uaddr2 == NULL) + ts = NULL; + else { + error = umtx_copyin_timeout(uap->uaddr2, &timeout); + if (error != 0) + return (error); + ts = &timeout; + } + return (do_lock_umtx(td, uap->obj, uap->val, ts)); +} - return (EOPNOTSUPP); +static int +__umtx_op_unlock_umtx(struct thread *td, struct _umtx_op_args *uap) +{ + return (do_unlock_umtx(td, uap->obj, uap->val)); } static int @@ -3926,8 +4334,8 @@ typedef int (*_umtx_op_func)(struct thread *td, struct _umtx_op_args *uap); static const _umtx_op_func op_table[] = { - [UMTX_OP_RESERVED0] = __umtx_op_unimpl, - [UMTX_OP_RESERVED1] = __umtx_op_unimpl, + [UMTX_OP_LOCK] = __umtx_op_lock_umtx, + [UMTX_OP_UNLOCK] = __umtx_op_unlock_umtx, [UMTX_OP_WAIT] = __umtx_op_wait, [UMTX_OP_WAKE] = __umtx_op_wake, [UMTX_OP_MUTEX_TRYLOCK] = __umtx_op_trylock_umutex, @@ -3970,6 +4378,19 @@ } #ifdef COMPAT_FREEBSD32 +int +freebsd32_umtx_lock(struct thread *td, struct freebsd32_umtx_lock_args *uap) + /* struct umtx *umtx */ +{ + return (do_lock_umtx32(td, (uint32_t *)uap->umtx, td->td_tid, NULL)); +} + +int +freebsd32_umtx_unlock(struct thread *td, struct freebsd32_umtx_unlock_args *uap) + /* struct umtx *umtx */ +{ + return (do_unlock_umtx32(td, (uint32_t *)uap->umtx, td->td_tid)); +} struct timespec32 { int32_t tv_sec; @@ -4027,6 +4448,30 @@ } static int +__umtx_op_lock_umtx_compat32(struct thread *td, struct _umtx_op_args *uap) +{ + struct timespec *ts, timeout; + int error; + + /* Allow a null timespec (wait forever). */ + if (uap->uaddr2 == NULL) + ts = NULL; + else { + error = umtx_copyin_timeout32(uap->uaddr2, &timeout); + if (error != 0) + return (error); + ts = &timeout; + } + return (do_lock_umtx32(td, uap->obj, uap->val, ts)); +} + +static int +__umtx_op_unlock_umtx_compat32(struct thread *td, struct _umtx_op_args *uap) +{ + return (do_unlock_umtx32(td, uap->obj, (uint32_t)uap->val)); +} + +static int __umtx_op_wait_compat32(struct thread *td, struct _umtx_op_args *uap) { struct _umtx_time *tm_p, timeout; @@ -4245,8 +4690,8 @@ } static const _umtx_op_func op_table_compat32[] = { - [UMTX_OP_RESERVED0] = __umtx_op_unimpl, - [UMTX_OP_RESERVED1] = __umtx_op_unimpl, + [UMTX_OP_LOCK] = __umtx_op_lock_umtx_compat32, + [UMTX_OP_UNLOCK] = __umtx_op_unlock_umtx_compat32, [UMTX_OP_WAIT] = __umtx_op_wait_compat32, [UMTX_OP_WAKE] = __umtx_op_wake, [UMTX_OP_MUTEX_TRYLOCK] = __umtx_op_trylock_umutex, diff -u -r src.fbsd11.stock/sys/kern/syscalls.c src.oldumtx/sys/kern/syscalls.c --- src.fbsd11.stock/sys/kern/syscalls.c 2016-09-28 19:24:40.000000000 -0400 +++ src.oldumtx/sys/kern/syscalls.c 2017-04-05 15:44:29.738110000 -0400 @@ -2,8 +2,8 @@ * System call names. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: releng/11.0/sys/kern/syscalls.c 303858 2016-08-08 21:19:57Z bdrewery $ - * created from FreeBSD: stable/11/sys/kern/syscalls.master 303854 2016-08-08 20:23:11Z bdrewery + * $FreeBSD$ + * created from FreeBSD: releng/11.0/sys/kern/syscalls.master 303854 2016-08-08 20:23:11Z bdrewery */ const char *syscallnames[] = { @@ -441,8 +441,8 @@ "thr_exit", /* 431 = thr_exit */ "thr_self", /* 432 = thr_self */ "thr_kill", /* 433 = thr_kill */ - "#434", /* 434 = nosys */ - "#435", /* 435 = nosys */ + "_umtx_lock", /* 434 = _umtx_lock */ + "_umtx_unlock", /* 435 = _umtx_unlock */ "jail_attach", /* 436 = jail_attach */ "extattr_list_fd", /* 437 = extattr_list_fd */ "extattr_list_file", /* 438 = extattr_list_file */ diff -u -r src.fbsd11.stock/sys/kern/syscalls.master src.oldumtx/sys/kern/syscalls.master --- src.fbsd11.stock/sys/kern/syscalls.master 2016-09-28 19:24:40.000000000 -0400 +++ src.oldumtx/sys/kern/syscalls.master 2017-04-04 13:50:05.910545000 -0400 @@ -774,8 +774,8 @@ 431 AUE_NULL STD { void thr_exit(long *state); } 432 AUE_NULL STD { int thr_self(long *id); } 433 AUE_NULL STD { int thr_kill(long id, int sig); } -434 AUE_NULL UNIMPL nosys -435 AUE_NULL UNIMPL nosys +434 AUE_NULL STD { int _umtx_lock(struct umtx *umtx); } +435 AUE_NULL STD { int _umtx_unlock(struct umtx *umtx); } 436 AUE_NULL STD { int jail_attach(int jid); } 437 AUE_EXTATTR_LIST_FD STD { ssize_t extattr_list_fd(int fd, \ int attrnamespace, void *data, \ diff -u -r src.fbsd11.stock/sys/kern/systrace_args.c src.oldumtx/sys/kern/systrace_args.c --- src.fbsd11.stock/sys/kern/systrace_args.c 2016-09-28 19:24:40.000000000 -0400 +++ src.oldumtx/sys/kern/systrace_args.c 2017-04-05 15:44:29.743862000 -0400 @@ -2,7 +2,7 @@ * System call argument to DTrace register array converstion. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: releng/11.0/sys/kern/systrace_args.c 302095 2016-06-22 21:18:19Z brooks $ + * $FreeBSD$ * This file is part of the DTrace syscall provider. */ @@ -2362,6 +2362,20 @@ *n_args = 2; break; } + /* _umtx_lock */ + case 434: { + struct _umtx_lock_args *p = params; + uarg[0] = (intptr_t) p->umtx; /* struct umtx * */ + *n_args = 1; + break; + } + /* _umtx_unlock */ + case 435: { + struct _umtx_unlock_args *p = params; + uarg[0] = (intptr_t) p->umtx; /* struct umtx * */ + *n_args = 1; + break; + } /* jail_attach */ case 436: { struct jail_attach_args *p = params; @@ -7148,6 +7162,26 @@ break; }; break; + /* _umtx_lock */ + case 434: + switch(ndx) { + case 0: + p = "struct umtx *"; + break; + default: + break; + }; + break; + /* _umtx_unlock */ + case 435: + switch(ndx) { + case 0: + p = "struct umtx *"; + break; + default: + break; + }; + break; /* jail_attach */ case 436: switch(ndx) { @@ -10246,6 +10280,16 @@ if (ndx == 0 || ndx == 1) p = "int"; break; + /* _umtx_lock */ + case 434: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* _umtx_unlock */ + case 435: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* jail_attach */ case 436: if (ndx == 0 || ndx == 1) diff -u -r src.fbsd11.stock/sys/sys/_umtx.h src.oldumtx/sys/sys/_umtx.h --- src.fbsd11.stock/sys/sys/_umtx.h 2016-09-28 19:24:41.000000000 -0400 +++ src.oldumtx/sys/sys/_umtx.h 2017-04-04 13:51:15.942811000 -0400 @@ -33,6 +33,10 @@ #include <sys/_types.h> #include <sys/_timespec.h> +struct umtx { + volatile unsigned long u_owner; /*Owner of the mutex. */ +}; + struct umutex { volatile __lwpid_t m_owner; /* Owner of the mutex */ __uint32_t m_flags; /* Flags of the mutex */ diff -u -r src.fbsd11.stock/sys/sys/syscall.h src.oldumtx/sys/sys/syscall.h --- src.fbsd11.stock/sys/sys/syscall.h 2016-09-28 19:24:41.000000000 -0400 +++ src.oldumtx/sys/sys/syscall.h 2017-04-05 15:44:29.738119000 -0400 @@ -2,8 +2,8 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: releng/11.0/sys/sys/syscall.h 303858 2016-08-08 21:19:57Z bdrewery $ - * created from FreeBSD: stable/11/sys/kern/syscalls.master 303854 2016-08-08 20:23:11Z bdrewery + * $FreeBSD$ + * created from FreeBSD: releng/11.0/sys/kern/syscalls.master 303854 2016-08-08 20:23:11Z bdrewery */ #define SYS_syscall 0 @@ -359,6 +359,8 @@ #define SYS_thr_exit 431 #define SYS_thr_self 432 #define SYS_thr_kill 433 +#define SYS__umtx_lock 434 +#define SYS__umtx_unlock 435 #define SYS_jail_attach 436 #define SYS_extattr_list_fd 437 #define SYS_extattr_list_file 438 diff -u -r src.fbsd11.stock/sys/sys/syscall.mk src.oldumtx/sys/sys/syscall.mk --- src.fbsd11.stock/sys/sys/syscall.mk 2016-09-28 19:24:41.000000000 -0400 +++ src.oldumtx/sys/sys/syscall.mk 2017-04-05 15:44:29.738095000 -0400 @@ -1,7 +1,7 @@ # FreeBSD system call object files. # DO NOT EDIT-- this file is automatically generated. -# $FreeBSD: releng/11.0/sys/sys/syscall.mk 303858 2016-08-08 21:19:57Z bdrewery $ -# created from FreeBSD: stable/11/sys/kern/syscalls.master 303854 2016-08-08 20:23:11Z bdrewery +# $FreeBSD$ +# created from FreeBSD: releng/11.0/sys/kern/syscalls.master 303854 2016-08-08 20:23:11Z bdrewery MIASM = \ syscall.o \ exit.o \ @@ -289,6 +289,8 @@ thr_exit.o \ thr_self.o \ thr_kill.o \ + _umtx_lock.o \ + _umtx_unlock.o \ jail_attach.o \ extattr_list_fd.o \ extattr_list_file.o \ diff -u -r src.fbsd11.stock/sys/sys/sysproto.h src.oldumtx/sys/sys/sysproto.h --- src.fbsd11.stock/sys/sys/sysproto.h 2016-09-28 19:24:41.000000000 -0400 +++ src.oldumtx/sys/sys/sysproto.h 2017-04-05 15:44:29.741627000 -0400 @@ -2,8 +2,8 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: releng/11.0/sys/sys/sysproto.h 303858 2016-08-08 21:19:57Z bdrewery $ - * created from FreeBSD: stable/11/sys/kern/syscalls.master 303854 2016-08-08 20:23:11Z bdrewery + * $FreeBSD$ + * created from FreeBSD: releng/11.0/sys/kern/syscalls.master 303854 2016-08-08 20:23:11Z bdrewery */ #ifndef _SYS_SYSPROTO_H_ @@ -1250,6 +1250,12 @@ char id_l_[PADL_(long)]; long id; char id_r_[PADR_(long)]; char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)]; }; +struct _umtx_lock_args { + char umtx_l_[PADL_(struct umtx *)]; struct umtx * umtx; char umtx_r_[PADR_(struct umtx *)]; +}; +struct _umtx_unlock_args { + char umtx_l_[PADL_(struct umtx *)]; struct umtx * umtx; char umtx_r_[PADR_(struct umtx *)]; +}; struct jail_attach_args { char jid_l_[PADL_(int)]; int jid; char jid_r_[PADR_(int)]; }; @@ -2067,6 +2073,8 @@ int sys_thr_exit(struct thread *, struct thr_exit_args *); int sys_thr_self(struct thread *, struct thr_self_args *); int sys_thr_kill(struct thread *, struct thr_kill_args *); +int sys__umtx_lock(struct thread *, struct _umtx_lock_args *); +int sys__umtx_unlock(struct thread *, struct _umtx_unlock_args *); int sys_jail_attach(struct thread *, struct jail_attach_args *); int sys_extattr_list_fd(struct thread *, struct extattr_list_fd_args *); int sys_extattr_list_file(struct thread *, struct extattr_list_file_args *); @@ -2844,6 +2852,8 @@ #define SYS_AUE_thr_exit AUE_NULL #define SYS_AUE_thr_self AUE_NULL #define SYS_AUE_thr_kill AUE_NULL +#define SYS_AUE__umtx_lock AUE_NULL +#define SYS_AUE__umtx_unlock AUE_NULL #define SYS_AUE_jail_attach AUE_NULL #define SYS_AUE_extattr_list_fd AUE_EXTATTR_LIST_FD #define SYS_AUE_extattr_list_file AUE_EXTATTR_LIST_FILE diff -u -r src.fbsd11.stock/sys/sys/umtx.h src.oldumtx/sys/sys/umtx.h --- src.fbsd11.stock/sys/sys/umtx.h 2016-09-28 19:24:41.000000000 -0400 +++ src.oldumtx/sys/sys/umtx.h 2017-04-05 17:10:53.884429000 -0400 @@ -31,11 +31,16 @@ #define _SYS_UMTX_H_ #include <sys/_umtx.h> +#include <sys/limits.h> + +#define UMTX_UNOWNED 0x0 +#define UMTX_CONTESTED LONG_MIN /* Common lock flags */ #define USYNC_PROCESS_SHARED 0x0001 /* Process shared sync objs */ /* umutex flags */ +#define UMUTEX_ERROR_CHECK 0x0002 /* Error-checking mutex */ #define UMUTEX_PRIO_INHERIT 0x0004 /* Priority inherited mutex */ #define UMUTEX_PRIO_PROTECT 0x0008 /* Priority protect mutex */ #define UMUTEX_ROBUST 0x0010 /* Robust mutex */ @@ -71,8 +76,8 @@ #define USEM_COUNT(c) ((c) & USEM_MAX_COUNT) /* op code for _umtx_op */ -#define UMTX_OP_RESERVED0 0 -#define UMTX_OP_RESERVED1 1 +#define UMTX_OP_LOCK 0 +#define UMTX_OP_UNLOCK 1 #define UMTX_OP_WAIT 2 #define UMTX_OP_WAKE 3 #define UMTX_OP_MUTEX_TRYLOCK 4 @@ -124,6 +129,88 @@ int _umtx_op(void *obj, int op, u_long val, void *uaddr, void *uaddr2); +/* + * Old (deprecated) userland mutex system calls. + */ +int _umtx_lock(struct umtx *mtx); +int _umtx_unlock(struct umtx *mtx); + +/* + * Standard api. Try uncontested acquire/release and asks the + * kernel to resolve failures. + */ +static __inline void +umtx_init(struct umtx *umtx) +{ + umtx->u_owner = UMTX_UNOWNED; +} + +static __inline u_long +umtx_owner(struct umtx *umtx) +{ + return (umtx->u_owner & ~LONG_MIN); +} + +static __inline int +umtx_lock(struct umtx *umtx, u_long id) +{ + if (atomic_cmpset_acq_long(&umtx->u_owner, UMTX_UNOWNED, id) == 0) + if (_umtx_lock(umtx) == -1) + /* return (errno); */ + return (88); /*TODO: Fix all these returns once I know what I'm doing*/ + return (0); +} + +static __inline int +umtx_trylock(struct umtx *umtx, u_long id) +{ + if (atomic_cmpset_acq_long(&umtx->u_owner, UMTX_UNOWNED, id) == 0) + /* return (EBUSY); */ + return (16); + return (0); +} + +static __inline int +umtx_timedlock(struct umtx *umtx, u_long id, const struct timespec *timeout) +{ + if (atomic_cmpset_acq_long(&umtx->u_owner, UMTX_UNOWNED, id) == 0) + if (_umtx_op(umtx, UMTX_OP_LOCK, id, 0, + __DECONST(void *, timeout)) == -1) + /*return (errno); */ + return (88); + return (0); +} + +static __inline int +umtx_unlock(struct umtx *umtx, u_long id) +{ + if (atomic_cmpset_rel_long(&umtx->u_owner, id, UMTX_UNOWNED) == 0) + if (_umtx_unlock(umtx) == -1) + /* return (errno); */ + return (88); + return (0); +} + +static __inline int +umtx_wait(u_long *p, long val, const struct timespec *timeout) +{ + if (_umtx_op(p, UMTX_OP_WAIT, val, 0, + __DECONST(void *, timeout)) == -1) + /* return (errno); */ + return (88); + return (0); +} + +/* Wake threads waiting on a user address. */ +static __inline int +umtx_wake(u_long *p, int nr_wakeup) +{ + if (_umtx_op(p, UMTX_OP_WAKE, nr_wakeup, 0, 0) == -1) + /* return (errno); */ + return (88); + return (0); +} + #else /* diff -u -r src.fbsd11.stock/usr.bin/truss/syscall.h src.oldumtx/usr.bin/truss/syscall.h --- src.fbsd11.stock/usr.bin/truss/syscall.h 2016-09-28 19:26:03.000000000 -0400 +++ src.oldumtx/usr.bin/truss/syscall.h 2017-04-04 14:45:02.960814000 -0400 @@ -23,6 +23,7 @@ * Pollfd -- a pointer to an array of struct pollfd. Prints .fd and .events. * Fd_set -- a pointer to an array of fd_set. Prints the fds that are set. * Sigaction -- a pointer to a struct sigaction. Prints all elements. + * Umtx -- a pointer to a struct umtx. Prints the value of owner. * Sigset -- a pointer to a sigset_t. Prints the signals that are set. * Sigprocmask -- the first argument to sigprocmask(). Prints the name. * Kevent -- a pointer to an array of struct kevents. Prints all elements. @@ -40,7 +41,7 @@ enum Argtype { None = 1, Hex, Octal, Int, UInt, LongHex, Name, Ptr, Stat, Ioctl, Quad, Signal, Sockaddr, StringArray, Timespec, Timeval, Itimerval, Pollfd, Fd_set, Sigaction, Fcntl, Mprot, Mmapflags, Whence, Readlinkres, - Sigset, Sigprocmask, StatFs, Kevent, Sockdomain, Socktype, Open, + Umtx, Sigset, Sigprocmask, StatFs, Kevent, Sockdomain, Socktype, Open, Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2, Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl, LinuxSockArgs, Umtxop, Atfd, Atflags, Timespec2, Accessmode, Long, diff -u -r src.fbsd11.stock/usr.bin/truss/syscalls.c src.oldumtx/usr.bin/truss/syscalls.c --- src.fbsd11.stock/usr.bin/truss/syscalls.c 2016-09-28 19:26:03.000000000 -0400 +++ src.oldumtx/usr.bin/truss/syscalls.c 2017-04-04 14:46:19.634451000 -0400 @@ -187,6 +187,10 @@ { .name = "kevent", .ret_type = 1, .nargs = 6, .args = { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 }, { Int, 4 }, { Timespec, 5 } } }, + { .name = "_umtx_lock", .ret_type = 0, .nargs = 1, + .args = { { Umtx, 0 } } }, + { .name = "_umtx_unlock", .ret_type = 0, .nargs = 1, + .args = { { Umtx, 0 } } }, { .name = "kill", .ret_type = 1, .nargs = 2, .args = { { Int | IN, 0 }, { Signal | IN, 1 } } }, { .name = "kldfind", .ret_type = 1, .nargs = 1, @@ -668,7 +672,7 @@ }; static struct xlat umtx_ops[] = { - X(UMTX_OP_RESERVED0) X(UMTX_OP_RESERVED1) X(UMTX_OP_WAIT) + X(UMTX_OP_LOCK) X(UMTX_OP_UNLOCK) X(UMTX_OP_WAIT) X(UMTX_OP_WAKE) X(UMTX_OP_MUTEX_TRYLOCK) X(UMTX_OP_MUTEX_LOCK) X(UMTX_OP_MUTEX_UNLOCK) X(UMTX_OP_SET_CEILING) X(UMTX_OP_CV_WAIT) X(UMTX_OP_CV_SIGNAL) X(UMTX_OP_CV_BROADCAST) X(UMTX_OP_WAIT_UINT) @@ -1329,6 +1333,15 @@ } break; } + case Umtx: { + struct umtx umtx; + if (get_struct(pid, (void *)args[sc->offset], &umtx, + sizeof(umtx)) != -1) + asprintf(&tmp, "{ 0x%lx }", (long)umtx.u_owner); + else + asprintf(&tmp, "0x%lx", args[sc->offset]); + break; + } case Timespec: { struct timespec ts; -- You are receiving this mail because: You are the assignee for the bug. _______________________________________________ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"