Date: Thu, 6 Mar 2003 19:49:58 -0500 From: Hiten Pandya <hiten@unixdaemons.com> To: arch@FreeBSD.org Subject: Using m_getcl() in network and nfs code paths Message-ID: <20030307004958.GA98917@unixdaemons.com>
next in thread | raw e-mail | index | archive | help
--xHFwDpU9dbj6ez1V Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi gang. After discussing this with Bosko Mikelic and some other people, I have made some changes to net, netinet, and the NFS server and client code to utilize the m_getcl() routine. The m_getcl routine does mbuf and cluster allocation in a single shot without dropping the Cache lock, hence reducing lock operations. This could prove beneficial. Comments are welcome. If there are no objections, hopefully, Bosko will commit the patches. Cheers. -- Hiten Pandya (hiten@unixdaemons.com, hiten@uk.FreeBSD.org) http://www.unixdaemons.com/~hiten/ --xHFwDpU9dbj6ez1V Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="bmilekic-prelim.patch" Index: src/sys/kern/uipc_mbuf2.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_mbuf2.c,v retrieving revision 1.18 diff -u -r1.18 uipc_mbuf2.c --- src/sys/kern/uipc_mbuf2.c 19 Feb 2003 05:47:26 -0000 1.18 +++ src/sys/kern/uipc_mbuf2.c 7 Mar 2003 00:31:27 -0000 @@ -230,14 +230,9 @@ * now, we need to do the hard way. don't m_copy as there's no room * on both end. */ - MGET(o, M_DONTWAIT, m->m_type); - if (o && len > MLEN) { - MCLGET(o, M_DONTWAIT); - if ((o->m_flags & M_EXT) == 0) { - m_free(o); - o = NULL; - } - } + o = (len > MLEN) ? + m_getcl(M_DONTWAIT, m->m_type, m->m_flags) : + m_get(M_DONTWAIT, m->m_type); if (!o) { m_freem(m); return NULL; /* ENOBUFS */ Index: kern/uipc_socket2.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_socket2.c,v retrieving revision 1.111 diff -u -r1.111 uipc_socket2.c --- kern/uipc_socket2.c 21 Feb 2003 22:23:40 -0000 1.111 +++ kern/uipc_socket2.c 5 Mar 2003 00:55:21 -0000 @@ -833,15 +833,11 @@ if (CMSG_SPACE((u_int)size) > MCLBYTES) return ((struct mbuf *) NULL); - if ((m = m_get(M_DONTWAIT, MT_CONTROL)) == NULL) - return ((struct mbuf *) NULL); - if (CMSG_SPACE((u_int)size) > MLEN) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - m_free(m); - return ((struct mbuf *) NULL); - } - } + m = CMSG_SPACE((u_int)size > MLEN) ? + m_getcl(M_DONTWAIT, MT_CONTROL, 0) : /* Note: !M_PKTHDR */ + m_get(M_DONTWAIT, MT_CONTROL); + if (m == NULL) + return NULL; cp = mtod(m, struct cmsghdr *); m->m_len = 0; KASSERT(CMSG_SPACE((u_int)size) <= M_TRAILINGSPACE(m), Index: net/if_ieee80211subr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_ieee80211subr.c,v retrieving revision 1.7 diff -u -r1.7 if_ieee80211subr.c --- net/if_ieee80211subr.c 3 Mar 2003 06:09:18 -0000 1.7 +++ net/if_ieee80211subr.c 5 Mar 2003 01:02:34 -0000 @@ -2544,16 +2544,14 @@ if (len > n->m_len - noff) { len = n->m_len - noff; if (len == 0) { - MGET(n->m_next, M_DONTWAIT, n->m_type); + n->m_next = (left >= MINCLSIZE) ? + m_getcl(M_DONTWAIT, n->m_type, M_PKTHDR) : + m_get(M_DONTWAIT, n->m_type); if (n->m_next == NULL) goto fail; n = n->m_next; - n->m_len = MLEN; - if (left >= MINCLSIZE) { - MCLGET(n, M_DONTWAIT); - if (n->m_flags & M_EXT) - n->m_len = n->m_ext.ext_size; - } + n->m_len = (left >= MINCLSIZE) ? + n->m_len = n->m_ext.ext_size : MLEN; noff = 0; continue; } Index: net/if_ppp.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_ppp.c,v retrieving revision 1.89 diff -u -r1.89 if_ppp.c --- net/if_ppp.c 19 Feb 2003 05:47:29 -0000 1.89 +++ net/if_ppp.c 5 Mar 2003 01:02:34 -0000 @@ -1411,13 +1411,14 @@ } /* Copy the PPP and IP headers into a new mbuf. */ - MGETHDR(mp, M_DONTWAIT, MT_DATA); + mp = (hlen + PPP_HDRLEN > MHLEN) ? + m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR) : + m_gethdr(M_DONTWAIT, MT_DATA); if (mp == NULL) goto bad; mp->m_len = 0; mp->m_next = NULL; if (hlen + PPP_HDRLEN > MHLEN) { - MCLGET(mp, M_DONTWAIT); if (M_TRAILINGSPACE(mp) < hlen + PPP_HDRLEN) { m_freem(mp); goto bad; /* lose if big headers and no clusters */ Index: net/if_sl.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_sl.c,v retrieving revision 1.109 diff -u -r1.109 if_sl.c --- net/if_sl.c 19 Feb 2003 05:47:29 -0000 1.109 +++ net/if_sl.c 5 Mar 2003 01:02:34 -0000 @@ -266,14 +266,7 @@ MALLOC(sc, struct sl_softc *, sizeof(*sc), M_SL, M_WAITOK | M_ZERO); - m = m_gethdr(M_TRYWAIT, MT_DATA); - if (m != NULL) { - MCLGET(m, M_TRYWAIT); - if ((m->m_flags & M_EXT) == 0) { - m_free(m); - m = NULL; - } - } + m = m_getcl(m, M_TRYWAIT, MT_DATA); if (m == NULL) { printf("sl: can't allocate buffer\n"); @@ -791,10 +784,6 @@ { struct mbuf *m, *newm; - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) - return (NULL); - /* * If we have more than MHLEN bytes, it's cheaper to * queue the cluster we just filled & allocate a new one @@ -802,16 +791,13 @@ * allocated above. Note that code in the input routine * guarantees that packet will fit in a cluster. */ + m = (len >= MHLEN) ? + m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR) : + m_gethdr(M_DONTWAIT, MT_DATA); + if (m == NULL) + return (NULL); + if (len >= MHLEN) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - /* - * we couldn't get a cluster - if memory's this - * low, it's time to start dropping packets. - */ - (void) m_free(m); - return (NULL); - } /* Swap the new and old clusters */ newm = m; m = sc->sc_mbuf; Index: net/rtsock.c =================================================================== RCS file: /home/ncvs/src/sys/net/rtsock.c,v retrieving revision 1.88 diff -u -r1.88 rtsock.c --- net/rtsock.c 19 Feb 2003 05:47:29 -0000 1.88 +++ net/rtsock.c 5 Mar 2003 01:02:34 -0000 @@ -608,16 +608,12 @@ } if (len > MCLBYTES) panic("rt_msg1"); - m = m_gethdr(M_DONTWAIT, MT_DATA); - if (m && len > MHLEN) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - m_free(m); - m = NULL; - } - } + m = (len > MHLEN) ? + m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR) : + m_gethdr(M_DONTWAIT, MT_DATA); + if (m == 0) - return (m); + return (NULL); m->m_pkthdr.len = m->m_len = len; m->m_pkthdr.rcvif = 0; rtm = mtod(m, struct rt_msghdr *); Index: netatm/port.h =================================================================== RCS file: /home/ncvs/src/sys/netatm/port.h,v retrieving revision 1.15 diff -u -r1.15 port.h --- netatm/port.h 23 Feb 2003 22:26:39 -0000 1.15 +++ netatm/port.h 5 Mar 2003 01:02:35 -0000 @@ -151,14 +151,9 @@ } #define KB_ALLOCEXT(bfr, size, flags, type) { \ if ((size) <= MCLBYTES) { \ - MGET((bfr), (flags), (type)); \ - if ((bfr) != NULL) { \ - MCLGET((bfr), (flags)); \ - if (((bfr)->m_flags & M_EXT) == 0) { \ - m_freem((bfr)); \ - (bfr) = NULL; \ - } \ - } \ + (bfr) = m_getcl((flags), (type), 0); \ + if ((bfr) == NULL) \ + panic("Out of mbufs!"); \ } else \ (bfr) = NULL; \ } Index: netgraph/ng_pppoe.c =================================================================== RCS file: /home/ncvs/src/sys/netgraph/ng_pppoe.c,v retrieving revision 1.58 diff -u -r1.58 ng_pppoe.c --- netgraph/ng_pppoe.c 19 Feb 2003 05:47:31 -0000 1.58 +++ netgraph/ng_pppoe.c 5 Mar 2003 01:02:35 -0000 @@ -723,20 +723,13 @@ printf("pppoe: Session out of memory\n"); LEAVE(ENOMEM); } - MGETHDR(neg->m, M_DONTWAIT, MT_DATA); + neg->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); if(neg->m == NULL) { - printf("pppoe: Session out of mbufs\n"); + printf("pppoe: Session out of mbufs and cls\n"); FREE(neg, M_NETGRAPH_PPPOE); LEAVE(ENOBUFS); } neg->m->m_pkthdr.rcvif = NULL; - MCLGET(neg->m, M_DONTWAIT); - if ((neg->m->m_flags & M_EXT) == 0) { - printf("pppoe: Session out of mcls\n"); - m_freem(neg->m); - FREE(neg, M_NETGRAPH_PPPOE); - LEAVE(ENOBUFS); - } sp->neg = neg; callout_handle_init( &neg->timeout_handle); neg->m->m_len = sizeof(struct pppoe_full_hdr); Index: netgraph/ng_vjc.c =================================================================== RCS file: /home/ncvs/src/sys/netgraph/ng_vjc.c,v retrieving revision 1.23 diff -u -r1.23 ng_vjc.c --- netgraph/ng_vjc.c 19 Feb 2003 05:47:32 -0000 1.23 +++ netgraph/ng_vjc.c 5 Mar 2003 01:02:35 -0000 @@ -476,7 +476,9 @@ m_adj(m, vjlen); /* Copy the reconstructed TCP/IP headers into a new mbuf */ - MGETHDR(hm, M_DONTWAIT, MT_DATA); + hm = (hlen > MHLEN) ? + m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR) : + m_gethdr(M_DONTWAIT, MT_DATA); if (hm == NULL) { priv->slc.sls_errorin++; NG_FREE_M(m); @@ -485,16 +487,6 @@ } hm->m_len = 0; hm->m_pkthdr.rcvif = NULL; - if (hlen > MHLEN) { /* unlikely, but can happen */ - MCLGET(hm, M_DONTWAIT); - if ((hm->m_flags & M_EXT) == 0) { - m_freem(hm); - priv->slc.sls_errorin++; - NG_FREE_M(m); - NG_FREE_ITEM(item); - return (ENOBUFS); - } - } bcopy(hdr, mtod(hm, u_char *), hlen); hm->m_len = hlen; Index: netinet/tcp_output.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_output.c,v retrieving revision 1.78 diff -u -r1.78 tcp_output.c --- netinet/tcp_output.c 19 Feb 2003 22:18:05 -0000 1.78 +++ netinet/tcp_output.c 5 Mar 2003 01:02:35 -0000 @@ -604,21 +604,18 @@ m->m_len += hdrlen; m->m_data -= hdrlen; #else +#ifdef INET6 + m = (MHLEN < hdrlen + max_linkhdr) ? + m_getcl(M_DONTWAIT, MT_HEADER, M_PKTHDR) : + m_gethdr(M_DONTWAIT, MT_HEADER); +#else MGETHDR(m, M_DONTWAIT, MT_HEADER); +#endif if (m == NULL) { error = ENOBUFS; goto out; } -#ifdef INET6 - if (MHLEN < hdrlen + max_linkhdr) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - m_freem(m); - error = ENOBUFS; - goto out; - } - } -#endif + m->m_data += max_linkhdr; m->m_len = hdrlen; if (len <= MHLEN - hdrlen - max_linkhdr) { Index: netipsec/key.c =================================================================== RCS file: /home/ncvs/src/sys/netipsec/key.c,v retrieving revision 1.5 diff -u -r1.5 key.c --- netipsec/key.c 19 Feb 2003 05:47:36 -0000 1.5 +++ netipsec/key.c 5 Mar 2003 01:02:35 -0000 @@ -2079,14 +2079,10 @@ if (len > MCLBYTES) return key_senderror(so, m, ENOBUFS); - MGETHDR(n, M_DONTWAIT, MT_DATA); - if (n && len > MHLEN) { - MCLGET(n, M_DONTWAIT); - if ((n->m_flags & M_EXT) == 0) { - m_freem(n); - n = NULL; - } - } + n = (len > MHLEN) ? + m_getcl(n, M_DONTWAIT, MT_DATA) : + m_gethdr(M_DONTWAIT, MT_DATA); + if (!n) return key_senderror(so, m, ENOBUFS); Index: nfsclient/krpc_subr.c =================================================================== RCS file: /home/ncvs/src/sys/nfsclient/krpc_subr.c,v retrieving revision 1.22 diff -u -r1.22 krpc_subr.c --- nfsclient/krpc_subr.c 19 Feb 2003 05:47:38 -0000 1.22 +++ nfsclient/krpc_subr.c 4 Mar 2003 22:56:15 -0000 @@ -465,14 +465,12 @@ if (mlen > MCLBYTES) /* If too big, we just can't do it. */ return (NULL); - m = m_get(M_TRYWAIT, MT_DATA); - if (mlen > MLEN) { - MCLGET(m, M_TRYWAIT); - if ((m->m_flags & M_EXT) == 0) { - (void) m_free(m); /* There can be only one. */ - return (NULL); - } - } + m = (mlen > MLEN) ? + m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR) : + m_get(M_TRYWAIT, MT_DATA); + if (m == NULL) + return (NULL); + xs = mtod(m, struct xdr_string *); m->m_len = mlen; xs->len = txdr_unsigned(len); Index: nfsclient/nfs_socket.c =================================================================== RCS file: /home/ncvs/src/sys/nfsclient/nfs_socket.c,v retrieving revision 1.95 diff -u -r1.95 nfs_socket.c --- nfsclient/nfs_socket.c 2 Mar 2003 16:54:38 -0000 1.95 +++ nfsclient/nfs_socket.c 4 Mar 2003 22:56:15 -0000 @@ -1378,10 +1378,11 @@ ++nfs_realign_test; while ((m = *pm) != NULL) { if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) { - MGET(n, M_TRYWAIT, MT_DATA); - if (m->m_len >= MINCLSIZE) { - MCLGET(n, M_TRYWAIT); - } + n = (m->m_len >= MINCLSIZE) ? + m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR) : + m_get(M_TRYWAIT, MT_DATA); + if (n == NULL) + panic("nfs_realign: Out of mbufs"); n->m_len = 0; break; } Index: nfsclient/nfs_subs.c =================================================================== RCS file: /home/ncvs/src/sys/nfsclient/nfs_subs.c,v retrieving revision 1.117 diff -u -r1.117 nfs_subs.c --- nfsclient/nfs_subs.c 19 Feb 2003 05:47:38 -0000 1.117 +++ nfsclient/nfs_subs.c 4 Mar 2003 22:56:15 -0000 @@ -142,9 +142,11 @@ { struct mbuf *mb; - MGET(mb, M_TRYWAIT, MT_DATA); - if (hsiz >= MINCLSIZE) - MCLGET(mb, M_TRYWAIT); + mb = (hsiz >= MINCLSIZE) ? + m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR) : + m_get(M_TRYWAIT, MT_DATA); + if (mb == NULL) + return NULL; mb->m_len = 0; return (mb); } @@ -168,10 +170,12 @@ int grpsiz, authsiz; authsiz = nfsm_rndup(auth_len); - MGETHDR(mb, M_TRYWAIT, MT_DATA); - if ((authsiz + 10 * NFSX_UNSIGNED) >= MINCLSIZE) { - MCLGET(mb, M_TRYWAIT); - } else if ((authsiz + 10 * NFSX_UNSIGNED) < MHLEN) { + mb = (authsiz + 10 * NFSX_UNSIGNED >= MINCLSIZE) ? + m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR) : + m_gethdr(M_TRYWAIT, MT_DATA); + if (mb == NULL) + return NULL; + if ((authsiz + 10 * NFSX_UNSIGNED) < MHLEN) { MH_ALIGN(mb, authsiz + 10 * NFSX_UNSIGNED); } else { MH_ALIGN(mb, 8 * NFSX_UNSIGNED); @@ -271,9 +275,11 @@ while (left > 0) { mlen = M_TRAILINGSPACE(mp); if (mlen == 0) { - MGET(mp, M_TRYWAIT, MT_DATA); - if (clflg) - MCLGET(mp, M_TRYWAIT); + mp = (clflg) ? + m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR) : + m_get(M_TRYWAIT, MT_DATA); + if (mp == NULL) + return ENOBUFS; mp->m_len = 0; mp2->m_next = mp; mp2 = mp; @@ -349,9 +355,11 @@ } /* Loop around adding mbufs */ while (siz > 0) { - MGET(m1, M_TRYWAIT, MT_DATA); - if (siz > MLEN) - MCLGET(m1, M_TRYWAIT); + m1 = (siz > MLEN) ? + m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR) : + m_get(M_TRYWAIT, MT_DATA); + if (m1 == NULL) + return ENOBUFS; m1->m_len = NFSMSIZ(m1); m2->m_next = m1; m2 = m1; Index: nfsserver/nfs_serv.c =================================================================== RCS file: /home/ncvs/src/sys/nfsserver/nfs_serv.c,v retrieving revision 1.131 diff -u -r1.131 nfs_serv.c --- nfsserver/nfs_serv.c 25 Feb 2003 03:37:47 -0000 1.131 +++ nfsserver/nfs_serv.c 4 Mar 2003 22:56:15 -0000 @@ -656,8 +656,11 @@ len = 0; i = 0; while (len < NFS_MAXPATHLEN) { - MGET(nmp, M_TRYWAIT, MT_DATA); - MCLGET(nmp, M_TRYWAIT); + nmp = m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR); + if (nmp == NULL) { + error = ENOBUFS; + return (error); + } nmp->m_len = NFSMSIZ(nmp); if (len == 0) mp3 = mp = nmp; @@ -899,8 +902,9 @@ i++; } if (left > 0) { - MGET(m, M_TRYWAIT, MT_DATA); - MCLGET(m, M_TRYWAIT); + m = m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR); + if (m == NULL) + return (ENOBUFS); m->m_len = 0; m2->m_next = m; m2 = m; Index: nfsserver/nfs_srvsock.c =================================================================== RCS file: /home/ncvs/src/sys/nfsserver/nfs_srvsock.c,v retrieving revision 1.83 diff -u -r1.83 nfs_srvsock.c --- nfsserver/nfs_srvsock.c 2 Mar 2003 16:54:39 -0000 1.83 +++ nfsserver/nfs_srvsock.c 4 Mar 2003 22:56:15 -0000 @@ -148,18 +148,23 @@ nd->nd_repstat = err; if (err && (nd->nd_flag & ND_NFSV3) == 0) /* XXX recheck */ siz = 0; - MGETHDR(mreq, M_TRYWAIT, MT_DATA); - mb = mreq; /* * If this is a big reply, use a cluster else * try and leave leading space for the lower level headers. */ - mreq->m_len = 6 * NFSX_UNSIGNED; siz += RPC_REPLYSIZ; if ((max_hdr + siz) >= MINCLSIZE) { - MCLGET(mreq, M_TRYWAIT); - } else + mreq = m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR); + if (mreq == NULL) + return (NULL); + } else { + mreq = m_gethdr(M_TRYWAIT, MT_DATA); + if (mreq == NULL) + return (NULL); mreq->m_data += min(max_hdr, M_TRAILINGSPACE(mreq)); + } + mreq->m_len = 6 * NFSX_UNSIGNED; + mb = mreq; tl = mtod(mreq, u_int32_t *); bpos = ((caddr_t)tl) + mreq->m_len; *tl++ = txdr_unsigned(nd->nd_retxid); @@ -244,10 +249,11 @@ ++nfs_realign_test; while ((m = *pm) != NULL) { if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) { - MGET(n, M_TRYWAIT, MT_DATA); - if (m->m_len >= MINCLSIZE) { - MCLGET(n, M_TRYWAIT); - } + n = (m->m_len >= MINCLSIZE) ? + m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR) : + m_get(M_TRYWAIT, MT_DATA); + if (n == NULL) + panic("Out of mbufs!\n"); n->m_len = 0; break; } Index: nfsserver/nfs_srvsubs.c =================================================================== RCS file: /home/ncvs/src/sys/nfsserver/nfs_srvsubs.c,v retrieving revision 1.120 diff -u -r1.120 nfs_srvsubs.c --- nfsserver/nfs_srvsubs.c 19 Feb 2003 05:47:39 -0000 1.120 +++ nfsserver/nfs_srvsubs.c 4 Mar 2003 22:56:15 -0000 @@ -1287,8 +1287,9 @@ if (*bp >= *be) { if (*mp == mb) (*mp)->m_len += *bp - bpos; - MGET(nmp, M_TRYWAIT, MT_DATA); - MCLGET(nmp, M_TRYWAIT); + nmp = m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR); + if (nmp == NULL) + panic("nfsm_clget_xx: Out of mbufs"); nmp->m_len = NFSMSIZ(nmp); (*mp)->m_next = nmp; *mp = nmp; --xHFwDpU9dbj6ez1V-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030307004958.GA98917>