On Mon, Feb 13, 2017 at 10:45:43AM +0100, Martin Pieuchot wrote:
> On 10/02/17(Fri) 15:21, Alexander Bluhm wrote:
> > The 42 looks like an evil hack.
> It is.  I couldn't come to a better solution without refactoring the
> pr_usrreq interface.

The only problem I see is sofree().  In kern/uipc_socket.c sofree(so)
is called two times before unlock(s), so we cannot pass so to check
so->so_proto->pr_domain->dom_family.

There must be a better solution than 42, but this should not delay
this diff.  Add a comment that we have to fix it later.

> I also change the SOCKET_LOCK() macros into real
> functions to stop polluting <sys/systm.h>.

I would prefer if NET_LOCK(s) and solock(so) would look similar.
So either s = netlock(); s = solock(so); or NET_LOCK(s); SOCKET_LOCK(so, s);

> Comments, oks?

I did run the regression tests.  The same tests pass or fail with
and without this diff.

OK bluhm@

> Index: kern/sys_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/sys_socket.c,v
> retrieving revision 1.28
> diff -u -p -r1.28 sys_socket.c
> --- kern/sys_socket.c 31 Jan 2017 12:16:20 -0000      1.28
> +++ kern/sys_socket.c 13 Feb 2017 09:28:51 -0000
> @@ -127,10 +127,10 @@ soo_ioctl(struct file *fp, u_long cmd, c
>       }
>       if (IOCGROUP(cmd) == 'r')
>               return (EOPNOTSUPP);
> -     NET_LOCK(s);
> +     s = solock(so);
>       error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 
>           (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)NULL, p));
> -     NET_UNLOCK(s);
> +     sounlock(s);
>  
>       return (error);
>  }
> @@ -187,10 +187,10 @@ soo_stat(struct file *fp, struct stat *u
>               ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
>       ub->st_uid = so->so_euid;
>       ub->st_gid = so->so_egid;
> -     NET_LOCK(s);
> +     s = solock(so);
>       (void) ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
>           (struct mbuf *)ub, NULL, NULL, p));
> -     NET_UNLOCK(s);
> +     sounlock(s);
>       return (0);
>  }
>  
> Index: kern/uipc_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket.c,v
> retrieving revision 1.176
> diff -u -p -r1.176 uipc_socket.c
> --- kern/uipc_socket.c        1 Feb 2017 20:59:47 -0000       1.176
> +++ kern/uipc_socket.c        13 Feb 2017 09:29:45 -0000
> @@ -135,16 +135,16 @@ socreate(int dom, struct socket **aso, i
>       so->so_egid = p->p_ucred->cr_gid;
>       so->so_cpid = p->p_p->ps_pid;
>       so->so_proto = prp;
> -     NET_LOCK(s);
> +     s = solock(so);
>       error = (*prp->pr_usrreq)(so, PRU_ATTACH, NULL,
>           (struct mbuf *)(long)proto, NULL, p);
>       if (error) {
>               so->so_state |= SS_NOFDREF;
>               sofree(so);
> -             NET_UNLOCK(s);
> +             sounlock(s);
>               return (error);
>       }
> -     NET_UNLOCK(s);
> +     sounlock(s);
>       *aso = so;
>       return (0);
>  }
> @@ -154,9 +154,9 @@ sobind(struct socket *so, struct mbuf *n
>  {
>       int s, error;
>  
> -     NET_LOCK(s);
> +     s = solock(so);
>       error = (*so->so_proto->pr_usrreq)(so, PRU_BIND, NULL, nam, NULL, p);
> -     NET_UNLOCK(s);
> +     sounlock(s);
>       return (error);
>  }
>  
> @@ -171,11 +171,11 @@ solisten(struct socket *so, int backlog)
>       if (isspliced(so) || issplicedback(so))
>               return (EOPNOTSUPP);
>  #endif /* SOCKET_SPLICE */
> -     NET_LOCK(s);
> +     s = solock(so);
>       error = (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, NULL, NULL, NULL,
>           curproc);
>       if (error) {
> -             NET_UNLOCK(s);
> +             sounlock(s);
>               return (error);
>       }
>       if (TAILQ_FIRST(&so->so_q) == NULL)
> @@ -185,14 +185,14 @@ solisten(struct socket *so, int backlog)
>       if (backlog < sominconn)
>               backlog = sominconn;
>       so->so_qlimit = backlog;
> -     NET_UNLOCK(s);
> +     sounlock(s);
>       return (0);
>  }
>  
>  void
>  sofree(struct socket *so)
>  {
> -     NET_ASSERT_LOCKED();
> +     soassertlocked(so);
>  
>       if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
>               return;
> @@ -232,7 +232,7 @@ soclose(struct socket *so)
>       struct socket *so2;
>       int s, error = 0;
>  
> -     NET_LOCK(s);
> +     s = solock(so);
>       if (so->so_options & SO_ACCEPTCONN) {
>               while ((so2 = TAILQ_FIRST(&so->so_q0)) != NULL) {
>                       (void) soqremque(so2, 0);
> @@ -256,7 +256,7 @@ soclose(struct socket *so)
>                           (so->so_state & SS_NBIO))
>                               goto drop;
>                       while (so->so_state & SS_ISCONNECTED) {
> -                             error = rwsleep(&so->so_timeo, &netlock,
> +                             error = sosleep(so, &so->so_timeo,
>                                   PSOCK | PCATCH, "netcls",
>                                   so->so_linger * hz);
>                               if (error)
> @@ -276,14 +276,14 @@ discard:
>               panic("soclose NOFDREF: so %p, so_type %d", so, so->so_type);
>       so->so_state |= SS_NOFDREF;
>       sofree(so);
> -     NET_UNLOCK(s);
> +     sounlock(s);
>       return (error);
>  }
>  
>  int
>  soabort(struct socket *so)
>  {
> -     NET_ASSERT_LOCKED();
> +     soassertlocked(so);
>  
>       return (*so->so_proto->pr_usrreq)(so, PRU_ABORT, NULL, NULL, NULL,
>          curproc);
> @@ -294,7 +294,7 @@ soaccept(struct socket *so, struct mbuf 
>  {
>       int error = 0;
>  
> -     NET_ASSERT_LOCKED();
> +     soassertlocked(so);
>  
>       if ((so->so_state & SS_NOFDREF) == 0)
>               panic("soaccept !NOFDREF: so %p, so_type %d", so, so->so_type);
> @@ -315,7 +315,7 @@ soconnect(struct socket *so, struct mbuf
>  
>       if (so->so_options & SO_ACCEPTCONN)
>               return (EOPNOTSUPP);
> -     NET_LOCK(s);
> +     s = solock(so);
>       /*
>        * If protocol is connection-based, can only connect once.
>        * Otherwise, if connected, try to disconnect first.
> @@ -329,7 +329,7 @@ soconnect(struct socket *so, struct mbuf
>       else
>               error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
>                   NULL, nam, NULL, curproc);
> -     NET_UNLOCK(s);
> +     sounlock(s);
>       return (error);
>  }
>  
> @@ -338,10 +338,10 @@ soconnect2(struct socket *so1, struct so
>  {
>       int s, error;
>  
> -     NET_LOCK(s);
> +     s = solock(so1);
>       error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2, NULL,
>           (struct mbuf *)so2, NULL, curproc);
> -     NET_UNLOCK(s);
> +     sounlock(s);
>       return (error);
>  }
>  
> @@ -350,7 +350,7 @@ sodisconnect(struct socket *so)
>  {
>       int error;
>  
> -     NET_ASSERT_LOCKED();
> +     soassertlocked(so);
>  
>       if ((so->so_state & SS_ISCONNECTED) == 0)
>               return (ENOTCONN);
> @@ -418,14 +418,14 @@ sosend(struct socket *so, struct mbuf *a
>                           (sizeof(struct fdpass) / sizeof(int)));
>       }
>  
> -#define      snderr(errno)   { error = errno; NET_UNLOCK(s); goto release; }
> +#define      snderr(errno)   { error = errno; sounlock(s); goto release; }
>  
>  restart:
>       if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags), NULL)) != 0)
>               goto out;
>       so->so_state |= SS_ISSENDING;
>       do {
> -             NET_LOCK(s);
> +             s = solock(so);
>               if (so->so_state & SS_CANTSENDMORE)
>                       snderr(EPIPE);
>               if (so->so_error) {
> @@ -453,14 +453,14 @@ restart:
>                       if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT))
>                               snderr(EWOULDBLOCK);
>                       sbunlock(&so->so_snd);
> -                     error = sbwait(&so->so_snd);
> +                     error = sbwait(so, &so->so_snd);
>                       so->so_state &= ~SS_ISSENDING;
> -                     NET_UNLOCK(s);
> +                     sounlock(s);
>                       if (error)
>                               goto out;
>                       goto restart;
>               }
> -             NET_UNLOCK(s);
> +             sounlock(s);
>               space -= clen;
>               do {
>                       if (uio == NULL) {
> @@ -480,13 +480,13 @@ restart:
>                               if (flags & MSG_EOR)
>                                       top->m_flags |= M_EOR;
>                       }
> -                     NET_LOCK(s);
> +                     s = solock(so);
>                       if (resid == 0)
>                               so->so_state &= ~SS_ISSENDING;
>                       error = (*so->so_proto->pr_usrreq)(so,
>                           (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND,
>                           top, addr, control, curproc);
> -                     NET_UNLOCK(s);
> +                     sounlock(s);
>                       clen = 0;
>                       control = NULL;
>                       top = NULL;
> @@ -615,7 +615,7 @@ sbsync(struct sockbuf *sb, struct mbuf *
>   * followed by an optional mbuf or mbufs containing ancillary data,
>   * and then zero or more mbufs of data.
>   * In order to avoid blocking network for the entire time here, we release
> - * the NET_LOCK() while doing the actual copy to user space.
> + * the solock() while doing the actual copy to user space.
>   * Although the sockbuf is locked, new data may still be appended,
>   * and thus we must maintain consistency of the sockbuf during that time.
>   *
> @@ -649,10 +649,10 @@ soreceive(struct socket *so, struct mbuf
>               flags |= MSG_DONTWAIT;
>       if (flags & MSG_OOB) {
>               m = m_get(M_WAIT, MT_DATA);
> -             NET_LOCK(s);
> +             s = solock(so);
>               error = (*pr->pr_usrreq)(so, PRU_RCVOOB, m,
>                   (struct mbuf *)(long)(flags & MSG_PEEK), NULL, curproc);
> -             NET_UNLOCK(s);
> +             sounlock(s);
>               if (error)
>                       goto bad;
>               do {
> @@ -670,7 +670,7 @@ bad:
>  restart:
>       if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags), NULL)) != 0)
>               return (error);
> -     NET_LOCK(s);
> +     s = solock(so);
>  
>       m = so->so_rcv.sb_mb;
>  #ifdef SOCKET_SPLICE
> @@ -734,8 +734,8 @@ restart:
>               SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 1");
>               SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1");
>               sbunlock(&so->so_rcv);
> -             error = sbwait(&so->so_rcv);
> -             NET_UNLOCK(s);
> +             error = sbwait(so, &so->so_rcv);
> +             sounlock(s);
>               if (error)
>                       return (error);
>               goto restart;
> @@ -801,11 +801,9 @@ dontblock:
>                               if (pr->pr_domain->dom_externalize &&
>                                   mtod(cm, struct cmsghdr *)->cmsg_type ==
>                                   SCM_RIGHTS) {
> -                                     NET_UNLOCK(s);
>                                       error =
>                                           (*pr->pr_domain->dom_externalize)
>                                           (cm, controllen, flags);
> -                                     NET_LOCK(s);
>                               }
>                               *controlp = cm;
>                       } else {
> @@ -873,9 +871,9 @@ dontblock:
>                       SBLASTRECORDCHK(&so->so_rcv, "soreceive uiomove");
>                       SBLASTMBUFCHK(&so->so_rcv, "soreceive uiomove");
>                       resid = uio->uio_resid;
> -                     NET_UNLOCK(s);
> +                     sounlock(s);
>                       uio_error = uiomove(mtod(m, caddr_t) + moff, len, uio);
> -                     NET_LOCK(s);
> +                     s = solock(so);
>                       if (uio_error)
>                               uio->uio_resid = resid - len;
>               } else
> @@ -954,10 +952,10 @@ dontblock:
>                               break;
>                       SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2");
>                       SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2");
> -                     error = sbwait(&so->so_rcv);
> +                     error = sbwait(so, &so->so_rcv);
>                       if (error) {
>                               sbunlock(&so->so_rcv);
> -                             NET_UNLOCK(s);
> +                             sounlock(s);
>                               return (0);
>                       }
>                       if ((m = so->so_rcv.sb_mb) != NULL)
> @@ -993,7 +991,7 @@ dontblock:
>       if (orig_resid == uio->uio_resid && orig_resid &&
>           (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
>               sbunlock(&so->so_rcv);
> -             NET_UNLOCK(s);
> +             sounlock(s);
>               goto restart;
>       }
>  
> @@ -1004,7 +1002,7 @@ dontblock:
>               *flagsp |= flags;
>  release:
>       sbunlock(&so->so_rcv);
> -     NET_UNLOCK(s);
> +     sounlock(s);
>       return (error);
>  }
>  
> @@ -1014,7 +1012,7 @@ soshutdown(struct socket *so, int how)
>       struct protosw *pr = so->so_proto;
>       int s, error = 0;
>  
> -     NET_LOCK(s);
> +     s = solock(so);
>       switch (how) {
>       case SHUT_RD:
>       case SHUT_RDWR:
> @@ -1030,7 +1028,7 @@ soshutdown(struct socket *so, int how)
>               error = EINVAL;
>               break;
>       }
> -     NET_UNLOCK(s);
> +     sounlock(s);
>  
>       return (error);
>  }
> @@ -1043,7 +1041,8 @@ sorflush(struct socket *so)
>       struct sockbuf asb;
>  
>       sb->sb_flags |= SB_NOINTR;
> -     (void) sblock(sb, M_WAITOK, &netlock);
> +     sblock(sb, M_WAITOK,
> +         (pr->pr_domain->dom_family != PF_LOCAL) ? &netlock : NULL);
>       socantrcvmore(so);
>       sbunlock(sb);
>       asb = *sb;
> @@ -1094,10 +1093,10 @@ sosplice(struct socket *so, int fd, off_
>               if ((error = sblock(&so->so_rcv,
>                   (so->so_state & SS_NBIO) ? M_NOWAIT : M_WAITOK, NULL)) != 0)
>                       return (error);
> -             NET_LOCK(s);
> +             s = solock(so);
>               if (so->so_sp->ssp_socket)
>                       sounsplice(so, so->so_sp->ssp_socket, 1);
> -             NET_UNLOCK(s);
> +             sounlock(s);
>               sbunlock(&so->so_rcv);
>               return (0);
>       }
> @@ -1126,7 +1125,7 @@ sosplice(struct socket *so, int fd, off_
>               FRELE(fp, curproc);
>               return (error);
>       }
> -     NET_LOCK(s);
> +     s = solock(so);
>  
>       if (so->so_sp->ssp_socket || sosp->so_sp->ssp_soback) {
>               error = EBUSY;
> @@ -1167,7 +1166,7 @@ sosplice(struct socket *so, int fd, off_
>       }
>  
>   release:
> -     NET_UNLOCK(s);
> +     sounlock(s);
>       sbunlock(&sosp->so_snd);
>       sbunlock(&so->so_rcv);
>       FRELE(fp, curproc);
> @@ -1177,7 +1176,7 @@ sosplice(struct socket *so, int fd, off_
>  void
>  sounsplice(struct socket *so, struct socket *sosp, int wakeup)
>  {
> -     NET_ASSERT_LOCKED();
> +     soassertlocked(so);
>  
>       task_del(sosplice_taskq, &so->so_splicetask);
>       timeout_del(&so->so_idleto);
> @@ -1194,12 +1193,12 @@ soidle(void *arg)
>       struct socket *so = arg;
>       int s;
>  
> -     NET_LOCK(s);
> +     s = solock(so);
>       if (so->so_rcv.sb_flagsintr & SB_SPLICE) {
>               so->so_error = ETIMEDOUT;
>               sounsplice(so, so->so_sp->ssp_socket, 1);
>       }
> -     NET_UNLOCK(s);
> +     sounlock(s);
>  }
>  
>  void
> @@ -1208,7 +1207,7 @@ sotask(void *arg)
>       struct socket *so = arg;
>       int s;
>  
> -     NET_LOCK(s);
> +     s = solock(so);
>       if (so->so_rcv.sb_flagsintr & SB_SPLICE) {
>               /*
>                * We may not sleep here as sofree() and unsplice() may be
> @@ -1217,7 +1216,7 @@ sotask(void *arg)
>                */
>               somove(so, M_DONTWAIT);
>       }
> -     NET_UNLOCK(s);
> +     sounlock(s);
>  
>       /* Avoid user land starvation. */
>       yield();
> @@ -1239,7 +1238,7 @@ somove(struct socket *so, int wait)
>       int              error = 0, maxreached = 0;
>       short            state;
>  
> -     NET_ASSERT_LOCKED();
> +     soassertlocked(so);
>  
>   nextpkt:
>       if (so->so_error) {
> @@ -1509,7 +1508,7 @@ somove(struct socket *so, int wait)
>  void
>  sorwakeup(struct socket *so)
>  {
> -     NET_ASSERT_LOCKED();
> +     soassertlocked(so);
>  
>  #ifdef SOCKET_SPLICE
>       if (so->so_rcv.sb_flagsintr & SB_SPLICE) {
> @@ -1541,7 +1540,7 @@ sorwakeup(struct socket *so)
>  void
>  sowwakeup(struct socket *so)
>  {
> -     NET_ASSERT_LOCKED();
> +     soassertlocked(so);
>  
>  #ifdef SOCKET_SPLICE
>       if (so->so_snd.sb_flagsintr & SB_SPLICE)
> @@ -1558,10 +1557,10 @@ sosetopt(struct socket *so, int level, i
>  
>       if (level != SOL_SOCKET) {
>               if (so->so_proto && so->so_proto->pr_ctloutput) {
> -                     NET_LOCK(s);
> +                     s = solock(so);
>                       error = (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
>                           level, optname, m0);
> -                     NET_UNLOCK(s);
> +                     sounlock(s);
>                       return (error);
>               }
>               error = ENOPROTOOPT;
> @@ -1705,10 +1704,10 @@ sosetopt(struct socket *so, int level, i
>                               struct domain *dom = so->so_proto->pr_domain;
>  
>                               level = dom->dom_protosw->pr_protocol;
> -                             NET_LOCK(s);
> +                             s = solock(so);
>                               error = (*so->so_proto->pr_ctloutput)
>                                   (PRCO_SETOPT, so, level, optname, m0);
> -                             NET_UNLOCK(s);
> +                             sounlock(s);
>                               return (error);
>                       }
>                       error = ENOPROTOOPT;
> @@ -1737,10 +1736,10 @@ sosetopt(struct socket *so, int level, i
>                       break;
>               }
>               if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
> -                     NET_LOCK(s);
> +                     s = solock(so);
>                       (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
>                           level, optname, m0);
> -                     NET_UNLOCK(s);
> +                     sounlock(s);
>                       m = NULL;       /* freed by protocol */
>               }
>       }
> @@ -1761,10 +1760,10 @@ sogetopt(struct socket *so, int level, i
>                       m = m_get(M_WAIT, MT_SOOPTS);
>                       m->m_len = 0;
>  
> -                     NET_LOCK(s);
> +                     s = solock(so);
>                       error = (*so->so_proto->pr_ctloutput)(PRCO_GETOPT, so,
>                           level, optname, m);
> -                     NET_UNLOCK(s);
> +                     sounlock(s);
>                       if (error) {
>                               m_free(m);
>                               return (error);
> @@ -1849,10 +1848,10 @@ sogetopt(struct socket *so, int level, i
>                               struct domain *dom = so->so_proto->pr_domain;
>  
>                               level = dom->dom_protosw->pr_protocol;
> -                             NET_LOCK(s);
> +                             s = solock(so);
>                               error = (*so->so_proto->pr_ctloutput)
>                                   (PRCO_GETOPT, so, level, optname, m);
> -                             NET_UNLOCK(s);
> +                             sounlock(s);
>                               if (error) {
>                                       (void)m_free(m);
>                                       return (error);
> Index: kern/uipc_socket2.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket2.c,v
> retrieving revision 1.71
> diff -u -p -r1.71 uipc_socket2.c
> --- kern/uipc_socket2.c       25 Jan 2017 06:15:50 -0000      1.71
> +++ kern/uipc_socket2.c       13 Feb 2017 09:29:25 -0000
> @@ -38,6 +38,7 @@
>  #include <sys/malloc.h>
>  #include <sys/mbuf.h>
>  #include <sys/protosw.h>
> +#include <sys/domain.h>
>  #include <sys/socket.h>
>  #include <sys/socketvar.h>
>  #include <sys/signalvar.h>
> @@ -147,7 +148,7 @@ sonewconn(struct socket *head, int conns
>       struct socket *so;
>       int soqueue = connstatus ? 1 : 0;
>  
> -     NET_ASSERT_LOCKED();
> +     soassertlocked(head);
>  
>       if (mclpools[0].pr_nout > mclpools[0].pr_hardlimit * 95 / 100)
>               return (NULL);
> @@ -267,16 +268,52 @@ socantrcvmore(struct socket *so)
>       sorwakeup(so);
>  }
>  
> +int
> +solock(struct socket *so)
> +{
> +     int s;
> +
> +     if (so->so_proto->pr_domain->dom_family != PF_LOCAL)
> +             NET_LOCK(s);
> +     else
> +             s = -42;
> +
> +     return (s);
> +}
> +
> +void
> +sounlock(int s)
> +{
> +     if (s != -42)
> +             NET_UNLOCK(s);
> +}
> +
> +void
> +soassertlocked(struct socket *so)
> +{
> +     if (so->so_proto->pr_domain->dom_family != PF_LOCAL)
> +             NET_ASSERT_LOCKED();
> +}
> +
> +int
> +sosleep(struct socket *so, void *ident, int prio, const char *wmesg, int 
> timo)
> +{
> +     if (so->so_proto->pr_domain->dom_family != PF_LOCAL)
> +             return rwsleep(ident, &netlock, prio, wmesg, timo);
> +     else
> +             return tsleep(ident, prio, wmesg, timo);
> +}
> +
>  /*
>   * Wait for data to arrive at/drain from a socket buffer.
>   */
>  int
> -sbwait(struct sockbuf *sb)
> +sbwait(struct socket *so, struct sockbuf *sb)
>  {
> -     NET_ASSERT_LOCKED();
> +     soassertlocked(so);
>  
>       sb->sb_flagsintr |= SB_WAIT;
> -     return (rwsleep(&sb->sb_cc, &netlock,
> +     return (sosleep(so, &sb->sb_cc,
>           (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "netio",
>           sb->sb_timeo));
>  }
> @@ -338,7 +375,7 @@ sbunlock(struct sockbuf *sb)
>  void
>  sowakeup(struct socket *so, struct sockbuf *sb)
>  {
> -     NET_ASSERT_LOCKED();
> +     soassertlocked(so);
>  
>       selwakeup(&sb->sb_sel);
>       sb->sb_flagsintr &= ~SB_SEL;
> Index: kern/uipc_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
> retrieving revision 1.149
> diff -u -p -r1.149 uipc_syscalls.c
> --- kern/uipc_syscalls.c      11 Feb 2017 19:51:06 -0000      1.149
> +++ kern/uipc_syscalls.c      13 Feb 2017 09:30:07 -0000
> @@ -285,9 +285,9 @@ doaccept(struct proc *p, int sock, struc
>       }
>  
>       nam = m_get(M_WAIT, MT_SONAME);
> -     
> -     NET_LOCK(s);
> +
>       head = headfp->f_data;
> +     s = solock(head);
>       if (isdnssocket(head) || (head->so_options & SO_ACCEPTCONN) == 0) {
>               error = EINVAL;
>               goto out;
> @@ -304,8 +304,8 @@ doaccept(struct proc *p, int sock, struc
>                       head->so_error = ECONNABORTED;
>                       break;
>               }
> -             error = rwsleep(&head->so_timeo, &netlock, PSOCK | PCATCH,
> -                 "netcon", 0);
> +             error = sosleep(head, &head->so_timeo, PSOCK | PCATCH, "netcon",
> +                 0);
>               if (error)
>                       goto out;
>       }
> @@ -342,7 +342,7 @@ doaccept(struct proc *p, int sock, struc
>               *retval = tmpfd;
>       }
>  out:
> -     NET_UNLOCK(s);
> +     sounlock(s);
>       m_freem(nam);
>       if (error) {
>               fdplock(fdp);
> @@ -406,9 +406,9 @@ sys_connect(struct proc *p, void *v, reg
>               m_freem(nam);
>               return (EINPROGRESS);
>       }
> -     NET_LOCK(s);
> +     s = solock(so);
>       while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
> -             error = rwsleep(&so->so_timeo, &netlock, PSOCK | PCATCH,
> +             error = sosleep(so, &so->so_timeo, PSOCK | PCATCH,
>                   "netcon2", 0);
>               if (error) {
>                       if (error == EINTR || error == ERESTART)
> @@ -420,7 +420,7 @@ sys_connect(struct proc *p, void *v, reg
>               error = so->so_error;
>               so->so_error = 0;
>       }
> -     NET_UNLOCK(s);
> +     sounlock(s);
>  bad:
>       if (!interrupted)
>               so->so_state &= ~SS_ISCONNECTING;
> @@ -1044,9 +1044,9 @@ sys_getsockname(struct proc *p, void *v,
>       if (error)
>               goto bad;
>       m = m_getclr(M_WAIT, MT_SONAME);
> -     NET_LOCK(s);
> +     s = solock(so);
>       error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0, p);
> -     NET_UNLOCK(s);
> +     sounlock(s);
>       if (error)
>               goto bad;
>       error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen));
> @@ -1087,9 +1087,9 @@ sys_getpeername(struct proc *p, void *v,
>       if (error)
>               goto bad;
>       m = m_getclr(M_WAIT, MT_SONAME);
> -     NET_LOCK(s);
> +     s = solock(so);
>       error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0, p);
> -     NET_UNLOCK(s);
> +     sounlock(s);
>       if (error)
>               goto bad;
>       error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen));
> Index: kern/uipc_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
> retrieving revision 1.115
> diff -u -p -r1.115 uipc_usrreq.c
> --- kern/uipc_usrreq.c        9 Feb 2017 11:18:55 -0000       1.115
> +++ kern/uipc_usrreq.c        13 Feb 2017 09:27:32 -0000
> @@ -121,6 +121,9 @@ uipc_usrreq(struct socket *so, int req, 
>               error = EINVAL;
>               goto release;
>       }
> +
> +     NET_ASSERT_UNLOCKED();
> +
>       switch (req) {
>  
>       case PRU_ATTACH:
> @@ -132,17 +135,11 @@ uipc_usrreq(struct socket *so, int req, 
>               break;
>  
>       case PRU_DETACH:
> -             /* XXXSMP breaks atomicity */
> -             rw_exit_write(&netlock);
>               unp_detach(unp);
> -             rw_enter_write(&netlock);
>               break;
>  
>       case PRU_BIND:
> -             /* XXXSMP breaks atomicity */
> -             rw_exit_write(&netlock);
>               error = unp_bind(unp, nam, p);
> -             rw_enter_write(&netlock);
>               break;
>  
>       case PRU_LISTEN:
> @@ -151,10 +148,7 @@ uipc_usrreq(struct socket *so, int req, 
>               break;
>  
>       case PRU_CONNECT:
> -             /* XXXSMP breaks atomicity */
> -             rw_exit_write(&netlock);
>               error = unp_connect(so, nam, p);
> -             rw_enter_write(&netlock);
>               break;
>  
>       case PRU_CONNECT2:
> @@ -222,10 +216,7 @@ uipc_usrreq(struct socket *so, int req, 
>                                       error = EISCONN;
>                                       break;
>                               }
> -                             /* XXXSMP breaks atomicity */
> -                             rw_exit_write(&netlock);
>                               error = unp_connect(so, nam, p);
> -                             rw_enter_write(&netlock);
>                               if (error)
>                                       break;
>                       } else {
> @@ -398,8 +389,6 @@ unp_detach(struct unpcb *unp)
>  {
>       struct vnode *vp;
>  
> -     NET_ASSERT_UNLOCKED();
> -
>       LIST_REMOVE(unp, unp_link);
>       if (unp->unp_vnode) {
>               unp->unp_vnode->v_socket = NULL;
> @@ -411,10 +400,7 @@ unp_detach(struct unpcb *unp)
>               unp_disconnect(unp);
>       while (!SLIST_EMPTY(&unp->unp_refs))
>               unp_drop(SLIST_FIRST(&unp->unp_refs), ECONNRESET);
> -     /* XXXSMP The assert is wrong */
> -     rw_enter_write(&netlock);
>       soisdisconnected(unp->unp_socket);
> -     rw_exit_write(&netlock);
>       unp->unp_socket->so_pcb = NULL;
>       m_freem(unp->unp_addr);
>       free(unp, M_PCB, sizeof *unp);
> @@ -505,9 +491,7 @@ unp_connect(struct socket *so, struct mb
>       struct socket *so2, *so3;
>       struct unpcb *unp, *unp2, *unp3;
>       struct nameidata nd;
> -     int error, s;
> -
> -     NET_ASSERT_UNLOCKED();
> +     int error;
>  
>       if (soun->sun_family != AF_UNIX)
>               return (EAFNOSUPPORT);
> @@ -539,12 +523,11 @@ unp_connect(struct socket *so, struct mb
>               error = EPROTOTYPE;
>               goto bad;
>       }
> -     NET_LOCK(s);
>       if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
>               if ((so2->so_options & SO_ACCEPTCONN) == 0 ||
>                   (so3 = sonewconn(so2, 0)) == 0) {
>                       error = ECONNREFUSED;
> -                     goto unlock;
> +                     goto bad;
>               }
>               unp = sotounpcb(so);
>               unp2 = sotounpcb(so2);
> @@ -563,8 +546,6 @@ unp_connect(struct socket *so, struct mb
>               }
>       }
>       error = unp_connect2(so, so2);
> -unlock:
> -     NET_UNLOCK(s);
>  bad:
>       vput(vp);
>       return (error);
> Index: sys/socketvar.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/socketvar.h,v
> retrieving revision 1.67
> diff -u -p -r1.67 socketvar.h
> --- sys/socketvar.h   19 Dec 2016 08:36:50 -0000      1.67
> +++ sys/socketvar.h   13 Feb 2017 09:29:09 -0000
> @@ -278,7 +278,7 @@ void      sbrelease(struct sockbuf *sb);
>  int  sbcheckreserve(u_long cnt, u_long defcnt);
>  int  sbchecklowmem(void);
>  int  sbreserve(struct sockbuf *sb, u_long cc);
> -int  sbwait(struct sockbuf *sb);
> +int  sbwait(struct socket *, struct sockbuf *sb);
>  int  sb_lock(struct sockbuf *sb);
>  void soinit(void);
>  int  soabort(struct socket *so);
> @@ -317,6 +317,11 @@ void     sowakeup(struct socket *so, struct 
>  void sorwakeup(struct socket *);
>  void sowwakeup(struct socket *);
>  int  sockargs(struct mbuf **, const void *, size_t, int);
> +
> +int  sosleep(struct socket *, void *, int, const char *, int);
> +int  solock(struct socket *);
> +void sounlock(int);
> +void soassertlocked(struct socket *);
>  
>  int  sendit(struct proc *, int, struct msghdr *, int, register_t *);
>  int  recvit(struct proc *, int, struct msghdr *, caddr_t,
> Index: sys/systm.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/systm.h,v
> retrieving revision 1.123
> diff -u -p -r1.123 systm.h
> --- sys/systm.h       25 Jan 2017 06:15:50 -0000      1.123
> +++ sys/systm.h       13 Feb 2017 09:14:22 -0000
> @@ -301,7 +301,7 @@ do {                                                      
>                 \
>       s = splsoftnet();                                               \
>  } while (0)
>  
> -#define      NET_UNLOCK(s)                                           \
> +#define      NET_UNLOCK(s)                                                   
> \
>  do {                                                                 \
>       splx(s);                                                        \
>       rw_exit_write(&netlock);                                        \

Reply via email to