From patchwork Sun Dec 15 21:14:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 3350951 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 940FEC0D4A for ; Sun, 15 Dec 2013 21:15:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AC514201F9 for ; Sun, 15 Dec 2013 21:15:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C182C20461 for ; Sun, 15 Dec 2013 21:15:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752063Ab3LOVPX (ORCPT ); Sun, 15 Dec 2013 16:15:23 -0500 Received: from mail-pb0-f49.google.com ([209.85.160.49]:41825 "EHLO mail-pb0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752055Ab3LOVPW (ORCPT ); Sun, 15 Dec 2013 16:15:22 -0500 Received: by mail-pb0-f49.google.com with SMTP id jt11so4646989pbb.36 for ; Sun, 15 Dec 2013 13:15:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kRlzjj73PRPlKt3a0EPkGXOAFYGTbDXxoInJODhBUd8=; b=qvxtHukkeMgyPnQEaJyZm6GN53T+SM4pMWgc4FbutI3XgpqxB4q1ZDdCeNa6/P6Lag YHOLTKTQPrhMH87YMFnlZwrjtyIB8qDf41XHMc5HKwzwAU2bsp2LJyNFNV+P2Nqbkx+6 J4D8XGUS0JYgQ4fzC8sfuRwTMCfMuS4ojwy7w2P0fCakzNqhXnMGIRW6pAa/yRrMhdjy box9ZRyL5Jhy8UqSRzWqEQjRxsrz7HGMZSy8KEtkqHkeOj+mAFEqA3PyvSH1hoEaZj10 KKLmwT6dz/afjkHlDNO9ZEy0BRr1hcxS20wvfvKK+1254ZBOCbuoaqESP+o8RZIdB7/S m9hw== X-Received: by 10.68.190.103 with SMTP id gp7mr16448114pbc.74.1387142121567; Sun, 15 Dec 2013 13:15:21 -0800 (PST) Received: from localhost.localdomain (c-69-181-202-165.hsd1.ca.comcast.net. [69.181.202.165]) by mx.google.com with ESMTPSA id ql10sm21100387pbc.44.2013.12.15.13.15.20 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 15 Dec 2013 13:15:20 -0800 (PST) From: Thomas Pedersen To: Johannes Berg Cc: open80211s , linux-wireless , Thomas Pedersen Subject: [PATCH 3/3] mac80211: update adjusting TBTT bit in beacon Date: Sun, 15 Dec 2013 13:14:16 -0800 Message-Id: <1387142056-21850-3-git-send-email-twpedersen@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1387142056-21850-1-git-send-email-twpedersen@gmail.com> References: <1387142056-21850-1-git-send-email-twpedersen@gmail.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Thomas Pedersen This regression was introduced in "mac80211: cache mesh beacon". mesh_sync_offset_adjust_tbtt() was assuming that the beacon would be rebuilt in every single pre-tbtt interrupt, but now the beacon update happens on the workqueue, and it must be ready for immediate delivery to the driver. Save a pointer to the meshconf IE in the beacon_data (this works because both the IE pointer and beacon buffer are protected by the same rcu_{dereference,assign_pointer}()) for quick updates during pre-tbtt. This is faster and a little prettier than iterating over the elements to find the meshconf IE every time. Signed-off-by: Thomas Pedersen --- net/mac80211/ieee80211_i.h | 9 ++++++++- net/mac80211/mesh.c | 5 +++++ net/mac80211/mesh_sync.c | 9 ++++++++- net/mac80211/tx.c | 3 +-- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 32bae21..ec1d4a6 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -232,6 +232,7 @@ struct ieee80211_rx_data { struct beacon_data { u8 *head, *tail; int head_len, tail_len; + struct ieee80211_meshconf_ie *meshconf; struct rcu_head rcu_head; }; @@ -540,7 +541,10 @@ struct ieee80211_mesh_sync_ops { struct ieee80211_mgmt *mgmt, struct ieee802_11_elems *elems, struct ieee80211_rx_status *rx_status); - void (*adjust_tbtt)(struct ieee80211_sub_if_data *sdata); + + /* should be called with beacon_data under RCU read lock */ + void (*adjust_tbtt)(struct ieee80211_sub_if_data *sdata, + struct beacon_data *beacon); /* add other framework functions here */ }; @@ -614,6 +618,9 @@ struct ieee80211_if_mesh { bool chsw_init; u8 chsw_ttl; u16 pre_value; + + /* offset from skb->data while building IE */ + int meshconf_offset; }; #ifdef CONFIG_MAC80211_MESH diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 1174157..86c2d41 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -259,6 +259,9 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata, *pos++ = WLAN_EID_MESH_CONFIG; *pos++ = meshconf_len; + /* save a pointer for quick updates in pre-tbtt */ + ifmsh->meshconf_offset = pos - skb->data; + /* Active path selection protocol ID */ *pos++ = ifmsh->mesh_pp_id; /* Active path selection metric ID */ @@ -723,6 +726,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) bcn->tail_len = skb->len; memcpy(bcn->tail, skb->data, bcn->tail_len); + bcn->meshconf = (struct ieee80211_meshconf_ie *) + (bcn->tail + ifmsh->meshconf_offset); dev_kfree_skb(skb); rcu_assign_pointer(ifmsh->beacon, bcn); diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c index d1cf2d5..2bc5dc2 100644 --- a/net/mac80211/mesh_sync.c +++ b/net/mac80211/mesh_sync.c @@ -164,12 +164,15 @@ no_sync: rcu_read_unlock(); } -static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata) +static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata, + struct beacon_data *beacon) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; + u8 cap; WARN_ON(ifmsh->mesh_sp_id != IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET); BUG_ON(!rcu_read_lock_held()); + cap = beacon->meshconf->meshconf_cap; spin_lock_bh(&ifmsh->sync_offset_lock); @@ -194,6 +197,10 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata) ifmsh->adjusting_tbtt = false; } spin_unlock_bh(&ifmsh->sync_offset_lock); + + beacon->meshconf->meshconf_cap = ifmsh->adjusting_tbtt ? + IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING | cap : + ~IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING & cap; } static const struct sync_method sync_methods[] = { diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 6d59e21..d758509 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2602,8 +2602,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, ieee80211_update_csa(sdata, bcn); if (ifmsh->sync_ops) - ifmsh->sync_ops->adjust_tbtt( - sdata); + ifmsh->sync_ops->adjust_tbtt(sdata, bcn); skb = dev_alloc_skb(local->tx_headroom + bcn->head_len +