On Mon, 26 Jun 2017 16:07:00 +0200, Martin Pieuchot wrote:
> 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().
One comment inline, otherwise OK.
- todd
> 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) {
I think you meant "} else if (...)" there
> + 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