From patchwork Wed Jul 29 15:54:06 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Larry Finger X-Patchwork-Id: 38178 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n6TFrdvZ013268 for ; Wed, 29 Jul 2009 15:53:39 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752406AbZG2Pxg (ORCPT ); Wed, 29 Jul 2009 11:53:36 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751457AbZG2Pxg (ORCPT ); Wed, 29 Jul 2009 11:53:36 -0400 Received: from hrndva-omtalb.mail.rr.com ([71.74.56.122]:59995 "EHLO hrndva-omtalb.mail.rr.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751095AbZG2Pxg (ORCPT ); Wed, 29 Jul 2009 11:53:36 -0400 Received: from larrylap.site ([65.28.94.183]) by hrndva-omta01.mail.rr.com with SMTP id <20090729155334729.IQUV8759@hrndva-omta01.mail.rr.com>; Wed, 29 Jul 2009 15:53:34 +0000 Date: Wed, 29 Jul 2009 10:54:06 -0500 From: Larry Finger To: John W Linville , Michael Buesch Cc: Johannes Berg , linux-wireless@vger.kernel.org Subject: [PATCH V2] b43: Work around mac80211 race condition that may transmit one packet after queue is stopped Message-ID: <4a70709e.vHbkySjNME+wQsfz%Larry.Finger@lwfinger.net> User-Agent: Heirloom mailx 12.2 01/07/07 MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org As shown in http://thread.gmane.org/gmane.linux.kernel.wireless.general/36497, mac80211 has a bug that allows a call to the TX routine after the queues have been stopped. This situation will only occur under extreme stress. Although b43 does not crash when this condition occurs, it does generate a WARN_ON and also logs a queue overrun message. This patch recognizes b43 is not at fault and logs a message only when the most verbose debugging mode is enabled. In the unlikely event that the queue is not stopped when the DMA queue becomes full, then a warning is issued. During testing of this patch with one output stream running repeated tcpperf writes and a second running a flood ping, this routine was entered with the DMA ring stopped about once per hour. The condition where the DMA queue is full but the ring has not been stopped has never been seen by me. Signed-off-by: Larry Finger --- John, This patch is 2.6.32 material. Larry --- V2 - put WARN_ON in if statement. dma.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: wireless-testing/drivers/net/wireless/b43/dma.c =================================================================== --- wireless-testing.orig/drivers/net/wireless/b43/dma.c +++ wireless-testing/drivers/net/wireless/b43/dma.c @@ -1334,13 +1334,22 @@ int b43_dma_tx(struct b43_wldev *dev, st spin_lock_irqsave(&ring->lock, flags); B43_WARN_ON(!ring->tx); - /* Check if the queue was stopped in mac80211, - * but we got called nevertheless. - * That would be a mac80211 bug. */ - B43_WARN_ON(ring->stopped); - if (unlikely(free_slots(ring) < TX_SLOTS_PER_FRAME)) { - b43warn(dev->wl, "DMA queue overflow\n"); + if (unlikely(ring->stopped)) { + /* We get here only because of a bug in mac80211. + * Because of a race, one packet may be queued after + * the queue is stopped, thus we got called when we shouldn't. + * For now, just refuse the transmit. */ + if (b43_debug(dev, B43_DBG_DMAVERBOSE)) + b43err(dev->wl, "Packet after queue stopped\n"); + err = -ENOSPC; + goto out_unlock; + } + + if (unlikely(WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME))) { + /* If we get here, we have a real error with the queue + * full, but queues not stopped. */ + b43err(dev->wl, "DMA queue overflow\n"); err = -ENOSPC; goto out_unlock; }