Subject: kern/28411: bus_dmamap_load_mbuf may create zero length DMA segments
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <nludban@terabeam.com>
List: netbsd-bugs
Date: 11/24/2004 18:09:01
>Number:         28411
>Category:       kern
>Synopsis:       bus_dmamap_load_mbuf may create zero length DMA segments
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Nov 24 18:09:01 +0000 2004
>Originator:     Neil Ludban
>Release:        2.0 RC3
>Organization:
>Environment:
local port based on mvmeppc.
>Description:
The network stack passes packets to the drivers using mbufs, it's
possible that a chain of mbufs may have one (or more?) links with
length of zero.  The powerpc implementation of bus_dmamap_load_mbuf()
blindly converts these to zero length DMA segments, other ports
may do the same.

The network interface for which I'm writing a new driver goes
into an unexpected state when given a DMA segment length of zero.

>How-To-Repeat:
First discovered when pinging the target machine with "ping -s 2005".
The mbuf chains are probably from ip_fragment(), although there's a
small chance some local code is touching them.  YMMV.
>Fix:
An example patch to arch/powerpc/powerpc/bus_dma.c:

@@ -314,6 +314,9 @@
        seg = 0;
        error = 0;
        for (m = m0; m != NULL && error == 0; m = m->m_next, first = 0) {
+               if (m->m_len == 0)
+                       /* XXX avoid zero-length DMA segments */
+                       continue;
 #ifdef POOL_VTOPHYS
                /* XXX Could be better about coalescing. */
                /* XXX Doesn't check boundaries. */