From: MAEDA Naoaki <maeda.naoaki@jp.fujitsu.com>

I am testing PCI hot-plug in 2.6.2 kernel, but sometimes a struct resource
tree in kernel/resource.c was broken if multiple hot-plug requests are
issued at the same time.

The reason is lots of drivers call release_region() on hot removal, and
__release_region(), which is invoked by release_region() macro, changes the
tree without holding a writer lock for resource_lock.

I think __release_region() must hold a writer lock as well as
__request_region() does.

A following patch fixes the issue in my environment.



---

 kernel/resource.c |    6 ++++++
 1 files changed, 6 insertions(+)

diff -puN kernel/resource.c~release_region-race-fix kernel/resource.c
--- 25/kernel/resource.c~release_region-race-fix	2004-02-11 20:57:20.000000000 -0800
+++ 25-akpm/kernel/resource.c	2004-02-11 20:57:20.000000000 -0800
@@ -475,6 +475,8 @@ void __release_region(struct resource *p
 	p = &parent->child;
 	end = start + n - 1;
 
+	write_lock(&resource_lock);
+
 	for (;;) {
 		struct resource *res = *p;
 
@@ -488,11 +490,15 @@ void __release_region(struct resource *p
 			if (res->start != start || res->end != end)
 				break;
 			*p = res->sibling;
+			write_unlock(&resource_lock);
 			kfree(res);
 			return;
 		}
 		p = &res->sibling;
 	}
+
+	write_unlock(&resource_lock);
+
 	printk(KERN_WARNING "Trying to free nonexistent resource <%08lx-%08lx>\n", start, end);
 }
 

_