From owner-freebsd-net@FreeBSD.ORG Sat Oct 27 23:18:18 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 10F08146; Sat, 27 Oct 2012 23:18:18 +0000 (UTC) (envelope-from adrian.chadd@gmail.com) Received: from mail-pb0-f54.google.com (mail-pb0-f54.google.com [209.85.160.54]) by mx1.freebsd.org (Postfix) with ESMTP id C8C1A8FC08; Sat, 27 Oct 2012 23:18:17 +0000 (UTC) Received: by mail-pb0-f54.google.com with SMTP id rp8so3694252pbb.13 for ; Sat, 27 Oct 2012 16:18:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:cc:content-type; bh=b96HYW36O5OHgYA4N07oUosCjfyz74N2NZAf+fsnM4Q=; b=VQeC5nviTcpZ0XEzRvnzrUJHDa7yPt7Q3hFZgvnraMKIn1AXMHAapjEa8pgDxvzHAU NS1X3QuCPafeN0utWT1HQ0kABf6Qy2NEaYQ6hdmuMlnTKTp4CN8jH7HTmzNtOAPwoAdF ET9E1dKgvCbXfOu1YZ1k1+TvTyIQrCDklCb4Janu2D8grYyQamQJyPKyAs07yI9v/Jr3 llxFQ8WjtrR+ZH4S8HhH0OfQOZjMFTpOvxipDDdmTS4mwH8MDMxG3Da580DsPUYaHqWm 8hyX/9oAxqDI57xRz3VHG08WIFtWR/ejFckV8yRdef7AqeiEp/82wkMwVjlOnIarn0JJ Gt/w== MIME-Version: 1.0 Received: by 10.68.235.68 with SMTP id uk4mr81178726pbc.52.1351379891789; Sat, 27 Oct 2012 16:18:11 -0700 (PDT) Sender: adrian.chadd@gmail.com Received: by 10.68.146.233 with HTTP; Sat, 27 Oct 2012 16:18:11 -0700 (PDT) Date: Sat, 27 Oct 2012 16:18:11 -0700 X-Google-Sender-Auth: KruR67QSYLbPCbg8rXh8L-ec5cI Message-ID: Subject: request for help: 'fixing' the 802.11 TX path From: Adrian Chadd To: freebsd-wireless@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Cc: FreeBSD Net , freebsd-arch@freebsd.org X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 27 Oct 2012 23:18:18 -0000 Hi all, I'd like to try and sort out the last remaining niggles in the 802.11 code - this email is focusing on the TX path. The TX path has a few problems: * there's a normal versus raw TX path (for raw frames, management frames, etc) - the raw path doesn't necessarily queue frames into the raw TX queue, so it's a kind of "side path" to the driver. This causes frame ordering problems with things like sequence number allocation. * there's limited locking in the TX path, primarily because you can't _really_ fine grain lock the TX path. Since you have multiple TX thread contexts all sending into the same driver queue and that queue has to share incrementing sequence number, aggregate status and CCMP encryption replay counters, you _have_ to either use some long-held mutexes to enforce this _or_ throw all sending into a TX thread and run that. * raw TX requires some extra state to be glued (the bpf_params info); I'd like to glue that into mbufs as an option, so the driver can use those instead of interpreting their own 802.11 header contents. And the one I'd like to discuss here: * Fragment transmission is totally broken and causes mbufs to be just leaked. The problem with sending fragments (at least for the ath drivr) is the packet duration calcluation requires the _next_ fragment to be available. Now, this is a design hold-over from the previous, pre-vap scheme. The driver netif would be handed a raw mbuf frame, which it would then pass through the net80211 encapsulation code and that would potentially generate 802.11 fragments. The rest of the driver TX path would then see that it was handed a fragment list and TX those. Fragments were chained together using m_nextpkt, like a normal mbuf list. This doesn't happen any longer. The net80211 vap gets the raw frame, which then sends that to the driver netif after doing the vap and 802.11 state / encapsulation work. But since all the wifi drivers use if_start() right now, m_nextpkt gets blanked on both encap and decap.. and thus things leak. Now I can't really see a way around this, without doing dirty hacks with mbuf attributes to link the fragments together. The only clean way I can see is to force all wifi drivers to use if_transmit(), and then have if_transmit() interpret a chain of frames as "the fragment list." I'm tempted to just create a new TX ic method which does what if_transmit does(), and ignore the if_start/if_transmit stuff altogether. That way any changes to if_transmit() in the future (where people may decide to have if_transmit() take a _list_ of frames to transmit) doesn't screw me. Right now if_transmit() API just sends a single frame to the driver in question, so I also don't want to abuse the semantics there to include "oh, and also fragments." I'd like to get this in soon as I'm going to have to change a bunch of wireless code in all the drivers as well as the wifi stack and this is likely going to have some fallout. I'd like to do his before 10.0 branches. I'm open to suggestions/comments. :-) Thanks! Adrian