From patchwork Thu Oct 9 11:29:43 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jukka Rissanen X-Patchwork-Id: 5057571 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4E56D9F295 for ; Thu, 9 Oct 2014 11:29:54 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 53CD8201DD for ; Thu, 9 Oct 2014 11:29:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1F9B1201C8 for ; Thu, 9 Oct 2014 11:29:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755005AbaJIL3t (ORCPT ); Thu, 9 Oct 2014 07:29:49 -0400 Received: from mga03.intel.com ([134.134.136.65]:54338 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754947AbaJIL3s (ORCPT ); Thu, 9 Oct 2014 07:29:48 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP; 09 Oct 2014 04:27:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.04,684,1406617200"; d="scan'208";a="585969318" Received: from jrissane-mobl.ger.corp.intel.com ([10.237.67.33]) by orsmga001.jf.intel.com with ESMTP; 09 Oct 2014 04:29:45 -0700 From: Jukka Rissanen To: linux-wireless@vger.kernel.org Subject: [PATCH] mac80211-hwsim: Add support for HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE Date: Thu, 9 Oct 2014 14:29:43 +0300 Message-Id: <1412854183-27194-1-git-send-email-jukka.rissanen@linux.intel.com> X-Mailer: git-send-email 1.8.3.1 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 Add support for new attribute HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE which can be set by the user space component. The attribute will cause the kernel to destroy all those radios that were created by a process if that process dies. The old behaviour i.e., radios are persistent is still the default. Signed-off-by: Jukka Rissanen --- drivers/net/wireless/mac80211_hwsim.c | 52 +++++++++++++++++++++++++++++++++-- drivers/net/wireless/mac80211_hwsim.h | 3 ++ 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index babbdc1..2d27c12 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -412,6 +412,8 @@ struct mac80211_hwsim_data { struct mac_address addresses[2]; int channels, idx; bool use_chanctx; + bool destroy_on_close; + u32 portid; struct ieee80211_channel *tmp_chan; struct delayed_work roc_done; @@ -496,6 +498,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = { [HWSIM_ATTR_REG_CUSTOM_REG] = { .type = NLA_U32 }, [HWSIM_ATTR_REG_STRICT_REG] = { .type = NLA_FLAG }, [HWSIM_ATTR_SUPPORT_P2P_DEVICE] = { .type = NLA_FLAG }, + [HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE] = { .type = NLA_FLAG }, }; static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, @@ -1946,7 +1949,8 @@ static struct ieee80211_ops mac80211_hwsim_mchan_ops; static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, const struct ieee80211_regdomain *regd, bool reg_strict, bool p2p_device, - bool use_chanctx) + bool use_chanctx, bool destroy_on_close, + u32 portid) { int err; u8 addr[ETH_ALEN]; @@ -2006,6 +2010,8 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, data->channels = channels; data->use_chanctx = use_chanctx; data->idx = idx; + data->destroy_on_close = destroy_on_close; + data->portid = portid; if (data->use_chanctx) { hw->wiphy->max_scan_ssids = 255; @@ -2434,6 +2440,7 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) const struct ieee80211_regdomain *regd = NULL; bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; + bool destroy_on_close = info->attrs[HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE]; bool use_chanctx; if (info->attrs[HWSIM_ATTR_CHANNELS]) @@ -2456,7 +2463,8 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) } return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict, - p2p_device, use_chanctx); + p2p_device, use_chanctx, + destroy_on_close, info->snd_portid); } static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) @@ -2514,6 +2522,42 @@ static const struct genl_ops hwsim_ops[] = { }, }; +struct urelease_work { + struct work_struct w; + u32 portid; +}; + +static void urelease_event_work(struct work_struct *work) +{ + struct urelease_work *w = container_of(work, struct urelease_work, w); + struct mac80211_hwsim_data *entry, *tmp; + + spin_lock_bh(&hwsim_radio_lock); + list_for_each_entry_safe(entry, tmp, &hwsim_radios, list) { + if (entry->destroy_on_close && w->portid == entry->portid) { + list_del(&entry->list); + spin_unlock_bh(&hwsim_radio_lock); + mac80211_hwsim_destroy_radio(entry); + spin_lock_bh(&hwsim_radio_lock); + } + } + spin_unlock_bh(&hwsim_radio_lock); + + kfree(w); +} + +static void remove_user_radios(u32 portid) +{ + struct urelease_work *w; + + w = kmalloc(sizeof(*w), GFP_ATOMIC); + if (w) { + INIT_WORK((struct work_struct *)w, urelease_event_work); + w->portid = portid; + schedule_work((struct work_struct *)w); + } +} + static int mac80211_hwsim_netlink_notify(struct notifier_block *nb, unsigned long state, void *_notify) @@ -2523,6 +2567,8 @@ static int mac80211_hwsim_netlink_notify(struct notifier_block *nb, if (state != NETLINK_URELEASE) return NOTIFY_DONE; + remove_user_radios(notify->portid); + if (notify->portid == wmediumd_portid) { printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink" " socket, switching to perfect channel medium\n"); @@ -2676,7 +2722,7 @@ static int __init init_mac80211_hwsim(void) err = mac80211_hwsim_create_radio(channels, reg_alpha2, regd, reg_strict, support_p2p_device, - channels > 1); + channels > 1, false, 0); if (err < 0) goto out_free_radios; } diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h index c9d0315..b96d867 100644 --- a/drivers/net/wireless/mac80211_hwsim.h +++ b/drivers/net/wireless/mac80211_hwsim.h @@ -111,6 +111,8 @@ enum { * @HWSIM_ATTR_USE_CHANCTX: used with the %HWSIM_CMD_CREATE_RADIO * command to force use of channel contexts even when only a * single channel is supported + * @HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE: used with the %HWSIM_CMD_CREATE_RADIO + * command to force radio removal when process that created the radio dies * @__HWSIM_ATTR_MAX: enum limit */ @@ -132,6 +134,7 @@ enum { HWSIM_ATTR_REG_STRICT_REG, HWSIM_ATTR_SUPPORT_P2P_DEVICE, HWSIM_ATTR_USE_CHANCTX, + HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE, __HWSIM_ATTR_MAX, }; #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)