Re: Oops+Panic report - quite long

Keith Owens (kaos@ocs.com.au)
Sat, 27 Nov 1999 04:36:19 +1100


On Fri, 26 Nov 1999 17:57:35 +0530,
Raju K V <rajukv@wipinfo.soft.net> wrote:
>While loading my SCSI HBA driver with
>insmod driver.o
>I get the foll never ending Oops+panic. Here is the ksymoops o/p:
>No modules in ksyms, skipping objects
>EIP: 0010:[<c281832d>]
>>>EIP; c281832d <END_OF_CODE+25e7629/????> <=====

When modules fail during initialization they are left in limbo. The
module is loaded, symbols are stored, dependencies are logged but the
kernel refuses to let programs query the module because it is not
marked as running yet. Apply this patch against 2.2.10 and you will be
able to get symbols for modules that fail during initialization.
Reproduce the problem, feed the new log through ksymoops and you should
get symbols this time.

Index: 10.1/kernel/module.c
--- 10.1/kernel/module.c Fri, 05 Feb 1999 09:47:48 +1100 keith (linux-2.2/h/18_module.c 1.1 644)
+++ 10.1(w)/kernel/module.c Sat, 27 Nov 1999 04:29:01 +1100 keith (linux-2.2/h/18_module.c 1.1 644)
@@ -13,6 +13,7 @@
* 0.99.14 version by Jon Tombs <jon@gtex02.us.es>,
* Heavily modified by Bjorn Ekwall <bj0rn@blox.se> May 1994 (C)
* Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
+ * Add MOD_INITIALIZING Keith Owens <kaos@ocs.com.au> Nov 1999
*
* This source is covered by the GNU GPL, the same as all kernel sources.
*/
@@ -329,16 +330,18 @@
put_mod_name(name);

/* Initialize the module. */
+ mod->flags |= MOD_INITIALIZING;
atomic_set(&mod->uc.usecount,1);
if (mod->init && mod->init() != 0) {
atomic_set(&mod->uc.usecount,0);
+ mod->flags &= ~MOD_INITIALIZING;
error = -EBUSY;
goto err0;
}
atomic_dec(&mod->uc.usecount);

/* And set it running. */
- mod->flags |= MOD_RUNNING;
+ mod->flags = (mod->flags | MOD_RUNNING) & ~MOD_INITIALIZING;
error = 0;
goto err0;

@@ -462,7 +465,7 @@

if (mod == &kernel_module)
return -EINVAL;
- if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
+ if (!MOD_CAN_QUERY(mod))
if (put_user(0, ret))
return -EFAULT;
else
@@ -506,7 +509,7 @@

if (mod == &kernel_module)
return -EINVAL;
- if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
+ if (!MOD_CAN_QUERY(mod))
if (put_user(0, ret))
return -EFAULT;
else
@@ -550,7 +553,7 @@
char *strings;
unsigned long *vals;

- if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
+ if (!MOD_CAN_QUERY(mod))
if (put_user(0, ret))
return -EFAULT;
else
@@ -716,7 +719,7 @@
struct module_symbol *msym;
unsigned int j;

- if ((mod->flags & (MOD_RUNNING|MOD_DELETED)) != MOD_RUNNING)
+ if (!MOD_CAN_QUERY(mod))
continue;

/* magic: write module info as a pseudo symbol */
@@ -865,7 +868,10 @@
safe_copy_cstr(" (autoclean)");
if (!(mod->flags & MOD_USED_ONCE))
safe_copy_cstr(" (unused)");
- } else
+ }
+ else if (mod->flags & MOD_INITIALIZING)
+ safe_copy_cstr(" (initializing)");
+ else
safe_copy_cstr(" (uninitialized)");

if ((ref = mod->refs) != NULL) {
@@ -909,7 +915,7 @@
unsigned i;
struct module_symbol *sym;

- if (!(mod->flags & MOD_RUNNING) || (mod->flags & MOD_DELETED))
+ if (!MOD_CAN_QUERY(mod))
continue;

for (i = mod->nsyms, sym = mod->syms; i > 0; --i, ++sym) {
@@ -957,7 +963,7 @@

for (mp = module_list; mp; mp = mp->next) {
if (((modname == NULL) || (strcmp(mp->name, modname) == 0)) &&
- (mp->flags & (MOD_RUNNING | MOD_DELETED)) == MOD_RUNNING &&
+ MOD_CAN_QUERY(mp) &&
(mp->nsyms > 0)) {
for (i = mp->nsyms, sym = mp->syms;
i > 0; --i, ++sym) {
Index: 10.1/include/linux/module.h
--- 10.1/include/linux/module.h Fri, 05 Feb 1999 09:47:48 +1100 keith (linux-2.2/F/51_module.h 1.1 644)
+++ 10.1(w)/include/linux/module.h Sat, 27 Nov 1999 04:29:01 +1100 keith (linux-2.2/F/51_module.h 1.1 644)
@@ -101,6 +101,7 @@
#define MOD_VISITED 8
#define MOD_USED_ONCE 16
#define MOD_JUST_FREED 32
+#define MOD_INITIALIZING 64

/* Values for query_module's which. */

@@ -109,6 +110,9 @@
#define QM_REFS 3
#define QM_SYMBOLS 4
#define QM_INFO 5
+
+/* Can the module be queried? */
+#define MOD_CAN_QUERY(mod) (((mod)->flags & (MOD_RUNNING | MOD_INITIALIZING)) && !((mod)->flags & MOD_DELETED))

/* When struct module is extended, we must test whether the new member
is present in the header received from insmod before we can use it.
Index: 10.1/arch/sparc64/kernel/sys_sparc32.c
--- 10.1/arch/sparc64/kernel/sys_sparc32.c Mon, 14 Jun 1999 17:28:27 +1000 keith (linux-2.2/r/b/30_sys_sparc3 1.3 644)
+++ 10.1(w)/arch/sparc64/kernel/sys_sparc32.c Sat, 27 Nov 1999 04:29:01 +1100 keith (linux-2.2/r/b/30_sys_sparc3 1.3 644)
@@ -3034,7 +3034,7 @@

if (mod->next == NULL)
return -EINVAL;
- if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
+ if (!MOD_CAN_QUERY(mod))
if (put_user(0, ret))
return -EFAULT;
else
@@ -3078,7 +3078,7 @@

if (mod->next == NULL)
return -EINVAL;
- if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
+ if (!MOD_CAN_QUERY(mod))
if (put_user(0, ret))
return -EFAULT;
else
@@ -3122,7 +3122,7 @@
char *strings;
unsigned *vals;

- if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
+ if (!MOD_CAN_QUERY(mod))
if (put_user(0, ret))
return -EFAULT;
else

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/