This patch removes explicit kernel locking from futex_wait(). I think
the original reason for the KERNEL_LOCK() was that rwsleep() with PCATCH
needed it. Now rwsleep() does the necessary locking internally.

As a subtle detail, the copyin32() call is now run outside the kernel
lock. Algorithm-wise this should be fine because the kernel's futex
code is serialized by ftlock. The dynamics might change in some
situations, though, because it is likely that the copyin32() is reached
faster than before.

OK?

Index: kern/sys_futex.c
===================================================================
RCS file: src/sys/kern/sys_futex.c,v
retrieving revision 1.19
diff -u -p -r1.19 sys_futex.c
--- kern/sys_futex.c    19 Nov 2021 15:58:36 -0000      1.19
+++ kern/sys_futex.c    20 Nov 2021 05:10:22 -0000
@@ -104,31 +104,25 @@ sys_futex(struct proc *p, void *v, regis
        if (op & FUTEX_PRIVATE_FLAG)
                flags |= FT_PRIVATE;
 
+       rw_enter_write(&ftlock);
        switch (op) {
        case FUTEX_WAIT:
        case FUTEX_WAIT_PRIVATE:
-               KERNEL_LOCK();
-               rw_enter_write(&ftlock);
                error = futex_wait(uaddr, val, timeout, flags);
-               rw_exit_write(&ftlock);
-               KERNEL_UNLOCK();
                break;
        case FUTEX_WAKE:
        case FUTEX_WAKE_PRIVATE:
-               rw_enter_write(&ftlock);
                *retval = futex_wake(uaddr, val, flags);
-               rw_exit_write(&ftlock);
                break;
        case FUTEX_REQUEUE:
        case FUTEX_REQUEUE_PRIVATE:
-               rw_enter_write(&ftlock);
                *retval = futex_requeue(uaddr, val, g, (u_long)timeout, flags);
-               rw_exit_write(&ftlock);
                break;
        default:
                error = ENOSYS;
                break;
        }
+       rw_exit_write(&ftlock);
 
        return error;
 }

Reply via email to