From patchwork Tue Nov 21 12:17:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Beichler X-Patchwork-Id: 10068015 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7B4266022E for ; Tue, 21 Nov 2017 12:23:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6F4391FF29 for ; Tue, 21 Nov 2017 12:23:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 63DE5294AB; Tue, 21 Nov 2017 12:23:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E78CA29492 for ; Tue, 21 Nov 2017 12:23:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752006AbdKUMXW (ORCPT ); Tue, 21 Nov 2017 07:23:22 -0500 Received: from mx2.uni-rostock.de ([139.30.22.72]:57398 "EHLO mx1.uni-rostock.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751684AbdKUMXV (ORCPT ); Tue, 21 Nov 2017 07:23:21 -0500 DKIM-Signature: v=1; c=relaxed/relaxed; d=uni-rostock.de; s=itmz-nsp; t=1511266699; bh=u55wAEVH1B20lKogx2WxlIXqwNwV25vxmaZdfpl0zbY=; h= "Subject:Subject:From:From:Date:Date:ReplyTo:ReplyTo:Cc:Cc:Message-Id:Message-Id"; a=rsa-sha256; b= dwqFhBQKZptpJxvPb5YwloEMFpdYWVVb5iASTg4rhqG331tRu/AnWluWetgci1aO3yqiyCq24hODB6kudLHogoxRfCnZOsK8MJdvaIj3LQ1M+YpCXvdvIKayEyDnew6mX6NYElxkeW1Eq0t3ZXu1zoAopFeeW4Jqx6KnQNEtWPE= Received: from BB-manjaroVM.amd.e-technik.uni-rostock.de (139.30.201.113) by mail2.uni-rostock.de (139.30.8.210) with Microsoft SMTP Server (TLS) id 14.3.361.1; Tue, 21 Nov 2017 13:18:16 +0100 From: Benjamin Beichler To: CC: , Benjamin Beichler Subject: [PATCH v2 2/5] mac80211_hwsim: add hashtable with mac address keys for faster lookup Date: Tue, 21 Nov 2017 13:17:41 +0100 X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171121121744.23422-1-benjamin.beichler@uni-rostock.de> References: <20171121121744.23422-1-benjamin.beichler@uni-rostock.de> MIME-Version: 1.0 X-Originating-IP: [139.30.201.113] X-PMWin-Version: 3.1.3.0, Antivirus-Engine: 3.69.2, Antivirus-Data: 5.45 Message-ID: <7f6aabdb-0689-44b2-95e4-49696d765d0f@MAIL2.uni-rostock.de> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds a rhastable for mac address lookup of hwsim radios. This especially improve the speed on reception of a netlink message with a new frame. Although redundant, we keep holding a normal list for all radios, since the rhashtable_walk interface adds a lot of overhead for iterating over all radios and the doc of rhashtable recommend a redundant structure for stable walks in such situations. Since rhashtable is rcu protected we do not need a lock for delivering frames and thus improving this scenario. Signed-off-by: Benjamin Beichler --- drivers/net/wireless/mac80211_hwsim.c | 56 +++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index d35dc6b2a733..48b9efed725e 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "mac80211_hwsim.h" #define WARN_QUEUE 100 @@ -489,6 +490,7 @@ static const struct ieee80211_iface_combination hwsim_if_comb_p2p_dev[] = { static spinlock_t hwsim_radio_lock; static LIST_HEAD(hwsim_radios); +static struct rhashtable hwsim_radios_rht; static spinlock_t hwsim_delete_lock; static LIST_HEAD(delete_radios); static int hwsim_radio_idx; @@ -501,6 +503,7 @@ static struct platform_driver mac80211_hwsim_driver = { struct mac80211_hwsim_data { struct list_head list; + struct rhash_head rht; struct ieee80211_hw *hw; struct device *dev; struct ieee80211_supported_band bands[NUM_NL80211_BANDS]; @@ -575,6 +578,20 @@ struct mac80211_hwsim_data { u64 tx_failed; }; +static u32 hwsim_table_hash(const void *addr, u32 len, u32 seed) +{ + /* Use last four bytes of hw addr as hash index */ + return jhash_1word(*(u32 *)(addr + 2), seed); +} + +static const struct rhashtable_params hwsim_rht_params = { + .nelem_hint = 2, + .automatic_shrinking = true, + .key_len = ETH_ALEN, + .key_offset = offsetof(struct mac80211_hwsim_data, addresses[1]), + .head_offset = offsetof(struct mac80211_hwsim_data, rht), + .hashfn = hwsim_table_hash, +}; struct hwsim_radiotap_hdr { struct ieee80211_radiotap_header hdr; @@ -2727,6 +2744,15 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); spin_lock_bh(&hwsim_radio_lock); + err = rhashtable_insert_fast(&hwsim_radios_rht, &data->rht, + hwsim_rht_params); + if (err < 0) { + pr_debug("mac80211_hwsim: radio index %d already present\n", + idx); + spin_unlock_bh(&hwsim_radio_lock); + goto failed_final_insert; + } + list_add_tail(&data->list, &hwsim_radios); spin_unlock_bh(&hwsim_radio_lock); @@ -2735,6 +2761,9 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, return idx; +failed_final_insert: + debugfs_remove_recursive(data->debugfs); + ieee80211_unregister_hw(data->hw); failed_hw: device_release_driver(data->dev); failed_bind: @@ -2870,22 +2899,9 @@ static void hwsim_mon_setup(struct net_device *dev) static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(const u8 *addr) { - struct mac80211_hwsim_data *data; - bool _found = false; - - spin_lock_bh(&hwsim_radio_lock); - list_for_each_entry(data, &hwsim_radios, list) { - if (memcmp(data->addresses[1].addr, addr, ETH_ALEN) == 0) { - _found = true; - break; - } - } - spin_unlock_bh(&hwsim_radio_lock); - - if (!_found) - return NULL; - - return data; + return rhashtable_lookup_fast(&hwsim_radios_rht, + addr, + hwsim_rht_params); } static void hwsim_register_wmediumd(struct net *net, u32 portid) @@ -3184,6 +3200,8 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info) continue; list_del(&data->list); + rhashtable_remove_fast(&hwsim_radios_rht, &data->rht, + hwsim_rht_params); spin_unlock_bh(&hwsim_radio_lock); mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), info); @@ -3343,6 +3361,8 @@ static void remove_user_radios(u32 portid) list_for_each_entry_safe(entry, tmp, &hwsim_radios, list) { if (entry->destroy_on_close && entry->portid == portid) { list_del(&entry->list); + rhashtable_remove_fast(&hwsim_radios_rht, &entry->rht, + hwsim_rht_params); spin_lock_bh(&hwsim_delete_lock); list_add(&entry->list, &delete_radios); @@ -3423,6 +3443,8 @@ static void __net_exit hwsim_exit_net(struct net *net) continue; list_del(&data->list); + rhashtable_remove_fast(&hwsim_radios_rht, &data->rht, + hwsim_rht_params); spin_lock_bh(&hwsim_delete_lock); list_add(&data->list, &delete_radios); @@ -3461,6 +3483,7 @@ static int __init init_mac80211_hwsim(void) spin_lock_init(&hwsim_radio_lock); spin_lock_init(&hwsim_delete_lock); + rhashtable_init(&hwsim_radios_rht, &hwsim_rht_params); err = register_pernet_device(&hwsim_net_ops); if (err) @@ -3613,6 +3636,7 @@ static void __exit exit_mac80211_hwsim(void) } spin_unlock_bh(&hwsim_delete_lock); + rhashtable_destroy(&hwsim_radios_rht); unregister_netdev(hwsim_mon); platform_driver_unregister(&mac80211_hwsim_driver); unregister_pernet_device(&hwsim_net_ops);