NetBSD Problem Report #53566
From www@NetBSD.org Sat Sep 1 23:22:02 2018
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 93BA97A19F
for <gnats-bugs@gnats.NetBSD.org>; Sat, 1 Sep 2018 23:22:02 +0000 (UTC)
Message-Id: <20180901232201.57E847A1FA@mollari.NetBSD.org>
Date: Sat, 1 Sep 2018 23:22:01 +0000 (UTC)
From: coypu@sdf.org
Reply-To: coypu@sdf.org
To: gnats-bugs@NetBSD.org
Subject: rtwn's use of m_defrag can't work
X-Send-Pr-Version: www-1.0
>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
(Contact us)
$NetBSD: query-full-pr,v 1.43 2018/01/16 07:36:43 maya Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2017
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.