Re: Realtime Preemption, 2.6.12, Beginners Guide?

From: Paulo Marques
Date: Mon Jul 11 2005 - 08:29:46 EST


Ingo Molnar wrote:
(gdb) ####################################
(gdb) # c013ebf4, stack size: 388 bytes #
(gdb) ####################################
(gdb) 0xc013ebf4 is in __print_symbol (kernel/kallsyms.c:234).

The attached patch fixes this partially by reducing the stack usage by
128 bytes. Compile, boot and run tested and apparently it works fine.

I didn't want to use kmalloc's in there because this function is
probably called from very "hard" contexts (kernel OOPS, stack overflow
dumps, etc.).

The stack usage could be reduced even further (I can do a patch for this
if needed) by changing the function to receive a "prefix" and a "suffix"
string instead of a format string.

The function could then simply do:
printk(prefix);
printk(symbol);
printk(address);
if (module) printk(module name);
printk(suffix);

This way it wouldn't need to allocate a buffer big enough for the whole
string, just for one symbol name (128 bytes).

This is a much more intrusive change however (there are ~65 callers that
would need changing), so I leave the decision to more experienced hackers :)

--
Paulo Marques - www.grupopie.com

It is a mistake to think you can solve any major problems
just with potatoes.
Douglas Adams
--- ./kernel/kallsyms.c.orig 2005-07-11 12:32:32.000000000 +0100
+++ ./kernel/kallsyms.c 2005-07-11 12:34:42.000000000 +0100
@@ -232,23 +232,21 @@ const char *kallsyms_lookup(unsigned lon
/* Replace "%s" in format with address, or returns -errno. */
void __print_symbol(const char *fmt, unsigned long address)
{
- char *modname;
+ char *modname, *bufend;
const char *name;
unsigned long offset, size;
- char namebuf[KSYM_NAME_LEN+1];
char buffer[sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN +
2*(BITS_PER_LONG*3/10) + MODULE_NAME_LEN + 1];

- name = kallsyms_lookup(address, &size, &offset, &modname, namebuf);
+ name = kallsyms_lookup(address, &size, &offset, &modname, buffer);

if (!name)
sprintf(buffer, "0x%lx", address);
else {
+ bufend = strchr(buffer, '\0');
+ bufend += sprintf(bufend, "+%#lx/%#lx", offset, size);
if (modname)
- sprintf(buffer, "%s+%#lx/%#lx [%s]", name, offset,
- size, modname);
- else
- sprintf(buffer, "%s+%#lx/%#lx", name, offset, size);
+ sprintf(bufend, " [%s]", modname);
}
printk(fmt, buffer);
}