All of lore.kernel.org
 help / color / mirror / Atom feed
From: "John W. Linville" <linville@tuxdriver.com>
To: linux-kernel@vger.kernel.org
Cc: netdev@oss.sgi.com, jgarzik@pobox.com, cramerj@intel.com,
	john.ronciak@intel.com, ganesh.venkatesan@intel.com
Subject: [patch 2.6.11] e1000: avoid sleeping in watchdog timer context
Date: Mon, 14 Mar 2005 16:25:15 -0500	[thread overview]
Message-ID: <20050314212510.GA12573@tuxdriver.com> (raw)

Move bulk of e1000_watchdog to a workqueue to make it safe to call
functions which can sleep.

Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
The e1000 driver uses a timer to invoke e1000_watchdog().
e1000_watchdog() calls e1000_check_for_link() which can call
e1000_config_dsp_after_link_change().  This in turn can call
msec_delay().  msec_delay() is, of course, simply a wrapper for
msleep().

Since a timer does not have a process context, sleeping is impossible.
Attempting to do so causes a crash.

The fix is to move the body of e1000_watchdog() to the newly defined
e1000_watchdog_task().  This is invoked via the workqueue interface
from the new version of e1000_watchdog().

 drivers/net/e1000/e1000.h      |    1 +
 drivers/net/e1000/e1000_main.c |   15 +++++++++++++--
 2 files changed, 14 insertions(+), 2 deletions(-)

--- linux-2.6.11/drivers/net/e1000/e1000.h.orig	2005-03-14 16:06:53.000000000 -0500
+++ linux-2.6.11/drivers/net/e1000/e1000.h	2005-03-14 16:16:37.436364543 -0500
@@ -203,6 +203,7 @@ struct e1000_adapter {
 	spinlock_t stats_lock;
 	atomic_t irq_sem;
 	struct work_struct tx_timeout_task;
+	struct work_struct watchdog_task;
 	uint8_t fc_autoneg;
 
 	struct timer_list blink_timer;
--- linux-2.6.11/drivers/net/e1000/e1000_main.c.orig	2005-03-14 16:09:42.991007873 -0500
+++ linux-2.6.11/drivers/net/e1000/e1000_main.c	2005-03-14 16:16:37.438364260 -0500
@@ -142,6 +142,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 e1000_adapter *adapter);
 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);
@@ -574,6 +575,9 @@ e1000_probe(struct pci_dev *pdev,
 	adapter->watchdog_timer.function = &e1000_watchdog;
 	adapter->watchdog_timer.data = (unsigned long) adapter;
 
+	INIT_WORK(&adapter->watchdog_task,
+		(void (*)(void *))e1000_watchdog_task, adapter);
+
 	init_timer(&adapter->phy_info_timer);
 	adapter->phy_info_timer.function = &e1000_update_phy_info;
 	adapter->phy_info_timer.data = (unsigned long) adapter;
@@ -1529,13 +1533,20 @@ e1000_82547_tx_fifo_stall(unsigned long 
 
 /**
  * e1000_watchdog - Timer Call-back
- * @data: pointer to netdev cast into an unsigned long
+ * @data: pointer to adapter cast into an unsigned long
  **/
-
 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 e1000_adapter *adapter)
+{
 	struct net_device *netdev = adapter->netdev;
 	struct e1000_desc_ring *txdr = &adapter->tx_ring;
 	uint32_t link;
-- 
John W. Linville
linville@tuxdriver.com

             reply	other threads:[~2005-03-14 21:27 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-03-14 21:25 John W. Linville [this message]
2005-03-22 20:37 ` [patch 2.6.11] e1000: avoid sleeping in watchdog timer context Jeff Garzik

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=20050314212510.GA12573@tuxdriver.com \
    --to=linville@tuxdriver.com \
    --cc=cramerj@intel.com \
    --cc=ganesh.venkatesan@intel.com \
    --cc=jgarzik@pobox.com \
    --cc=john.ronciak@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@oss.sgi.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.