On Mon, Nov 07, 2016 at 10:16 +0100, Martin Pieuchot wrote:
> We're aiming to replace critical sections protected by splsoftnet() by
> a non recursive rwlock. So we'll have to care about recursivity.
>
> Diff below prevents a recursion in the error path. Currently closef()
> will call soclose() which will take splsoftnet() again. So let's
> release the spl level before.
>
> This is part of my bigger socket lock diff.
>
> ok?
>
Looks good to me. OK mikeb
> Index: kern/uipc_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
> retrieving revision 1.138
> diff -u -p -r1.138 uipc_syscalls.c
> --- kern/uipc_syscalls.c 23 Oct 2016 17:06:40 -0000 1.138
> +++ kern/uipc_syscalls.c 7 Nov 2016 09:10:32 -0000
> @@ -276,16 +276,11 @@ doaccept(struct proc *p, int sock, struc
> if ((error = getsock(p, sock, &fp)) != 0)
> return (error);
>
> - s = splsoftnet();
> headfp = fp;
> - head = fp->f_data;
> -
> - if (isdnssocket((struct socket *)fp->f_data)) {
> - error = EINVAL;
> - goto bad;
> - }
> redo:
> - if ((head->so_options & SO_ACCEPTCONN) == 0) {
> + s = splsoftnet();
> + head = headfp->f_data;
> + if (isdnssocket(head) || (head->so_options & SO_ACCEPTCONN) == 0) {
> error = EINVAL;
> goto bad;
> }
> @@ -311,7 +306,7 @@ redo:
> head->so_error = 0;
> goto bad;
> }
> -
> +
> /* Figure out whether the new socket should be non-blocking. */
> nflag = flags & SOCK_NONBLOCK_INHERIT ? (headfp->f_flag & FNONBLOCK)
> : (flags & SOCK_NONBLOCK ? FNONBLOCK : 0);
> @@ -338,6 +333,7 @@ redo:
> * or another thread or process to accept it. If so, start over.
> */
> if (head->so_qlen == 0) {
> + splx(s);
> m_freem(nam);
> fdplock(fdp);
> fdremove(fdp, tmpfd);
> @@ -366,18 +362,23 @@ redo:
>
> if (error) {
> /* if an error occurred, free the file descriptor */
> + splx(s);
> + m_freem(nam);
> fdplock(fdp);
> fdremove(fdp, tmpfd);
> closef(fp, p);
> fdpunlock(fdp);
> + goto out;
> } else {
> (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&nflag, p);
> FILE_SET_MATURE(fp, p);
> *retval = tmpfd;
> + m_freem(nam);
> }
> - m_freem(nam);
> +
> bad:
> splx(s);
> +out:
> FRELE(headfp, p);
> return (error);
> }
>