I'd like to reduce the number of blocking memory allocations holding the NET_LOCK().
Diff below moves m_get(M_WAIT) before grabbing the socket lock for sogetopt(). ok? Index: kern/uipc_socket.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_socket.c,v retrieving revision 1.201 diff -u -p -r1.201 uipc_socket.c --- kern/uipc_socket.c 10 Aug 2017 19:20:43 -0000 1.201 +++ kern/uipc_socket.c 21 Aug 2017 13:22:27 -0000 @@ -1755,30 +1755,24 @@ bad: } int -sogetopt(struct socket *so, int level, int optname, struct mbuf **mp) +sogetopt(struct socket *so, int level, int optname, struct mbuf *m) { int error = 0; - struct mbuf *m; soassertlocked(so); if (level != SOL_SOCKET) { if (so->so_proto->pr_ctloutput) { - m = m_get(M_WAIT, MT_SOOPTS); m->m_len = 0; error = (*so->so_proto->pr_ctloutput)(PRCO_GETOPT, so, level, optname, m); - if (error) { - m_free(m); + if (error) return (error); - } - *mp = m; return (0); } else return (ENOPROTOOPT); } else { - m = m_get(M_WAIT, MT_SOOPTS); m->m_len = sizeof (int); switch (optname) { @@ -1856,13 +1850,10 @@ sogetopt(struct socket *so, int level, i level = dom->dom_protosw->pr_protocol; error = (*so->so_proto->pr_ctloutput) (PRCO_GETOPT, so, level, optname, m); - if (error) { - (void)m_free(m); + if (error) return (error); - } break; } - (void)m_free(m); return (ENOPROTOOPT); #ifdef SOCKET_SPLICE @@ -1887,17 +1878,13 @@ sogetopt(struct socket *so, int level, i &(unp->unp_connid), m->m_len); break; } - (void)m_free(m); return (ENOTCONN); } - (void)m_free(m); return (EOPNOTSUPP); default: - (void)m_free(m); return (ENOPROTOOPT); } - *mp = m; return (0); } } Index: kern/uipc_syscalls.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.158 diff -u -p -r1.158 uipc_syscalls.c --- kern/uipc_syscalls.c 10 Aug 2017 19:20:43 -0000 1.158 +++ kern/uipc_syscalls.c 21 Aug 2017 13:17:17 -0000 @@ -1014,9 +1014,10 @@ sys_getsockopt(struct proc *p, void *v, goto out; } else valsize = 0; + m = m_get(M_WAIT, MT_SOOPTS); so = fp->f_data; s = solock(so); - error = sogetopt(so, SCARG(uap, level), SCARG(uap, name), &m); + error = sogetopt(so, SCARG(uap, level), SCARG(uap, name), m); sounlock(s); if (error == 0 && SCARG(uap, val) && valsize && m != NULL) { if (valsize > m->m_len) @@ -1026,9 +1027,9 @@ sys_getsockopt(struct proc *p, void *v, error = copyout(&valsize, SCARG(uap, avalsize), sizeof (valsize)); } + m_free(m); out: FRELE(fp, p); - m_free(m); return (error); }