Download raw body.
use softnet for socket splicing
Hi,
Currently socket splicing runs on one dedicated kernel thread. This
design is from a time when softnet was still a soft interrupt.
Now with multiple softnet threads, I want to retire the sosplice
thread. Instead call sotask() with the softnet task queue. For
that I have to pass the queue down in struct netstack. Basically
sorwakeup() and sowwakeup() get an additional argument. If netstack
and softnet are available, I use this specific tasks queue. Otherwise
softnet thread 0 is sufficient. The hot path receiving packets
will distribute them over all softnet threads.
Keeping the same softnet means that we take a bunch of packets from
the network driver, do input processing, store them in socket
buffers. Then the same thread handles the splicing task, calls
somove() and does output processing. There is no concurrent locking
or scheduling, ideally packets stay on the same CPU. Before I had
a yield() in sotask() to allow accumulation of packets. With the
new design this is no longer necessary.
As we run on softnet task queue and add splice tasks there, task
barrier causes deadlock. I replaced them with reference count in
task_add(), task_del(), and sotask().
Depending on the test, it improves TCP thoughput between 3% and
20%. For UDP I see 30% to 75% increase.
ok?
bluhm
Index: kern/uipc_socket.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket.c,v
diff -u -p -r1.384 uipc_socket.c
--- kern/uipc_socket.c 24 Jul 2025 23:30:04 -0000 1.384
+++ kern/uipc_socket.c 24 Jul 2025 23:43:04 -0000
@@ -52,6 +52,9 @@
#include <sys/time.h>
#include <sys/refcnt.h>
+#include <net/if.h>
+#include <net/if_var.h>
+
#ifdef DDB
#include <machine/db_machdep.h>
#endif
@@ -117,14 +120,13 @@ 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");
#define so_splicelen so_sp->ssp_len
#define so_splicemax so_sp->ssp_max
#define so_spliceidletv so_sp->ssp_idletv
#define so_spliceidleto so_sp->ssp_idleto
#define so_splicetask so_sp->ssp_task
+#define so_splicequeue so_sp->ssp_queue
#endif
void
@@ -475,8 +477,9 @@ notsplicedback:
sbunlock(&so->so_rcv);
timeout_del_barrier(&so->so_spliceidleto);
- task_del(sosplice_taskq, &so->so_splicetask);
- taskq_barrier(sosplice_taskq);
+ if (so->so_splicequeue != NULL &&
+ task_del(so->so_splicequeue, &so->so_splicetask))
+ sorele(so);
solock_shared(so);
}
@@ -1290,7 +1293,6 @@ sosplice(struct socket *so, int fd, off_
{
struct file *fp;
struct socket *sosp;
- struct taskq *tq;
int error = 0;
if ((so->so_proto->pr_flags & PR_SPLICE) == 0)
@@ -1312,25 +1314,6 @@ sosplice(struct socket *so, int fd, off_
return (error);
}
- if (sosplice_taskq == NULL) {
- rw_enter_write(&sosplice_lock);
- 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();
- }
-
/* Find sosp, the drain socket where data will be spliced into. */
if ((error = getsock(curproc, fd, &fp)) != 0)
return (error);
@@ -1441,8 +1424,10 @@ 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);
timeout_del(&so->so_spliceidleto);
+ if (so->so_splicequeue != NULL &&
+ task_del(so->so_splicequeue, &so->so_splicetask))
+ sorele(so);
/* Do not wakeup a socket that is about to be freed. */
if ((freeing & SOSP_FREEING_READ) == 0) {
@@ -1453,13 +1438,13 @@ sounsplice(struct socket *so, struct soc
readable = soreadable(so);
mtx_leave(&so->so_rcv.sb_mtx);
if (readable)
- sorwakeup(so);
+ sorwakeup(so, NULL);
sounlock_shared(so);
}
if ((freeing & SOSP_FREEING_WRITE) == 0) {
solock_shared(sosp);
if (sowriteable(sosp))
- sowwakeup(sosp);
+ sowwakeup(sosp, NULL);
sounlock_shared(sosp);
}
@@ -1484,20 +1469,12 @@ void
sotask(void *arg)
{
struct socket *so = arg;
- int doyield = 0;
sblock(&so->so_rcv, SBL_WAIT | SBL_NOINTR);
- if (so->so_rcv.sb_flags & SB_SPLICE) {
- if (so->so_proto->pr_flags & PR_WANTRCVD)
- doyield = 1;
+ if (so->so_rcv.sb_flags & SB_SPLICE)
somove(so, M_DONTWAIT);
- }
sbunlock(&so->so_rcv);
-
- if (doyield) {
- /* Avoid user land starvation. */
- yield();
- }
+ sorele(so);
}
/*
@@ -1853,13 +1830,19 @@ somove(struct socket *so, int wait)
#endif /* SOCKET_SPLICE */
void
-sorwakeup(struct socket *so)
+sorwakeup(struct socket *so, struct netstack *ns)
{
#ifdef SOCKET_SPLICE
if (so->so_proto->pr_flags & PR_SPLICE) {
mtx_enter(&so->so_rcv.sb_mtx);
- if (so->so_rcv.sb_flags & SB_SPLICE)
- task_add(sosplice_taskq, &so->so_splicetask);
+ if (so->so_rcv.sb_flags & SB_SPLICE) {
+ if (so->so_splicequeue == NULL) {
+ so->so_splicequeue = ns != NULL ?
+ ns->ns_nettaskq : net_tq(0);
+ }
+ if (task_add(so->so_splicequeue, &so->so_splicetask))
+ soref(so);
+ }
if (isspliced(so)) {
mtx_leave(&so->so_rcv.sb_mtx);
return;
@@ -1873,14 +1856,22 @@ sorwakeup(struct socket *so)
}
void
-sowwakeup(struct socket *so)
+sowwakeup(struct socket *so, struct netstack *ns)
{
#ifdef SOCKET_SPLICE
if (so->so_proto->pr_flags & PR_SPLICE) {
mtx_enter(&so->so_snd.sb_mtx);
- if (so->so_snd.sb_flags & SB_SPLICE)
- task_add(sosplice_taskq,
- &so->so_sp->ssp_soback->so_splicetask);
+ if (so->so_snd.sb_flags & SB_SPLICE) {
+ struct socket *soback = so->so_sp->ssp_soback;
+
+ if (soback->so_splicequeue == NULL) {
+ soback->so_splicequeue = ns != NULL ?
+ ns->ns_nettaskq : net_tq(0);
+ }
+ if (task_add(soback->so_splicequeue,
+ &soback->so_splicetask))
+ soref(soback);
+ }
if (issplicedback(so)) {
mtx_leave(&so->so_snd.sb_mtx);
return;
Index: kern/uipc_socket2.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket2.c,v
diff -u -p -r1.186 uipc_socket2.c
--- kern/uipc_socket2.c 14 Jul 2025 21:47:26 -0000 1.186
+++ kern/uipc_socket2.c 24 Jul 2025 23:43:04 -0000
@@ -113,15 +113,15 @@ soisconnected(struct socket *so)
soqremque(so, 0);
soqinsque(head, so, 1);
- sorwakeup(head);
+ sorwakeup(head, NULL);
wakeup_one(&head->so_timeo);
sounlock(head);
sorele(head);
} else {
wakeup(&so->so_timeo);
- sorwakeup(so);
- sowwakeup(so);
+ sorwakeup(so, NULL);
+ sowwakeup(so, NULL);
}
}
@@ -141,8 +141,8 @@ soisdisconnecting(struct socket *so)
mtx_leave(&so->so_snd.sb_mtx);
wakeup(&so->so_timeo);
- sowwakeup(so);
- sorwakeup(so);
+ sowwakeup(so, NULL);
+ sorwakeup(so, NULL);
}
void
@@ -162,8 +162,8 @@ soisdisconnected(struct socket *so)
so->so_state |= SS_ISDISCONNECTED;
wakeup(&so->so_timeo);
- sowwakeup(so);
- sorwakeup(so);
+ sowwakeup(so, NULL);
+ sorwakeup(so, NULL);
}
/*
@@ -233,7 +233,7 @@ sonewconn(struct socket *head, int conns
}
if (connstatus) {
so->so_state |= connstatus;
- sorwakeup(head);
+ sorwakeup(head, NULL);
wakeup(&head->so_timeo);
}
@@ -308,7 +308,7 @@ socantsendmore(struct socket *so)
mtx_enter(&so->so_snd.sb_mtx);
so->so_snd.sb_state |= SS_CANTSENDMORE;
mtx_leave(&so->so_snd.sb_mtx);
- sowwakeup(so);
+ sowwakeup(so, NULL);
}
void
@@ -317,7 +317,7 @@ socantrcvmore(struct socket *so)
mtx_enter(&so->so_rcv.sb_mtx);
so->so_rcv.sb_state |= SS_CANTRCVMORE;
mtx_leave(&so->so_rcv.sb_mtx);
- sorwakeup(so);
+ sorwakeup(so, NULL);
}
void
Index: kern/uipc_usrreq.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_usrreq.c,v
diff -u -p -r1.220 uipc_usrreq.c
--- kern/uipc_usrreq.c 12 Jun 2025 20:37:58 -0000 1.220
+++ kern/uipc_usrreq.c 24 Jul 2025 23:43:04 -0000
@@ -502,7 +502,7 @@ uipc_rcvd(struct socket *so)
so2->so_snd.sb_cc = so->so_rcv.sb_cc;
mtx_leave(&so2->so_snd.sb_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
- sowwakeup(so2);
+ sowwakeup(so2, NULL);
}
int
@@ -568,7 +568,7 @@ uipc_send(struct socket *so, struct mbuf
mtx_leave(&so2->so_rcv.sb_mtx);
if (dowakeup)
- sorwakeup(so2);
+ sorwakeup(so2, NULL);
m = NULL;
@@ -636,7 +636,7 @@ uipc_dgram_send(struct socket *so, struc
mtx_leave(&so2->so_rcv.sb_mtx);
if (dowakeup)
- sorwakeup(so2);
+ sorwakeup(so2, NULL);
if (nam)
unp_disconnect(unp);
Index: net/if.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if.c,v
diff -u -p -r1.740 if.c
--- net/if.c 21 Jul 2025 20:36:41 -0000 1.740
+++ net/if.c 24 Jul 2025 23:43:04 -0000
@@ -270,6 +270,7 @@ ifinit(void)
TASKQ_MPSAFE);
if (sn->sn_taskq == NULL)
panic("unable to create network taskq %d", i);
+ sn->sn_netstack.ns_nettaskq = sn->sn_taskq;
}
}
@@ -973,6 +974,7 @@ if_input_process(struct ifnet *ifp, stru
{
struct mbuf *m;
struct softnet *sn;
+ struct netstack *ns;
if (ml_empty(ml))
return;
@@ -988,19 +990,20 @@ if_input_process(struct ifnet *ifp, stru
*/
sn = net_sn(idx);
- ml_init(&sn->sn_netstack.ns_tcp_ml);
+ ns = &sn->sn_netstack;
+ ml_init(&ns->ns_tcp_ml);
#ifdef INET6
- ml_init(&sn->sn_netstack.ns_tcp6_ml);
+ ml_init(&ns->ns_tcp6_ml);
#endif
NET_LOCK_SHARED();
while ((m = ml_dequeue(ml)) != NULL)
- (*ifp->if_input)(ifp, m, &sn->sn_netstack);
+ (*ifp->if_input)(ifp, m, ns);
- tcp_input_mlist(&sn->sn_netstack.ns_tcp_ml, AF_INET);
+ tcp_input_mlist(&ns->ns_tcp_ml, AF_INET, ns);
#ifdef INET6
- tcp_input_mlist(&sn->sn_netstack.ns_tcp6_ml, AF_INET6);
+ tcp_input_mlist(&ns->ns_tcp6_ml, AF_INET6, ns);
#endif
NET_UNLOCK_SHARED();
Index: net/if_ethersubr.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_ethersubr.c,v
diff -u -p -r1.303 if_ethersubr.c
--- net/if_ethersubr.c 7 Jul 2025 02:28:50 -0000 1.303
+++ net/if_ethersubr.c 24 Jul 2025 23:43:04 -0000
@@ -2108,7 +2108,7 @@ ether_frm_recv(struct socket *so, struct
return;
}
- sorwakeup(so);
+ sorwakeup(so, NULL);
}
static struct mbuf *
Index: net/if_var.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_var.h,v
diff -u -p -r1.139 if_var.h
--- net/if_var.h 19 Jul 2025 16:40:40 -0000 1.139
+++ net/if_var.h 24 Jul 2025 23:43:04 -0000
@@ -92,9 +92,10 @@ struct task;
struct cpumem;
struct netstack {
- struct route ns_route;
- struct mbuf_list ns_tcp_ml;
- struct mbuf_list ns_tcp6_ml;
+ struct route ns_route;
+ struct mbuf_list ns_tcp_ml;
+ struct mbuf_list ns_tcp6_ml;
+ struct taskq *ns_nettaskq;
};
/*
Index: net/pfkeyv2.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pfkeyv2.c,v
diff -u -p -r1.270 pfkeyv2.c
--- net/pfkeyv2.c 7 Jul 2025 02:28:50 -0000 1.270
+++ net/pfkeyv2.c 24 Jul 2025 23:43:04 -0000
@@ -457,7 +457,7 @@ pfkey_sendup(struct pkpcb *kp, struct mb
return (ENOBUFS);
}
- sorwakeup(so);
+ sorwakeup(so, NULL);
return (0);
}
Index: net/rtsock.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/rtsock.c,v
diff -u -p -r1.386 rtsock.c
--- net/rtsock.c 15 Jul 2025 09:55:49 -0000 1.386
+++ net/rtsock.c 24 Jul 2025 23:43:04 -0000
@@ -485,7 +485,7 @@ rtm_senddesync(struct socket *so)
if (ret != 0) {
rop->rop_flags &= ~ROUTECB_FLAG_DESYNC;
- sorwakeup(rop->rop_socket);
+ sorwakeup(rop->rop_socket, NULL);
return;
}
m_freem(desync_mbuf);
@@ -612,7 +612,7 @@ rtm_sendup(struct socket *so, struct mbu
return (ENOBUFS);
}
- sorwakeup(so);
+ sorwakeup(so, NULL);
return (0);
}
Index: netinet/ip_divert.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_divert.c,v
diff -u -p -r1.107 ip_divert.c
--- netinet/ip_divert.c 8 Jul 2025 00:47:41 -0000 1.107
+++ netinet/ip_divert.c 24 Jul 2025 23:43:04 -0000
@@ -237,7 +237,7 @@ divert_packet(struct mbuf *m, int dir, u
goto bad;
}
mtx_leave(&so->so_rcv.sb_mtx);
- sorwakeup(so);
+ sorwakeup(so, NULL);
in_pcbunref(inp);
return;
Index: netinet/ip_mroute.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_mroute.c,v
diff -u -p -r1.150 ip_mroute.c
--- netinet/ip_mroute.c 19 Jul 2025 16:40:40 -0000 1.150
+++ netinet/ip_mroute.c 24 Jul 2025 23:43:04 -0000
@@ -1129,7 +1129,7 @@ socket_send(struct socket *so, struct mb
mtx_leave(&so->so_rcv.sb_mtx);
if (ret != 0) {
- sorwakeup(so);
+ sorwakeup(so, NULL);
return (0);
}
}
Index: netinet/raw_ip.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/raw_ip.c,v
diff -u -p -r1.167 raw_ip.c
--- netinet/raw_ip.c 8 Jul 2025 00:47:41 -0000 1.167
+++ netinet/raw_ip.c 24 Jul 2025 23:43:04 -0000
@@ -115,7 +115,7 @@ const struct pr_usrreqs rip_usrreqs = {
};
void rip_sbappend(struct inpcb *, struct mbuf *, struct ip *,
- struct sockaddr_in *);
+ struct sockaddr_in *, struct netstack *);
/*
* Initialize raw connection block q.
@@ -195,7 +195,7 @@ rip_input(struct mbuf **mp, int *offp, i
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
if (n != NULL)
- rip_sbappend(last, n, ip, &ripsrc);
+ rip_sbappend(last, n, ip, &ripsrc, ns);
in_pcbunref(last);
mtx_enter(&rawcbtable.inpt_mtx);
@@ -222,7 +222,7 @@ rip_input(struct mbuf **mp, int *offp, i
return IPPROTO_DONE;
}
- rip_sbappend(last, m, ip, &ripsrc);
+ rip_sbappend(last, m, ip, &ripsrc, ns);
in_pcbunref(last);
return IPPROTO_DONE;
@@ -230,7 +230,7 @@ rip_input(struct mbuf **mp, int *offp, i
void
rip_sbappend(struct inpcb *inp, struct mbuf *m, struct ip *ip,
- struct sockaddr_in *ripsrc)
+ struct sockaddr_in *ripsrc, struct netstack *ns)
{
struct socket *so = inp->inp_socket;
struct mbuf *opts = NULL;
@@ -249,7 +249,7 @@ rip_sbappend(struct inpcb *inp, struct m
m_freem(opts);
ipstat_inc(ips_noproto);
} else
- sorwakeup(so);
+ sorwakeup(so, ns);
}
/*
Index: netinet/tcp_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
diff -u -p -r1.457 tcp_input.c
--- netinet/tcp_input.c 24 Jul 2025 21:34:07 -0000 1.457
+++ netinet/tcp_input.c 24 Jul 2025 23:43:04 -0000
@@ -174,9 +174,10 @@ do { \
if_put(ifp); \
} while (0)
-int tcp_input_solocked(struct mbuf **, int *, int, int, struct socket **);
+int tcp_input_solocked(struct mbuf **, int *, int, int, struct socket **,
+ struct netstack *);
int tcp_mss_adv(struct rtentry *, int);
-int tcp_flush_queue(struct tcpcb *);
+int tcp_flush_queue(struct tcpcb *, struct netstack *);
void tcp_sack_partialack(struct tcpcb *, struct tcphdr *);
void tcp_newreno_partialack(struct tcpcb *, struct tcphdr *);
@@ -208,7 +209,8 @@ struct syn_cache *syn_cache_lookup(const
*/
int
-tcp_reass(struct tcpcb *tp, struct tcphdr *th, struct mbuf *m, int *tlen)
+tcp_reass(struct tcpcb *tp, struct tcphdr *th, struct mbuf *m, int *tlen,
+ struct netstack *ns)
{
struct tcpqent *p, *q, *nq, *tiqe;
@@ -303,11 +305,11 @@ tcp_reass(struct tcpcb *tp, struct tcphd
if (th->th_seq != tp->rcv_nxt)
return (0);
- return (tcp_flush_queue(tp));
+ return (tcp_flush_queue(tp, ns));
}
int
-tcp_flush_queue(struct tcpcb *tp)
+tcp_flush_queue(struct tcpcb *tp, struct netstack *ns)
{
struct socket *so = tp->t_inpcb->inp_socket;
struct tcpqent *q, *nq;
@@ -342,7 +344,7 @@ tcp_flush_queue(struct tcpcb *tp)
q = nq;
} while (q != NULL && q->tcpqe_tcp->th_seq == tp->rcv_nxt);
tp->t_flags |= TF_BLOCKOUTPUT;
- sorwakeup(so);
+ sorwakeup(so, ns);
tp->t_flags &= ~TF_BLOCKOUTPUT;
return (flags);
}
@@ -351,7 +353,7 @@ int
tcp_input(struct mbuf **mp, int *offp, int proto, int af, struct netstack *ns)
{
if (ns == NULL)
- return tcp_input_solocked(mp, offp, proto, af, NULL);
+ return tcp_input_solocked(mp, offp, proto, af, NULL, ns);
(*mp)->m_pkthdr.ph_cookie = (void *)(long)(*offp);
switch (af) {
case AF_INET:
@@ -370,7 +372,7 @@ tcp_input(struct mbuf **mp, int *offp, i
}
void
-tcp_input_mlist(struct mbuf_list *ml, int af)
+tcp_input_mlist(struct mbuf_list *ml, int af, struct netstack *ns)
{
struct socket *so = NULL;
struct mbuf *m;
@@ -380,7 +382,7 @@ tcp_input_mlist(struct mbuf_list *ml, in
off = (long)m->m_pkthdr.ph_cookie;
m->m_pkthdr.ph_cookie = NULL;
- nxt = tcp_input_solocked(&m, &off, IPPROTO_TCP, af, &so);
+ nxt = tcp_input_solocked(&m, &off, IPPROTO_TCP, af, &so, ns);
KASSERT(nxt == IPPROTO_DONE);
}
@@ -393,7 +395,7 @@ tcp_input_mlist(struct mbuf_list *ml, in
*/
int
tcp_input_solocked(struct mbuf **mp, int *offp, int proto, int af,
- struct socket **solocked)
+ struct socket **solocked, struct netstack *ns)
{
struct mbuf *m = *mp;
int iphlen = *offp;
@@ -1075,7 +1077,7 @@ findpcb:
tcp_update_sndspace(tp);
if (sb_notify(&so->so_snd)) {
tp->t_flags |= TF_BLOCKOUTPUT;
- sowwakeup(so);
+ sowwakeup(so, ns);
tp->t_flags &= ~TF_BLOCKOUTPUT;
}
if (so->so_snd.sb_cc ||
@@ -1131,7 +1133,7 @@ findpcb:
mtx_leave(&so->so_rcv.sb_mtx);
}
tp->t_flags |= TF_BLOCKOUTPUT;
- sorwakeup(so);
+ sorwakeup(so, ns);
tp->t_flags &= ~TF_BLOCKOUTPUT;
if (tp->t_flags & (TF_ACKNOW|TF_NEEDOUTPUT))
(void) tcp_output(tp);
@@ -1264,7 +1266,7 @@ findpcb:
tp->snd_scale = tp->requested_s_scale;
tp->rcv_scale = tp->request_r_scale;
}
- tcp_flush_queue(tp);
+ tcp_flush_queue(tp, ns);
/*
* if we didn't have to retransmit the SYN,
@@ -1553,7 +1555,7 @@ trimthenstep6:
tp->rcv_scale = tp->request_r_scale;
tiwin = th->th_win << tp->snd_scale;
}
- tcp_flush_queue(tp);
+ tcp_flush_queue(tp, ns);
tp->snd_wl1 = th->th_seq - 1;
/* fall into ... */
@@ -1835,7 +1837,7 @@ trimthenstep6:
tcp_update_sndspace(tp);
if (sb_notify(&so->so_snd)) {
tp->t_flags |= TF_BLOCKOUTPUT;
- sowwakeup(so);
+ sowwakeup(so, ns);
tp->t_flags &= ~TF_BLOCKOUTPUT;
}
@@ -2051,11 +2053,11 @@ dodata: /* XXX */
mtx_leave(&so->so_rcv.sb_mtx);
}
tp->t_flags |= TF_BLOCKOUTPUT;
- sorwakeup(so);
+ sorwakeup(so, ns);
tp->t_flags &= ~TF_BLOCKOUTPUT;
} else {
m_adj(m, hdroptlen);
- tiflags = tcp_reass(tp, th, m, &tlen);
+ tiflags = tcp_reass(tp, th, m, &tlen, ns);
tp->t_flags |= TF_ACKNOW;
}
if (tp->sack_enable)
Index: netinet/tcp_subr.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_subr.c,v
diff -u -p -r1.216 tcp_subr.c
--- netinet/tcp_subr.c 18 Jul 2025 08:39:14 -0000 1.216
+++ netinet/tcp_subr.c 24 Jul 2025 23:43:04 -0000
@@ -589,8 +589,8 @@ tcp_notify(struct inpcb *inp, int error)
else
tp->t_softerror = error;
wakeup((caddr_t) &so->so_timeo);
- sorwakeup(so);
- sowwakeup(so);
+ sorwakeup(so, NULL);
+ sowwakeup(so, NULL);
}
#ifdef INET6
Index: netinet/tcp_var.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_var.h,v
diff -u -p -r1.195 tcp_var.h
--- netinet/tcp_var.h 18 Jun 2025 16:15:46 -0000 1.195
+++ netinet/tcp_var.h 24 Jul 2025 23:43:04 -0000
@@ -725,7 +725,7 @@ int tcp_dooptions(struct tcpcb *, u_cha
struct mbuf *, int, struct tcp_opt_info *, u_int, uint64_t);
void tcp_init(void);
int tcp_input(struct mbuf **, int *, int, int, struct netstack *);
-void tcp_input_mlist(struct mbuf_list *, int);
+void tcp_input_mlist(struct mbuf_list *, int, struct netstack *);
int tcp_mss(struct tcpcb *, int);
void tcp_mss_update(struct tcpcb *);
void tcp_softlro_glue(struct mbuf_list *, struct mbuf *, struct ifnet *);
@@ -744,7 +744,8 @@ int tcp_softtso_chop(struct mbuf_list *
int tcp_if_output_tso(struct ifnet *, struct mbuf **, struct sockaddr *,
struct rtentry *, uint32_t, u_int);
void tcp_pulloutofband(struct socket *, u_int, struct mbuf *, int);
-int tcp_reass(struct tcpcb *, struct tcphdr *, struct mbuf *, int *);
+int tcp_reass(struct tcpcb *, struct tcphdr *, struct mbuf *, int *,
+ struct netstack *);
void tcp_rscale(struct tcpcb *, u_long);
void tcp_respond(struct tcpcb *, caddr_t, struct tcphdr *, tcp_seq,
tcp_seq, int, u_int, uint64_t);
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/udp_usrreq.c,v
diff -u -p -r1.349 udp_usrreq.c
--- netinet/udp_usrreq.c 18 Jul 2025 08:39:14 -0000 1.349
+++ netinet/udp_usrreq.c 24 Jul 2025 23:43:04 -0000
@@ -709,7 +709,7 @@ udp_sbappend(struct inpcb *inp, struct m
}
mtx_leave(&so->so_rcv.sb_mtx);
- sorwakeup(so);
+ sorwakeup(so, ns);
}
/*
@@ -720,8 +720,8 @@ void
udp_notify(struct inpcb *inp, int errno)
{
inp->inp_socket->so_error = errno;
- sorwakeup(inp->inp_socket);
- sowwakeup(inp->inp_socket);
+ sorwakeup(inp->inp_socket, NULL);
+ sowwakeup(inp->inp_socket, NULL);
}
#ifdef INET6
Index: netinet6/ip6_divert.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_divert.c,v
diff -u -p -r1.108 ip6_divert.c
--- netinet6/ip6_divert.c 8 Jul 2025 00:47:41 -0000 1.108
+++ netinet6/ip6_divert.c 24 Jul 2025 23:43:04 -0000
@@ -235,7 +235,7 @@ divert6_packet(struct mbuf *m, int dir,
goto bad;
}
mtx_leave(&so->so_rcv.sb_mtx);
- sorwakeup(so);
+ sorwakeup(so, NULL);
in_pcbunref(inp);
return;
Index: netinet6/ip6_mroute.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_mroute.c,v
diff -u -p -r1.152 ip6_mroute.c
--- netinet6/ip6_mroute.c 24 Jul 2025 21:35:53 -0000 1.152
+++ netinet6/ip6_mroute.c 24 Jul 2025 23:43:04 -0000
@@ -906,7 +906,7 @@ socket6_send(struct socket *so, struct m
mtx_leave(&so->so_rcv.sb_mtx);
if (ret != 0) {
- sorwakeup(so);
+ sorwakeup(so, NULL);
return 0;
}
}
Index: netinet6/raw_ip6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/raw_ip6.c,v
diff -u -p -r1.194 raw_ip6.c
--- netinet6/raw_ip6.c 8 Jul 2025 00:47:41 -0000 1.194
+++ netinet6/raw_ip6.c 24 Jul 2025 23:43:04 -0000
@@ -114,7 +114,7 @@ const struct pr_usrreqs rip6_usrreqs = {
};
void rip6_sbappend(struct inpcb *, struct mbuf *, struct ip6_hdr *, int,
- struct sockaddr_in6 *);
+ struct sockaddr_in6 *, struct netstack *);
/*
* Initialize raw connection block queue.
@@ -229,7 +229,8 @@ rip6_input(struct mbuf **mp, int *offp,
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
if (n != NULL)
- rip6_sbappend(last, n, ip6, *offp, &rip6src);
+ rip6_sbappend(last, n, ip6, *offp, &rip6src,
+ ns);
in_pcbunref(last);
mtx_enter(&rawin6pcbtable.inpt_mtx);
@@ -262,7 +263,7 @@ rip6_input(struct mbuf **mp, int *offp,
return IPPROTO_DONE;
}
- rip6_sbappend(last, m, ip6, *offp, &rip6src);
+ rip6_sbappend(last, m, ip6, *offp, &rip6src, ns);
in_pcbunref(last);
return IPPROTO_DONE;
@@ -270,7 +271,7 @@ rip6_input(struct mbuf **mp, int *offp,
void
rip6_sbappend(struct inpcb *inp, struct mbuf *m, struct ip6_hdr *ip6, int hlen,
- struct sockaddr_in6 *rip6src)
+ struct sockaddr_in6 *rip6src, struct netstack *ns)
{
struct socket *so = inp->inp_socket;
struct mbuf *opts = NULL;
@@ -291,7 +292,7 @@ rip6_sbappend(struct inpcb *inp, struct
m_freem(opts);
rip6stat_inc(rip6s_fullsock);
} else
- sorwakeup(so);
+ sorwakeup(so, ns);
}
void
Index: sys/socketvar.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/sys/socketvar.h,v
diff -u -p -r1.158 socketvar.h
--- sys/socketvar.h 8 Apr 2025 15:31:22 -0000 1.158
+++ sys/socketvar.h 24 Jul 2025 23:43:04 -0000
@@ -74,6 +74,7 @@ struct sosplice {
struct timeval ssp_idletv; /* [I] idle timeout */
struct timeout ssp_idleto;
struct task ssp_task; /* task for somove */
+ struct taskq *ssp_queue; /* softnet queue where we were added */
};
/*
@@ -267,8 +268,8 @@ int sosend(struct socket *, struct mbuf
int sosetopt(struct socket *, int, int, struct mbuf *);
int soshutdown(struct socket *, int);
void sowakeup(struct socket *, struct sockbuf *);
-void sorwakeup(struct socket *);
-void sowwakeup(struct socket *);
+void sorwakeup(struct socket *, struct netstack *);
+void sowwakeup(struct socket *, struct netstack *);
int sockargs(struct mbuf **, const void *, size_t, int);
int sosleep_nsec(struct socket *, void *, int, const char *, uint64_t);
use softnet for socket splicing