diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2018-05-08 15:03:28 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2018-05-08 15:03:28 +0000 |
commit | 479e52bcb99dcccb1b215dcf654953eaabd4c26c (patch) | |
tree | a66b3de994092188069369eb0f0281308b5c0812 /sys/kern/uipc_socket.c | |
parent | 9d98525bec1e44f47c47b9fdcda782d27a873404 (diff) |
Socket splicing can delay operations by task or timeout. Introduce
soreaper() that is scheduled onto the timer thread. soput() is
scheduled from there onto the sosplice task thread. After that it
is save to pool_put() the socket and splicing data structures.
OK mpi@ visa@
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r-- | sys/kern/uipc_socket.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index c47209e8c2a..6ad6f8f855e 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.220 2018/04/08 18:57:39 guenther Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.221 2018/05/08 15:03:27 bluhm Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -60,6 +60,7 @@ int sosplice(struct socket *, int, off_t, struct timeval *); void sounsplice(struct socket *, struct socket *, int); void soidle(void *); void sotask(void *); +void soreaper(void *); void soput(void *); int somove(struct socket *, int); @@ -219,9 +220,9 @@ sofree(struct socket *so) sorflush(so); #ifdef SOCKET_SPLICE if (so->so_sp) { - /* Reuse splice task, sounsplice() has been called before. */ - task_set(&so->so_sp->ssp_task, soput, so); - task_add(sosplice_taskq, &so->so_sp->ssp_task); + /* Reuse splice idle, sounsplice() has been called before. */ + timeout_set_proc(&so->so_sp->ssp_idleto, soreaper, so); + timeout_add(&so->so_sp->ssp_idleto, 0); } else #endif /* SOCKET_SPLICE */ { @@ -1244,12 +1245,23 @@ sotask(void *arg) } /* - * The socket splicing task may sleep while grabbing the net lock. As sofree() - * can be called anytime, sotask() can access the socket memory of a freed - * socket after wakeup. So delay the pool_put() after all pending socket - * splicing tasks have finished. Do this by scheduling it on the same thread. + * The socket splicing task or idle timeout may sleep while grabbing the net + * lock. As sofree() can be called anytime, sotask() or soidle() could access + * the socket memory of a freed socket after wakeup. So delay the pool_put() + * after all pending socket splicing tasks or timeouts have finished. Do this + * by scheduling it on the same threads. */ void +soreaper(void *arg) +{ + struct socket *so = arg; + + /* Reuse splice task, sounsplice() has been called before. */ + task_set(&so->so_sp->ssp_task, soput, so); + task_add(sosplice_taskq, &so->so_sp->ssp_task); +} + +void soput(void *arg) { struct socket *so = arg; |