Index: sys/kern/uipc_socket.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/kern/uipc_socket.c,v diff -u -p -u -p -r1.360 uipc_socket.c --- sys/kern/uipc_socket.c 13 Jan 2025 18:10:20 -0000 1.360 +++ sys/kern/uipc_socket.c 14 Jan 2025 17:22:52 -0000 @@ -112,11 +112,24 @@ int somaxconn = SOMAXCONN; int sominconn = SOMINCONN; struct pool socket_pool; + #ifdef SOCKET_SPLICE struct pool sosplice_pool; -struct taskq *sosplice_taskq; struct rwlock sosplice_lock = RWLOCK_INITIALIZER("sosplicelk"); -#endif + +#define SOSPLICE_TASKQS 4 + +struct taskq *sosplice_taskqs[SOSPLICE_TASKQS]; +int sosplice_taskqs_num = 0; + +static inline struct taskq * +sosplice_taskq(struct socket *so) +{ + if (sosplice_taskqs_num == 0) + sosplice_taskqs_num = min(SOSPLICE_TASKQS, ncpus); + return sosplice_taskqs[(long)so % sosplice_taskqs_num]; +} +#endif /* SOCKET_SPLICE */ void soinit(void) @@ -470,8 +483,8 @@ notsplicedback: sbunlock(&so->so_rcv); timeout_del_barrier(&so->so_sp->ssp_idleto); - task_del(sosplice_taskq, &so->so_sp->ssp_task); - taskq_barrier(sosplice_taskq); + task_del(sosplice_taskq(so), &so->so_sp->ssp_task); + taskq_barrier(sosplice_taskq(so)); solock(so); } @@ -1394,9 +1407,9 @@ sosplice(struct socket *so, int fd, off_ return (error); } - if (sosplice_taskq == NULL) { + if ((tq = sosplice_taskq(so)) == NULL) { rw_enter_write(&sosplice_lock); - if (sosplice_taskq == NULL) { + if ((tq = sosplice_taskq(so)) == NULL) { tq = taskq_create("sosplice", 1, IPL_SOFTNET, TASKQ_MPSAFE); if (tq == NULL) { @@ -1405,7 +1418,7 @@ sosplice(struct socket *so, int fd, off_ } /* Ensure the taskq is fully visible to other CPUs. */ membar_producer(); - sosplice_taskq = tq; + sosplice_taskqs[(long)so % sosplice_taskqs_num] = tq; } rw_exit_write(&sosplice_lock); } else { @@ -1529,7 +1542,7 @@ sounsplice(struct socket *so, struct soc mtx_leave(&sosp->so_snd.sb_mtx); mtx_leave(&so->so_rcv.sb_mtx); - task_del(sosplice_taskq, &so->so_splicetask); + task_del(sosplice_taskq(so), &so->so_splicetask); timeout_del(&so->so_idleto); /* Do not wakeup a socket that is about to be freed. */ @@ -1942,7 +1955,7 @@ sorwakeup(struct socket *so) if (so->so_proto->pr_flags & PR_SPLICE) { sb_mtx_lock(&so->so_rcv); if (so->so_rcv.sb_flags & SB_SPLICE) - task_add(sosplice_taskq, &so->so_splicetask); + task_add(sosplice_taskq(so), &so->so_splicetask); if (isspliced(so)) { sb_mtx_unlock(&so->so_rcv); return; @@ -1965,7 +1978,7 @@ sowwakeup(struct socket *so) if (so->so_proto->pr_flags & PR_SPLICE) { sb_mtx_lock(&so->so_snd); if (so->so_snd.sb_flags & SB_SPLICE) - task_add(sosplice_taskq, + task_add(sosplice_taskq(so->so_sp->ssp_soback), &so->so_sp->ssp_soback->so_splicetask); if (issplicedback(so)) { sb_mtx_unlock(&so->so_snd);