Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic don't allocate a mbuf cluster if we don't need.



details:   https://anonhg.NetBSD.org/src/rev/d1c148130a7b
branches:  trunk
changeset: 518291:d1c148130a7b
user:      yamt <yamt%NetBSD.org@localhost>
date:      Tue Nov 27 21:40:55 2001 +0000

description:
don't allocate a mbuf cluster if we don't need.

diffstat:

 sys/dev/ic/cs89x0.c |  61 +++++++++++++++++++++++++++++++++-------------------
 1 files changed, 38 insertions(+), 23 deletions(-)

diffs (123 lines):

diff -r 6be7ed5117c9 -r d1c148130a7b sys/dev/ic/cs89x0.c
--- a/sys/dev/ic/cs89x0.c       Tue Nov 27 20:00:36 2001 +0000
+++ b/sys/dev/ic/cs89x0.c       Tue Nov 27 21:40:55 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cs89x0.c,v 1.1 2001/11/26 19:17:08 yamt Exp $  */
+/*     $NetBSD: cs89x0.c,v 1.2 2001/11/27 21:40:55 yamt Exp $  */
 
 /*
  * Copyright 1997
@@ -186,7 +186,7 @@
 */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cs89x0.c,v 1.1 2001/11/26 19:17:08 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cs89x0.c,v 1.2 2001/11/27 21:40:55 yamt Exp $");
 
 #include "opt_inet.h"
 
@@ -354,8 +354,13 @@
         * greater than the MTU for an ethernet frame. The code depends on
         * this and to port this to a OS where this was not the case would
         * not be straightforward.
+        *
+        * we need 1 byte spare because our
+        * packet read loop can overrun.
+        * and we may need pad bytes to align ip header.
         */
-       if (MCLBYTES < ETHER_MAX_LEN) {
+       if (MCLBYTES < ETHER_MAX_LEN + 1 +
+               ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header)) {
                printf("%s: MCLBYTES too small for Ethernet frame\n",
                    sc->sc_dev.dv_xname);
                return 1;
@@ -1544,7 +1549,6 @@
        struct ifnet *ifp;
        struct mbuf *m;
        int totlen;
-       int len;
        u_int16_t *pBuff, *pBuffLimit;
        int pad;
        unsigned int frameOffset;
@@ -1574,6 +1578,15 @@
                totlen = CS_READ_PORT(sc, PORT_RXTX_DATA);
        }
 
+       if (totlen > ETHER_MAX_LEN) {
+               printf("%s: invalid packet length\n", sc->sc_dev.dv_xname);
+
+               /* skip the received frame */
+               CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG,
+                       CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP);
+               return;
+       }
+
        MGETHDR(m, M_DONTWAIT, MT_DATA);
        if (m == 0) {
                printf("%s: cs_process_receive: unable to allocate mbuf\n",
@@ -1593,36 +1606,38 @@
        m->m_pkthdr.rcvif = ifp;
        m->m_pkthdr.len = totlen;
 
+       /* number of bytes to align ip header on word boundary for ipintr */
+       pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
+
        /*
-        * save processing by always using a mbuf cluster, guarenteed to fit
-        * packet, on i386 NetBSD anyway.
+        * alloc mbuf cluster if we need.
+        * we need 1 byte spare because following
+        * packet read loop can overrun.
         */
-       MCLGET(m, M_DONTWAIT);
-       if (m->m_flags & M_EXT) {
-               len = MCLBYTES;
-       } else {
-               /* couldn't allocate an mbuf cluster */
-               printf("%s: cs_process_receive: unable to allocate a cluster\n",
-                   sc->sc_dev.dv_xname);
-               m_freem(m);
+       if (totlen + pad + 1 > MHLEN) {
+               MCLGET(m, M_DONTWAIT);
+               if ((m->m_flags & M_EXT) == 0) {
+                       /* couldn't allocate an mbuf cluster */
+                       printf("%s: cs_process_receive: unable to allocate a cluster\n",
+                               sc->sc_dev.dv_xname);
+                       m_freem(m);
 
-               /* skip the received frame */
-               CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG,
-                   CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP);
-               return;
+                       /* skip the received frame */
+                       CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG,
+                               CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP);
+                       return;
+               }
        }
 
        /* align ip header on word boundary for ipintr */
-       pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
        m->m_data += pad;
-       len -= pad + 1;
 
-       m->m_len = len = min(totlen, len);
+       m->m_len = totlen;
        pBuff = mtod(m, u_int16_t *);
 
        /* now read the data from the chip */
        if (sc->sc_memorymode) {
-               pBuffLimit = pBuff + (len + 1) / 2;     /* don't want to go over */
+               pBuffLimit = pBuff + (totlen + 1) / 2;  /* don't want to go over */
                while (pBuff < pBuffLimit) {
                        *pBuff++ = CS_READ_PACKET_PAGE(sc, frameOffset);
                        frameOffset += 2;
@@ -1630,7 +1645,7 @@
        }
        else {
                bus_space_read_multi_2(sc->sc_iot, sc->sc_ioh, PORT_RXTX_DATA,
-                       pBuff, (len + 1)>>1);
+                       pBuff, (totlen + 1)>>1);
        }
 
        cs_ether_input(sc, m);



Home | Main Index | Thread Index | Old Index