git: 6e449c51a907 - stable/13 - linux(4): Factor out the FUTEX_WAIT op into linux_futex_wait().

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Fri, 17 Jun 2022 19:37:05 UTC
The branch stable/13 has been updated by dchagin:

URL: https://cgit.FreeBSD.org/src/commit/?id=6e449c51a90791c76cc473151b275a9a508dc81f

commit 6e449c51a90791c76cc473151b275a9a508dc81f
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2021-07-20 11:37:51 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-06-17 19:33:10 +0000

    linux(4): Factor out the FUTEX_WAIT op into linux_futex_wait().
    
    MFC after:              2 weeks
    
    (cherry picked from commit f6b0d275eb9eb89b9719ca835b34116257f6a236)
---
 sys/compat/linux/linux_futex.c | 94 +++++++++++++++++++++++-------------------
 1 file changed, 51 insertions(+), 43 deletions(-)

diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c
index d89b9fd89f3b..15357e75c8af 100644
--- a/sys/compat/linux/linux_futex.c
+++ b/sys/compat/linux/linux_futex.c
@@ -238,6 +238,7 @@ struct linux_futex_args {
 };
 
 static int	linux_futex(struct thread *, struct linux_futex_args *);
+static int linux_futex_wait(struct thread *, struct linux_futex_args *);
 
 static void
 futex_put(struct futex *f, struct waiting_proc *wp)
@@ -645,9 +646,7 @@ linux_futex(struct thread *td, struct linux_futex_args *args)
 {
 	int nrwake, nrrequeue, op_ret, ret;
 	struct linux_pemuldata *pem;
-	struct waiting_proc *wp;
 	struct futex *f, *f2;
-	struct timespec kts;
 	int error, save;
 	uint32_t val;
 
@@ -686,47 +685,7 @@ linux_futex(struct thread *td, struct linux_futex_args *args)
 		LINUX_CTR3(sys_futex, "WAIT uaddr %p val 0x%x bitset 0x%x",
 		    args->uaddr, args->val, args->val3);
 
-		if (args->ts != NULL) {
-			if (args->clockrt) {
-				nanotime(&kts);
-				timespecsub(args->ts, &kts, args->ts);
-			} else if (args->op == LINUX_FUTEX_WAIT_BITSET) {
-				nanouptime(&kts);
-				timespecsub(args->ts, &kts, args->ts);
-			}
-		}
-
-retry0:
-		error = futex_get(args->uaddr, &wp, &f,
-		    args->flags | FUTEX_CREATE_WP);
-		if (error)
-			return (error);
-
-		error = copyin_nofault(args->uaddr, &val, sizeof(val));
-		if (error) {
-			futex_put(f, wp);
-			error = copyin(args->uaddr, &val, sizeof(val));
-			if (error == 0)
-				goto retry0;
-			LIN_SDT_PROBE1(futex, linux_futex, copyin_error,
-			    error);
-			LINUX_CTR1(sys_futex, "WAIT copyin failed %d",
-			    error);
-			return (error);
-		}
-		if (val != args->val) {
-			LIN_SDT_PROBE4(futex, linux_futex,
-			    debug_wait_value_neq, args->uaddr, args->val, val,
-			    args->val3);
-			LINUX_CTR3(sys_futex,
-			    "WAIT uaddr %p val 0x%x != uval 0x%x",
-			    args->uaddr, args->val, val);
-			futex_put(f, wp);
-			return (EWOULDBLOCK);
-		}
-
-		error = futex_wait(f, wp, args->ts, args->val3);
-		break;
+		return (linux_futex_wait(td, args));
 
 	case LINUX_FUTEX_WAKE:
 		args->val3 = FUTEX_BITSET_MATCH_ANY;
@@ -974,6 +933,55 @@ retry2:
 	return (error);
 }
 
+static int
+linux_futex_wait(struct thread *td, struct linux_futex_args *args)
+{
+	struct waiting_proc *wp;
+	struct timespec kts;
+	struct futex *f;
+	int error;
+	uint32_t val;
+
+	if (args->ts != NULL) {
+		if (args->clockrt) {
+			nanotime(&kts);
+			timespecsub(args->ts, &kts, args->ts);
+		} else if (args->op == LINUX_FUTEX_WAIT_BITSET) {
+			nanouptime(&kts);
+			timespecsub(args->ts, &kts, args->ts);
+		}
+	}
+
+retry:
+	f = NULL;
+	error = futex_get(args->uaddr, &wp, &f, args->flags | FUTEX_CREATE_WP);
+	if (error != 0)
+		return (error);
+
+	error = copyin_nofault(args->uaddr, &val, sizeof(val));
+	if (error != 0) {
+		futex_put(f, wp);
+		error = copyin(args->uaddr, &val, sizeof(val));
+		if (error == 0)
+			goto retry;
+		LIN_SDT_PROBE1(futex, linux_futex, copyin_error, error);
+		LINUX_CTR1(sys_futex, "WAIT copyin failed %d", error);
+		return (error);
+	}
+	if (val != args->val) {
+		LIN_SDT_PROBE4(futex, linux_futex,
+		    debug_wait_value_neq, args->uaddr, args->val, val,
+			args->val3);
+		LINUX_CTR3(sys_futex,
+		    "WAIT uaddr %p val 0x%x != uval 0x%x",
+		    args->uaddr, args->val, val);
+		futex_put(f, wp);
+		return (EWOULDBLOCK);
+	}
+
+	return (futex_wait(f, wp, args->ts, args->val3));
+}
+
 int
 linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
 {