On Wed, Nov 16, 2016 at 11:38:06AM +0100, Martin Pieuchot wrote:
> I'd like to enforce that pr_usrreq functions are always called at
> IPL_SOFTNET. This will allow us to keep locking simple as soon as
> we trade splsoftnet() for a rwlock.
>
> Most of the PRU_* actions are already called under splsoftnet() and
> the ones that are not are relatively small, so it should not really
> matter since processes are already serialized by the KERNEL_LOCK().
>
> I'd even argue that this is a step forward removing the KERNEL_LOCK
> from the socket layer.
>
> Comments, oks?
Agreed and OK
> Index: kern/sys_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/sys_socket.c,v
> retrieving revision 1.22
> diff -u -p -r1.22 sys_socket.c
> --- kern/sys_socket.c 6 Oct 2016 17:02:10 -0000 1.22
> +++ kern/sys_socket.c 16 Nov 2016 09:58:54 -0000
> @@ -73,6 +73,7 @@ int
> soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p)
> {
> struct socket *so = (struct socket *)fp->f_data;
> + int s, error = 0;
>
> switch (cmd) {
>
> @@ -122,8 +123,12 @@ soo_ioctl(struct file *fp, u_long cmd, c
> return (ifioctl(so, cmd, data, p));
> if (IOCGROUP(cmd) == 'r')
> return (rtioctl(cmd, data, p));
> - return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
> + s = splsoftnet();
> + error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
> (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)NULL, p));
> + splx(s);
> +
> + return (error);
> }
>
> int
> @@ -167,6 +172,7 @@ int
> soo_stat(struct file *fp, struct stat *ub, struct proc *p)
> {
> struct socket *so = fp->f_data;
> + int s;
>
> memset(ub, 0, sizeof (*ub));
> ub->st_mode = S_IFSOCK;
> @@ -177,8 +183,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;
> + s = splsoftnet();
> (void) ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
> (struct mbuf *)ub, NULL, NULL, p));
> + splx(s);
> return (0);
> }
>
> Index: kern/uipc_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket.c,v
> retrieving revision 1.164
> diff -u -p -r1.164 uipc_socket.c
> --- kern/uipc_socket.c 14 Nov 2016 08:45:30 -0000 1.164
> +++ kern/uipc_socket.c 16 Nov 2016 10:14:05 -0000
> @@ -652,8 +652,10 @@ soreceive(struct socket *so, struct mbuf
> flags |= MSG_DONTWAIT;
> if (flags & MSG_OOB) {
> m = m_get(M_WAIT, MT_DATA);
> + s = splsoftnet();
> error = (*pr->pr_usrreq)(so, PRU_RCVOOB, m,
> (struct mbuf *)(long)(flags & MSG_PEEK), NULL, curproc);
> + splx(s);
> if (error)
> goto bad;
> do {
> Index: kern/uipc_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
> retrieving revision 1.139
> diff -u -p -r1.139 uipc_syscalls.c
> --- kern/uipc_syscalls.c 9 Nov 2016 09:39:43 -0000 1.139
> +++ kern/uipc_syscalls.c 16 Nov 2016 10:17:08 -0000
> @@ -1066,7 +1066,7 @@ sys_getsockname(struct proc *p, void *v,
> struct socket *so;
> struct mbuf *m = NULL;
> socklen_t len;
> - int error;
> + int error, s;
>
> if ((error = getsock(p, SCARG(uap, fdes), &fp)) != 0)
> return (error);
> @@ -1078,14 +1078,15 @@ sys_getsockname(struct proc *p, void *v,
> if (error)
> goto bad;
> m = m_getclr(M_WAIT, MT_SONAME);
> + s = splsoftnet();
> error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0, p);
> + splx(s);
> if (error)
> goto bad;
> error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen));
> bad:
> FRELE(fp, p);
> - if (m)
> - m_freem(m);
> + m_freem(m);
> return (error);
> }
>
> @@ -1104,7 +1105,7 @@ sys_getpeername(struct proc *p, void *v,
> struct socket *so;
> struct mbuf *m = NULL;
> socklen_t len;
> - int error;
> + int error, s;
>
> if ((error = getsock(p, SCARG(uap, fdes), &fp)) != 0)
> return (error);
> @@ -1120,7 +1121,9 @@ sys_getpeername(struct proc *p, void *v,
> if (error)
> goto bad;
> m = m_getclr(M_WAIT, MT_SONAME);
> + s = splsoftnet();
> error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0, p);
> + splx(s);
> if (error)
> goto bad;
> error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen));
> Index: net/if.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if.c,v
> retrieving revision 1.461
> diff -u -p -r1.461 if.c
> --- net/if.c 14 Nov 2016 10:52:04 -0000 1.461
> +++ net/if.c 16 Nov 2016 09:58:54 -0000
> @@ -2046,9 +2046,11 @@ ifioctl(struct socket *so, u_long cmd, c
> default:
> if (so->so_proto == 0)
> return (EOPNOTSUPP);
> + s = splsoftnet();
> error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
> (struct mbuf *) cmd, (struct mbuf *) data,
> (struct mbuf *) ifp, p));
> + splx(s);
> break;
> }
>
> Index: net/raw_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/net/raw_usrreq.c,v
> retrieving revision 1.25
> diff -u -p -r1.25 raw_usrreq.c
> --- net/raw_usrreq.c 8 Oct 2016 03:32:25 -0000 1.25
> +++ net/raw_usrreq.c 16 Nov 2016 09:58:54 -0000
> @@ -137,7 +137,9 @@ raw_usrreq(struct socket *so, int req, s
> {
> struct rawcb *rp = sotorawcb(so);
> int error = 0;
> - int len, s;
> + int len;
> +
> + splsoftassert(IPL_SOFTNET);
>
> if (req == PRU_CONTROL)
> return (EOPNOTSUPP);
> @@ -149,7 +151,6 @@ raw_usrreq(struct socket *so, int req, s
> m_freem(m);
> return (EINVAL);
> }
> - s = splsoftnet();
> switch (req) {
>
> /*
> @@ -230,7 +231,6 @@ raw_usrreq(struct socket *so, int req, s
> /*
> * stat: don't bother with a blocksize.
> */
> - splx(s);
> return (0);
>
> /*
> @@ -238,7 +238,6 @@ raw_usrreq(struct socket *so, int req, s
> */
> case PRU_RCVOOB:
> case PRU_RCVD:
> - splx(s);
> return (EOPNOTSUPP);
>
> case PRU_LISTEN:
> @@ -270,7 +269,6 @@ raw_usrreq(struct socket *so, int req, s
> default:
> panic("raw_usrreq");
> }
> - splx(s);
> m_freem(m);
> return (error);
> }
> Index: net/rtsock.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.208
> diff -u -p -r1.208 rtsock.c
> --- net/rtsock.c 18 Oct 2016 11:05:45 -0000 1.208
> +++ net/rtsock.c 16 Nov 2016 09:58:54 -0000
> @@ -149,10 +149,11 @@ route_usrreq(struct socket *so, int req,
> {
> struct rawcb *rp;
> struct routecb *rop;
> - int s, af;
> + int af;
> int error = 0;
>
> - s = splsoftnet();
> + splsoftassert(IPL_SOFTNET);
> +
> rp = sotorawcb(so);
>
> switch (req) {
> @@ -178,7 +179,6 @@ route_usrreq(struct socket *so, int req,
> error = raw_attach(so, (int)(long)nam);
> if (error) {
> free(rop, M_PCB, sizeof(struct routecb));
> - splx(s);
> return (error);
> }
> rop->rtableid = curproc->p_p->ps_rtableid;
> @@ -229,7 +229,6 @@ route_usrreq(struct socket *so, int req,
> error = raw_usrreq(so, req, m, nam, control, p);
> }
>
> - splx(s);
> return (error);
> }
>
> Index: netinet/ip_divert.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_divert.c,v
> retrieving revision 1.39
> diff -u -p -r1.39 ip_divert.c
> --- netinet/ip_divert.c 7 Mar 2016 18:44:00 -0000 1.39
> +++ netinet/ip_divert.c 16 Nov 2016 09:58:54 -0000
> @@ -63,7 +63,6 @@ int divbhashsize = DIVERTHASHSIZE;
>
> static struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
>
> -void divert_detach(struct inpcb *);
> int divert_output(struct inpcb *, struct mbuf *, struct mbuf *,
> struct mbuf *);
> void
> @@ -248,7 +247,8 @@ divert_usrreq(struct socket *so, int req
> {
> struct inpcb *inp = sotoinpcb(so);
> int error = 0;
> - int s;
> +
> + splsoftassert(IPL_SOFTNET);
>
> if (req == PRU_CONTROL) {
> return (in_control(so, (u_long)m, (caddr_t)addr,
> @@ -269,9 +269,7 @@ divert_usrreq(struct socket *so, int req
> error = EACCES;
> break;
> }
> - s = splsoftnet();
> error = in_pcballoc(so, &divbtable);
> - splx(s);
> if (error)
> break;
>
> @@ -282,13 +280,11 @@ divert_usrreq(struct socket *so, int req
> break;
>
> case PRU_DETACH:
> - divert_detach(inp);
> + in_pcbdetach(inp);
> break;
>
> case PRU_BIND:
> - s = splsoftnet();
> error = in_pcbbind(inp, addr, p);
> - splx(s);
> break;
>
> case PRU_SHUTDOWN:
> @@ -300,7 +296,7 @@ divert_usrreq(struct socket *so, int req
>
> case PRU_ABORT:
> soisdisconnected(so);
> - divert_detach(inp);
> + in_pcbdetach(inp);
> break;
>
> case PRU_SOCKADDR:
> @@ -339,15 +335,6 @@ release:
> m_freem(control);
> m_freem(m);
> return (error);
> -}
> -
> -void
> -divert_detach(struct inpcb *inp)
> -{
> - int s = splsoftnet();
> -
> - in_pcbdetach(inp);
> - splx(s);
> }
>
> /*
> Index: netinet/raw_ip.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/raw_ip.c,v
> retrieving revision 1.87
> diff -u -p -r1.87 raw_ip.c
> --- netinet/raw_ip.c 14 Nov 2016 03:51:53 -0000 1.87
> +++ netinet/raw_ip.c 16 Nov 2016 09:58:54 -0000
> @@ -409,7 +409,8 @@ rip_usrreq(struct socket *so, int req, s
> {
> struct inpcb *inp = sotoinpcb(so);
> int error = 0;
> - int s;
> +
> + splsoftassert(IPL_SOFTNET);
>
> if (req == PRU_CONTROL)
> return (in_control(so, (u_long)m, (caddr_t)nam,
> @@ -433,13 +434,10 @@ rip_usrreq(struct socket *so, int req, s
> error = EPROTONOSUPPORT;
> break;
> }
> - s = splsoftnet();
> if ((error = soreserve(so, rip_sendspace, rip_recvspace)) ||
> (error = in_pcballoc(so, &rawcbtable))) {
> - splx(s);
> break;
> }
> - splx(s);
> inp = sotoinpcb(so);
> inp->inp_ip.ip_p = (long)nam;
> break;
> Index: netinet/tcp_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v
> retrieving revision 1.135
> diff -u -p -r1.135 tcp_usrreq.c
> --- netinet/tcp_usrreq.c 24 Sep 2016 14:51:37 -0000 1.135
> +++ netinet/tcp_usrreq.c 16 Nov 2016 09:58:54 -0000
> @@ -130,10 +130,11 @@ tcp_usrreq(struct socket *so, int req, s
> struct sockaddr_in *sin;
> struct inpcb *inp;
> struct tcpcb *tp = NULL;
> - int s;
> int error = 0;
> short ostate;
>
> + splsoftassert(IPL_SOFTNET);
> +
> if (req == PRU_CONTROL) {
> #ifdef INET6
> if (sotopf(so) == PF_INET6)
> @@ -150,7 +151,6 @@ tcp_usrreq(struct socket *so, int req, s
> return (EINVAL);
> }
>
> - s = splsoftnet();
> inp = sotoinpcb(so);
> /*
> * When a TCP is attached to a socket, then there will be
> @@ -161,7 +161,6 @@ tcp_usrreq(struct socket *so, int req, s
> error = so->so_error;
> if (error == 0)
> error = EINVAL;
> - splx(s);
> /*
> * The following corrects an mbuf leak under rare
> * circumstances
> @@ -174,7 +173,6 @@ tcp_usrreq(struct socket *so, int req, s
> tp = intotcpcb(inp);
> /* tp might get 0 when using socket splicing */
> if (tp == NULL) {
> - splx(s);
> return (0);
> }
> #ifdef KPROF
> @@ -382,7 +380,6 @@ tcp_usrreq(struct socket *so, int req, s
>
> case PRU_SENSE:
> ((struct stat *) m)->st_blksize = so->so_snd.sb_hiwat;
> - splx(s);
> return (0);
>
> case PRU_RCVOOB:
> @@ -447,7 +444,6 @@ tcp_usrreq(struct socket *so, int req, s
> }
> if (tp && (so->so_options & SO_DEBUG))
> tcp_trace(TA_USER, ostate, tp, (caddr_t)0, req, 0);
> - splx(s);
> return (error);
> }
>
> Index: netinet/udp_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
> retrieving revision 1.220
> diff -u -p -r1.220 udp_usrreq.c
> --- netinet/udp_usrreq.c 3 Nov 2016 18:42:35 -0000 1.220
> +++ netinet/udp_usrreq.c 16 Nov 2016 09:58:54 -0000
> @@ -1105,7 +1105,8 @@ udp_usrreq(struct socket *so, int req, s
> {
> struct inpcb *inp;
> int error = 0;
> - int s;
> +
> + splsoftassert(IPL_SOFTNET);
>
> if (req == PRU_CONTROL) {
> #ifdef INET6
> @@ -1118,7 +1119,6 @@ udp_usrreq(struct socket *so, int req, s
> (struct ifnet *)control));
> }
>
> - s = splsoftnet();
> inp = sotoinpcb(so);
> if (inp == NULL && req != PRU_ATTACH) {
> error = EINVAL;
> @@ -1255,7 +1255,6 @@ udp_usrreq(struct socket *so, int req, s
> else
> #endif
> error = udp_output(inp, m, addr, control);
> - splx(s);
> return (error);
>
> case PRU_ABORT:
> @@ -1289,7 +1288,6 @@ udp_usrreq(struct socket *so, int req, s
> * Perhaps Path MTU might be returned for a connected
> * UDP socket in this case.
> */
> - splx(s);
> return (0);
>
> case PRU_SENDOOB:
> @@ -1302,7 +1300,6 @@ udp_usrreq(struct socket *so, int req, s
>
> case PRU_RCVD:
> case PRU_RCVOOB:
> - splx(s);
> return (EOPNOTSUPP); /* do not free mbuf's */
>
> default:
> @@ -1310,7 +1307,6 @@ udp_usrreq(struct socket *so, int req, s
> }
>
> release:
> - splx(s);
> m_freem(control);
> m_freem(m);
> return (error);
> Index: netinet6/ip6_divert.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/ip6_divert.c,v
> retrieving revision 1.41
> diff -u -p -r1.41 ip6_divert.c
> --- netinet6/ip6_divert.c 29 Mar 2016 11:57:51 -0000 1.41
> +++ netinet6/ip6_divert.c 16 Nov 2016 09:58:54 -0000
> @@ -64,7 +64,6 @@ int divb6hashsize = DIVERTHASHSIZE;
>
> static struct sockaddr_in6 ip6addr = { sizeof(ip6addr), AF_INET6 };
>
> -void divert6_detach(struct inpcb *);
> int divert6_output(struct inpcb *, struct mbuf *, struct mbuf *,
> struct mbuf *);
>
> @@ -251,7 +250,8 @@ divert6_usrreq(struct socket *so, int re
> {
> struct inpcb *inp = sotoinpcb(so);
> int error = 0;
> - int s;
> +
> + splsoftassert(IPL_SOFTNET);
>
> if (req == PRU_CONTROL) {
> return (in6_control(so, (u_long)m, (caddr_t)addr,
> @@ -272,9 +272,7 @@ divert6_usrreq(struct socket *so, int re
> error = EACCES;
> break;
> }
> - s = splsoftnet();
> error = in_pcballoc(so, &divb6table);
> - splx(s);
> if (error)
> break;
>
> @@ -285,13 +283,11 @@ divert6_usrreq(struct socket *so, int re
> break;
>
> case PRU_DETACH:
> - divert6_detach(inp);
> + in_pcbdetach(inp);
> break;
>
> case PRU_BIND:
> - s = splsoftnet();
> error = in_pcbbind(inp, addr, p);
> - splx(s);
> break;
>
> case PRU_SHUTDOWN:
> @@ -303,7 +299,7 @@ divert6_usrreq(struct socket *so, int re
>
> case PRU_ABORT:
> soisdisconnected(so);
> - divert6_detach(inp);
> + in_pcbdetach(inp);
> break;
>
> case PRU_SOCKADDR:
> @@ -342,15 +338,6 @@ release:
> m_freem(control);
> m_freem(m);
> return (error);
> -}
> -
> -void
> -divert6_detach(struct inpcb *inp)
> -{
> - int s = splsoftnet();
> -
> - in_pcbdetach(inp);
> - splx(s);
> }
>
> /*
> Index: netinet6/raw_ip6.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/raw_ip6.c,v
> retrieving revision 1.98
> diff -u -p -r1.98 raw_ip6.c
> --- netinet6/raw_ip6.c 25 Oct 2016 19:40:57 -0000 1.98
> +++ netinet6/raw_ip6.c 16 Nov 2016 09:58:54 -0000
> @@ -568,9 +568,10 @@ rip6_usrreq(struct socket *so, int req,
> {
> struct inpcb *in6p = sotoinpcb(so);
> int error = 0;
> - int s;
> int priv;
>
> + splsoftassert(IPL_SOFTNET);
> +
> priv = 0;
> if ((so->so_state & SS_PRIV) != 0)
> priv++;
> @@ -591,13 +592,10 @@ rip6_usrreq(struct socket *so, int req,
> error = EPROTONOSUPPORT;
> break;
> }
> - s = splsoftnet();
> if ((error = soreserve(so, rip6_sendspace, rip6_recvspace)) ||
> (error = in_pcballoc(so, &rawin6pcbtable))) {
> - splx(s);
> break;
> }
> - splx(s);
> in6p = sotoinpcb(so);
> in6p->inp_ipv6.ip6_nxt = (long)nam;
> in6p->inp_cksum6 = -1;
>
--
:wq Claudio