Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Apr 2017 21:26:34 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 218571] umtx compat6 regression affecting 'jar' command
Message-ID:  <bug-218571-8@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D218571

            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.hardison@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 b=
uilt
on 6.3-RELEASE I believe), which goes into a loop and hangs.  Replicating i=
t 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 rem=
oved
in https://svnweb.freebsd.org/base?view=3Drevision&revision=3D263318 and
https://svnweb.freebsd.org/base?view=3Drevision&revision=3D304525.  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 f=
ix
the jar issue.  Looking through the rest of the code, it feels to me like t=
he
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 approa=
ch
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.0000000=
00
-0400
+++ src.oldumtx/lib/libc/sys/Symbol.map    2017-04-05 13:54:37.026112000 -0=
400
@@ -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 30=
2094
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 timesp=
ec32
* abstime; char abstime_r_[PADR_(const struct timespec32 *)];
@@ -757,6 +763,8 @@
 int    freebsd32_getcontext(struct thread *, struct freebsd32_getcontext_a=
rgs
*);
 int    freebsd32_setcontext(struct thread *, struct freebsd32_setcontext_a=
rgs
*);
 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 30=
2094
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 30=
2094
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[] =3D {
@@ -444,8 +444,8 @@
     "thr_exit",            /* 431 =3D thr_exit */
     "thr_self",            /* 432 =3D thr_self */
     "thr_kill",            /* 433 =3D thr_kill */
-    "#434",            /* 434 =3D nosys */
-    "#435",            /* 435 =3D nosys */
+    "freebsd32_umtx_lock",            /* 434 =3D freebsd32_umtx_lock */
+    "freebsd32_umtx_unlock",            /* 435 =3D freebsd32_umtx_unlock */
     "jail_attach",            /* 436 =3D jail_attach */
     "extattr_list_fd",            /* 437 =3D extattr_list_fd */
     "extattr_list_file",            /* 438 =3D 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 30=
2094
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 =3D thr_exit */
     { AS(thr_self_args), (sy_call_t *)sys_thr_self, AUE_NULL, NULL, 0, 0, =
0,
SY_THR_STATIC },    /* 432 =3D thr_self */
     { AS(thr_kill_args), (sy_call_t *)sys_thr_kill, AUE_NULL, NULL, 0, 0, =
0,
SY_THR_STATIC },    /* 433 =3D thr_kill */
-    { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },=20=
=20=20=20=20=20=20=20
   /* 434 =3D nosys */
-    { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },=20=
=20=20=20=20=20=20=20
   /* 435 =3D nosys */
+    { AS(freebsd32_umtx_lock_args), (sy_call_t *)freebsd32_umtx_lock,
AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },    /* 434 =3D freebsd32_umtx_lock=
 */
+    { AS(freebsd32_umtx_unlock_args), (sy_call_t *)freebsd32_umtx_unlock,
AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },    /* 435 =3D freebsd32_umtx_unlo=
ck */
     { AS(jail_attach_args), (sy_call_t *)sys_jail_attach, AUE_NULL, NULL, =
0,
0, 0, SY_THR_STATIC },    /* 436 =3D 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 =3D
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 =3D
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=20=20=20
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 30=
2095
2016-06-22 21:18:19Z brooks $
+ * $FreeBSD$
  * This file is part of the DTrace syscall provider.
  */

@@ -2200,6 +2200,20 @@
         *n_args =3D 2;
         break;
     }
+    /* freebsd32_umtx_lock */
+    case 434: {
+        struct freebsd32_umtx_lock_args *p =3D params;
+        uarg[0] =3D (intptr_t) p->umtx; /* struct umtx * */
+        *n_args =3D 1;
+        break;
+    }
+    /* freebsd32_umtx_unlock */
+    case 435: {
+        struct freebsd32_umtx_unlock_args *p =3D params;
+        uarg[0] =3D (intptr_t) p->umtx; /* struct umtx * */
+        *n_args =3D 1;
+        break;
+    }
     /* jail_attach */
     case 436: {
         struct jail_attach_args *p =3D params;
@@ -6866,6 +6880,26 @@
             break;
         };
         break;
+    /* freebsd32_umtx_lock */
+    case 434:
+        switch(ndx) {
+        case 0:
+            p =3D "struct umtx *";
+            break;
+        default:
+            break;
+        };
+        break;
+    /* freebsd32_umtx_unlock */
+    case 435:
+        switch(ndx) {
+        case 0:
+            p =3D "struct umtx *";
+            break;
+        default:
+            break;
+        };
+        break;
     /* jail_attach */
     case 436:
         switch(ndx) {
@@ -10189,6 +10223,16 @@
         if (ndx =3D=3D 0 || ndx =3D=3D 1)
             p =3D "int";
         break;
+    /* freebsd32_umtx_lock */
+    case 434:
+        if (ndx =3D=3D 0 || ndx =3D=3D 1)
+            p =3D "int";
+        break;
+    /* freebsd32_umtx_unlock */
+    case 435:
+        if (ndx =3D=3D 0 || ndx =3D=3D 1)
+            p =3D "int";
+        break;
     /* jail_attach */
     case 436:
         if (ndx =3D=3D 0 || ndx =3D=3D 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 -04=
00
@@ -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 =3D thr_exit */
     { AS(thr_self_args), (sy_call_t *)sys_thr_self, AUE_NULL, NULL, 0, 0,
SYF_CAPENABLED, SY_THR_STATIC },    /* 432 =3D thr_self */
     { AS(thr_kill_args), (sy_call_t *)sys_thr_kill, AUE_NULL, NULL, 0, 0,
SYF_CAPENABLED, SY_THR_STATIC },    /* 433 =3D thr_kill */
-    { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },=20=
=20=20=20=20=20=20=20
   /* 434 =3D nosys */
-    { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },=20=
=20=20=20=20=20=20=20
   /* 435 =3D nosys */
+    { AS(_umtx_lock_args), (sy_call_t *)sys__umtx_lock, AUE_NULL, NULL, 0,=
 0,
SYF_CAPENABLED, SY_THR_STATIC },    /* 434 =3D _umtx_lock */
+    { AS(_umtx_unlock_args), (sy_call_t *)sys__umtx_unlock, AUE_NULL, NULL=
, 0,
0, SYF_CAPENABLED, SY_THR_STATIC },    /* 435 =3D _umtx_unlock */
     { AS(jail_attach_args), (sy_call_t *)sys_jail_attach, AUE_NULL, NULL, =
0,
0, 0, SY_THR_STATIC },    /* 436 =3D 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=
 =3D
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 =3D
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 =3D 0;
+
+    uq =3D td->td_umtxq;
+    if (timeout !=3D 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 =3D casuword(&umtx->u_owner, UMTX_UNOWNED, id);
+
+        /* The acquire succeeded. */
+        if (owner =3D=3D UMTX_UNOWNED)
+            return (0);
+
+        /* The address was invalid. */
+        if (owner =3D=3D -1)
+            return (EFAULT);
+
+        /* If no one owns it but it is contested try to acquire it. */
+        if (owner =3D=3D UMTX_CONTESTED) {
+            owner =3D casuword(&umtx->u_owner,
+                UMTX_CONTESTED, id | UMTX_CONTESTED);
+
+            if (owner =3D=3D UMTX_CONTESTED)
+                return (0);
+
+            /* The address was invalid. */
+            if (owner =3D=3D -1)
+                return (EFAULT);
+
+            error =3D umtxq_check_susp(td);
+            if (error !=3D 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 !=3D 0)
+            break;
+
+        if ((error =3D umtx_key_get(umtx, TYPE_SIMPLE_LOCK,
+            AUTO_SHARE, &uq->uq_key)) !=3D 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 =3D casuword(&umtx->u_owner, owner, owner | UMTX_CONTESTED);
+
+        /* The address was invalid. */
+        if (old =3D=3D -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 =3D=3D owner)
+            error =3D umtxq_sleep(uq, "umtx", timeout =3D=3D NULL ? NULL :
+                &timo);
+        umtxq_remove(uq);
+        umtxq_unlock(&uq->uq_key);
+        umtx_key_release(&uq->uq_key);
+
+        if (error =3D=3D 0)
+            error =3D umtxq_check_susp(td);
+    }
+
+    if (timeout =3D=3D NULL) {
+        /* Mutex locking is restarted if it is interrupted. */
+        if (error =3D=3D EINTR)
+            error =3D ERESTART;
+    } else {
+        /* Timed-locking is not restarted. */
+        if (error =3D=3D ERESTART)
+            error =3D 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 =3D fuword(__DEVOLATILE(u_long *, &umtx->u_owner));
+    if (owner =3D=3D -1)
+        return (EFAULT);
+
+    if ((owner & ~UMTX_CONTESTED) !=3D id)
+        return (EPERM);
+
+    /* This should be done in userland */
+    if ((owner & UMTX_CONTESTED) =3D=3D 0) {
+        old =3D casuword(&umtx->u_owner, owner, UMTX_UNOWNED);
+        if (old =3D=3D -1)
+            return (EFAULT);
+        if (old =3D=3D owner)
+            return (0);
+        owner =3D old;
+    }
+
+    /* We should only ever be in here for contested locks */
+    if ((error =3D umtx_key_get(umtx, TYPE_SIMPLE_LOCK, AUTO_SHARE,
+        &key)) !=3D 0)
+        return (error);
+
+    umtxq_lock(&key);
+    umtxq_busy(&key);
+    count =3D 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 =3D casuword(&umtx->u_owner, owner,
+        count <=3D 1 ? UMTX_UNOWNED : UMTX_CONTESTED);
+    umtxq_lock(&key);
+    umtxq_signal(&key,1);
+    umtxq_unbusy(&key);
+    umtxq_unlock(&key);
+    umtx_key_release(&key);
+    if (old =3D=3D -1)
+        return (EFAULT);
+    if (old !=3D 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 =3D 0;
+
+    uq =3D td->td_umtxq;
+
+    if (timeout !=3D 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 =3D casuword32(m, UMUTEX_UNOWNED, id);
+
+        /* The acquire succeeded. */
+        if (owner =3D=3D UMUTEX_UNOWNED)
+            return (0);
+
+        /* The address was invalid. */
+        if (owner =3D=3D -1)
+            return (EFAULT);
+
+        /* If no one owns it but it is contested try to acquire it. */
+        if (owner =3D=3D UMUTEX_CONTESTED) {
+            owner =3D casuword32(m,
+                UMUTEX_CONTESTED, id | UMUTEX_CONTESTED);
+            if (owner =3D=3D UMUTEX_CONTESTED)
+                return (0);
+
+            /* The address was invalid. */
+            if (owner =3D=3D -1)
+                return (EFAULT);
+
+            error =3D umtxq_check_susp(td);
+            if (error !=3D 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 !=3D 0)
+            return (error);
+
+        if ((error =3D umtx_key_get(m, TYPE_SIMPLE_LOCK,
+            AUTO_SHARE, &uq->uq_key)) !=3D 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 =3D casuword32(m, owner, owner | UMUTEX_CONTESTED);
+
+        /* The address was invalid. */
+        if (old =3D=3D -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 =3D=3D owner)
+            error =3D umtxq_sleep(uq, "umtx", timeout =3D=3D NULL ?
+                NULL : &timo);
+        umtxq_remove(uq);
+        umtxq_unlock(&uq->uq_key);
+        umtx_key_release(&uq->uq_key);
+
+        if (error =3D=3D 0)
+            error =3D umtxq_check_susp(td);
+    }
+
+    if (timeout =3D=3D NULL) {
+        /* Mutex locking is restarted if it is interrupted. */
+        if (error =3D=3D EINTR)
+            error =3D ERESTART;
+    } else {
+        /* Timed-locking is not restarted. */
+        if (error =3D=3D ERESTART)
+            error =3D 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 =3D fuword32(m);
+    if (owner =3D=3D -1)
+        return (EFAULT);
+
+    if ((owner & ~UMUTEX_CONTESTED) !=3D id)
+        return (EPERM);
+
+    /* This should be done in userland */
+    if ((owner & UMUTEX_CONTESTED) =3D=3D 0) {
+        old =3D casuword32(m, owner, UMUTEX_UNOWNED);
+        if (old =3D=3D -1)
+            return (EFAULT);
+        if (old =3D=3D owner)
+            return (0);
+        owner =3D old;
+    }
+
+    /* We should only ever be in here for contested locks */
+    if ((error =3D umtx_key_get(m, TYPE_SIMPLE_LOCK, AUTO_SHARE,
+        &key)) !=3D 0)
+        return (error);
+
+    umtxq_lock(&key);
+    umtxq_busy(&key);
+    count =3D 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 =3D casuword32(m, owner,
+        count <=3D 1 ? UMUTEX_UNOWNED : UMUTEX_CONTESTED);
+    umtxq_lock(&key);
+    umtxq_signal(&key,1);
+    umtxq_unbusy(&key);
+    umtxq_unlock(&key);
+    umtx_key_release(&key);
+    if (old =3D=3D -1)
+        return (EFAULT);
+    if (old !=3D 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) !=3D 0 &&
+            (owner & ~UMUTEX_CONTESTED) =3D=3D id)
+            return (EDEADLK);
+
         if (mode =3D=3D _UMUTEX_TRY)
             return (EBUSY);

@@ -1880,6 +2245,12 @@
             break;
         }

+        if ((flags & UMUTEX_ERROR_CHECK) !=3D 0 &&
+            (owner & ~UMUTEX_CONTESTED) =3D=3D id) {
+            error =3D EDEADLK;
+            break;
+        }
+
         if (try !=3D 0) {
             error =3D EBUSY;
             break;
@@ -2149,6 +2520,12 @@
             break;
         }

+        if ((flags & UMUTEX_ERROR_CHECK) !=3D 0 &&
+            (owner & ~UMUTEX_CONTESTED) =3D=3D id) {
+            error =3D EDEADLK;
+            break;
+        }
+
         if (try !=3D 0) {
             error =3D 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 =3D=3D NULL)
+        ts =3D NULL;
+    else {
+        error =3D umtx_copyin_timeout(uap->uaddr2, &timeout);
+        if (error !=3D 0)
+            return (error);
+        ts =3D &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[] =3D {
-    [UMTX_OP_RESERVED0]    =3D __umtx_op_unimpl,
-    [UMTX_OP_RESERVED1]    =3D __umtx_op_unimpl,
+    [UMTX_OP_LOCK]        =3D __umtx_op_lock_umtx,
+    [UMTX_OP_UNLOCK]    =3D __umtx_op_unlock_umtx,
     [UMTX_OP_WAIT]        =3D __umtx_op_wait,
     [UMTX_OP_WAKE]        =3D __umtx_op_wake,
     [UMTX_OP_MUTEX_TRYLOCK]    =3D __umtx_op_trylock_umutex,
@@ -3970,6 +4378,19 @@
 }

 #ifdef COMPAT_FREEBSD32
+int
+freebsd32_umtx_lock(struct thread *td, struct freebsd32_umtx_lock_args *ua=
p)
+    /* 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 =3D=3D NULL)
+        ts =3D NULL;
+    else {
+        error =3D umtx_copyin_timeout32(uap->uaddr2, &timeout);
+        if (error !=3D 0)
+            return (error);
+        ts =3D &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 *ua=
p)
+{
+    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[] =3D {
-    [UMTX_OP_RESERVED0]    =3D __umtx_op_unimpl,
-    [UMTX_OP_RESERVED1]    =3D __umtx_op_unimpl,
+    [UMTX_OP_LOCK]        =3D __umtx_op_lock_umtx_compat32,
+    [UMTX_OP_UNLOCK]    =3D __umtx_op_unlock_umtx_compat32,
     [UMTX_OP_WAIT]        =3D __umtx_op_wait_compat32,
     [UMTX_OP_WAKE]        =3D __umtx_op_wake,
     [UMTX_OP_MUTEX_TRYLOCK]    =3D __umtx_op_trylock_umutex,
diff -u -r src.fbsd11.stock/sys/kern/syscalls.c src.oldumtx/sys/kern/syscal=
ls.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[] =3D {
@@ -441,8 +441,8 @@
     "thr_exit",            /* 431 =3D thr_exit */
     "thr_self",            /* 432 =3D thr_self */
     "thr_kill",            /* 433 =3D thr_kill */
-    "#434",            /* 434 =3D nosys */
-    "#435",            /* 435 =3D nosys */
+    "_umtx_lock",            /* 434 =3D _umtx_lock */
+    "_umtx_unlock",            /* 435 =3D _umtx_unlock */
     "jail_attach",            /* 436 =3D jail_attach */
     "extattr_list_fd",            /* 437 =3D extattr_list_fd */
     "extattr_list_file",            /* 438 =3D 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.000000=
000
-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.000000=
000
-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 =3D 2;
         break;
     }
+    /* _umtx_lock */
+    case 434: {
+        struct _umtx_lock_args *p =3D params;
+        uarg[0] =3D (intptr_t) p->umtx; /* struct umtx * */
+        *n_args =3D 1;
+        break;
+    }
+    /* _umtx_unlock */
+    case 435: {
+        struct _umtx_unlock_args *p =3D params;
+        uarg[0] =3D (intptr_t) p->umtx; /* struct umtx * */
+        *n_args =3D 1;
+        break;
+    }
     /* jail_attach */
     case 436: {
         struct jail_attach_args *p =3D params;
@@ -7148,6 +7162,26 @@
             break;
         };
         break;
+    /* _umtx_lock */
+    case 434:
+        switch(ndx) {
+        case 0:
+            p =3D "struct umtx *";
+            break;
+        default:
+            break;
+        };
+        break;
+    /* _umtx_unlock */
+    case 435:
+        switch(ndx) {
+        case 0:
+            p =3D "struct umtx *";
+            break;
+        default:
+            break;
+        };
+        break;
     /* jail_attach */
     case 436:
         switch(ndx) {
@@ -10246,6 +10280,16 @@
         if (ndx =3D=3D 0 || ndx =3D=3D 1)
             p =3D "int";
         break;
+    /* _umtx_lock */
+    case 434:
+        if (ndx =3D=3D 0 || ndx =3D=3D 1)
+            p =3D "int";
+        break;
+    /* _umtx_unlock */
+    case 435:
+        if (ndx =3D=3D 0 || ndx =3D=3D 1)
+            p =3D "int";
+        break;
     /* jail_attach */
     case 436:
         if (ndx =3D=3D 0 || ndx =3D=3D 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 -04=
00
+++ 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 -0=
400
+++ 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-0=
8-08
20:23:11Z bdrewery
 MIASM =3D  \
     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 -0=
400
+++ 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);

+/*=20=20=20=20=20
+ * Old (deprecated) userland mutex system calls.=20=20=20=20=20
+ */=20=20=20=20=20
+int _umtx_lock(struct umtx *mtx);=20=20=20=20=20
+int _umtx_unlock(struct umtx *mtx);=20=20=20=20=20
+=20=20=20=20=20
+/*=20=20=20=20=20
+ * Standard api.  Try uncontested acquire/release and asks the=20=20=20=20=
=20
+ * kernel to resolve failures.=20=20=20=20=20
+ */=20=20=20=20=20
+static __inline void=20=20=20=20=20
+umtx_init(struct umtx *umtx)=20=20=20=20=20
+{=20=20=20=20=20
+        umtx->u_owner =3D UMTX_UNOWNED;=20=20=20=20=20
+}=20=20=20=20=20
+=20=20=20=20=20
+static __inline u_long=20=20=20=20=20
+umtx_owner(struct umtx *umtx)=20=20=20=20=20
+{=20=20=20=20=20
+        return (umtx->u_owner & ~LONG_MIN);=20=20=20=20=20
+}=20=20=20=20=20
+=20=20=20=20=20
+static __inline int=20=20=20=20=20
+umtx_lock(struct umtx *umtx, u_long id)=20=20=20=20=20
+{=20=20=20=20=20
+        if (atomic_cmpset_acq_long(&umtx->u_owner, UMTX_UNOWNED, id) =3D=
=3D 0)=20=20=20=20=20
+                if (_umtx_lock(umtx) =3D=3D -1)=20=20=20=20=20
+                        /* return (errno); */
+            return (88); /*TODO: Fix all these returns once I know what I'm
doing*/
+        return (0);=20=20=20=20=20
+}=20=20=20=20=20
+=20=20=20=20=20
+static __inline int=20=20=20=20=20
+umtx_trylock(struct umtx *umtx, u_long id)=20=20=20=20=20
+{=20=20=20=20=20
+        if (atomic_cmpset_acq_long(&umtx->u_owner, UMTX_UNOWNED, id) =3D=
=3D 0)=20=20=20=20=20
+                /* return (EBUSY);     */
+        return (16);
+        return (0);=20=20=20=20=20
+}=20=20=20=20=20
+=20=20=20=20=20
+static __inline int=20=20=20=20=20
+umtx_timedlock(struct umtx *umtx, u_long id, const struct timespec *timeou=
t)=20=20=20
+{=20=20=20=20=20
+        if (atomic_cmpset_acq_long(&umtx->u_owner, UMTX_UNOWNED, id) =3D=
=3D 0)=20=20=20=20=20
+                if (_umtx_op(umtx, UMTX_OP_LOCK, id, 0,=20=20=20=20=20
+                    __DECONST(void *, timeout)) =3D=3D -1)=20=20=20=20=20
+                        /*return (errno);     */
+            return (88);
+        return (0);=20=20=20=20=20
+}=20=20=20=20=20
+=20=20=20=20=20
+static __inline int=20=20=20=20=20
+umtx_unlock(struct umtx *umtx, u_long id)=20=20=20=20=20
+{=20=20=20=20=20
+        if (atomic_cmpset_rel_long(&umtx->u_owner, id, UMTX_UNOWNED) =3D=
=3D 0)=20=20=20=20=20
+                if (_umtx_unlock(umtx) =3D=3D -1)=20=20=20=20=20
+                        /* return (errno);     */
+            return (88);
+        return (0);=20=20=20=20=20
+}=20=20=20=20=20
+=20=20=20=20=20
+static __inline int=20=20=20=20=20
+umtx_wait(u_long *p, long val, const struct timespec *timeout)=20=20=20=20=
=20
+{=20=20=20=20=20
+        if (_umtx_op(p, UMTX_OP_WAIT, val, 0,=20=20=20=20=20
+            __DECONST(void *, timeout)) =3D=3D -1)=20=20=20=20=20
+                /* return (errno);     */
+        return (88);
+        return (0);=20=20=20=20=20
+}=20=20=20=20=20
+=20=20=20=20=20
+/* Wake threads waiting on a user address. */=20=20=20=20=20
+static __inline int=20=20=20=20=20
+umtx_wake(u_long *p, int nr_wakeup)=20=20=20=20=20
+{=20=20=20=20=20
+        if (_umtx_op(p, UMTX_OP_WAKE, nr_wakeup, 0, 0) =3D=3D -1)=20=20=20=
=20=20
+                /* return (errno);     */
+        return (88);
+        return (0);=20=20=20=20=20
+}
+
 #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.0000000=
00
-0400
+++ src.oldumtx/usr.bin/truss/syscall.h    2017-04-04 14:45:02.960814000 -0=
400
@@ -23,6 +23,7 @@
  * Pollfd -- a pointer to an array of struct pollfd.  Prints .fd and .even=
ts.
  * 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 =3D 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, Readlinkre=
s,
-    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.000000=
000
-0400
+++ src.oldumtx/usr.bin/truss/syscalls.c    2017-04-04 14:46:19.634451000 -=
0400
@@ -187,6 +187,10 @@
     { .name =3D "kevent", .ret_type =3D 1, .nargs =3D 6,
       .args =3D { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3=
 },
             { Int, 4 }, { Timespec, 5 } } },
+    { .name =3D "_umtx_lock", .ret_type =3D 0, .nargs =3D 1,=20=20=20=20=20
+      .args =3D { { Umtx, 0 } } },=20=20=20=20=20
+    { .name =3D "_umtx_unlock", .ret_type =3D 0, .nargs =3D 1,=20=20=20=20=
=20
+      .args =3D { { Umtx, 0 } } },
     { .name =3D "kill", .ret_type =3D 1, .nargs =3D 2,
       .args =3D { { Int | IN, 0 }, { Signal | IN, 1 } } },
     { .name =3D "kldfind", .ret_type =3D 1, .nargs =3D 1,
@@ -668,7 +672,7 @@
 };

 static struct xlat umtx_ops[] =3D {
-    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: {=20=20=20=20=20
+        struct umtx umtx;
+        if (get_struct(pid, (void *)args[sc->offset], &umtx,
+            sizeof(umtx)) !=3D -1)
+            asprintf(&tmp, "{ 0x%lx }", (long)umtx.u_owner);
+        else
+            asprintf(&tmp, "0x%lx", args[sc->offset]);
+        break;
+    }
     case Timespec: {
         struct timespec ts;

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-218571-8>