From 203c115311736d26f7522cedb23471514e1521df Mon Sep 17 00:00:00 2001 From: Visa Hankala Date: Thu, 5 Jul 2018 14:45:08 +0000 Subject: Serialize the sosplice taskq allocation. This prevents an unlikely duplicate allocation that could happen in the future when each socket has a dedicated lock. Right now, the code path is serialized also by the NET_LOCK() (and the KERNEL_LOCK()). OK mpi@ --- sys/kern/uipc_socket.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 010b18aebea..793914b0a0c 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.224 2018/06/14 08:46:09 bluhm Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.225 2018/07/05 14:45:07 visa Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -49,6 +49,8 @@ #include #include #include +#include +#include #ifdef DDB #include @@ -89,6 +91,7 @@ struct pool socket_pool; #ifdef SOCKET_SPLICE struct pool sosplice_pool; struct taskq *sosplice_taskq; +struct rwlock sosplice_lock = RWLOCK_INITIALIZER("sosplicelk"); #endif void @@ -1088,13 +1091,22 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv) struct file *fp; struct socket *sosp; struct sosplice *sp; + struct taskq *tq; int error = 0; soassertlocked(so); - if (sosplice_taskq == NULL) - sosplice_taskq = taskq_create("sosplice", 1, IPL_SOFTNET, - TASKQ_MPSAFE); + if (sosplice_taskq == NULL) { + rw_enter_write(&sosplice_lock); + if (sosplice_taskq == NULL) { + tq = taskq_create("sosplice", 1, IPL_SOFTNET, + TASKQ_MPSAFE); + /* Ensure the taskq is fully visible to other CPUs. */ + membar_producer(); + sosplice_taskq = tq; + } + rw_exit_write(&sosplice_lock); + } if (sosplice_taskq == NULL) return (ENOMEM); -- cgit v1.2.3