> Date: Mon, 21 Aug 2017 15:35:30 +0200
> From: Martin Pieuchot <m...@openbsd.org>
> 
> On 21/08/17(Mon) 15:33, Martin Pieuchot wrote:
> > 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().
> 
> Diff below includes the prototype change.
> 
> ok?

Totally makes sense; ok kettenis@

> 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);
>  }
>  
> Index: sys/socketvar.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/socketvar.h,v
> retrieving revision 1.74
> diff -u -p -r1.74 socketvar.h
> --- sys/socketvar.h   12 Jul 2017 10:56:47 -0000      1.74
> +++ sys/socketvar.h   21 Aug 2017 13:15:54 -0000
> @@ -312,8 +312,7 @@ int       soconnect2(struct socket *so1, struc
>  int  socreate(int dom, struct socket **aso, int type, int proto);
>  int  sodisconnect(struct socket *so);
>  void sofree(struct socket *so);
> -int  sogetopt(struct socket *so, int level, int optname,
> -         struct mbuf **mp);
> +int  sogetopt(struct socket *so, int level, int optname, struct mbuf *m);
>  void sohasoutofband(struct socket *so);
>  void soisconnected(struct socket *so);
>  void soisconnecting(struct socket *so);
> 
> 

Reply via email to