mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] expand_resource
@ 2003-09-30 21:04 Matthew Wilcox
  2003-09-30 21:27 ` Russell King
  0 siblings, 1 reply; 6+ messages in thread
From: Matthew Wilcox @ 2003-09-30 21:04 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel


Rewrite expand_resource() to be racefree and move it to kernel/resource.c.

Index: linux-2.6/kernel/resource.c
===================================================================
RCS file: /var/cvs/linux-2.6/kernel/resource.c,v
retrieving revision 1.3.2.1
retrieving revision 1.4
diff -u -p -r1.3.2.1 -r1.4
--- linux-2.6/kernel/resource.c	28 Sep 2003 02:27:48 -0000	1.3.2.1
+++ linux-2.6/kernel/resource.c	28 Sep 2003 04:06:24 -0000	1.4
@@ -266,6 +268,53 @@ int allocate_resource(struct resource *r
 		err = -EBUSY;
 	write_unlock(&resource_lock);
 	return err;
+}
+
+/*
+ * Expand an existing resource by size amount.
+ */
+int expand_resource(struct resource *res, unsigned long size,
+			   unsigned long align)
+{
+	unsigned long start, end;
+
+	/* see if we can expand above */
+	end = (res->end + size + align - 1) & ~(align - 1);
+
+	write_lock(&resource_lock);
+	if (res->sibling) {
+		if (res->sibling->start > end)
+			goto end;
+	} else {
+		if (res->parent->end >= end)
+			goto end;
+	}
+
+	/* now try below */
+	start = ((res->start - size + align) & ~(align - 1)) - align;
+
+	if (res->parent->child == res) {
+		if (res->start <= start)
+			goto start;
+	} else {
+		struct resource *prev = res->parent->child;
+		while (prev->sibling != res)
+			prev = prev->sibling;
+		if (prev->end < start)
+			goto start;
+	}
+
+	write_unlock(&resource_lock);
+	return -ENOMEM;
+
+ start:
+	res->start = start;
+	write_unlock(&resource_lock);
+	return 0;
+ end:
+	res->end = end;
+	write_unlock(&resource_lock);
+	return 0;
 }
 
 /*
Index: linux-2.6/drivers/parisc/ccio-dma.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/parisc/ccio-dma.c,v
retrieving revision 1.7.2.1
retrieving revision 1.7
diff -u -p -r1.7.2.1 -r1.7
--- linux-2.6/drivers/parisc/ccio-dma.c	28 Sep 2003 02:27:09 -0000	1.7.2.1
+++ linux-2.6/drivers/parisc/ccio-dma.c	27 Sep 2003 20:03:16 -0000	1.7
@@ -1534,42 +1534,6 @@ static void __init ccio_init_resources(s
 			(unsigned long)&ioc->ioc_hpa->io_io_low_hv);
 }
 
-static int expand_resource(struct resource *res, unsigned long size,
-			   unsigned long align)
-{
-	struct resource *temp_res;
-	unsigned long start = res->start;
-	unsigned long end ;
-
-	/* see if we can expand above */
-	end = (res->end + size + align - 1) & ~(align - 1);;
-	
-	temp_res = __request_region(res->parent, res->end, end - res->end,
-				    "expansion");
-	if(!temp_res) {
-		/* now try below */
-		start = ((res->start - size + align) & ~(align - 1)) - align;
-		end = res->end;
-		temp_res = __request_region(res->parent, start, size,
-					    "expansion");	
-		if(!temp_res) {
-			return -ENOMEM;
-		}
-	} 
-	release_resource(temp_res);
-	temp_res = res->parent;
-	release_resource(res);
-	res->start = start;
-	res->end = end;
-
-	/* This could be caused by some sort of race.  Basically, if
-	 * this tripped something stole the region we just reserved
-	 * and then released to check for expansion */
-	BUG_ON(request_resource(temp_res, res) != 0);
-
-	return 0;
-}
-
 static void expand_ioc_area(struct resource *parent, struct ioc *ioc,
 			    unsigned long size,	unsigned long min,
 			    unsigned long max, unsigned long align)
Index: linux-2.6/include/linux/ioport.h
===================================================================
RCS file: /var/cvs/linux-2.6/include/linux/ioport.h,v
retrieving revision 1.2.2.1
retrieving revision 1.2
diff -u -p -r1.2.2.1 -r1.2
--- linux-2.6/include/linux/ioport.h	28 Sep 2003 02:27:45 -0000	1.2.2.1
+++ linux-2.6/include/linux/ioport.h	27 Sep 2003 20:03:18 -0000	1.2
@@ -97,6 +97,8 @@ extern int allocate_resource(struct reso
 			     void (*alignf)(void *, struct resource *,
 					    unsigned long, unsigned long),
 			     void *alignf_data);
+int expand_resource(struct resource *res, unsigned long size,
+		    unsigned long align);
 
 /* Convenience shorthand with allocation */
 #define request_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name))

-- 
"It's not Hollywood.  War is real, war is primarily not about defeat or
victory, it is about death.  I've seen thousands and thousands of dead bodies.
Do you think I want to have an academic debate on this subject?" -- Robert Fisk

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-10-05 20:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-09-30 21:04 [PATCH] expand_resource Matthew Wilcox
2003-09-30 21:27 ` Russell King
2003-09-30 22:14   ` Matthew Wilcox
2003-09-30 22:33     ` Russell King
2003-10-01 14:25       ` Matthew Wilcox
2003-10-01 17:50         ` Matthias Urlichs

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome