diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2012-03-07 12:52:33 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-03-08 13:59:54 -0500 |
commit | 354928dd00d0437149991fad7637c411ba1c62f0 (patch) | |
tree | 31b46e1b4c9e7e3401b2be5882c9d5f529a29f75 /drivers/net/wireless/iwlwifi | |
parent | 9a716863ae4a2f039bc4d0b2b2bb4b24a1dc7a91 (diff) |
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: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-ucode.c | 9 |
5 files changed, 21 insertions, 22 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index a19db4c0c9fa..97ebfd26212e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -367,7 +367,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
367 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | 367 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
368 | is_agg = true; | 368 | is_agg = true; |
369 | 369 | ||
370 | dev_cmd = kmem_cache_alloc(priv->tx_cmd_pool, GFP_ATOMIC); | 370 | dev_cmd = kmem_cache_alloc(iwl_tx_cmd_pool, GFP_ATOMIC); |
371 | 371 | ||
372 | if (unlikely(!dev_cmd)) | 372 | if (unlikely(!dev_cmd)) |
373 | goto drop_unlock_priv; | 373 | goto drop_unlock_priv; |
@@ -458,7 +458,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
458 | 458 | ||
459 | drop_unlock_sta: | 459 | drop_unlock_sta: |
460 | if (dev_cmd) | 460 | if (dev_cmd) |
461 | kmem_cache_free(priv->tx_cmd_pool, dev_cmd); | 461 | kmem_cache_free(iwl_tx_cmd_pool, dev_cmd); |
462 | spin_unlock(&priv->sta_lock); | 462 | spin_unlock(&priv->sta_lock); |
463 | drop_unlock_priv: | 463 | drop_unlock_priv: |
464 | return -1; | 464 | return -1; |
@@ -1078,7 +1078,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1078 | 1078 | ||
1079 | info = IEEE80211_SKB_CB(skb); | 1079 | info = IEEE80211_SKB_CB(skb); |
1080 | ctx = info->driver_data[0]; | 1080 | ctx = info->driver_data[0]; |
1081 | kmem_cache_free(priv->tx_cmd_pool, | 1081 | kmem_cache_free(iwl_tx_cmd_pool, |
1082 | (info->driver_data[1])); | 1082 | (info->driver_data[1])); |
1083 | 1083 | ||
1084 | memset(&info->status, 0, sizeof(info->status)); | 1084 | memset(&info->status, 0, sizeof(info->status)); |
@@ -1229,7 +1229,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1229 | WARN_ON_ONCE(1); | 1229 | WARN_ON_ONCE(1); |
1230 | 1230 | ||
1231 | info = IEEE80211_SKB_CB(skb); | 1231 | info = IEEE80211_SKB_CB(skb); |
1232 | kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); | 1232 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); |
1233 | 1233 | ||
1234 | if (freed == 1) { | 1234 | if (freed == 1) { |
1235 | /* this is the first skb we deliver in this batch */ | 1235 | /* this is the first skb we deliver in this batch */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 64bc2859dd1b..7927e3e11097 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1102,8 +1102,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
1102 | { | 1102 | { |
1103 | iwl_free_geos(priv); | 1103 | iwl_free_geos(priv); |
1104 | iwl_free_channel_map(priv); | 1104 | iwl_free_channel_map(priv); |
1105 | if (priv->tx_cmd_pool) | ||
1106 | kmem_cache_destroy(priv->tx_cmd_pool); | ||
1107 | kfree(priv->scan_cmd); | 1105 | kfree(priv->scan_cmd); |
1108 | kfree(priv->beacon_cmd); | 1106 | kfree(priv->beacon_cmd); |
1109 | kfree(rcu_dereference_raw(priv->noa_data)); | 1107 | kfree(rcu_dereference_raw(priv->noa_data)); |
@@ -1477,6 +1475,9 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { | |||
1477 | * driver and module entry point | 1475 | * driver and module entry point |
1478 | * | 1476 | * |
1479 | *****************************************************************************/ | 1477 | *****************************************************************************/ |
1478 | |||
1479 | struct kmem_cache *iwl_tx_cmd_pool; | ||
1480 | |||
1480 | static int __init iwl_init(void) | 1481 | static int __init iwl_init(void) |
1481 | { | 1482 | { |
1482 | 1483 | ||
@@ -1484,20 +1485,27 @@ static int __init iwl_init(void) | |||
1484 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); | 1485 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); |
1485 | pr_info(DRV_COPYRIGHT "\n"); | 1486 | pr_info(DRV_COPYRIGHT "\n"); |
1486 | 1487 | ||
1488 | iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd", | ||
1489 | sizeof(struct iwl_device_cmd), | ||
1490 | sizeof(void *), 0, NULL); | ||
1491 | if (!iwl_tx_cmd_pool) | ||
1492 | return -ENOMEM; | ||
1493 | |||
1487 | ret = iwlagn_rate_control_register(); | 1494 | ret = iwlagn_rate_control_register(); |
1488 | if (ret) { | 1495 | if (ret) { |
1489 | pr_err("Unable to register rate control algorithm: %d\n", ret); | 1496 | pr_err("Unable to register rate control algorithm: %d\n", ret); |
1490 | return ret; | 1497 | goto error_rc_register; |
1491 | } | 1498 | } |
1492 | 1499 | ||
1493 | ret = iwl_pci_register_driver(); | 1500 | ret = iwl_pci_register_driver(); |
1494 | |||
1495 | if (ret) | 1501 | if (ret) |
1496 | goto error_register; | 1502 | goto error_pci_register; |
1497 | return ret; | 1503 | return ret; |
1498 | 1504 | ||
1499 | error_register: | 1505 | error_pci_register: |
1500 | iwlagn_rate_control_unregister(); | 1506 | iwlagn_rate_control_unregister(); |
1507 | error_rc_register: | ||
1508 | kmem_cache_destroy(iwl_tx_cmd_pool); | ||
1501 | return ret; | 1509 | return ret; |
1502 | } | 1510 | } |
1503 | 1511 | ||
@@ -1505,6 +1513,7 @@ static void __exit iwl_exit(void) | |||
1505 | { | 1513 | { |
1506 | iwl_pci_unregister_driver(); | 1514 | iwl_pci_unregister_driver(); |
1507 | iwlagn_rate_control_unregister(); | 1515 | iwlagn_rate_control_unregister(); |
1516 | kmem_cache_destroy(iwl_tx_cmd_pool); | ||
1508 | } | 1517 | } |
1509 | 1518 | ||
1510 | module_exit(iwl_exit); | 1519 | module_exit(iwl_exit); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f50bd4263b88..df7b165b290c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1470,10 +1470,9 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | |||
1470 | 1470 | ||
1471 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) | 1471 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) |
1472 | { | 1472 | { |
1473 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1474 | struct ieee80211_tx_info *info; | 1473 | struct ieee80211_tx_info *info; |
1475 | 1474 | ||
1476 | info = IEEE80211_SKB_CB(skb); | 1475 | info = IEEE80211_SKB_CB(skb); |
1477 | kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); | 1476 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); |
1478 | dev_kfree_skb_any(skb); | 1477 | dev_kfree_skb_any(skb); |
1479 | } | 1478 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1b05faea7965..aa4b3b122da4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -725,7 +725,6 @@ struct iwl_priv { | |||
725 | struct ieee80211_hw *hw; | 725 | struct ieee80211_hw *hw; |
726 | struct ieee80211_channel *ieee_channels; | 726 | struct ieee80211_channel *ieee_channels; |
727 | struct ieee80211_rate *ieee_rates; | 727 | struct ieee80211_rate *ieee_rates; |
728 | struct kmem_cache *tx_cmd_pool; | ||
729 | 728 | ||
730 | struct list_head calib_results; | 729 | struct list_head calib_results; |
731 | 730 | ||
@@ -983,6 +982,7 @@ struct iwl_priv { | |||
983 | bool have_rekey_data; | 982 | bool have_rekey_data; |
984 | }; /*iwl_priv */ | 983 | }; /*iwl_priv */ |
985 | 984 | ||
985 | extern struct kmem_cache *iwl_tx_cmd_pool; | ||
986 | extern struct iwl_mod_params iwlagn_mod_params; | 986 | extern struct iwl_mod_params iwlagn_mod_params; |
987 | 987 | ||
988 | static inline struct iwl_rxon_context * | 988 | static inline struct iwl_rxon_context * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 404fd8e7958b..d97cf44b75ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c | |||
@@ -318,15 +318,6 @@ static int iwl_alive_notify(struct iwl_priv *priv) | |||
318 | { | 318 | { |
319 | int ret; | 319 | int ret; |
320 | 320 | ||
321 | if (!priv->tx_cmd_pool) | ||
322 | priv->tx_cmd_pool = | ||
323 | kmem_cache_create("iwl_dev_cmd", | ||
324 | sizeof(struct iwl_device_cmd), | ||
325 | sizeof(void *), 0, NULL); | ||
326 | |||
327 | if (!priv->tx_cmd_pool) | ||
328 | return -ENOMEM; | ||
329 | |||
330 | iwl_trans_fw_alive(trans(priv)); | 321 | iwl_trans_fw_alive(trans(priv)); |
331 | 322 | ||
332 | priv->passive_no_rx = false; | 323 | priv->passive_no_rx = false; |