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