Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 354928dd authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by John W. Linville
Browse files

iwlwifi: make tx_cmd_pool kmem cache global



Otherwise we are not able to run more than one device per driver:

[   24.743045] kmem_cache_create: duplicate cache iwl_dev_cmd
[   24.743051] Pid: 3165, comm: NetworkManager Not tainted 3.3.0-rc2-wl+ #5
[   24.743054] Call Trace:
[   24.743066]  [<ffffffff811717d5>] kmem_cache_create+0x655/0x700
[   24.743101]  [<ffffffffa03b9f8b>] iwl_alive_notify+0x1cb/0x1f0 [iwlwifi]
[   24.743111]  [<ffffffffa03ba442>] iwl_load_ucode_wait_alive+0x1b2/0x220 [iwlwifi]
[   24.743142]  [<ffffffffa03ba893>] iwl_run_init_ucode+0x73/0x100 [iwlwifi]
[   24.743152]  [<ffffffffa03b8fa1>] __iwl_up+0x81/0x220 [iwlwifi]
[   24.743161]  [<ffffffffa03b91c0>] iwlagn_mac_start+0x80/0x190 [iwlwifi]
[   24.743188]  [<ffffffffa03307b3>] ieee80211_do_open+0x293/0x770 [mac80211]

Signed-off-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 9a716863
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -367,7 +367,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
	if (info->flags & IEEE80211_TX_CTL_AMPDU)
	if (info->flags & IEEE80211_TX_CTL_AMPDU)
		is_agg = true;
		is_agg = true;


	dev_cmd = kmem_cache_alloc(priv->tx_cmd_pool, GFP_ATOMIC);
	dev_cmd = kmem_cache_alloc(iwl_tx_cmd_pool, GFP_ATOMIC);


	if (unlikely(!dev_cmd))
	if (unlikely(!dev_cmd))
		goto drop_unlock_priv;
		goto drop_unlock_priv;
@@ -458,7 +458,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)


drop_unlock_sta:
drop_unlock_sta:
	if (dev_cmd)
	if (dev_cmd)
		kmem_cache_free(priv->tx_cmd_pool, dev_cmd);
		kmem_cache_free(iwl_tx_cmd_pool, dev_cmd);
	spin_unlock(&priv->sta_lock);
	spin_unlock(&priv->sta_lock);
drop_unlock_priv:
drop_unlock_priv:
	return -1;
	return -1;
@@ -1078,7 +1078,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,


			info = IEEE80211_SKB_CB(skb);
			info = IEEE80211_SKB_CB(skb);
			ctx = info->driver_data[0];
			ctx = info->driver_data[0];
			kmem_cache_free(priv->tx_cmd_pool,
			kmem_cache_free(iwl_tx_cmd_pool,
					(info->driver_data[1]));
					(info->driver_data[1]));


			memset(&info->status, 0, sizeof(info->status));
			memset(&info->status, 0, sizeof(info->status));
@@ -1229,7 +1229,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
			WARN_ON_ONCE(1);
			WARN_ON_ONCE(1);


		info = IEEE80211_SKB_CB(skb);
		info = IEEE80211_SKB_CB(skb);
		kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1]));
		kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1]));


		if (freed == 1) {
		if (freed == 1) {
			/* this is the first skb we deliver in this batch */
			/* this is the first skb we deliver in this batch */
+15 −6
Original line number Original line Diff line number Diff line
@@ -1102,8 +1102,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
{
{
	iwl_free_geos(priv);
	iwl_free_geos(priv);
	iwl_free_channel_map(priv);
	iwl_free_channel_map(priv);
	if (priv->tx_cmd_pool)
		kmem_cache_destroy(priv->tx_cmd_pool);
	kfree(priv->scan_cmd);
	kfree(priv->scan_cmd);
	kfree(priv->beacon_cmd);
	kfree(priv->beacon_cmd);
	kfree(rcu_dereference_raw(priv->noa_data));
	kfree(rcu_dereference_raw(priv->noa_data));
@@ -1477,6 +1475,9 @@ const struct iwl_op_mode_ops iwl_dvm_ops = {
 * driver and module entry point
 * driver and module entry point
 *
 *
 *****************************************************************************/
 *****************************************************************************/

struct kmem_cache *iwl_tx_cmd_pool;

static int __init iwl_init(void)
static int __init iwl_init(void)
{
{


@@ -1484,20 +1485,27 @@ static int __init iwl_init(void)
	pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
	pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
	pr_info(DRV_COPYRIGHT "\n");
	pr_info(DRV_COPYRIGHT "\n");


	iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd",
					    sizeof(struct iwl_device_cmd),
					    sizeof(void *), 0, NULL);
	if (!iwl_tx_cmd_pool)
		return -ENOMEM;

	ret = iwlagn_rate_control_register();
	ret = iwlagn_rate_control_register();
	if (ret) {
	if (ret) {
		pr_err("Unable to register rate control algorithm: %d\n", ret);
		pr_err("Unable to register rate control algorithm: %d\n", ret);
		return ret;
		goto error_rc_register;
	}
	}


	ret = iwl_pci_register_driver();
	ret = iwl_pci_register_driver();

	if (ret)
	if (ret)
		goto error_register;
		goto error_pci_register;
	return ret;
	return ret;


error_register:
error_pci_register:
	iwlagn_rate_control_unregister();
	iwlagn_rate_control_unregister();
error_rc_register:
	kmem_cache_destroy(iwl_tx_cmd_pool);
	return ret;
	return ret;
}
}


@@ -1505,6 +1513,7 @@ static void __exit iwl_exit(void)
{
{
	iwl_pci_unregister_driver();
	iwl_pci_unregister_driver();
	iwlagn_rate_control_unregister();
	iwlagn_rate_control_unregister();
	kmem_cache_destroy(iwl_tx_cmd_pool);
}
}


module_exit(iwl_exit);
module_exit(iwl_exit);
+1 −2
Original line number Original line Diff line number Diff line
@@ -1470,10 +1470,9 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)


void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
{
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
	struct ieee80211_tx_info *info;
	struct ieee80211_tx_info *info;


	info = IEEE80211_SKB_CB(skb);
	info = IEEE80211_SKB_CB(skb);
	kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1]));
	kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1]));
	dev_kfree_skb_any(skb);
	dev_kfree_skb_any(skb);
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -725,7 +725,6 @@ struct iwl_priv {
	struct ieee80211_hw *hw;
	struct ieee80211_hw *hw;
	struct ieee80211_channel *ieee_channels;
	struct ieee80211_channel *ieee_channels;
	struct ieee80211_rate *ieee_rates;
	struct ieee80211_rate *ieee_rates;
	struct kmem_cache *tx_cmd_pool;


	struct list_head calib_results;
	struct list_head calib_results;


@@ -983,6 +982,7 @@ struct iwl_priv {
	bool have_rekey_data;
	bool have_rekey_data;
}; /*iwl_priv */
}; /*iwl_priv */


extern struct kmem_cache *iwl_tx_cmd_pool;
extern struct iwl_mod_params iwlagn_mod_params;
extern struct iwl_mod_params iwlagn_mod_params;


static inline struct iwl_rxon_context *
static inline struct iwl_rxon_context *
+0 −9
Original line number Original line Diff line number Diff line
@@ -318,15 +318,6 @@ static int iwl_alive_notify(struct iwl_priv *priv)
{
{
	int ret;
	int ret;


	if (!priv->tx_cmd_pool)
		priv->tx_cmd_pool =
			kmem_cache_create("iwl_dev_cmd",
					  sizeof(struct iwl_device_cmd),
					  sizeof(void *), 0, NULL);

	if (!priv->tx_cmd_pool)
		return -ENOMEM;

	iwl_trans_fw_alive(trans(priv));
	iwl_trans_fw_alive(trans(priv));


	priv->passive_no_rx = false;
	priv->passive_no_rx = false;