Add a membar_consumer() for the taskq_create() in sosplice(). Membar
authorbluhm <bluhm@openbsd.org>
Fri, 28 Apr 2023 12:53:42 +0000 (12:53 +0000)
committerbluhm <bluhm@openbsd.org>
Fri, 28 Apr 2023 12:53:42 +0000 (12:53 +0000)
producer and consumer must come in pair and the latter was missing.
Also move the code a bit to make clear which check is needed for
what.
OK mvs@

sys/kern/uipc_socket.c

index 3c8d08b..0c3b5bb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uipc_socket.c,v 1.302 2023/04/24 09:20:09 mvs Exp $   */
+/*     $OpenBSD: uipc_socket.c,v 1.303 2023/04/28 12:53:42 bluhm Exp $ */
 /*     $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $        */
 
 /*
@@ -1258,14 +1258,19 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv)
                if (sosplice_taskq == NULL) {
                        tq = taskq_create("sosplice", 1, IPL_SOFTNET,
                            TASKQ_MPSAFE);
+                       if (tq == NULL) {
+                               rw_exit_write(&sosplice_lock);
+                               return (ENOMEM);
+                       }
                        /* Ensure the taskq is fully visible to other CPUs. */
                        membar_producer();
                        sosplice_taskq = tq;
                }
                rw_exit_write(&sosplice_lock);
+       } else {
+               /* Ensure the taskq is fully visible on this CPU. */
+               membar_consumer();
        }
-       if (sosplice_taskq == NULL)
-               return (ENOMEM);
 
        if ((so->so_proto->pr_flags & PR_SPLICE) == 0)
                return (EPROTONOSUPPORT);