Skip to contentSkip to conversation

x86: OLPC: speed up device tree creation during boot (v2)

PATCH In review Andres Salomon 5 participants 17 messages Nov 12, 2010 – Dec 23, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 3/3 x86: OLPC: speed up device tree creation during boot (v2)

Calling alloc_bootmem() for tiny chunks of memory over and over is really slow; on an XO-1, it caused the time between when the kernel started booting and when the display came alive (post-lxfb probe) to increase to 44s. This patch optimizes the prom_early_alloc function by calling alloc_bootmem for 4k-sized blocks of memory, and handing out chunks of that to callers. With this patch, the time between kernel load and display initialization decreased to 23s. If there's a better way to do this early in the boot process, please let me know.

(Note: increasing the chunk size to 16k didn't noticably affect boot time, and wasted 9k.)

v2: reorder function as suggested by Grant.

---
 arch/x86/platform/olpc/olpc_dt.c |   27 ++++++++++++++++++++++-----
 1 files changed, 22 insertions(+), 5 deletions(-)
arch/x86/platform/olpc/olpc_dt.c +22 -5
index b8c8ff9..0ab824d 100644
@@ -126,14 +126,31 @@ static unsigned int prom_early_allocated __initdata;
 
 void * __init prom_early_alloc(unsigned long size)
 {
+	static u8 *mem = NULL;
+	static size_t free_mem = 0;
 	void *res;
 
-	res = alloc_bootmem(size);
-	if (res)
-		memset(res, 0, size);
-
-	prom_early_allocated += size;
+	if (free_mem < size) {
+		const size_t chunk_size = max(PAGE_SIZE, size);
+
+		/*
+		 * To mimimize the number of allocations, grab at least 4k of
+		 * memory (that's an arbitrary choice that matches PAGE_SIZE on
+		 * the platforms we care about, and minimizes wasted bootmem)
+		 * and hand off chunks of it to callers.
+		 */
+		res = mem = alloc_bootmem(chunk_size);
+		if (!res)
+			return NULL;
+		prom_early_allocated += chunk_size;
+		memset(res, 0, chunk_size);
+		free_mem = chunk_size;
+	}
 
+	/* allocate from the local cache */
+	free_mem -= size;
+	res = mem;
+	mem += size;
 	return res;
 }
 
Signature · 1 line
1.7.2.3
#1 lore raw

arch/x86/platform/olpc/olpc_dt.c static unsigned int prom_early_allocated __initdata; · line 130

Quoted 10 lines · Andres Salomon
arch/x86/platform/olpc/olpc_dt.c +2 -0
index b8c8ff9..0ab824d 100644
@@ -126,14 +126,31 @@  static unsigned int prom_early_allocated __initdata;
 
 void * __init prom_early_alloc(unsigned long size)
 {
+	static u8 *mem = NULL;
+	static size_t free_mem = 0;

Static variables are implicitly 0 and NULL

Quoted 9 lines
arch/x86/platform/olpc/olpc_dt.c +2 -5
 	void *res;
 
-	res = alloc_bootmem(size);
-	if (res)
-		memset(res, 0, size);
-
-	prom_early_allocated += size;
+	if (free_mem < size) {
+		const size_t chunk_size = max(PAGE_SIZE, size);

arch/x86/platform/olpc/olpc_dt.c static unsigned int prom_early_allocated __initdata; · line 144

Quoted 10 lines
arch/x86/platform/olpc/olpc_dt.c +10 -0
+
+		/*
+		 * To mimimize the number of allocations, grab at least 4k of
+		 * memory (that's an arbitrary choice that matches PAGE_SIZE on
+		 * the platforms we care about, and minimizes wasted bootmem)
+		 * and hand off chunks of it to callers.
+		 */
+		res = mem = alloc_bootmem(chunk_size);
+		if (!res)
+			return NULL;

Oops. If alloc_bootmem fails, we loose mem but don't reset free_mem, so a later call (possibly for a smaller chunk) may return memory starting at NULL.

I suggest just assinging res above and then add mem = res inside this if.

Oh, this is alloc_bootmem not alloc_bootmem_nopainc ... should it be?

arch/x86/platform/olpc/olpc_dt.c static unsigned int prom_early_allocated __initdata; · line 156

Quoted 12 lines
arch/x86/platform/olpc/olpc_dt.c +8 -0
+		prom_early_allocated += chunk_size;
+		memset(res, 0, chunk_size);
+		free_mem = chunk_size;
+	}
 
+	/* allocate from the local cache */
+	free_mem -= size;
+	res = mem;
+	mem += size;
 	return res;
 }
 

milton

#2 lore raw
Quoted 13 lines · On Fri, 12 Nov 2010 01:48:30 -0600 Milton Miller…

arch/x86/platform/olpc/olpc_dt.c static unsigned int prom_early_allocated · line 130

Quoted 10 lines · Andres Salomon
(quoted diff) +0 -0

b/arch/x86/platform/olpc/olpc_dt.c index b8c8ff9..0ab824d 100644

arch/x86/platform/olpc/olpc_dt.c +2 -0
@@ -126,14 +126,31 @@  static unsigned int prom_early_allocated
 __initdata; 
 void * __init prom_early_alloc(unsigned long size)
 {
+	static u8 *mem = NULL;
+	static size_t free_mem = 0;

Static variables are implicitly 0 and NULL

That's true for global static variables; is it also true for static variables that are local to a function?

Quoted 19 lines
Quoted 19 lines
arch/x86/platform/olpc/olpc_dt.c +5 -5
 	void *res;
 
-	res = alloc_bootmem(size);
-	if (res)
-		memset(res, 0, size);
-
-	prom_early_allocated += size;
+	if (free_mem < size) {
+		const size_t chunk_size = max(PAGE_SIZE, size);
+
+		/*
+		 * To mimimize the number of allocations, grab at

least 4k of

arch/x86/platform/olpc/olpc_dt.c +1 -0
+		 * memory (that's an arbitrary choice that matches

PAGE_SIZE on

arch/x86/platform/olpc/olpc_dt.c +1 -0
+		 * the platforms we care about, and minimizes

wasted bootmem)

arch/x86/platform/olpc/olpc_dt.c +1 -0
+		 * and hand off chunks of it to callers.
Quoted 8 lines

arch/x86/platform/olpc/olpc_dt.c static unsigned int prom_early_allocated __initdata; · line 144

Quoted 4 lines
arch/x86/platform/olpc/olpc_dt.c +4 -0
+		 */
+		res = mem = alloc_bootmem(chunk_size);
+		if (!res)
+			return NULL;

Oops. If alloc_bootmem fails, we loose mem but don't reset free_mem, so a later call (possibly for a smaller chunk) may return memory starting at NULL.

You're right, good catch. Thanks!

Quoted 6 lines

I suggest just assinging res above and then add mem = res inside this if.

Oh, this is alloc_bootmem not alloc_bootmem_nopainc ... should it be?

Currently, nothing in drivers/of/pdt.c actually checks alloc_bootmem results.. so we're panicking whether we like it or not. It would be good to actually handle memory failures gracefully and not oops (the DT certainly isn't essential to booting in OLPC's case), but that's a separate patch (series).

Quoted 14 lines

arch/x86/platform/olpc/olpc_dt.c static unsigned int prom_early_allocated __initdata; · line 155

Quoted 12 lines
arch/x86/platform/olpc/olpc_dt.c +8 -0
+		prom_early_allocated += chunk_size;
+		memset(res, 0, chunk_size);
+		free_mem = chunk_size;
+	}
 
+	/* allocate from the local cache */
+	free_mem -= size;
+	res = mem;
+	mem += size;
 	return res;
 }

milton

#3 lore raw
Quoted 17 lines · Andres Salomon
Quoted 13 lines · On Fri, 12 Nov 2010 01:48:30 -0600 Milton Miller <[email protected]> wrote:

arch/x86/platform/olpc/olpc_dt.c static unsigned int prom_early_allocated · line 130

Quoted 10 lines · Andres Salomon
(quoted diff) +0 -0

b/arch/x86/platform/olpc/olpc_dt.c index b8c8ff9..0ab824d 100644

arch/x86/platform/olpc/olpc_dt.c +2 -0
@@ -126,14 +126,31 @@  static unsigned int prom_early_allocated
 __initdata; 
 void * __init prom_early_alloc(unsigned long size)
 {
+	static u8 *mem = NULL;
+	static size_t free_mem = 0;

Static variables are implicitly 0 and NULL

Quoted 2 lines

That's true for global static variables; is it also true for static variables that are local to a function?

It is the same allocation and initialization wise - just not visible to functions outside this one.

It's being frowned upon btw, because it's easy to overlook (and for other reasons) - please dont use statics inside functions - please put them in front of the function or further up into file scope.

Ingo

#4 lore raw
Quoted 5 lines · Ingo Molnar

It's being frowned upon btw, because it's easy to overlook (and for other reasons) - please dont use statics inside functions - please put them in front of the function or further up into file scope.

What? What is wrong with static variables in functions? It really doesn't seem to be a good idea to make them file-scope if they don't need to be.

-hpa

Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel.  I don't speak on their behalf.
#5 lore raw
Quoted 2 lines · H. Peter Anvin

What? What is wrong with static variables in functions? It really doesn't seem to be a good idea to make them file-scope if they don't need to be.

They are very easy to overlook and mix up with regular stack variables and i've seen (and introduced myself) a number of bugs due to them.

They also often are used in buggy ways (with SMP not taken into consideration), so overlooking them during review compounds their negative effects. Putting them in front of the function isnt a big deal in exchange.

There are people who never overlook them (like yourself), but my brain is wired up differently.

Thanks,

Ingo

#6 lore raw
Quoted 9 lines · Ingo Molnar
Quoted 2 lines · H. Peter Anvin

What? What is wrong with static variables in functions? It really doesn't seem to be a good idea to make them file-scope if they don't need to be.

They are very easy to overlook and mix up with regular stack variables and i've seen (and introduced myself) a number of bugs due to them.

Quoted 7 lines

They also often are used in buggy ways (with SMP not taken into consideration), so overlooking them during review compounds their negative effects. Putting them in front of the function isnt a big deal in exchange.

There are people who never overlook them (like yourself), but my brain is wired up differently.

However, I have to vehemently object to putting them in a wider scope than is otherwise necessary. I agree that static variables should be used sparsely if at all (there really are vary few uses of them that are valid), but putting them in a larger scope screams "I'm used in more than one function", and that is *not* a good thing.

-hpa

Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel.  I don't speak on their behalf.
#7 lore raw

PATCH 3/3 x86: OLPC: speed up device tree creation during boot (v3)

Calling alloc_bootmem() for tiny chunks of memory over and over is really slow; on an XO-1, it caused the time between when the kernel started booting and when the display came alive (post-lxfb probe) to increase to 44s. This patch optimizes the prom_early_alloc function by calling alloc_bootmem for 4k-sized blocks of memory, and handing out chunks of that to callers. With this patch, the time between kernel load and display initialization decreased to 23s. If there's a better way to do this early in the boot process, please let me know.

(Note: increasing the chunk size to 16k didn't noticably affect boot time, and wasted 9k.)

v3: fix wasted memory buglet found by Milton Miller, and style fixes.
v2: reorder prom_early_alloc as suggested by Grant Likely.

---
 arch/x86/platform/olpc/olpc_dt.c |   28 +++++++++++++++++++++++-----
 1 files changed, 23 insertions(+), 5 deletions(-)
arch/x86/platform/olpc/olpc_dt.c +23 -5
index 7054697..6614ec4 100644
@@ -126,14 +126,32 @@ static unsigned int prom_early_allocated __initdata;
 
 void * __init prom_early_alloc(unsigned long size)
 {
+	static u8 *mem;
+	static size_t free_mem;
 	void *res;
 
-	res = alloc_bootmem(size);
-	if (res)
-		memset(res, 0, size);
-
-	prom_early_allocated += size;
+	if (free_mem < size) {
+		const size_t chunk_size = max(PAGE_SIZE, size);
+
+		/*
+		 * To mimimize the number of allocations, grab at least 4k of
+		 * memory (that's an arbitrary choice that matches PAGE_SIZE on
+		 * the platforms we care about, and minimizes wasted bootmem)
+		 * and hand off chunks of it to callers.
+		 */
+		res = alloc_bootmem(chunk_size);
+		if (!res)
+			return NULL;
+		prom_early_allocated += chunk_size;
+		memset(res, 0, chunk_size);
+		free_mem = chunk_size;
+		mem = res;
+	}
 
+	/* allocate from the local cache */
+	free_mem -= size;
+	res = mem;
+	mem += size;
 	return res;
 }
 
Signature · 1 line
1.7.2.3
#8 lore raw

PATCH 3/3 x86: OLPC: speed up device tree creation during boot (v4)

Calling alloc_bootmem() for tiny chunks of memory over and over is really slow; on an XO-1, it caused the time between when the kernel started booting and when the display came alive (post-lxfb probe) to increase to 44s. This patch optimizes the prom_early_alloc function by calling alloc_bootmem for 4k-sized blocks of memory, and handing out chunks of that to callers. With this patch, the time between kernel load and display initialization decreased to 23s. If there's a better way to do this early in the boot process, please let me know.

(Note: increasing the chunk size to 16k didn't noticably affect boot time, and wasted 9k.)

v4: clarify comment, requested by hpa
v3: fix wasted memory buglet found by Milton Miller, and style fix.
v2: reorder prom_early_alloc as suggested by Grant.

---
 arch/x86/platform/olpc/olpc_dt.c |   28 +++++++++++++++++++++++-----
 1 files changed, 23 insertions(+), 5 deletions(-)
arch/x86/platform/olpc/olpc_dt.c +23 -5
index 7054697..dab8746 100644
@@ -126,14 +126,32 @@ static unsigned int prom_early_allocated __initdata;
 
 void * __init prom_early_alloc(unsigned long size)
 {
+	static u8 *mem;
+	static size_t free_mem;
 	void *res;
 
-	res = alloc_bootmem(size);
-	if (res)
-		memset(res, 0, size);
-
-	prom_early_allocated += size;
+	if (free_mem < size) {
+		const size_t chunk_size = max(PAGE_SIZE, size);
+
+		/*
+		 * To mimimize the number of allocations, grab at least
+		 * PAGE_SIZE of memory (that's an arbitrary choice that's
+		 * fast enough on the platforms we care about while minimizing
+		 * wasted bootmem) and hand off chunks of it to callers.
+		 */
+		res = alloc_bootmem(chunk_size);
+		if (!res)
+			return NULL;
+		prom_early_allocated += chunk_size;
+		memset(res, 0, chunk_size);
+		free_mem = chunk_size;
+		mem = res;
+	}
 
+	/* allocate from the local cache */
+	free_mem -= size;
+	res = mem;
+	mem += size;
 	return res;
 }
 
Signature · 1 line
1.7.2.3
#9 lore raw

[tip:x86/olpc] x86, olpc: Speed up device tree creation during boot

Commit-ID:  b5318d302f8a20eacbbfc01b0ee35b108085a363
Gitweb:     http://git.kernel.org/tip/b5318d302f8a20eacbbfc01b0ee35b108085a363
Author:     Andres Salomon <[email protected]>
AuthorDate: Mon, 29 Nov 2010 23:39:51 +0000
Committer:  H. Peter Anvin <[email protected]>
CommitDate: Wed, 15 Dec 2010 17:11:40 -0800

x86, olpc: Speed up device tree creation during boot

Calling alloc_bootmem() for tiny chunks of memory over and over is really slow; on an XO-1, it caused the time between when the kernel started booting and when the display came alive (post-lxfb probe) to increase to 44s. This patch optimizes the prom_early_alloc function by calling alloc_bootmem for 4k-sized blocks of memory, and handing out chunks of that to callers. With this patch, the time between kernel load and display initialization decreased to 23s. If there's a better way to do this early in the boot process, please let me know.

(Note: increasing the chunk size to 16k didn't noticably affect boot time, and wasted 9k.)

v4: clarify comment, requested by hpa
v3: fix wasted memory buglet found by Milton Miller, and style fix.
v2: reorder prom_early_alloc as suggested by Grant.

LKML-Reference: <[email protected]>

---
 arch/x86/platform/olpc/olpc_dt.c |   28 +++++++++++++++++++++++-----
 1 files changed, 23 insertions(+), 5 deletions(-)
arch/x86/platform/olpc/olpc_dt.c +23 -5
index 7054697..dab8746 100644
@@ -126,14 +126,32 @@ static unsigned int prom_early_allocated __initdata;
 
 void * __init prom_early_alloc(unsigned long size)
 {
+	static u8 *mem;
+	static size_t free_mem;
 	void *res;
 
-	res = alloc_bootmem(size);
-	if (res)
-		memset(res, 0, size);
-
-	prom_early_allocated += size;
+	if (free_mem < size) {
+		const size_t chunk_size = max(PAGE_SIZE, size);
+
+		/*
+		 * To mimimize the number of allocations, grab at least
+		 * PAGE_SIZE of memory (that's an arbitrary choice that's
+		 * fast enough on the platforms we care about while minimizing
+		 * wasted bootmem) and hand off chunks of it to callers.
+		 */
+		res = alloc_bootmem(chunk_size);
+		if (!res)
+			return NULL;
+		prom_early_allocated += chunk_size;
+		memset(res, 0, chunk_size);
+		free_mem = chunk_size;
+		mem = res;
+	}
 
+	/* allocate from the local cache */
+	free_mem -= size;
+	res = mem;
+	mem += size;
 	return res;
 }
 
#10 lore raw
In reply to H. Peter Anvin
Quoted 18 lines · H. Peter Anvin
Quoted 9 lines · Ingo Molnar
Quoted 2 lines · H. Peter Anvin

What? What is wrong with static variables in functions? It really doesn't seem to be a good idea to make them file-scope if they don't need to be.

They are very easy to overlook and mix up with regular stack variables and i've seen (and introduced myself) a number of bugs due to them.

Quoted 7 lines

They also often are used in buggy ways (with SMP not taken into consideration), so overlooking them during review compounds their negative effects. Putting them in front of the function isnt a big deal in exchange.

There are people who never overlook them (like yourself), but my brain is wired up differently.

Quoted 5 lines

However, I have to vehemently object to putting them in a wider scope than is otherwise necessary. I agree that static variables should be used sparsely if at all (there really are vary few uses of them that are valid), but putting them in a larger scope screams "I'm used in more than one function", and that is *not* a good thing.

That's why we sometimes use the (imperfect) compromise to put them in front of that function, not at the top of the file.

Look at the general balance of hardship: very little harm is done (it's not a big deal if a variable is only used in a single function) but having it with local variables can be _really_ harmful - for example i overlooked them when i reviewed this patch. I dont like important details obscured - i like them to be apparent. Again, this is something that some people can parse immediately on the visual level
- me and many others cannot.

Thanks,

Ingo

#11 lore raw
Quoted 29 lines · Ingo Molnar
Quoted 18 lines · H. Peter Anvin
Quoted 9 lines · Ingo Molnar
Quoted 2 lines · H. Peter Anvin

What? What is wrong with static variables in functions? It really doesn't seem to be a good idea to make them file-scope if they don't need to be.

They are very easy to overlook and mix up with regular stack variables and i've seen (and introduced myself) a number of bugs due to them.

Quoted 7 lines

They also often are used in buggy ways (with SMP not taken into consideration), so overlooking them during review compounds their negative effects. Putting them in front of the function isnt a big deal in exchange.

There are people who never overlook them (like yourself), but my brain is wired up differently.

Quoted 5 lines

However, I have to vehemently object to putting them in a wider scope than is otherwise necessary. I agree that static variables should be used sparsely if at all (there really are vary few uses of them that are valid), but putting them in a larger scope screams "I'm used in more than one function", and that is *not* a good thing.

That's why we sometimes use the (imperfect) compromise to put them in front of that function, not at the top of the file.

Quoted 6 lines

Look at the general balance of hardship: very little harm is done (it's not a big deal if a variable is only used in a single function) but having it with local variables can be _really_ harmful - for example i overlooked them when i reviewed this patch. I dont like important details obscured - i like them to be apparent. Again, this is something that some people can parse immediately on the visual level
- me and many others cannot.

What about:

int foo(void)

{
	static int bar;

	struct thing_struct *thing;
	int other_var;
	char *p;

	...
}

I think the visual wrongness of that formatting would be enough for me to stop and look twice. Though I guess it doesn't work if you have few, or no other variables other than the statics to declare.

cheers

_______________________________________________
devicetree-discuss mailing list devicetree-discuss-uLR06cmDAlY/[email protected]
https://lists.ozlabs.org/listinfo/devicetree-discuss

#12 lore raw
Quoted 9 lines · Michael Ellerman
Quoted 7 lines · Ingo Molnar

Look at the general balance of hardship: very little harm is done (it's not a big deal if a variable is only used in a single function) but having it with local variables can be _really_ harmful - for example i overlooked them when i reviewed this patch. I dont like important details obscured - i like them to be apparent. Again, this is something that some people can parse immediately on the visual level
- me and many others cannot.

No, sorry, this sounds like a personal preference that is well out of line with the vast majority of C programmers I've ever come across, not just in the Linux kernel world but outside of it.

Quoted 13 lines

What about:

int foo(void)

{
	static int bar;

	struct thing_struct *thing;
	int other_var;
	char *p;

	...
}
Quoted 4 lines

I think the visual wrongness of that formatting would be enough for me to stop and look twice. Though I guess it doesn't work if you have few, or no other variables other than the statics to declare.

I wouldn't object to a convention like that, but let's bloody well realize that that is a brand new convention, and if this convention is going to stick at all it needs to be made official and put in CodingStyle.

-hpa

Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel.  I don't speak on their behalf.
#13 lore raw
Quoted 13 lines · On Thu, 18 Nov 2010 07:04:04 -0800 "H. Peter Anvin"…
Quoted 11 lines · Michael Ellerman
Quoted 9 lines · Ingo Molnar

Look at the general balance of hardship: very little harm is done (it's not a big deal if a variable is only used in a single function) but having it with local variables can be _really_ harmful - for example i overlooked them when i reviewed this patch. I dont like important details obscured - i like them to be apparent. Again, this is something that some people can parse immediately on the visual level
- me and many others cannot.

Quoted 3 lines

No, sorry, this sounds like a personal preference that is well out of line with the vast majority of C programmers I've ever come across, not just in the Linux kernel world but outside of it.

This is actually one of the reasons I specifically like initialized static variables (inside of functions). Take the following code:

int foo(void)

{
	static char *frob = NULL;
	int p;

	if (frob) {
		...
	}

Upon seeing that and thinking "whoa, how could frob be initialized and then checked?", I realize that it's either a bug or I look back at the initialization and realize that frob is static. It's less obvious (to me) with non-explicit initialization.

#14 lore raw
Quoted 19 lines · Andres Salomon
Quoted 4 lines

No, sorry, this sounds like a personal preference that is well out of line with the vast majority of C programmers I've ever come across, not just in the Linux kernel world but outside of it.

This is actually one of the reasons I specifically like initialized static variables (inside of functions). Take the following code:

int foo(void)

{
	static char *frob = NULL;
	int p;

	if (frob) {
		...
	}
Quoted 4 lines

Upon seeing that and thinking "whoa, how could frob be initialized and then checked?", I realize that it's either a bug or I look back at the initialization and realize that frob is static. It's less obvious (to me) with non-explicit initialization.

I have to agree with this one. In general I dislike relying on an implicit (even well-defined) initialized value; unfortunately we ripped out explicit initializations across the Linux kernel, not due to readability but due to the fact that long-since-obsolete versions of gcc would put explicitly-initialized variables in data rather than bss even if the initial value is zero.

-hpa

Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel.  I don't speak on their behalf.
#15 lore raw
Quoted 25 lines · On Thu, 18 Nov 2010 09:48:59 -0800 "H. Peter Anvin"…
Quoted 19 lines · Andres Salomon
Quoted 4 lines

No, sorry, this sounds like a personal preference that is well out of line with the vast majority of C programmers I've ever come across, not just in the Linux kernel world but outside of it.

This is actually one of the reasons I specifically like initialized static variables (inside of functions). Take the following code:

int foo(void)

{
	static char *frob = NULL;
	int p;

	if (frob) {
		...
	}
Quoted 4 lines

Upon seeing that and thinking "whoa, how could frob be initialized and then checked?", I realize that it's either a bug or I look back at the initialization and realize that frob is static. It's less obvious (to me) with non-explicit initialization.

Quoted 10 lines

I have to agree with this one. In general I dislike relying on an implicit (even well-defined) initialized value; unfortunately we ripped out explicit initializations across the Linux kernel, not due to readability but due to the fact that long-since-obsolete versions of gcc would put explicitly-initialized variables in data rather than bss even if the initial value is zero.

-hpa

Note that I sent another update for this patch the other day (Tuesday). It uses implicit initialization. Some Acks would be awesome if folks are happy w/ the way I've done things.. ;)

Acked-by Chris Mason
#16 lore raw
In reply to Ingo Molnar
Quoted 9 lines · Ingo Molnar
Quoted 5 lines

However, I have to vehemently object to putting them in a wider scope than is otherwise necessary. I agree that static variables should be used sparsely if at all (there really are vary few uses of them that are valid), but putting them in a larger scope screams "I'm used in more than one function", and that is *not* a good thing.

That's why we sometimes use the (imperfect) compromise to put them in front of that function, not at the top of the file.

Quoted 6 lines

Look at the general balance of hardship: very little harm is done (it's not a big deal if a variable is only used in a single function) but having it with local variables can be _really_ harmful - for example i overlooked them when i reviewed this patch. I dont like important details obscured - i like them to be apparent. Again, this is something that some people can parse immediately on the visual level - me and many others cannot.

As an addendum, beyond my own bad experience with them, see below a recent upstream fix that shows the kinds of problems that overlooked function scope statics can cause.

Ingo

------------->

Quoted 1 line

From 3cb50ddf97a0a1ca4c68bc12fa1e727a6b45fbf2 Mon Sep 17 00:00:00 2001

From: Al Viro <[email protected]>
Date: Mon, 20 Dec 2010 15:53:18 +0000
Subject: [PATCH] Fix btrfs b0rkage

Buggered-in: 76dda93c6ae2 ("Btrfs: add snapshot/subvolume destroy ioctl")

---
 fs/btrfs/export.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
fs/btrfs/export.c +1 -1
index 6f04444..659f532 100644
@@ -166,7 +166,7 @@ static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
 static struct dentry *btrfs_get_parent(struct dentry *child)
 {
 	struct inode *dir = child->d_inode;
-	static struct dentry *dentry;
+	struct dentry *dentry;
 	struct btrfs_root *root = BTRFS_I(dir)->root;
 	struct btrfs_path *path;
 	struct extent_buffer *leaf;