From: Kenzo Iwami <k-iwami@cj.jp.nec.com>
To: Auke Kok <auke-jan.h.kok@intel.com>,
Jesse Brandeburg <jesse.brandeburg@intel.com>
Cc: netdev@vger.kernel.org, "Ronciak, John" <john.ronciak@intel.com>
Subject: Re: watchdog timeout panic in e1000 driver
Date: Tue, 20 Feb 2007 18:26:39 +0900 [thread overview]
Message-ID: <45DABECF.5020202@cj.jp.nec.com> (raw)
In-Reply-To: <45375135.5050206@cj.jp.nec.com>
Hi,
I created a patch that uses watchdog_task but fixes the race condition
that occurred in old the e1000 driver.
I've obtained information about the panic caused by the old e1000 driver
using e1000_watchdog_task. According to the crash dump, the panic was
caused by a timer_list whose contents were NULLs. Further trace
information revealed that the function in the timer list was
e1000_watchdog().
This function is registered in timer_list during e1000_watchdog_task.
It seems that e1000_watchdog_task could be called after the adapter is
removed, and freed memory is registered to timer_list.
By looking at the source code, e1000_watchdog_task will be scheduled if
e1000_watchdog is invoked during e1000_remove, after flush_scheduled_work()
is called, but before del_timer_sync() is called in e1000_down().
The attached patch adds back the e1000_watchdog_task(), but it will
prevent the old race condition from happening by deleting e1000_watchdog
from timer_list before flush_scheduled_work() is called.
Please incorporate this patch to e1000 source code.
--
Kenzo Iwami (k-iwami@cj.jp.nec.com)
Signed-off-by: Kenzo Iwami <k-iwami@cj.jp.nec.com>
diff -urpN linux-2.6.20_org/drivers/net/e1000/e1000.h linux-2.6.20_fix/drivers/net/e1000/e1000.h
--- linux-2.6.20_org/drivers/net/e1000/e1000.h 2007-02-05 03:44:54.000000000 +0900
+++ linux-2.6.20_fix/drivers/net/e1000/e1000.h 2007-02-19 09:52:22.000000000 +0900
@@ -268,6 +268,7 @@ struct e1000_adapter {
uint16_t tx_itr;
uint16_t rx_itr;
+ struct work_struct watchdog_task;
struct work_struct reset_task;
uint8_t fc_autoneg;
@@ -355,6 +356,8 @@ struct e1000_adapter {
boolean_t quad_port_a;
unsigned long flags;
uint32_t eeprom_wol;
+ /* Indicates that the adapter is being removed if remove_state==1.*/
+ int remove_state;
};
enum e1000_state_t {
diff -urpN linux-2.6.20_org/drivers/net/e1000/e1000_main.c linux-2.6.20_fix/drivers/net/e1000/e1000_main.c
--- linux-2.6.20_org/drivers/net/e1000/e1000_main.c 2007-02-05 03:44:54.000000000 +0900
+++ linux-2.6.20_fix/drivers/net/e1000/e1000_main.c 2007-02-20 15:14:40.000000000 +0900
@@ -152,6 +152,7 @@ static void e1000_clean_rx_ring(struct e
static void e1000_set_multi(struct net_device *netdev);
static void e1000_update_phy_info(unsigned long data);
static void e1000_watchdog(unsigned long data);
+static void e1000_watchdog_task(struct work_struct *work);
static void e1000_82547_tx_fifo_stall(unsigned long data);
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
@@ -1044,10 +1045,14 @@ e1000_probe(struct pci_dev *pdev,
adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
adapter->tx_fifo_stall_timer.data = (unsigned long) adapter;
+ adapter->remove_state = 0;
+
init_timer(&adapter->watchdog_timer);
adapter->watchdog_timer.function = &e1000_watchdog;
adapter->watchdog_timer.data = (unsigned long) adapter;
+ INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
+
init_timer(&adapter->phy_info_timer);
adapter->phy_info_timer.function = &e1000_update_phy_info;
adapter->phy_info_timer.data = (unsigned long) adapter;
@@ -1219,7 +1224,15 @@ e1000_remove(struct pci_dev *pdev)
#ifdef CONFIG_E1000_NAPI
int i;
#endif
-
+ /* If e1000_watchdog runs between flush_scheduled_work and
+ * del_timer_sync(in e1000_down), e1000_watchdog_task is
+ * called after the adapter is removed. This will cause
+ * freed memory to be registered to timer list and
+ * result in system panic. Delete e1000_watchdog from
+ * timer list to prevent this from happening.
+ */
+ adapter->remove_state = 1;
+ del_timer_sync(&adapter->watchdog_timer);
flush_scheduled_work();
e1000_release_manageability(adapter);
@@ -2555,6 +2568,16 @@ static void
e1000_watchdog(unsigned long data)
{
struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+
+ /* Do the rest outside of interrupt context */
+ schedule_work(&adapter->watchdog_task);
+}
+
+static void
+e1000_watchdog_task(struct work_struct *work)
+{
+ struct e1000_adapter *adapter =
+ container_of(work, struct e1000_adapter, watchdog_task);
struct net_device *netdev = adapter->netdev;
struct e1000_tx_ring *txdr = adapter->tx_ring;
uint32_t link, tctl;
@@ -2724,7 +2747,8 @@ e1000_watchdog(unsigned long data)
e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
/* Reset the timer */
- mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+ if (!adapter->remove_state)
+ mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
}
enum latency_range {
next prev parent reply other threads:[~2007-02-20 9:26 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-10-19 10:19 watchdog timeout panic in e1000 driver Kenzo Iwami
2006-10-19 15:39 ` Auke Kok
[not found] ` <4538BFF2.2040207@cj.jp.nec.com>
2006-10-20 15:51 ` Auke Kok
2006-10-24 9:01 ` Kenzo Iwami
2006-10-24 16:15 ` Auke Kok
2006-10-25 13:41 ` Kenzo Iwami
2006-10-25 15:09 ` Auke Kok
2006-10-26 10:35 ` Kenzo Iwami
2006-10-26 14:34 ` Auke Kok
2006-10-30 11:36 ` Kenzo Iwami
2006-10-30 17:30 ` Auke Kok
2006-10-31 3:22 ` Shaw Vrana
2006-11-01 13:21 ` Kenzo Iwami
2006-11-15 10:33 ` Kenzo Iwami
2006-11-15 16:11 ` Auke Kok
2006-11-16 9:23 ` Kenzo Iwami
2007-02-20 9:26 ` Kenzo Iwami [this message]
2007-02-20 16:10 ` Auke Kok
2007-02-21 5:17 ` Kenzo Iwami
-- strict thread matches above, loose matches on Subject: below --
2006-11-16 17:20 Brandeburg, Jesse
2006-11-21 10:16 ` Kenzo Iwami
2006-12-04 9:14 ` Kenzo Iwami
2006-12-05 0:46 ` Auke Kok
2006-12-12 7:58 ` Kenzo Iwami
2006-12-19 0:13 ` Kenzo Iwami
2007-01-15 9:12 ` Kenzo Iwami
2007-01-15 16:14 ` Auke Kok
2007-01-16 8:42 ` Kenzo Iwami
2007-01-18 9:22 ` Kenzo Iwami
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=45DABECF.5020202@cj.jp.nec.com \
--to=k-iwami@cj.jp.nec.com \
--cc=auke-jan.h.kok@intel.com \
--cc=jesse.brandeburg@intel.com \
--cc=john.ronciak@intel.com \
--cc=netdev@vger.kernel.org \
/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.