Also tested this patch on my old i386.

xl0 at pci2 dev 1 function 0 "3Com 3c905B 100Base-TX" rev 0x30: apic 2 int 17 
(irq 12), address 00:50:04:44:dc:5c
exphy0 at xl0 phy 24: 3Com internal media interface

Same tests (ftp, nfs, ssh, ipv4 and ipv6), no regressions.

Paul 'WEiRD' de Weerd

On Thu, Dec 24, 2009 at 03:08:54AM -0500, Brad wrote:
| The following diff replaces the hand rolled code to deal with
| really long mbuf chains with the use of m_defrag().
| 
| 
| Index: xl.c
| ===================================================================
| RCS file: /cvs/src/sys/dev/ic/xl.c,v
| retrieving revision 1.88
| diff -u -p -r1.88 xl.c
| --- xl.c      22 Dec 2009 21:10:25 -0000      1.88
| +++ xl.c      24 Dec 2009 07:57:00 -0000
| @@ -1614,23 +1614,25 @@ xl_encap(struct xl_softc *sc, struct xl_
|  
|       map = sc->sc_tx_sparemap;
|  
| -reload:
|       error = bus_dmamap_load_mbuf(sc->sc_dmat, map,
|           m_head, BUS_DMA_NOWAIT);
| -
| -     if (error && error != EFBIG) {
| -             m_freem(m_head);
| -             return (1);
| +     if (error != 0 && error != EFBIG)
| +             goto drop;
| +     if (error != 0) {
| +             if (m_defrag(m_head, M_DONTWAIT))
| +                     goto drop;
| +             error = bus_dmamap_load_mbuf(sc->sc_dmat, map,
| +                 m_head, BUS_DMA_NOWAIT);
| +             if (error != 0)
| +                     goto drop;
|       }
|  
|       /*
|        * Start packing the mbufs in this chain into
| -      * the fragment pointers. Stop when we run out
| -      * of fragments or hit the end of the mbuf chain.
| +      * the fragment pointers. Stop when we hit the
| +      * end of the mbuf chain.
|        */
|       for (frag = 0, total_len = 0; frag < map->dm_nsegs; frag++) {
| -             if (frag == XL_MAXFRAGS)
| -                     break;
|               total_len += map->dm_segs[frag].ds_len;
|               c->xl_ptr->xl_frag[frag].xl_addr =
|                   htole32(map->dm_segs[frag].ds_addr);
| @@ -1638,38 +1640,6 @@ reload:
|                   htole32(map->dm_segs[frag].ds_len);
|       }
|  
| -     /*
| -      * Handle special case: we used up all 63 fragments,
| -      * but we have more mbufs left in the chain. Copy the
| -      * data into an mbuf cluster. Note that we don't
| -      * bother clearing the values in the other fragment
| -      * pointers/counters; it wouldn't gain us anything,
| -      * and would waste cycles.
| -      */
| -     if (error) {
| -             struct mbuf     *m_new = NULL;
| -
| -             MGETHDR(m_new, M_DONTWAIT, MT_DATA);
| -             if (m_new == NULL) {
| -                     m_freem(m_head);
| -                     return (1);
| -             }
| -             if (m_head->m_pkthdr.len > MHLEN) {
| -                     MCLGET(m_new, M_DONTWAIT);
| -                     if (!(m_new->m_flags & M_EXT)) {
| -                             m_freem(m_new);
| -                             m_freem(m_head);
| -                             return (1);
| -                     }
| -             }
| -             m_copydata(m_head, 0, m_head->m_pkthdr.len,     
| -                 mtod(m_new, caddr_t));
| -             m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len;
| -             m_freem(m_head);
| -             m_head = m_new;
| -             goto reload;
| -     }
| -
|       bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
|           BUS_DMASYNC_PREWRITE);
|  
| @@ -1708,6 +1678,10 @@ reload:
|           BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|  
|       return (0);
| +
| + drop:
| +     m_freem(m_head);
| +     return (1);
|  }
|  
|  /*
| 
| -- 
| This message has been scanned for viruses and
| dangerous content by MailScanner, and is
| believed to be clean.
| 

-- 
>++++++++[<++++++++++>-]<+++++++.>+++[<------>-]<.>+++[<+
+++++++++++>-]<.>++[<------------>-]<+.--------------.[-]
                 http://www.weirdnet.nl/                 

Reply via email to