[Linux1394-cvslog] rev 840 - trunk
Brought to you by:
aeb,
bencollins
|
From: SVN U. <ben...@li...> - 2003-03-14 21:57:22
|
Author: bencollins
Date: 2003-03-14 16:56:41 -0500 (Fri, 14 Mar 2003)
New Revision: 840
Modified:
trunk/nodemgr.c
Log:
Handle back-to-back resets better, and fix what appears to be a race in
the generation check. Also handle forced IRM reset better.
Patch from Jim Radford.
Modified: trunk/nodemgr.c
==============================================================================
--- trunk/nodemgr.c (original)
+++ trunk/nodemgr.c 2003-03-14 16:56:43.000000000 -0500
@@ -1455,27 +1455,12 @@
}
-static void nodemgr_node_probe(struct host_info *hi)
+static void nodemgr_node_probe(struct host_info *hi, int generation)
{
int count;
struct hpsb_host *host = hi->host;
struct selfid *sid = (struct selfid *)host->topology_map;
nodeid_t nodeid = LOCAL_BUS;
- unsigned int generation;
-
- /* Pause for 1/4 second, to make sure things settle down. If
- * schedule_timeout returns non-zero, it means we caught a signal
- * and need to return. */
- set_current_state(TASK_INTERRUPTIBLE);
- if (schedule_timeout (HZ/4))
- return;
-
- /* Now get the generation in which the node ID's we collect
- * are valid. During the bus scan we will use this generation
- * for the read transactions, so that if another reset occurs
- * during the scan the transactions will fail instead of
- * returning bogus data. */
- generation = get_hpsb_generation(host);
/* Scan each node on the bus */
for (count = host->selfid_count; count; count--, sid++) {
@@ -1588,6 +1573,29 @@
* happens when we get a bus reset. */
while (!down_interruptible(&hi->reset_sem) &&
!down_interruptible(&nodemgr_serialize)) {
+ unsigned int generation;
+
+ /* Many resets can happen while we are waiting below.
+ * Make sure we respond only to the most recent one. */
+ do {
+ /* Pause for 1/4 second, to make sure things
+ * settle down. If schedule_timeout returns
+ * non-zero, it means we caught a signal and that
+ * we should exit. */
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (schedule_timeout (HZ/4)) {
+ up(&nodemgr_serialize);
+ goto caught_signal;
+ }
+
+ /* Now get the generation in which the node ID's
+ * we collect are valid. During the bus scan we
+ * will use this generation for the read
+ * transactions, so that if another reset occurs
+ * during the scan the transactions will fail
+ * instead of returning bogus data. */
+ generation = get_hpsb_generation(hi->host);
+ } while (!down_trylock(&hi->reset_sem));
if (!nodemgr_check_root_capability(host)) {
/* Do nothing, we are resetting */
@@ -1595,7 +1603,7 @@
continue;
}
- nodemgr_node_probe(hi);
+ nodemgr_node_probe(hi, generation);
nodemgr_do_irm_duties(host);
up(&nodemgr_serialize);
|