Index: sys/netinet/in_pcb.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet/in_pcb.c,v diff -u -p -u -p -r1.309 in_pcb.c --- sys/netinet/in_pcb.c 3 Jan 2025 12:56:15 -0000 1.309 +++ sys/netinet/in_pcb.c 5 Jan 2025 17:05:40 -0000 @@ -634,18 +634,18 @@ in_pcbsolock(struct inpcb *inp) mtx_leave(&inp->inp_sofree_mtx); if (so == NULL) return NULL; - rw_enter_write(&so->so_lock); - sorele(so); - return so; } void in_pcbsounlock(struct inpcb *inp, struct socket *so) { - KASSERT(inp->inp_socket == so); + if (so == NULL) + return; + KASSERT(inp->inp_socket == NULL || inp->inp_socket == so); rw_exit_write(&so->so_lock); + sorele(so); } struct inpcb * Index: sys/netinet/tcp_timer.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet/tcp_timer.c,v diff -u -p -u -p -r1.80 tcp_timer.c --- sys/netinet/tcp_timer.c 5 Jan 2025 12:18:48 -0000 1.80 +++ sys/netinet/tcp_timer.c 5 Jan 2025 17:05:40 -0000 @@ -113,6 +113,7 @@ void tcp_timer_delack(void *arg) { struct inpcb *inp = arg; + struct socket *so; struct tcpcb *otp = NULL, *tp; short ostate; @@ -121,7 +122,10 @@ tcp_timer_delack(void *arg) * for whatever reason, it will restart the delayed * ACK callout. */ - NET_LOCK(); + NET_LOCK_SHARED(); + so = in_pcbsolock(inp); + if (so == NULL) + goto out; tp = intotcpcb(inp); /* Ignore canceled timeouts or timeouts that have been rescheduled. */ if (tp == NULL || !ISSET(tp->t_flags, TF_TMR_DELACK) || @@ -138,7 +142,8 @@ tcp_timer_delack(void *arg) if (otp) tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_DELACK, 0); out: - NET_UNLOCK(); + in_pcbsounlock(inp, so); + NET_UNLOCK_SHARED(); in_pcbunref(inp); } @@ -199,11 +204,15 @@ void tcp_timer_rexmt(void *arg) { struct inpcb *inp = arg; + struct socket *so; struct tcpcb *otp = NULL, *tp; - uint32_t rto; short ostate; + uint32_t rto; - NET_LOCK(); + NET_LOCK_SHARED(); + so = in_pcbsolock(inp); + if (so == NULL) + goto out; tp = intotcpcb(inp); /* Ignore canceled timeouts or timeouts that have been rescheduled. */ if (tp == NULL || !ISSET(tp->t_flags, TF_TMR_REXMT) || @@ -391,7 +400,8 @@ tcp_timer_rexmt(void *arg) if (otp) tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_REXMT, 0); out: - NET_UNLOCK(); + in_pcbsounlock(inp, so); + NET_UNLOCK_SHARED(); in_pcbunref(inp); } @@ -399,12 +409,16 @@ void tcp_timer_persist(void *arg) { struct inpcb *inp = arg; + struct socket *so; struct tcpcb *otp = NULL, *tp; - uint32_t rto; short ostate; uint64_t now; + uint32_t rto; - NET_LOCK(); + NET_LOCK_SHARED(); + so = in_pcbsolock(inp); + if (so == NULL) + goto out; tp = intotcpcb(inp); /* Ignore canceled timeouts or timeouts that have been rescheduled. */ if (tp == NULL || !ISSET(tp->t_flags, TF_TMR_PERSIST) || @@ -445,7 +459,8 @@ tcp_timer_persist(void *arg) if (otp) tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_PERSIST, 0); out: - NET_UNLOCK(); + in_pcbsounlock(inp, so); + NET_UNLOCK_SHARED(); in_pcbunref(inp); } @@ -453,10 +468,14 @@ void tcp_timer_keep(void *arg) { struct inpcb *inp = arg; + struct socket *so; struct tcpcb *otp = NULL, *tp; short ostate; - NET_LOCK(); + NET_LOCK_SHARED(); + so = in_pcbsolock(inp); + if (so == NULL) + goto out; tp = intotcpcb(inp); /* Ignore canceled timeouts or timeouts that have been rescheduled. */ if (tp == NULL || !ISSET(tp->t_flags, TF_TMR_KEEP) || @@ -509,7 +528,8 @@ tcp_timer_keep(void *arg) if (otp) tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_KEEP, 0); out: - NET_UNLOCK(); + in_pcbsounlock(inp, so); + NET_UNLOCK_SHARED(); in_pcbunref(inp); } @@ -517,12 +537,16 @@ void tcp_timer_2msl(void *arg) { struct inpcb *inp = arg; + struct socket *so; struct tcpcb *otp = NULL, *tp; short ostate; - int maxidle; uint64_t now; + int maxidle; - NET_LOCK(); + NET_LOCK_SHARED(); + so = in_pcbsolock(inp); + if (so == NULL) + goto out; tp = intotcpcb(inp); /* Ignore canceled timeouts or timeouts that have been rescheduled. */ if (tp == NULL || !ISSET(tp->t_flags, TF_TMR_2MSL) || @@ -546,7 +570,8 @@ tcp_timer_2msl(void *arg) if (otp) tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_2MSL, 0); out: - NET_UNLOCK(); + in_pcbsounlock(inp, so); + NET_UNLOCK_SHARED(); in_pcbunref(inp); }