Thread: [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); |