[Linux1394-cvslog] rev 842 - trunk
Brought to you by:
aeb,
bencollins
|
From: SVN U. <ben...@li...> - 2003-03-15 06:41:05
|
Author: bencollins
Date: 2003-03-15 01:40:15 -0500 (Sat, 15 Mar 2003)
New Revision: 842
Modified:
trunk/nodemgr.c
Log:
Fix a thinko I introduced causing an oops on >1 host.
Also, add some more locks on host_list to get rid of a race. I can't cause
on oops when plugging/unplugging lots of times now (the last patch for the
1/4 second delay fix also helps).
Modified: trunk/nodemgr.c
==============================================================================
--- trunk/nodemgr.c (original)
+++ trunk/nodemgr.c 2003-03-15 01:40:16.000000000 -0500
@@ -33,7 +33,7 @@
#if 1
#define FW_BUS_ID_FMT "%012Lx"
-#define FW_BUS_ID_ARGS(__hi, __ne) (unsigned long long)__ne->guid & 0xffffffffffff
+#define FW_BUS_ID_ARGS(__hi, __ne) (unsigned long long)(__ne->guid & 0xffffffffffffL)
#else
#define FW_BUS_ID_FMT "%d-" NODE_BUS_FMT
#define FW_BUS_ID_ARGS(__hi, __ne) __hi->id, NODE_BUS_ARGS(__ne->nodeid)
@@ -319,6 +319,8 @@
}
+static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t nodeid);
+
static void nodemgr_update_host_dev_links(struct hpsb_host *host)
{
struct device *dev = &host->device;
@@ -328,11 +330,11 @@
sysfs_remove_link(&dev->kobj, "busmgr_id");
sysfs_remove_link(&dev->kobj, "host_id");
- if ((ne = hpsb_nodeid_get_entry(host, host->irm_id)))
+ if ((ne = find_entry_by_nodeid(host, host->irm_id)))
sysfs_create_link(&dev->kobj, &ne->device.kobj, "irm_id");
- if ((ne = hpsb_nodeid_get_entry(host, host->busmgr_id)))
+ if ((ne = find_entry_by_nodeid(host, host->busmgr_id)))
sysfs_create_link(&dev->kobj, &ne->device.kobj, "busmgr_id");
- if ((ne = hpsb_nodeid_get_entry(host, host->node_id)))
+ if ((ne = find_entry_by_nodeid(host, host->node_id)))
sysfs_create_link(&dev->kobj, &ne->device.kobj, "host_id");
}
@@ -1166,36 +1168,34 @@
#endif /* CONFIG_HOTPLUG */
-static struct host_info *nodemgr_find_host_by_num(int hostnum)
+static int nodemgr_alloc_host_num(void)
{
+ int hostnum = 0;
unsigned long flags;
struct list_head *lh;
- struct host_info *hi = NULL;
spin_lock_irqsave (&host_info_lock, flags);
- list_for_each(lh, &host_info_list) {
- struct host_info *myhi = list_entry(lh, struct host_info, list);
- if (hi->id == hostnum) {
- hi = myhi;
- break;
- }
- }
- spin_unlock_irqrestore (&host_info_lock, flags);
-
- return hi;
-}
+ while (1) {
+ int found = 0;
-static int nodemgr_alloc_host_num(void)
-{
- int hostnum = 0;
+ list_for_each(lh, &host_info_list) {
+ struct host_info *hi = list_entry(lh, struct host_info, list);
+ if (hi->id == hostnum) {
+ found = 1;
+ break;
+ }
+ }
- while (1) {
- if (!nodemgr_find_host_by_num(hostnum))
- return hostnum;
+ if (!found)
+ break;
hostnum++;
}
+
+ spin_unlock_irqrestore (&host_info_lock, flags);
+
+ return hostnum;
}
@@ -1606,11 +1606,13 @@
nodemgr_node_probe(hi, generation);
nodemgr_do_irm_duties(host);
- up(&nodemgr_serialize);
-
/* Update some of our sysfs symlinks */
nodemgr_update_host_dev_links(host);
+
+ up(&nodemgr_serialize);
}
+
+caught_signal:
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_DEBUG ("NodeMgr: Exiting thread for %s", hi->host->driver->name);
#endif
@@ -1720,6 +1722,7 @@
/* Initialize the hostinfo here and start the thread. The
* thread blocks on the reset semaphore until a bus reset
* happens. */
+ memset(hi, 0, sizeof(*hi));
hi->host = host;
INIT_LIST_HEAD(&hi->list);
init_completion(&hi->exited);
@@ -1735,6 +1738,8 @@
sprintf(hi->daemon_name, "knodemgrd_%d", hi->id);
+ spin_lock_irqsave (&host_info_lock, flags);
+
hi->pid = kernel_thread(nodemgr_host_thread, hi,
CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
@@ -1742,11 +1747,12 @@
HPSB_ERR ("NodeMgr: failed to start %s thread for %s",
hi->daemon_name, host->driver->name);
kfree(hi);
+ spin_unlock_irqrestore (&host_info_lock, flags);
return;
}
- spin_lock_irqsave (&host_info_lock, flags);
list_add_tail (&hi->list, &host_info_list);
+
spin_unlock_irqrestore (&host_info_lock, flags);
return;
@@ -1795,7 +1801,6 @@
break;
}
}
- spin_unlock_irqrestore (&host_info_lock, flags);
if (hi) {
if (hi->pid >= 0) {
@@ -1809,6 +1814,8 @@
HPSB_ERR("NodeMgr: host %s does not exist, cannot remove",
host->driver->name);
+ spin_unlock_irqrestore (&host_info_lock, flags);
+
return;
}
|