> 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 = ⊤
>> 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 = ⊤
>> + 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 = ⊤
>> + 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;
>> }
>>
>> /*
>>