From: Joonwoo Park <joonwpark81@gmail.com>
To: "Zhu, Yi" <yi.zhu@intel.com>, netdev@vger.kernel.org
Cc: "Chatre, Reinette" <reinette.chatre@intel.com>,
linux-wireless@vger.kernel.org,
ipw3945-devel@lists.sourceforge.net,
linux-kernel@vger.kernel.org
Subject: Re: [ipw3945-devel] [PATCH 2/5] iwlwifi: iwl3945 synchronize interruptand tasklet for down iwlwifi
Date: Mon, 14 Jan 2008 17:35:11 +0900 [thread overview]
Message-ID: <478B1EBF.8030701@gmail.com> (raw)
In-Reply-To: <b25c3fa70801101838o7a71cc60h1c8b8a71624aeff9@mail.gmail.com>
Joonwoo Park wrote:
> 2008/1/11, Chatre, Reinette <reinette.chatre@intel.com>:
>> On Thursday, January 10, 2008 5:25 PM, Joonwoo Park wrote:
>
>> What modification are you considering?
>
> Roughly, I'm considering make synchronize_irq() be moved into
> iwl_disable_interrupts() and fix iwl_irq_tasket not to call
> iwl_disable_interrupts with irq disabled.
> For now iwl_irq_tasklet calls iwl_disable_interrupts() with local irq disabled.
> like this:
>
> static void iwl_irq_tasklet(struct iwl_priv *priv)
> {
> ...
> spin_lock_irqsave(&priv->lock, flags);
>
> ...
> /* Now service all interrupt bits discovered above. */
> if (inta & CSR_INT_BIT_HW_ERR) {
> IWL_ERROR("Microcode HW error detected. Restarting.\n");
>
> /* Tell the device to stop sending interrupts */
> iwl_disable_interrupts(priv);
> ...
> spin_unlock_irqrestore(&priv->lock, flags);
> return;
> }
>
>
After disabling interrupts, it's possible irq & tasklet is pending or running
This patch eleminates races for down iwlwifi
Since synchronize_irq can introduce iwl_irq_tasklet, tasklet_kill
should be called after doing synchronize_irq
To avoid races between iwl_synchronize_irq and iwl_irq_tasklet STATUS_INT_ENABLED
flag is needed.
Signed-off-by: Joonwoo Park <joonwpark81@gmail.com>
---
drivers/net/wireless/iwlwifi/iwl3945-base.c | 33 ++++++++++++++++++++++-----
1 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 6e20725..f98cd4f 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4405,6 +4405,14 @@ static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon)
}
#endif
+static void iwl_synchronize_interrupts(struct iwl_priv *priv)
+{
+ synchronize_irq(priv->pci_dev->irq);
+ /* synchornize_irq introduces irq_tasklet,
+ * tasklet_kill should be called after doing synchronize_irq */
+ tasklet_kill(&priv->irq_tasklet);
+}
+
static void iwl_enable_interrupts(struct iwl_priv *priv)
{
IWL_DEBUG_ISR("Enabling interrupts\n");
@@ -4413,7 +4421,7 @@ static void iwl_enable_interrupts(struct iwl_priv *priv)
iwl_flush32(priv, CSR_INT_MASK);
}
-static inline void iwl_disable_interrupts(struct iwl_priv *priv)
+static inline void __iwl_disable_interrupts(struct iwl_priv *priv)
{
clear_bit(STATUS_INT_ENABLED, &priv->status);
@@ -4427,6 +4435,13 @@ static inline void iwl_disable_interrupts(struct iwl_priv *priv)
iwl_flush32(priv, CSR_INT);
iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
iwl_flush32(priv, CSR_FH_INT_STATUS);
+}
+
+static inline void iwl_disable_interrupts(struct iwl_priv *priv)
+{
+ __iwl_disable_interrupts(priv);
+
+ iwl_synchronize_interrupts(priv);
IWL_DEBUG_ISR("Disabled interrupts\n");
}
@@ -4708,7 +4723,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
IWL_ERROR("Microcode HW error detected. Restarting.\n");
/* Tell the device to stop sending interrupts */
- iwl_disable_interrupts(priv);
+ __iwl_disable_interrupts(priv);
+ IWL_DEBUG_ISR("Disabled interrupts\n");
iwl_irq_handle_error(priv);
@@ -4814,8 +4830,11 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
IWL_WARNING(" with FH_INT = 0x%08x\n", inta_fh);
}
- /* Re-enable all interrupts */
- iwl_enable_interrupts(priv);
+ /* To avoid race when device goes down,
+ * it should be discarded to enable interrupts */
+ if (test_bit(STATUS_INT_ENABLED, &priv->status))
+ /* Re-enable all interrupts */
+ iwl_enable_interrupts(priv);
#ifdef CONFIG_IWLWIFI_DEBUG
if (iwl_debug_level & (IWL_DL_ISR)) {
@@ -4876,8 +4895,10 @@ unplugged:
return IRQ_HANDLED;
none:
- /* re-enable interrupts here since we don't have anything to service. */
- iwl_enable_interrupts(priv);
+ if (test_bit(STATUS_INT_ENABLED, &priv->status))
+ /* re-enable interrupts here since we don't have anything
+ * to service. */
+ iwl_enable_interrupts(priv);
spin_unlock(&priv->lock);
return IRQ_NONE;
}
---
Thanks,
Joonwoo
WARNING: multiple messages have this Message-ID (diff)
From: Joonwoo Park <joonwpark81-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: "Zhu, Yi" <yi.zhu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: "Chatre,
Reinette"
<reinette.chatre-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [ipw3945-devel] [PATCH 2/5] iwlwifi: iwl3945 synchronize interruptand tasklet for down iwlwifi
Date: Mon, 14 Jan 2008 17:35:11 +0900 [thread overview]
Message-ID: <478B1EBF.8030701@gmail.com> (raw)
In-Reply-To: <b25c3fa70801101838o7a71cc60h1c8b8a71624aeff9-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Joonwoo Park wrote:
> 2008/1/11, Chatre, Reinette <reinette.chatre-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>:
>> On Thursday, January 10, 2008 5:25 PM, Joonwoo Park wrote:
>
>> What modification are you considering?
>
> Roughly, I'm considering make synchronize_irq() be moved into
> iwl_disable_interrupts() and fix iwl_irq_tasket not to call
> iwl_disable_interrupts with irq disabled.
> For now iwl_irq_tasklet calls iwl_disable_interrupts() with local irq disabled.
> like this:
>
> static void iwl_irq_tasklet(struct iwl_priv *priv)
> {
> ...
> spin_lock_irqsave(&priv->lock, flags);
>
> ...
> /* Now service all interrupt bits discovered above. */
> if (inta & CSR_INT_BIT_HW_ERR) {
> IWL_ERROR("Microcode HW error detected. Restarting.\n");
>
> /* Tell the device to stop sending interrupts */
> iwl_disable_interrupts(priv);
> ...
> spin_unlock_irqrestore(&priv->lock, flags);
> return;
> }
>
>
After disabling interrupts, it's possible irq & tasklet is pending or running
This patch eleminates races for down iwlwifi
Since synchronize_irq can introduce iwl_irq_tasklet, tasklet_kill
should be called after doing synchronize_irq
To avoid races between iwl_synchronize_irq and iwl_irq_tasklet STATUS_INT_ENABLED
flag is needed.
Signed-off-by: Joonwoo Park <joonwpark81-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
drivers/net/wireless/iwlwifi/iwl3945-base.c | 33 ++++++++++++++++++++++-----
1 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 6e20725..f98cd4f 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4405,6 +4405,14 @@ static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon)
}
#endif
+static void iwl_synchronize_interrupts(struct iwl_priv *priv)
+{
+ synchronize_irq(priv->pci_dev->irq);
+ /* synchornize_irq introduces irq_tasklet,
+ * tasklet_kill should be called after doing synchronize_irq */
+ tasklet_kill(&priv->irq_tasklet);
+}
+
static void iwl_enable_interrupts(struct iwl_priv *priv)
{
IWL_DEBUG_ISR("Enabling interrupts\n");
@@ -4413,7 +4421,7 @@ static void iwl_enable_interrupts(struct iwl_priv *priv)
iwl_flush32(priv, CSR_INT_MASK);
}
-static inline void iwl_disable_interrupts(struct iwl_priv *priv)
+static inline void __iwl_disable_interrupts(struct iwl_priv *priv)
{
clear_bit(STATUS_INT_ENABLED, &priv->status);
@@ -4427,6 +4435,13 @@ static inline void iwl_disable_interrupts(struct iwl_priv *priv)
iwl_flush32(priv, CSR_INT);
iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
iwl_flush32(priv, CSR_FH_INT_STATUS);
+}
+
+static inline void iwl_disable_interrupts(struct iwl_priv *priv)
+{
+ __iwl_disable_interrupts(priv);
+
+ iwl_synchronize_interrupts(priv);
IWL_DEBUG_ISR("Disabled interrupts\n");
}
@@ -4708,7 +4723,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
IWL_ERROR("Microcode HW error detected. Restarting.\n");
/* Tell the device to stop sending interrupts */
- iwl_disable_interrupts(priv);
+ __iwl_disable_interrupts(priv);
+ IWL_DEBUG_ISR("Disabled interrupts\n");
iwl_irq_handle_error(priv);
@@ -4814,8 +4830,11 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
IWL_WARNING(" with FH_INT = 0x%08x\n", inta_fh);
}
- /* Re-enable all interrupts */
- iwl_enable_interrupts(priv);
+ /* To avoid race when device goes down,
+ * it should be discarded to enable interrupts */
+ if (test_bit(STATUS_INT_ENABLED, &priv->status))
+ /* Re-enable all interrupts */
+ iwl_enable_interrupts(priv);
#ifdef CONFIG_IWLWIFI_DEBUG
if (iwl_debug_level & (IWL_DL_ISR)) {
@@ -4876,8 +4895,10 @@ unplugged:
return IRQ_HANDLED;
none:
- /* re-enable interrupts here since we don't have anything to service. */
- iwl_enable_interrupts(priv);
+ if (test_bit(STATUS_INT_ENABLED, &priv->status))
+ /* re-enable interrupts here since we don't have anything
+ * to service. */
+ iwl_enable_interrupts(priv);
spin_unlock(&priv->lock);
return IRQ_NONE;
}
---
Thanks,
Joonwoo
next prev parent reply other threads:[~2008-01-14 8:35 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-09 11:02 [PATCH 2/5] iwlwifi: iwl3945 synchronize interrupt and tasklet for down iwlwifi Joonwoo Park
2008-01-09 11:02 ` Joonwoo Park
2008-01-10 19:10 ` [ipw3945-devel] [PATCH 2/5] iwlwifi: iwl3945 synchronize interruptand " Chatre, Reinette
2008-01-10 19:10 ` Chatre, Reinette
2008-01-11 1:24 ` Joonwoo Park
2008-01-11 1:24 ` Joonwoo Park
2008-01-11 1:42 ` [ipw3945-devel] " Chatre, Reinette
2008-01-11 2:38 ` Joonwoo Park
2008-01-14 8:35 ` Joonwoo Park [this message]
2008-01-14 8:35 ` Joonwoo Park
2008-01-14 9:42 ` Joonwoo Park
2008-01-15 19:21 ` Chatre, Reinette
2008-01-16 4:15 ` Joonwoo Park
2008-01-16 16:37 ` Chatre, Reinette
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=478B1EBF.8030701@gmail.com \
--to=joonwpark81@gmail.com \
--cc=ipw3945-devel@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=reinette.chatre@intel.com \
--cc=yi.zhu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.