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);
>  }
> 

Reply via email to