From 49898852e6aa8a6de9a5bc0bab2cf305b3583bbf Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 2 Sep 2008 15:07:18 -0400 Subject: iwlwifi: do not use GFP_DMA in iwl_tx_queue_init GFP_DMA is not necessary for the iwlwifi hardware and it can cause allocation failures and/or invoke the OOM killer on lots of systems. For reference: https://bugzilla.redhat.com/show_bug.cgi?id=459709 Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c') diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index d82823b5c8a..ff879d46624 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -426,7 +426,7 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, continue; } - txq->cmd[i] = kmalloc(len, GFP_KERNEL | GFP_DMA); + txq->cmd[i] = kmalloc(len, GFP_KERNEL); if (!txq->cmd[i]) return -ENOMEM; } -- cgit v1.2.3 From 73b7d742519ab4cc1b7a12c7af15187fc0ede8e7 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 3 Sep 2008 11:18:48 +0800 Subject: iwlwifi: fix Tx cmd memory allocation failure handling This patch "iwlwifi: do not use GFP_DMA in iwl_tx_queue_init" removes GFP_DMA from allocation tx command buffers. GFP_DMA allows allocation only for memory under 16M which causes allocation problems suspend/resume flows. Using kmalloc is temporal solution and some consistent/coherent allocation schema will be more correct. Since iwlwifi hardware supports 64bit address this solution should work on x86 (32 and 64bit) for now. This patch fixes memory freeing problem in the previous patch. Signed-off-by: Tomas Winkler Signed-off-by: Ian Schram Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-tx.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c') diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index ff879d46624..78b1a7a4ca4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -402,12 +402,11 @@ static int iwl_hw_tx_queue_init(struct iwl_priv *priv, /** * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue */ -static int iwl_tx_queue_init(struct iwl_priv *priv, - struct iwl_tx_queue *txq, +static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id) { int i, len; - int rc = 0; + int ret; /* * Alloc buffer array for commands (Tx or other types of commands). @@ -428,17 +427,14 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, txq->cmd[i] = kmalloc(len, GFP_KERNEL); if (!txq->cmd[i]) - return -ENOMEM; + goto err; } /* Alloc driver data array and TFD circular buffer */ - rc = iwl_tx_queue_alloc(priv, txq, txq_id); - if (rc) { - for (i = 0; i < slots_num; i++) - kfree(txq->cmd[i]); + ret = iwl_tx_queue_alloc(priv, txq, txq_id); + if (ret) + goto err; - return -ENOMEM; - } txq->need_update = 0; /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise @@ -452,6 +448,17 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, iwl_hw_tx_queue_init(priv, txq); return 0; +err: + for (i = 0; i < slots_num; i++) { + kfree(txq->cmd[i]); + txq->cmd[i] = NULL; + } + + if (txq_id == IWL_CMD_QUEUE_NUM) { + kfree(txq->cmd[slots_num]); + txq->cmd[slots_num] = NULL; + } + return -ENOMEM; } /** * iwl_hw_txq_ctx_free - Free TXQ Context -- cgit v1.2.3