NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/53566: rtwn's use of m_defrag can't work
>Number: 53566
>Category: kern
>Synopsis: rtwn's use of m_defrag can't work
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Sep 01 23:25:00 +0000 2018
>Originator: coypu
>Release: NetBSD 8.99.21
>Organization:
>Environment:
NetBSD planets 8.99.21 NetBSD 8.99.21 (GENERIC) #0: Fri Jul 13 14:49:46 IDT 2018 fly@planets:/tmp/build3/sys/arch/amd64/compile/GENERIC amd64
>Description:
Looking at rtwn, it looks like it can only do 1 tx descriptor
529 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
530 0, BUS_DMA_NOWAIT, &rx_data->map);
so it can only handle one mbuf at a time.
on some packets, the mbuf chain length will be >1.
to work around it, rtwn tries to use m_defrag:
1962 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
1963 BUS_DMA_NOWAIT | BUS_DMA_WRITE);
1964 if (error && error != EFBIG) {
1965 aprint_error_dev(sc->sc_dev, "can't map mbuf (error %d)\n",
1966 error);
1967 m_freem(m);
1968 return error;
1969 }
1970 if (error != 0) {
1971 /* Too many DMA segments, linearize mbuf. */
1972 struct mbuf *newm = m_defrag(m, M_DONTWAIT);
1973 if (newm == NULL) {
1974 aprint_error_dev(sc->sc_dev, "can't defrag mbuf\n");
1975 m_freem(m);
1976 return ENOBUFS;
1977 }
1978 m = newm;
1979
1980 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
1981 BUS_DMA_NOWAIT | BUS_DMA_WRITE);
this won't work, because m_defrag doesn't guarantee the result is in one mbuf (it in fact guarantees a minimum of two).
>How-To-Repeat:
a way of testing it is using ping -s for various sizes. some will fail.
This is by code inspection, I don't have an rtwn.
>Fix:
replace m_defrag use by an API which can make a guarantee that the result fits in as many mbufs as we want (or fails).
a similar problem was fixed in:
https://mail-index.netbsd.org/source-changes/2018/09/01/msg098767.html
Home |
Main Index |
Thread Index |
Old Index