> On 17 Aug 2016, at 5:23 PM, Simon Mages <[email protected]> wrote:
> 
> Hi,
> 
> this diff works for me.
> 
> I tested TCP and Unix Domain Sockets. I did no performance tests though.
> 
> I like this version better then the one i was working with, it really
> is easier to read.

cool. id like to see it go in.

ok by me.

> 
> For completeness follows the diff i was using:

thanks for looking at this.

cheers,
dlg

> 
> Index: kern/uipc_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket.c,v
> retrieving revision 1.152
> diff -u -p -u -p -r1.152 uipc_socket.c
> --- kern/uipc_socket.c        13 Jun 2016 21:24:43 -0000      1.152
> +++ kern/uipc_socket.c        16 Aug 2016 14:01:39 -0000
> @@ -496,15 +496,18 @@ restart:
>                                       mlen = MLEN;
>                               }
>                               if (resid >= MINCLSIZE && space >= MCLBYTES) {
> -                                     MCLGET(m, M_NOWAIT);
> +                                     MCLGETI(m, M_NOWAIT, NULL, lmin(resid,
> +                                             lmin(space, MAXMCLBYTES)));
>                                       if ((m->m_flags & M_EXT) == 0)
>                                               goto nopages;
>                                       if (atomic && top == 0) {
> -                                             len = ulmin(MCLBYTES - max_hdr,
> -                                                 resid);
> +                                             len = lmin(lmin(resid, space),
> +                                                 m->m_ext.ext_size -
> +                                                 max_hdr);
>                                               m->m_data += max_hdr;
>                                       } else
> -                                             len = ulmin(MCLBYTES, resid);
> +                                             len = lmin(lmin(resid, space),
> +                                                 m->m_ext.ext_size);
>                                       space -= len;
>                               } else {
> nopages:
> 
> 
> 2016-08-13 10:59 GMT+02:00, Claudio Jeker <[email protected]>:
>> This diff refactors the uio to mbuf code to make use of bigger buffers (up
>> to 64k) and also switches the MCLGET to use M_WAIT like the MGET calls in
>> the same function. I see no point in not waiting for a cluster and instead
>> chain lots of mbufs together as a consequence.
>> 
>> This makes in my opinion the code easier to read and allows for further
>> optimizations (like using non-DMA reachable mbufs for AF_UNIX sockets).
>> 
>> This increased the preformance of loopback connections significantly when
>> I tested this at n2k16.
>> --
>> :wq Claudio
>> 
>> 
>> Index: kern//uipc_socket.c
>> ===================================================================
>> RCS file: /cvs/src/sys/kern/uipc_socket.c,v
>> retrieving revision 1.152
>> diff -u -p -r1.152 uipc_socket.c
>> --- kern//uipc_socket.c      13 Jun 2016 21:24:43 -0000      1.152
>> +++ kern//uipc_socket.c      12 Aug 2016 14:07:36 -0000
>> @@ -373,6 +373,8 @@ bad:
>>      return (error);
>> }
>> 
>> +int m_getuio(struct mbuf **, int, long, struct uio *);
>> +
>> #define      SBLOCKWAIT(f)   (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
>> /*
>>  * Send on a socket.
>> @@ -395,10 +397,7 @@ int
>> sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf
>> *top,
>>     struct mbuf *control, int flags)
>> {
>> -    struct mbuf **mp;
>> -    struct mbuf *m;
>>      long space, clen = 0;
>> -    u_long len, mlen;
>>      size_t resid;
>>      int error, s;
>>      int atomic = sosendallatonce(so) || top;
>> @@ -475,7 +474,6 @@ restart:
>>                      goto restart;
>>              }
>>              splx(s);
>> -            mp = &top;
>>              space -= clen;
>>              do {
>>                      if (uio == NULL) {
>> @@ -485,52 +483,14 @@ restart:
>>                              resid = 0;
>>                              if (flags & MSG_EOR)
>>                                      top->m_flags |= M_EOR;
>> -                    } else do {
>> -                            if (top == 0) {
>> -                                    MGETHDR(m, M_WAIT, MT_DATA);
>> -                                    mlen = MHLEN;
>> -                                    m->m_pkthdr.len = 0;
>> -                                    m->m_pkthdr.ph_ifidx = 0;
>> -                            } else {
>> -                                    MGET(m, M_WAIT, MT_DATA);
>> -                                    mlen = MLEN;
>> -                            }
>> -                            if (resid >= MINCLSIZE && space >= MCLBYTES) {
>> -                                    MCLGET(m, M_NOWAIT);
>> -                                    if ((m->m_flags & M_EXT) == 0)
>> -                                            goto nopages;
>> -                                    if (atomic && top == 0) {
>> -                                            len = ulmin(MCLBYTES - max_hdr,
>> -                                                resid);
>> -                                            m->m_data += max_hdr;
>> -                                    } else
>> -                                            len = ulmin(MCLBYTES, resid);
>> -                                    space -= len;
>> -                            } else {
>> -nopages:
>> -                                    len = ulmin(ulmin(mlen, resid), space);
>> -                                    space -= len;
>> -                                    /*
>> -                                     * For datagram protocols, leave room
>> -                                     * for protocol headers in first mbuf.
>> -                                     */
>> -                                    if (atomic && top == 0 && len < mlen)
>> -                                            MH_ALIGN(m, len);
>> -                            }
>> -                            error = uiomove(mtod(m, caddr_t), len, uio);
>> +                    } else {
>> +                            error = m_getuio(&top, atomic,
>> +                                space, uio);
>> +                            space -= top->m_pkthdr.len;
>>                              resid = uio->uio_resid;
>> -                            m->m_len = len;
>> -                            *mp = m;
>> -                            top->m_pkthdr.len += len;
>> -                            if (error)
>> -                                    goto release;
>> -                            mp = &m->m_next;
>> -                            if (resid == 0) {
>> -                                    if (flags & MSG_EOR)
>> -                                            top->m_flags |= M_EOR;
>> -                                    break;
>> -                            }
>> -                    } while (space > 0 && atomic);
>> +                            if (flags & MSG_EOR)
>> +                                    top->m_flags |= M_EOR;
>> +                    }
>>                      s = splsoftnet();               /* XXX */
>>                      if (resid == 0)
>>                              so->so_state &= ~SS_ISSENDING;
>> @@ -539,9 +499,8 @@ nopages:
>>                          top, addr, control, curproc);
>>                      splx(s);
>>                      clen = 0;
>> -                    control = 0;
>> -                    top = 0;
>> -                    mp = &top;
>> +                    control = NULL;
>> +                    top = NULL;
>>                      if (error)
>>                              goto release;
>>              } while (resid && space > 0);
>> @@ -556,6 +515,76 @@ out:
>>      if (control)
>>              m_freem(control);
>>      return (error);
>> +}
>> +
>> +int
>> +m_getuio(struct mbuf **mp, int atomic, long space, struct uio *uio)
>> +{
>> +    struct mbuf *m, *top = NULL;
>> +    struct mbuf **nextp = &top;
>> +    u_long len, mlen;
>> +    size_t resid = uio->uio_resid;
>> +    int error;
>> +
>> +    do {
>> +            if (top == NULL) {
>> +                    MGETHDR(m, M_WAIT, MT_DATA);
>> +                    mlen = MHLEN;
>> +                    m->m_pkthdr.len = 0;
>> +                    m->m_pkthdr.ph_ifidx = 0;
>> +            } else {
>> +                    MGET(m, M_WAIT, MT_DATA);
>> +                    mlen = MLEN;
>> +            }
>> +            /* chain mbuf together */
>> +            *nextp = m;
>> +            nextp = &m->m_next;
>> +
>> +            resid = ulmin(resid, space);
>> +            if (resid >= MINCLSIZE) {
>> +                    mlen = ulmin(resid, MAXMCLBYTES);
>> +                    MCLGETI(m, M_WAIT, NULL, mlen);
>> +
>> +                    if ((m->m_flags & M_EXT) == 0) {
>> +                            /* should not happen */
>> +                            m_freem(top);
>> +                            return (ENOBUFS);
>> +                    }
>> +                    mlen = m->m_ext.ext_size;
>> +                    len = ulmin(mlen, resid);
>> +                    /*
>> +                     * For datagram protocols, leave room
>> +                     * for protocol headers in first mbuf.
>> +                     */
>> +                    if (atomic && top == NULL && len < mlen - max_hdr)
>> +                            m->m_data += max_hdr;
>> +            } else {
>> +                    len = ulmin(mlen, resid);
>> +                    /*
>> +                     * For datagram protocols, leave room
>> +                     * for protocol headers in first mbuf.
>> +                     */
>> +                    if (atomic && top == NULL && len < mlen - max_hdr)
>> +                            MH_ALIGN(m, len);
>> +            }
>> +
>> +            error = uiomove(mtod(m, caddr_t), len, uio);
>> +            if (error) {
>> +                    m_freem(top);
>> +                    return (error);
>> +            }
>> +
>> +            /* adjust counters */
>> +            resid = uio->uio_resid;
>> +            space -= len;
>> +            m->m_len = len;
>> +            top->m_pkthdr.len += len;
>> +
>> +            /* Is there more space and more data? */
>> +    } while (space > 0 && resid > 0);
>> +
>> +    *mp = top;
>> +    return 0;
>> }
>> 
>> /*
>> 

Reply via email to