* [PATCH v2 1/3] iwlwifi: fix dma mappings and skbs leak
@ 2011-02-25 15:57 Stanislaw Gruszka
2011-02-25 15:57 ` [PATCH 2/3] iwlegacy: " Stanislaw Gruszka
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Stanislaw Gruszka @ 2011-02-25 15:57 UTC (permalink / raw)
To: Wey-Yi Guy, Intel Linux Wireless; +Cc: linux-wireless, Stanislaw Gruszka
Since commit commit 470058e0ad82fcfaaffd57307d8bf8c094e8e9d7
"iwlwifi: avoid Tx queue memory allocation in interface down" we do
not unmap dma and free skbs when down device and there is pending
transfer. What in consequence may cause that system hung (waiting
for free skb's) when performing shutdown at iptables module unload.
DMA leak manifest itself following warning:
WARNING: at lib/dma-debug.c:689 dma_debug_device_change+0x15a/0x1b0()
Hardware name: HP xw8600 Workstation
pci 0000:80:00.0: DMA-API: device driver has pending DMA allocations while released from device [count=240]
Modules linked in: iwlagn(-) aes_x86_64 aes_generic fuse cpufreq_ondemand acpi_cpufreq freq_table mperf xt_physdev ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 ext3 jbd dm_mirror dm_region_hash dm_log dm_mod uinput hp_wmi sparse_keymap sg wmi microcode serio_raw tg3 arc4 ecb shpchp mac80211 cfg80211 rfkill ext4 mbcache jbd2 sr_mod cdrom sd_mod crc_t10dif firewire_ohci firewire_core crc_itu_t mptsas mptscsih mptbase scsi_transport_sas pata_acpi ata_generic ata_piix ahci libahci floppy nouveau ttm drm_kms_helper drm i2c_algo_bit i2c_core video [last unloaded: iwlagn]
Pid: 9131, comm: rmmod Tainted: G W 2.6.38-rc6-wl+ #33
Call Trace:
[<ffffffff810649ef>] ? warn_slowpath_common+0x7f/0xc0
[<ffffffff81064ae6>] ? warn_slowpath_fmt+0x46/0x50
[<ffffffff812320ab>] ? dma_debug_device_change+0xdb/0x1b0
[<ffffffff8123212a>] ? dma_debug_device_change+0x15a/0x1b0
[<ffffffff8149dc18>] ? notifier_call_chain+0x58/0xb0
[<ffffffff8108e370>] ? __blocking_notifier_call_chain+0x60/0x90
[<ffffffff8108e3b6>] ? blocking_notifier_call_chain+0x16/0x20
[<ffffffff812f570c>] ? __device_release_driver+0xbc/0xe0
[<ffffffff812f5808>] ? driver_detach+0xd8/0xe0
[<ffffffff812f45d1>] ? bus_remove_driver+0x91/0x100
[<ffffffff812f6022>] ? driver_unregister+0x62/0xa0
[<ffffffff8123d5d4>] ? pci_unregister_driver+0x44/0xa0
[<ffffffffa05632d1>] ? iwl_exit+0x15/0x1c [iwlagn]
[<ffffffff810ab492>] ? sys_delete_module+0x1a2/0x270
[<ffffffff81498da9>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[<ffffffff8100bf42>] ? system_call_fastpath+0x16/0x1b
I still can observe above warning after apply patch, but it is very
hard to reproduce it, and have count=1. Whereas that one is easy to
reproduce using debugfs force_reset while transmitting data, and have
very big counts eg. 240, like quoted here. So count=1 WARNING seems
to be different issue that need to be resolved separately.
v1 -> v2: fix infinity loop bug I made during "for" to "while" loop transition.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 12 ++++-
drivers/net/wireless/iwlwifi/iwl-core.h | 2 +
drivers/net/wireless/iwlwifi/iwl-tx.c | 73 +++++++++++++++++++----------
3 files changed, 61 insertions(+), 26 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 266490d..a709d05 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -947,7 +947,7 @@ void iwlagn_txq_ctx_reset(struct iwl_priv *priv)
*/
void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
{
- int ch;
+ int ch, txq_id;
unsigned long flags;
/* Turn off all Tx DMA fifos */
@@ -966,6 +966,16 @@ void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
iwl_read_direct32(priv, FH_TSSR_TX_STATUS_REG));
}
spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (!priv->txq)
+ return;
+
+ /* Unmap DMA from host system and free skb's */
+ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
+ if (txq_id == priv->cmd_queue)
+ iwl_cmd_queue_unmap(priv);
+ else
+ iwl_tx_queue_unmap(priv, txq_id);
}
/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index e0ec170..ed701f9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -509,6 +509,7 @@ void iwl_rx_reply_error(struct iwl_priv *priv,
* RX
******************************************************/
void iwl_cmd_queue_free(struct iwl_priv *priv);
+void iwl_cmd_queue_unmap(struct iwl_priv *priv);
int iwl_rx_queue_alloc(struct iwl_priv *priv);
void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
struct iwl_rx_queue *q);
@@ -533,6 +534,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id);
void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
+void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id);
void iwl_setup_watchdog(struct iwl_priv *priv);
/*****************************************************
* TX power
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 7e607d3..a91b43f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -86,6 +86,24 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
}
/**
+ * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's
+ */
+void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id)
+{
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_queue *q = &txq->q;
+
+ if (q->n_bd == 0)
+ return;
+
+ while (q->write_ptr != q->read_ptr) {
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
+ }
+}
+EXPORT_SYMBOL(iwl_tx_queue_unmap);
+
+/**
* iwl_tx_queue_free - Deallocate DMA queue.
* @txq: Transmit queue to deallocate.
*
@@ -96,17 +114,10 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
{
struct iwl_tx_queue *txq = &priv->txq[txq_id];
- struct iwl_queue *q = &txq->q;
struct device *dev = &priv->pci_dev->dev;
int i;
- if (q->n_bd == 0)
- return;
-
- /* first, empty all BD's */
- for (; q->write_ptr != q->read_ptr;
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
- priv->cfg->ops->lib->txq_free_tfd(priv, txq);
+ iwl_tx_queue_unmap(priv, txq_id);
/* De-alloc array of command/tx buffers */
for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
@@ -132,39 +143,33 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
}
/**
- * iwl_cmd_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
+ * iwl_cmd_queue_unmap - Unmap any remaining DMA mappings from command queue
*/
-void iwl_cmd_queue_free(struct iwl_priv *priv)
+void iwl_cmd_queue_unmap(struct iwl_priv *priv)
{
struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
struct iwl_queue *q = &txq->q;
- struct device *dev = &priv->pci_dev->dev;
int i;
bool huge = false;
if (q->n_bd == 0)
return;
- for (; q->read_ptr != q->write_ptr;
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+ while (q->read_ptr != q->write_ptr) {
/* we have no way to tell if it is a huge cmd ATM */
i = get_cmd_index(q, q->read_ptr, 0);
- if (txq->meta[i].flags & CMD_SIZE_HUGE) {
+ if (txq->meta[i].flags & CMD_SIZE_HUGE)
huge = true;
- continue;
- }
+ else
+ pci_unmap_single(priv->pci_dev,
+ dma_unmap_addr(&txq->meta[i], mapping),
+ dma_unmap_len(&txq->meta[i], len),
+ PCI_DMA_BIDIRECTIONAL);
- pci_unmap_single(priv->pci_dev,
- dma_unmap_addr(&txq->meta[i], mapping),
- dma_unmap_len(&txq->meta[i], len),
- PCI_DMA_BIDIRECTIONAL);
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
}
+
if (huge) {
i = q->n_window;
pci_unmap_single(priv->pci_dev,
@@ -172,6 +177,24 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
dma_unmap_len(&txq->meta[i], len),
PCI_DMA_BIDIRECTIONAL);
}
+}
+EXPORT_SYMBOL(iwl_cmd_queue_unmap);
+
+/**
+ * iwl_cmd_queue_free - Deallocate DMA queue.
+ * @txq: Transmit queue to deallocate.
+ *
+ * Empty queue by removing and destroying all BD's.
+ * Free all buffers.
+ * 0-fill, but do not free "txq" descriptor structure.
+ */
+void iwl_cmd_queue_free(struct iwl_priv *priv)
+{
+ struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
+ struct device *dev = &priv->pci_dev->dev;
+ int i;
+
+ iwl_cmd_queue_unmap(priv);
/* De-alloc array of command/tx buffers */
for (i = 0; i <= TFD_CMD_SLOTS; i++)
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] iwlegacy: fix dma mappings and skbs leak
2011-02-25 15:57 [PATCH v2 1/3] iwlwifi: fix dma mappings and skbs leak Stanislaw Gruszka
@ 2011-02-25 15:57 ` Stanislaw Gruszka
2011-02-25 16:49 ` Guy, Wey-Yi
2011-02-25 15:57 ` [PATCH 3/3] iwlwifi: ack,plcp check health changes Stanislaw Gruszka
2011-02-25 16:47 ` [PATCH v2 1/3] iwlwifi: fix dma mappings and skbs leak Guy, Wey-Yi
2 siblings, 1 reply; 7+ messages in thread
From: Stanislaw Gruszka @ 2011-02-25 15:57 UTC (permalink / raw)
To: Wey-Yi Guy, Intel Linux Wireless; +Cc: linux-wireless, Stanislaw Gruszka
Fix possible dma mappings and skbs introduced by commit
470058e0ad82fcfaaffd57307d8bf8c094e8e9d7 "iwlwifi: avoid Tx queue
memory allocation in interface down".
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/iwlegacy/iwl-4965-tx.c | 12 ++++-
drivers/net/wireless/iwlegacy/iwl-core.h | 2 +
drivers/net/wireless/iwlegacy/iwl-tx.c | 75 +++++++++++++++++---------
3 files changed, 62 insertions(+), 27 deletions(-)
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
index 2e0f0db..eff3743 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
@@ -698,7 +698,7 @@ void iwl4965_txq_ctx_reset(struct iwl_priv *priv)
*/
void iwl4965_txq_ctx_stop(struct iwl_priv *priv)
{
- int ch;
+ int ch, txq_id;
unsigned long flags;
/* Turn off all Tx DMA fifos */
@@ -719,6 +719,16 @@ void iwl4965_txq_ctx_stop(struct iwl_priv *priv)
FH_TSSR_TX_STATUS_REG));
}
spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (!priv->txq)
+ return;
+
+ /* Unmap DMA from host system and free skb's */
+ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
+ if (txq_id == priv->cmd_queue)
+ iwl_legacy_cmd_queue_unmap(priv);
+ else
+ iwl_legacy_tx_queue_unmap(priv, txq_id);
}
/*
diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h
index 1159b0d..c7d2310 100644
--- a/drivers/net/wireless/iwlegacy/iwl-core.h
+++ b/drivers/net/wireless/iwlegacy/iwl-core.h
@@ -388,6 +388,7 @@ void iwl_legacy_rx_reply_error(struct iwl_priv *priv,
/*****************************************************
* RX
******************************************************/
+void iwl_legacy_cmd_queue_unmap(struct iwl_priv *priv);
void iwl_legacy_cmd_queue_free(struct iwl_priv *priv);
int iwl_legacy_rx_queue_alloc(struct iwl_priv *priv);
void iwl_legacy_rx_queue_update_write_ptr(struct iwl_priv *priv,
@@ -415,6 +416,7 @@ int iwl_legacy_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
void iwl_legacy_tx_queue_reset(struct iwl_priv *priv,
struct iwl_tx_queue *txq,
int slots_num, u32 txq_id);
+void iwl_legacy_tx_queue_unmap(struct iwl_priv *priv, int txq_id);
void iwl_legacy_tx_queue_free(struct iwl_priv *priv, int txq_id);
void iwl_legacy_setup_watchdog(struct iwl_priv *priv);
/*****************************************************
diff --git a/drivers/net/wireless/iwlegacy/iwl-tx.c b/drivers/net/wireless/iwlegacy/iwl-tx.c
index 7db8340..a227773 100644
--- a/drivers/net/wireless/iwlegacy/iwl-tx.c
+++ b/drivers/net/wireless/iwlegacy/iwl-tx.c
@@ -82,6 +82,24 @@ iwl_legacy_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
EXPORT_SYMBOL(iwl_legacy_txq_update_write_ptr);
/**
+ * iwl_legacy_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's
+ */
+void iwl_legacy_tx_queue_unmap(struct iwl_priv *priv, int txq_id)
+{
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_queue *q = &txq->q;
+
+ if (q->n_bd == 0)
+ return;
+
+ while (q->write_ptr != q->read_ptr) {
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
+ q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd);
+ }
+}
+EXPORT_SYMBOL(iwl_legacy_tx_queue_unmap);
+
+/**
* iwl_legacy_tx_queue_free - Deallocate DMA queue.
* @txq: Transmit queue to deallocate.
*
@@ -92,17 +110,10 @@ EXPORT_SYMBOL(iwl_legacy_txq_update_write_ptr);
void iwl_legacy_tx_queue_free(struct iwl_priv *priv, int txq_id)
{
struct iwl_tx_queue *txq = &priv->txq[txq_id];
- struct iwl_queue *q = &txq->q;
struct device *dev = &priv->pci_dev->dev;
int i;
- if (q->n_bd == 0)
- return;
-
- /* first, empty all BD's */
- for (; q->write_ptr != q->read_ptr;
- q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd))
- priv->cfg->ops->lib->txq_free_tfd(priv, txq);
+ iwl_legacy_tx_queue_unmap(priv, txq_id);
/* De-alloc array of command/tx buffers */
for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
@@ -129,39 +140,33 @@ void iwl_legacy_tx_queue_free(struct iwl_priv *priv, int txq_id)
EXPORT_SYMBOL(iwl_legacy_tx_queue_free);
/**
- * iwl_legacy_cmd_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
+ * iwl_cmd_queue_unmap - Unmap any remaining DMA mappings from command queue
*/
-void iwl_legacy_cmd_queue_free(struct iwl_priv *priv)
+void iwl_legacy_cmd_queue_unmap(struct iwl_priv *priv)
{
struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
struct iwl_queue *q = &txq->q;
- struct device *dev = &priv->pci_dev->dev;
- int i;
bool huge = false;
+ int i;
if (q->n_bd == 0)
return;
- for (; q->read_ptr != q->write_ptr;
- q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+ while (q->read_ptr != q->write_ptr) {
/* we have no way to tell if it is a huge cmd ATM */
i = iwl_legacy_get_cmd_index(q, q->read_ptr, 0);
- if (txq->meta[i].flags & CMD_SIZE_HUGE) {
+ if (txq->meta[i].flags & CMD_SIZE_HUGE)
huge = true;
- continue;
- }
+ else
+ pci_unmap_single(priv->pci_dev,
+ dma_unmap_addr(&txq->meta[i], mapping),
+ dma_unmap_len(&txq->meta[i], len),
+ PCI_DMA_BIDIRECTIONAL);
- pci_unmap_single(priv->pci_dev,
- dma_unmap_addr(&txq->meta[i], mapping),
- dma_unmap_len(&txq->meta[i], len),
- PCI_DMA_BIDIRECTIONAL);
+ q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd);
}
+
if (huge) {
i = q->n_window;
pci_unmap_single(priv->pci_dev,
@@ -169,6 +174,24 @@ void iwl_legacy_cmd_queue_free(struct iwl_priv *priv)
dma_unmap_len(&txq->meta[i], len),
PCI_DMA_BIDIRECTIONAL);
}
+}
+EXPORT_SYMBOL(iwl_legacy_cmd_queue_unmap);
+
+/**
+ * iwl_legacy_cmd_queue_free - Deallocate DMA queue.
+ * @txq: Transmit queue to deallocate.
+ *
+ * Empty queue by removing and destroying all BD's.
+ * Free all buffers.
+ * 0-fill, but do not free "txq" descriptor structure.
+ */
+void iwl_legacy_cmd_queue_free(struct iwl_priv *priv)
+{
+ struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
+ struct device *dev = &priv->pci_dev->dev;
+ int i;
+
+ iwl_legacy_cmd_queue_unmap(priv);
/* De-alloc array of command/tx buffers */
for (i = 0; i <= TFD_CMD_SLOTS; i++)
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] iwlwifi: ack,plcp check health changes
2011-02-25 15:57 [PATCH v2 1/3] iwlwifi: fix dma mappings and skbs leak Stanislaw Gruszka
2011-02-25 15:57 ` [PATCH 2/3] iwlegacy: " Stanislaw Gruszka
@ 2011-02-25 15:57 ` Stanislaw Gruszka
2011-02-25 16:58 ` Guy, Wey-Yi
2011-02-25 16:47 ` [PATCH v2 1/3] iwlwifi: fix dma mappings and skbs leak Guy, Wey-Yi
2 siblings, 1 reply; 7+ messages in thread
From: Stanislaw Gruszka @ 2011-02-25 15:57 UTC (permalink / raw)
To: Wey-Yi Guy, Intel Linux Wireless; +Cc: linux-wireless, Stanislaw Gruszka
Add module ack_check, and plcp_check parameters, Ack_check is disabled
by default since is proved that check ack health can cause troubles.
Plcp_check is enabled by default.
Remove iwl_lib_ops methods, they are unneeded after iwlegacy driver
split. Merge check health code into to iwl-rx.c and make functions
static.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -
drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -
drivers/net/wireless/iwlwifi/iwl-5000.c | 4 -
drivers/net/wireless/iwlwifi/iwl-6000.c | 4 -
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 +
drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 87 ---------------
drivers/net/wireless/iwlwifi/iwl-agn.c | 73 ++-----------
drivers/net/wireless/iwlwifi/iwl-agn.h | 4 -
drivers/net/wireless/iwlwifi/iwl-core.h | 9 +-
drivers/net/wireless/iwlwifi/iwl-rx.c | 162 ++++++++++++++++++++++++++-
10 files changed, 167 insertions(+), 181 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index ba78bc8..e8e1c2d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -232,8 +232,6 @@ static struct iwl_lib_ops iwl1000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .check_plcp_health = iwl_good_plcp_health,
- .check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
.tt_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index 30483e2..894cb24 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -315,8 +315,6 @@ static struct iwl_lib_ops iwl2000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .check_plcp_health = iwl_good_plcp_health,
- .check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
.tt_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 79ab0a6..90e727b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -402,8 +402,6 @@ static struct iwl_lib_ops iwl5000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .check_plcp_health = iwl_good_plcp_health,
- .check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
.tt_ops = {
@@ -471,8 +469,6 @@ static struct iwl_lib_ops iwl5150_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .check_plcp_health = iwl_good_plcp_health,
- .check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
.tt_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index f6493f7..a745b01 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -343,8 +343,6 @@ static struct iwl_lib_ops iwl6000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .check_plcp_health = iwl_good_plcp_health,
- .check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
.tt_ops = {
@@ -415,8 +413,6 @@ static struct iwl_lib_ops iwl6030_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .check_plcp_health = iwl_good_plcp_health,
- .check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
.tt_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 0d0572c..693a1fa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -609,6 +609,7 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
struct iwl_mod_params iwlagn_mod_params = {
.amsdu_size_8K = 1,
.restart_fw = 1,
+ .plcp_check = true,
/* the rest are 0 by default */
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index b192ca8..7a89a55 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -169,93 +169,6 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
#define REG_RECALIB_PERIOD (60)
-/**
- * iwl_good_plcp_health - checks for plcp error.
- *
- * When the plcp error is exceeding the thresholds, reset the radio
- * to improve the throughput.
- */
-bool iwl_good_plcp_health(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt)
-{
- bool rc = true;
- int combined_plcp_delta;
- unsigned int plcp_msec;
- unsigned long plcp_received_jiffies;
-
- if (priv->cfg->base_params->plcp_delta_threshold ==
- IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
- IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
- return rc;
- }
-
- /*
- * check for plcp_err and trigger radio reset if it exceeds
- * the plcp error threshold plcp_delta.
- */
- plcp_received_jiffies = jiffies;
- plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
- (long) priv->plcp_jiffies);
- priv->plcp_jiffies = plcp_received_jiffies;
- /*
- * check to make sure plcp_msec is not 0 to prevent division
- * by zero.
- */
- if (plcp_msec) {
- struct statistics_rx_phy *ofdm;
- struct statistics_rx_ht_phy *ofdm_ht;
-
- if (iwl_bt_statistics(priv)) {
- ofdm = &pkt->u.stats_bt.rx.ofdm;
- ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht;
- combined_plcp_delta =
- (le32_to_cpu(ofdm->plcp_err) -
- le32_to_cpu(priv->_agn.statistics_bt.
- rx.ofdm.plcp_err)) +
- (le32_to_cpu(ofdm_ht->plcp_err) -
- le32_to_cpu(priv->_agn.statistics_bt.
- rx.ofdm_ht.plcp_err));
- } else {
- ofdm = &pkt->u.stats.rx.ofdm;
- ofdm_ht = &pkt->u.stats.rx.ofdm_ht;
- combined_plcp_delta =
- (le32_to_cpu(ofdm->plcp_err) -
- le32_to_cpu(priv->_agn.statistics.
- rx.ofdm.plcp_err)) +
- (le32_to_cpu(ofdm_ht->plcp_err) -
- le32_to_cpu(priv->_agn.statistics.
- rx.ofdm_ht.plcp_err));
- }
-
- if ((combined_plcp_delta > 0) &&
- ((combined_plcp_delta * 100) / plcp_msec) >
- priv->cfg->base_params->plcp_delta_threshold) {
- /*
- * if plcp_err exceed the threshold,
- * the following data is printed in csv format:
- * Text: plcp_err exceeded %d,
- * Received ofdm.plcp_err,
- * Current ofdm.plcp_err,
- * Received ofdm_ht.plcp_err,
- * Current ofdm_ht.plcp_err,
- * combined_plcp_delta,
- * plcp_msec
- */
- IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
- "%u, %u, %u, %u, %d, %u mSecs\n",
- priv->cfg->base_params->plcp_delta_threshold,
- le32_to_cpu(ofdm->plcp_err),
- le32_to_cpu(ofdm->plcp_err),
- le32_to_cpu(ofdm_ht->plcp_err),
- le32_to_cpu(ofdm_ht->plcp_err),
- combined_plcp_delta, plcp_msec);
-
- rc = false;
- }
- }
- return rc;
-}
-
void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index d08fa93..31d2190 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1413,72 +1413,6 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
iwl_enable_rfkill_int(priv);
}
-/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
-#define ACK_CNT_RATIO (50)
-#define BA_TIMEOUT_CNT (5)
-#define BA_TIMEOUT_MAX (16)
-
-/**
- * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries.
- *
- * When the ACK count ratio is low and aggregated BA timeout retries exceeding
- * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
- * operation state.
- */
-bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
-{
- int actual_delta, expected_delta, ba_timeout_delta;
- struct statistics_tx *cur, *old;
-
- if (priv->_agn.agg_tids_count)
- return true;
-
- if (iwl_bt_statistics(priv)) {
- cur = &pkt->u.stats_bt.tx;
- old = &priv->_agn.statistics_bt.tx;
- } else {
- cur = &pkt->u.stats.tx;
- old = &priv->_agn.statistics.tx;
- }
-
- actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
- le32_to_cpu(old->actual_ack_cnt);
- expected_delta = le32_to_cpu(cur->expected_ack_cnt) -
- le32_to_cpu(old->expected_ack_cnt);
-
- /* Values should not be negative, but we do not trust the firmware */
- if (actual_delta <= 0 || expected_delta <= 0)
- return true;
-
- ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) -
- le32_to_cpu(old->agg.ba_timeout);
-
- if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO &&
- ba_timeout_delta > BA_TIMEOUT_CNT) {
- IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n",
- actual_delta, expected_delta, ba_timeout_delta);
-
-#ifdef CONFIG_IWLWIFI_DEBUGFS
- /*
- * This is ifdef'ed on DEBUGFS because otherwise the
- * statistics aren't available. If DEBUGFS is set but
- * DEBUG is not, these will just compile out.
- */
- IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n",
- priv->_agn.delta_statistics.tx.rx_detected_cnt);
- IWL_DEBUG_RADIO(priv,
- "ack_or_ba_timeout_collision delta %d\n",
- priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision);
-#endif
-
- if (ba_timeout_delta >= BA_TIMEOUT_MAX)
- return false;
- }
-
- return true;
-}
-
-
/*****************************************************************************
*
* sysfs attributes
@@ -4786,3 +4720,10 @@ MODULE_PARM_DESC(antenna_coupling,
module_param_named(bt_ch_inhibition, iwlagn_bt_ch_announce, bool, S_IRUGO);
MODULE_PARM_DESC(bt_ch_inhibition,
"Disable BT channel inhibition (default: enable)");
+
+module_param_named(plcp_check, iwlagn_mod_params.plcp_check, bool, S_IRUGO);
+MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");
+
+module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO);
+MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])");
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index d00e1ea..96d98fa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -121,8 +121,6 @@ void iwl_disable_ict(struct iwl_priv *priv);
int iwl_alloc_isr_ict(struct iwl_priv *priv);
void iwl_free_isr_ict(struct iwl_priv *priv);
irqreturn_t iwl_isr_ict(int irq, void *data);
-bool iwl_good_ack_health(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt);
/* tx queue */
void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
@@ -248,8 +246,6 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
/* rx */
void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
-bool iwl_good_plcp_health(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt);
void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
void iwl_reply_statistics(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index ed701f9..22dc435 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -210,12 +210,7 @@ struct iwl_lib_ops {
/* temperature */
struct iwl_temp_ops temp_ops;
- /* check for plcp health */
- bool (*check_plcp_health)(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt);
- /* check for ack health */
- bool (*check_ack_health)(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt);
+
int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
@@ -261,6 +256,8 @@ struct iwl_mod_params {
int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
int antenna; /* def: 0 = both antennas (use diversity) */
int restart_fw; /* def: 1 = restart firmware */
+ bool plcp_check; /* def: true = enable plcp health check */
+ bool ack_check; /* def: false = disable ack health check */
};
/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index a21f6fe..feee761 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -227,22 +227,172 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
priv->measurement_status |= MEASUREMENT_READY;
}
-void iwl_recover_from_statistics(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt)
+/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
+#define ACK_CNT_RATIO (50)
+#define BA_TIMEOUT_CNT (5)
+#define BA_TIMEOUT_MAX (16)
+
+/**
+ * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries.
+ *
+ * When the ACK count ratio is low and aggregated BA timeout retries exceeding
+ * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
+ * operation state.
+ */
+static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
+{
+ int actual_delta, expected_delta, ba_timeout_delta;
+ struct statistics_tx *cur, *old;
+
+ if (priv->_agn.agg_tids_count)
+ return true;
+
+ if (iwl_bt_statistics(priv)) {
+ cur = &pkt->u.stats_bt.tx;
+ old = &priv->_agn.statistics_bt.tx;
+ } else {
+ cur = &pkt->u.stats.tx;
+ old = &priv->_agn.statistics.tx;
+ }
+
+ actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
+ le32_to_cpu(old->actual_ack_cnt);
+ expected_delta = le32_to_cpu(cur->expected_ack_cnt) -
+ le32_to_cpu(old->expected_ack_cnt);
+
+ /* Values should not be negative, but we do not trust the firmware */
+ if (actual_delta <= 0 || expected_delta <= 0)
+ return true;
+
+ ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) -
+ le32_to_cpu(old->agg.ba_timeout);
+
+ if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO &&
+ ba_timeout_delta > BA_TIMEOUT_CNT) {
+ IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n",
+ actual_delta, expected_delta, ba_timeout_delta);
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+ /*
+ * This is ifdef'ed on DEBUGFS because otherwise the
+ * statistics aren't available. If DEBUGFS is set but
+ * DEBUG is not, these will just compile out.
+ */
+ IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n",
+ priv->_agn.delta_statistics.tx.rx_detected_cnt);
+ IWL_DEBUG_RADIO(priv,
+ "ack_or_ba_timeout_collision delta %d\n",
+ priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision);
+#endif
+
+ if (ba_timeout_delta >= BA_TIMEOUT_MAX)
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * iwl_good_plcp_health - checks for plcp error.
+ *
+ * When the plcp error is exceeding the thresholds, reset the radio
+ * to improve the throughput.
+ */
+static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
+{
+ bool rc = true;
+ int combined_plcp_delta;
+ unsigned int plcp_msec;
+ unsigned long plcp_received_jiffies;
+
+ if (priv->cfg->base_params->plcp_delta_threshold ==
+ IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
+ IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
+ return rc;
+ }
+
+ /*
+ * check for plcp_err and trigger radio reset if it exceeds
+ * the plcp error threshold plcp_delta.
+ */
+ plcp_received_jiffies = jiffies;
+ plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
+ (long) priv->plcp_jiffies);
+ priv->plcp_jiffies = plcp_received_jiffies;
+ /*
+ * check to make sure plcp_msec is not 0 to prevent division
+ * by zero.
+ */
+ if (plcp_msec) {
+ struct statistics_rx_phy *ofdm;
+ struct statistics_rx_ht_phy *ofdm_ht;
+
+ if (iwl_bt_statistics(priv)) {
+ ofdm = &pkt->u.stats_bt.rx.ofdm;
+ ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht;
+ combined_plcp_delta =
+ (le32_to_cpu(ofdm->plcp_err) -
+ le32_to_cpu(priv->_agn.statistics_bt.
+ rx.ofdm.plcp_err)) +
+ (le32_to_cpu(ofdm_ht->plcp_err) -
+ le32_to_cpu(priv->_agn.statistics_bt.
+ rx.ofdm_ht.plcp_err));
+ } else {
+ ofdm = &pkt->u.stats.rx.ofdm;
+ ofdm_ht = &pkt->u.stats.rx.ofdm_ht;
+ combined_plcp_delta =
+ (le32_to_cpu(ofdm->plcp_err) -
+ le32_to_cpu(priv->_agn.statistics.
+ rx.ofdm.plcp_err)) +
+ (le32_to_cpu(ofdm_ht->plcp_err) -
+ le32_to_cpu(priv->_agn.statistics.
+ rx.ofdm_ht.plcp_err));
+ }
+
+ if ((combined_plcp_delta > 0) &&
+ ((combined_plcp_delta * 100) / plcp_msec) >
+ priv->cfg->base_params->plcp_delta_threshold) {
+ /*
+ * if plcp_err exceed the threshold,
+ * the following data is printed in csv format:
+ * Text: plcp_err exceeded %d,
+ * Received ofdm.plcp_err,
+ * Current ofdm.plcp_err,
+ * Received ofdm_ht.plcp_err,
+ * Current ofdm_ht.plcp_err,
+ * combined_plcp_delta,
+ * plcp_msec
+ */
+ IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
+ "%u, %u, %u, %u, %d, %u mSecs\n",
+ priv->cfg->base_params->plcp_delta_threshold,
+ le32_to_cpu(ofdm->plcp_err),
+ le32_to_cpu(ofdm->plcp_err),
+ le32_to_cpu(ofdm_ht->plcp_err),
+ le32_to_cpu(ofdm_ht->plcp_err),
+ combined_plcp_delta, plcp_msec);
+
+ rc = false;
+ }
+ }
+ return rc;
+}
+
+void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
{
+ const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
+
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
!iwl_is_any_associated(priv))
return;
- if (priv->cfg->ops->lib->check_ack_health &&
- !priv->cfg->ops->lib->check_ack_health(priv, pkt)) {
+ if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) {
IWL_ERR(priv, "low ack count detected, restart firmware\n");
if (!iwl_force_reset(priv, IWL_FW_RESET, false))
return;
}
- if (priv->cfg->ops->lib->check_plcp_health &&
- !priv->cfg->ops->lib->check_plcp_health(priv, pkt))
+ if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt))
iwl_force_reset(priv, IWL_RF_RESET, false);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/3] iwlwifi: fix dma mappings and skbs leak
2011-02-25 15:57 [PATCH v2 1/3] iwlwifi: fix dma mappings and skbs leak Stanislaw Gruszka
2011-02-25 15:57 ` [PATCH 2/3] iwlegacy: " Stanislaw Gruszka
2011-02-25 15:57 ` [PATCH 3/3] iwlwifi: ack,plcp check health changes Stanislaw Gruszka
@ 2011-02-25 16:47 ` Guy, Wey-Yi
2011-02-28 9:24 ` Stanislaw Gruszka
2 siblings, 1 reply; 7+ messages in thread
From: Guy, Wey-Yi @ 2011-02-25 16:47 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
Hi Stanislaw,
On Fri, 2011-02-25 at 07:57 -0800, Stanislaw Gruszka wrote:
> Since commit commit 470058e0ad82fcfaaffd57307d8bf8c094e8e9d7
> "iwlwifi: avoid Tx queue memory allocation in interface down" we do
> not unmap dma and free skbs when down device and there is pending
> transfer. What in consequence may cause that system hung (waiting
> for free skb's) when performing shutdown at iptables module unload.
>
> DMA leak manifest itself following warning:
>
> WARNING: at lib/dma-debug.c:689 dma_debug_device_change+0x15a/0x1b0()
> Hardware name: HP xw8600 Workstation
> pci 0000:80:00.0: DMA-API: device driver has pending DMA allocations while released from device [count=240]
> Modules linked in: iwlagn(-) aes_x86_64 aes_generic fuse cpufreq_ondemand acpi_cpufreq freq_table mperf xt_physdev ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 ext3 jbd dm_mirror dm_region_hash dm_log dm_mod uinput hp_wmi sparse_keymap sg wmi microcode serio_raw tg3 arc4 ecb shpchp mac80211 cfg80211 rfkill ext4 mbcache jbd2 sr_mod cdrom sd_mod crc_t10dif firewire_ohci firewire_core crc_itu_t mptsas mptscsih mptbase scsi_transport_sas pata_acpi ata_generic ata_piix ahci libahci floppy nouveau ttm drm_kms_helper drm i2c_algo_bit i2c_core video [last unloaded: iwlagn]
> Pid: 9131, comm: rmmod Tainted: G W 2.6.38-rc6-wl+ #33
> Call Trace:
> [<ffffffff810649ef>] ? warn_slowpath_common+0x7f/0xc0
> [<ffffffff81064ae6>] ? warn_slowpath_fmt+0x46/0x50
> [<ffffffff812320ab>] ? dma_debug_device_change+0xdb/0x1b0
> [<ffffffff8123212a>] ? dma_debug_device_change+0x15a/0x1b0
> [<ffffffff8149dc18>] ? notifier_call_chain+0x58/0xb0
> [<ffffffff8108e370>] ? __blocking_notifier_call_chain+0x60/0x90
> [<ffffffff8108e3b6>] ? blocking_notifier_call_chain+0x16/0x20
> [<ffffffff812f570c>] ? __device_release_driver+0xbc/0xe0
> [<ffffffff812f5808>] ? driver_detach+0xd8/0xe0
> [<ffffffff812f45d1>] ? bus_remove_driver+0x91/0x100
> [<ffffffff812f6022>] ? driver_unregister+0x62/0xa0
> [<ffffffff8123d5d4>] ? pci_unregister_driver+0x44/0xa0
> [<ffffffffa05632d1>] ? iwl_exit+0x15/0x1c [iwlagn]
> [<ffffffff810ab492>] ? sys_delete_module+0x1a2/0x270
> [<ffffffff81498da9>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> [<ffffffff8100bf42>] ? system_call_fastpath+0x16/0x1b
>
> I still can observe above warning after apply patch, but it is very
> hard to reproduce it, and have count=1. Whereas that one is easy to
> reproduce using debugfs force_reset while transmitting data, and have
> very big counts eg. 240, like quoted here. So count=1 WARNING seems
> to be different issue that need to be resolved separately.
>
> v1 -> v2: fix infinity loop bug I made during "for" to "while" loop transition.
>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> ---
> drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 12 ++++-
> drivers/net/wireless/iwlwifi/iwl-core.h | 2 +
> drivers/net/wireless/iwlwifi/iwl-tx.c | 73 +++++++++++++++++++----------
> 3 files changed, 61 insertions(+), 26 deletions(-)
>
Good catch, thank you very much
I don't think we need EXPORT_SYMBOL anymore after driver split
Wey
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] iwlegacy: fix dma mappings and skbs leak
2011-02-25 15:57 ` [PATCH 2/3] iwlegacy: " Stanislaw Gruszka
@ 2011-02-25 16:49 ` Guy, Wey-Yi
0 siblings, 0 replies; 7+ messages in thread
From: Guy, Wey-Yi @ 2011-02-25 16:49 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
On Fri, 2011-02-25 at 07:57 -0800, Stanislaw Gruszka wrote:
> Fix possible dma mappings and skbs introduced by commit
> 470058e0ad82fcfaaffd57307d8bf8c094e8e9d7 "iwlwifi: avoid Tx queue
> memory allocation in interface down".
>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
> ---
> drivers/net/wireless/iwlegacy/iwl-4965-tx.c | 12 ++++-
> drivers/net/wireless/iwlegacy/iwl-core.h | 2 +
> drivers/net/wireless/iwlegacy/iwl-tx.c | 75 +++++++++++++++++---------
> 3 files changed, 62 insertions(+), 27 deletions(-)
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] iwlwifi: ack,plcp check health changes
2011-02-25 15:57 ` [PATCH 3/3] iwlwifi: ack,plcp check health changes Stanislaw Gruszka
@ 2011-02-25 16:58 ` Guy, Wey-Yi
0 siblings, 0 replies; 7+ messages in thread
From: Guy, Wey-Yi @ 2011-02-25 16:58 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
On Fri, 2011-02-25 at 07:57 -0800, Stanislaw Gruszka wrote:
> Add module ack_check, and plcp_check parameters, Ack_check is disabled
> by default since is proved that check ack health can cause troubles.
> Plcp_check is enabled by default.
>
> Remove iwl_lib_ops methods, they are unneeded after iwlegacy driver
> split. Merge check health code into to iwl-rx.c and make functions
> static.
>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
> ---
> drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -
> drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -
> drivers/net/wireless/iwlwifi/iwl-5000.c | 4 -
> drivers/net/wireless/iwlwifi/iwl-6000.c | 4 -
> drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 +
> drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 87 ---------------
> drivers/net/wireless/iwlwifi/iwl-agn.c | 73 ++-----------
> drivers/net/wireless/iwlwifi/iwl-agn.h | 4 -
> drivers/net/wireless/iwlwifi/iwl-core.h | 9 +-
> drivers/net/wireless/iwlwifi/iwl-rx.c | 162 ++++++++++++++++++++++++++-
> 10 files changed, 167 insertions(+), 181 deletions(-)
>
looks good, just wonder should it split into 2 patches, one for module
parameter, and the other for moving the function?
Your call
Wey
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/3] iwlwifi: fix dma mappings and skbs leak
2011-02-25 16:47 ` [PATCH v2 1/3] iwlwifi: fix dma mappings and skbs leak Guy, Wey-Yi
@ 2011-02-28 9:24 ` Stanislaw Gruszka
0 siblings, 0 replies; 7+ messages in thread
From: Stanislaw Gruszka @ 2011-02-28 9:24 UTC (permalink / raw)
To: Guy, Wey-Yi; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
Hi
On Fri, Feb 25, 2011 at 08:47:44AM -0800, Guy, Wey-Yi wrote:
> I don't think we need EXPORT_SYMBOL anymore after driver split
I will repost series addressing that and also comment from patch 3.
Thanks
Stanislaw
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2011-02-28 9:24 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-25 15:57 [PATCH v2 1/3] iwlwifi: fix dma mappings and skbs leak Stanislaw Gruszka
2011-02-25 15:57 ` [PATCH 2/3] iwlegacy: " Stanislaw Gruszka
2011-02-25 16:49 ` Guy, Wey-Yi
2011-02-25 15:57 ` [PATCH 3/3] iwlwifi: ack,plcp check health changes Stanislaw Gruszka
2011-02-25 16:58 ` Guy, Wey-Yi
2011-02-25 16:47 ` [PATCH v2 1/3] iwlwifi: fix dma mappings and skbs leak Guy, Wey-Yi
2011-02-28 9:24 ` Stanislaw Gruszka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).