Now that we have a mechanism to check when to lock the socket inside a kqueue filter, let's use it.
Diff below protects `so_qlen', `so_state' and `so_snd.sb_lowat' which are accessed in tcp_input(). ok? Index: kern/uipc_socket.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_socket.c,v retrieving revision 1.189 diff -u -p -r1.189 uipc_socket.c --- kern/uipc_socket.c 26 Jun 2017 09:32:31 -0000 1.189 +++ kern/uipc_socket.c 26 Jun 2017 14:00:46 -0000 @@ -1991,35 +1991,44 @@ int filt_sowrite(struct knote *kn, long hint) { struct socket *so = kn->kn_fp->f_data; - int s; + int s, rv; if (!(hint & NOTE_SUBMIT)) s = solock(so); kn->kn_data = sbspace(so, &so->so_snd); - if (!(hint & NOTE_SUBMIT)) - sounlock(s); if (so->so_state & SS_CANTSENDMORE) { kn->kn_flags |= EV_EOF; kn->kn_fflags = so->so_error; - return (1); + rv = 1; + } else if (so->so_error) { /* temporary udp error */ + rv = 1; + } else if (((so->so_state & SS_ISCONNECTED) == 0) && + (so->so_proto->pr_flags & PR_CONNREQUIRED)) { + rv = 0; + } if (kn->kn_sfflags & NOTE_LOWAT) { + rv = (kn->kn_data >= kn->kn_sdata); + } else { + rv = (kn->kn_data >= so->so_snd.sb_lowat); } - if (so->so_error) /* temporary udp error */ - return (1); - if (((so->so_state & SS_ISCONNECTED) == 0) && - (so->so_proto->pr_flags & PR_CONNREQUIRED)) - return (0); - if (kn->kn_sfflags & NOTE_LOWAT) - return (kn->kn_data >= kn->kn_sdata); - return (kn->kn_data >= so->so_snd.sb_lowat); + if (!(hint & NOTE_SUBMIT)) + sounlock(s); + + return (rv); } int filt_solisten(struct knote *kn, long hint) { struct socket *so = kn->kn_fp->f_data; + int s; + if (!(hint & NOTE_SUBMIT)) + s = solock(so); kn->kn_data = so->so_qlen; - return (so->so_qlen != 0); + if (!(hint & NOTE_SUBMIT)) + sounlock(s); + + return (kn->kn_data != 0); } #ifdef DDB