John,

Ok, following patch (removing f_state and f_sem cruft) works
on all cases of driver/module internal loadable/external loadable
and handles manual unloads and demand reloads.  I'll let the
one that put the f_state and f_sem cruft in explain why it was
so necessary.

I always find it interesting when code can be fixed by deleting
most of it...

I'm going with this.

--brian

Index: head/mod.c
===================================================================
RCS file: /home/common/cvsroot/LiSnew/head/mod.c,v
retrieving revision 1.1.1.4
diff -U5 -r1.1.1.4 mod.c
--- head/mod.c  22 Nov 2003 23:01:43 -0000      1.1.1.4
+++ head/mod.c  16 Feb 2004 06:04:27 -0000
@@ -451,11 +451,11 @@
        if (list->npush < 0 || list->npush > MAXAPUSH)
                return -1;
        for (i = 0; i < list->npush; ++i) {
                modID_t mod = list->mod[i];
 
-               if (lis_fmod_sw[mod].f_state & LIS_MODSTATE_INITED)
+               if (lis_fmod_sw[mod].f_str != NULL)
                        continue; /* registered */
                return -1; /* not registered or configured */
        }
        return 0;
 }
@@ -635,11 +635,10 @@
 modID_t
 lis_register_strmod(struct streamtab *strtab, const char *name)
 {
        modID_t id = LIS_NULL_MID;
        int     inx ;
-       int     new_entry = 0 ;
 
        if (name == NULL)
                return LIS_NULL_MID;
 
        /* See if the module is already registered */
@@ -656,14 +655,11 @@
        else
        {                               /* not in the table */
            /* Find a free id */
            for (id = 1; id < lis_fmodcnt; ++id)
                if (lis_fmod_sw[id].f_name[0] == 0)
-               {
-                   new_entry = 1 ;
                    break;
-               }
        }
 
        if (id == lis_fmodcnt) {
                if (id == MAX_STRMOD) {
                        printk("Unable to register module \"%s\", "
@@ -673,19 +669,12 @@
                lis_fmodcnt++;
        }
 
        lis_fmod_sw[id].f_str = strtab; /* always save strtab */
 
-       if (!(lis_fmod_sw[id].f_state & LIS_MODSTATE_INITED))
-       {                               /* do this once */
-           lis_fmod_sw[id].f_count = 0;
-           strncpy(lis_fmod_sw[id].f_name, name, LIS_NAMESZ);
-           lis_sem_init(&lis_fmod_sw[id].f_sem, 1) ;
-           if (new_entry && strtab)    /* must be extl module, now loaded */
-               lis_fmod_sw[id].f_state = LIS_MODSTATE_LOADED ;
-           lis_fmod_sw[id].f_state |= LIS_MODSTATE_INITED ;
-       }
+       lis_fmod_sw[id].f_count = 0;
+       strncpy(lis_fmod_sw[id].f_name, name, LIS_NAMESZ);
 
        printk("STREAMS module \"%s\" registered%s, id %d\n",
               lis_fmod_sw[id].f_name,
               strtab == NULL ? " (loadable)" : "",
               id);
@@ -697,14 +686,13 @@
 /* unregister this module
  */
 static int unregister_module(fmodsw_t *slot)
 {
     modID_t id;
-    int            err;
     char    name[LIS_NAMESZ + 1];
 
-    if (!(slot->f_state & LIS_MODSTATE_INITED))
+    if (slot->f_str == NULL)
        return(0) ;                     /* already done */
 
     if (slot->f_count)
     {
        printk("LiS: unregister module \"%s\" f_count=%d -- busy\n",
@@ -713,37 +701,15 @@
     }
 
     strncpy(name, slot->f_name, LIS_NAMESZ);
     id = slot - lis_fmod_sw;
 
-    if ((err = lis_down(&slot->f_sem)) < 0)
-    {
-       printk("LiS: unregister module \"%s\" semaphore-error=%d\n",
-               slot->f_name, err) ;
-       return(err);
-    }
-
-    switch (slot->f_state & LIS_MODSTATE_MASK)
-    {
-    case LIS_MODSTATE_LINKED:
-    case LIS_MODSTATE_LOADED:
-       break ;
-
-    case LIS_MODSTATE_LOADING:
-       lis_up(&slot->f_sem) ;
-       printk("LiS: unregister module \"%s\" -- loading\n", slot->f_name) ;
-       return(-EBUSY) ;
-
-    case LIS_MODSTATE_UNLOADED:
-       slot->f_str = NULL;
-       break ;
-    }
+    slot->f_str = NULL;
+    if (slot->f_objname[0] == '\0')
+       slot->f_name[0] = '\0';
 
     apush_drop_mod(id);
-    lis_up(&slot->f_sem) ;
-    lis_sem_destroy(&slot->f_sem) ;
-    slot->f_state &= ~LIS_MODSTATE_INITED ;
 
     printk("STREAMS module \"%s\" unregistered, id %d\n", name, id);
 
     return 0;
 }
@@ -775,94 +741,69 @@
        return(LIS_NULL_MID) ;
     
     /* Look for the module */
     for (id = lis_fmodcnt; id > 0; id--)
        if (!strcmp(lis_fmod_sw[id].f_name, name))
-           break ;
+           return id; /* found it */
 
-    return (id > 0 ? id : LIS_NULL_MID);
+    return LIS_NULL_MID;
 } /* lis_findmod */
 
 /*  -------------------------------------------------------------------  */
 /* Load module by name into lis_fmod_sw[]
  */
 modID_t
 lis_loadmod(const char *name)
 {
-       int id = lis_findmod(name);
-       int err;
+       int id;
        int configured;
        const char *objname;
 #ifdef LIS_LOADABLE_SUPPORT
        char req[LIS_NAMESZ + 10];
 #endif
+       id = lis_findmod(name);
 
-       if (id == LIS_NULL_MID)
-           return LIS_NULL_MID;
+       if (id != LIS_NULL_MID && lis_fmod_sw[id].f_str != NULL)
+               return id;
 
        /* Find object name of this module */
        objname = name; /* default objname */
        configured = 0;
-       if (lis_fmod_sw[id].f_objname[0])
+       if (id != LIS_NULL_MID && lis_fmod_sw[id].f_objname[0])
        {
            objname = lis_fmod_sw[id].f_objname ;
            configured = 1;
        }
 
-       if ((err = lis_down(&lis_fmod_sw[id].f_sem)) < 0)
-          return(LIS_NULL_MID);
-
-       switch (lis_fmod_sw[id].f_state & LIS_MODSTATE_MASK)
-       {
-       case LIS_MODSTATE_LINKED:
-       case LIS_MODSTATE_LOADED:
-           lis_up(&lis_fmod_sw[id].f_sem) ;
-           return id ;                         /* found and loaded */
-
-       case LIS_MODSTATE_UNLOADED:             /* needs loading */
-           break ;
-
-       case LIS_MODSTATE_LOADING:
-           printk("Bad module state for %s (LOADING)\n", name) ;
-           lis_up(&lis_fmod_sw[id].f_sem) ;
-           return(LIS_NULL_MID);
-       }
-
 #ifdef LIS_LOADABLE_SUPPORT
        /* Ask kerneld to load the module.
         * When the module loads it will call lis_register_strmod()
         * to register itself and will then acquire an available
         * slot in the fmod_sw table.  So if the module can now
         * be found the load succeeded, otherwise not.
         */
        sprintf(req, "streams-%s", objname);
-       lis_fmod_sw[id].f_state &= ~LIS_MODSTATE_MASK ;
-       lis_fmod_sw[id].f_state |= LIS_MODSTATE_LOADING ;
-       if (request_module(req) < 0 || lis_fmod_sw[id].f_str == NULL)
+       request_module(req);
+
+       id = lis_findmod(name);
+       if (id == LIS_NULL_MID || lis_fmod_sw[id].f_str == NULL)
        {
            if (configured)
                printk("Unable to demand load LiS objname %s, "
                       "STREAMS module %s\n ",
                                       objname, (name) ? name : "(null)");
            else
                printk("Unable to demand load STREAMS module %s\n",
                                               (name) ? name : "(null)");
 
-           lis_fmod_sw[id].f_state &= ~LIS_MODSTATE_MASK ;
-           lis_fmod_sw[id].f_state |= LIS_MODSTATE_UNLOADED ;
-           lis_up(&lis_fmod_sw[id].f_sem) ;
            return LIS_NULL_MID;
        }
-
-       lis_fmod_sw[id].f_state &= ~LIS_MODSTATE_MASK ;
-       lis_fmod_sw[id].f_state |= LIS_MODSTATE_LOADED ;
 #else
        printk("Cannot load %s, LIS_LOADABLE_SUPPORT not set\n", name) ;
        id = LIS_NULL_MID;
 #endif
 
-       lis_up(&lis_fmod_sw[id].f_sem) ;
        return id;
 } /* lis_loadmod */
 
 /*  -------------------------------------------------------------------  */
 void
@@ -1274,21 +1215,12 @@
                    printk("Failed to register module \"%s\".\n",
                                       lis_module_config[i].cnf_name);
                    continue ;
                }
 
-               /*
-                * If the module has an object file name then it is
-                * loadable, otherwise it is linked in with LiS.
-                */
                strncpy(lis_fmod_sw[modid].f_objname,
                        lis_module_config[i].cnf_objname, LIS_NAMESZ) ;
-               lis_fmod_sw[i].f_state &= ~LIS_MODSTATE_MASK ;
-               if (lis_fmod_sw[modid].f_objname[0])
-                   lis_fmod_sw[modid].f_state |= LIS_MODSTATE_UNLOADED ;
-               else
-                   lis_fmod_sw[modid].f_state |= LIS_MODSTATE_LINKED ;
        }
 
        for (i = 0; i < DRV_CONFIG_SIZE; ++i) {
            for (j = 0;  j < lis_driver_config[i].cnf_n_majors;  j++) {
                if (lis_register_strdev(lis_driver_config[i].cnf_major[j],
Index: include/sys/LiS/mod.h
===================================================================
RCS file: /home/common/cvsroot/LiSnew/include/sys/LiS/mod.h,v
retrieving revision 1.1.1.3
diff -U5 -r1.1.1.3 mod.h
--- include/sys/LiS/mod.h       22 Nov 2003 23:02:25 -0000      1.1.1.3
+++ include/sys/LiS/mod.h       16 Feb 2004 05:50:20 -0000
@@ -151,28 +151,15 @@
         struct streamtab  *f_str;
        ushort             f_count;     /* open count */
         short              f_flags;     /* module/driver flags */
         char               f_name[LIS_NAMESZ+1];
         char               f_objname[LIS_NAMESZ+1];
-        int               f_state;     /* state of module */
-       lis_semaphore_t    f_sem;       /* to synchronize loading */
 } fmodsw_t;
 
 #define LIS_MODFLG_CLONE   0x0001       /* module is 'clone' */
 #define LIS_MODFLG_FIFO    0x0002       /* module is 'fifo'  */
 #define LIS_MODFLG_REOPEN  0x0004       /* cloned minors can reopen */
-
-/*
- * States
- */
-#define LIS_MODSTATE_MASK      0x0FF   /* isolates state variable */
-#define        LIS_MODSTATE_LINKED     0       /* linked in with LiS */
-#define        LIS_MODSTATE_UNLOADED   1       /* not loaded */
-#define        LIS_MODSTATE_LOADING    2       /* loading */
-#define        LIS_MODSTATE_LOADED     3       /* loaded */
-
-#define LIS_MODSTATE_INITED    0x100   /* initialized */
 
 #endif /* __KERNEL__ */
 
 /*  -------------------------------------------------------------------  */
 /*                              Glob. Vars.                             */


On Sun, 15 Feb 2004, Brian F. G. Bidulock wrote:

> John,
> 
> Well, its really external loadable modules.
> 
> I_PUSH calls lis_loadmod which calls lis_findmod which doesn't
> find anything on name and returns LIS_NULL_MODID which returns
> from lis_loadmod with LIS_NULL_MODID which fails in I_PUSH.
> 
> I didn't have any problems with LiS included loadable modules
> such as timod.
> 
> The above has not worked since 2.16.15 where lines such as:
> 
>       if (id == LIS_NULL_MODID)
>               return LIS_NULL_MODID;
> 
> were added to the top of lis_loadmod.
> 
> I have also found that if f_name is not nulled, problems
> ensue: lis_register_strmod looks for existing registered
> modules on name first, and then never sets new_entry which
> results in incorrect state.
> 
> I have also found that in unregister_module, f_str is never
> nulled.  (It is only nulled for the non-existent case where
> f_state contains LIS_MODSTATE_UNLOADED, which should never
> occur.)  The result is that once loaded, f_str is left as a
> hanging reference after module unloading and the module will
> not reload.
> 
> There are so many bugs in this code I'm beginning to get angry
> about it.  The thing is not going to work without significant
> rework.  The original patch between 2.16.14 and 2.16.15 was a
> very poor one.  It might work for LiS included modules but is
> completely busted for external modules.  It was obviously
> never tested for external modules.
> 
> Also, I don't see any need for the semaphore.  Whoever calls
> request_module already holds the big kernel lock.
> 
> --brian
> 
> 
> On Sun, 15 Feb 2004, John A. Boyd Jr. wrote:
> 
> > Let me try to synchronize my recollection with yours.
> > 
> > I submitted patches to Dave in response to brokenness of module (not
> > driver) loading in 2.16.15, and the patched behavior was evident in
> > 2.16.16.  I.e., my patches were thus not the source of the problems
> > you had, but were apparently a response to the same problem(s) you
> > had and just might not have completely resolved them.  That's pretty
> > much consistent with what I first wrote about this issue last night,
> > i.e., that I tried to fix it but don't know if I did it completely
> > or not.
> > 
> > But you say "in 2.16.15 forward, if the module is not found, it is never
> > loaded."  That's not my recollection at all.  What I found was that in
> > 2.16.15, if a module was not at first found to be loaded, it might
> > actually get loaded, but the attempt would return failure state/status,
> > thus falsely indicating that it didn't load.  But since 2.16.16, my
> > tests have shown that module loading works OK, as far as my tests go
> > (I_PUSH/I_FIND).  I just tested with 2.16.18, and I_PUSH/I_FIND still
> > work OK for me.
> > 
> > As I recall, the person who reported the problem with 2.16.15 was
> > satisfied with the patched behavior of 2.16.16 as well.
> > 
> > -John
> > 
> > Brian F. G. Bidulock wrote:
> > > John,
> > > 
> > > Well, whoever made changes between 2.16.14 and 2.16.15 broke module
> > > ("module" as opposed to "driver") demand loading altogether.  Which
> > > is where I started having problems.
> > > 
> > > In 2.16.14 if lis_findmod could not find a module by name and KMOD
> > > is configured, it would attempt to load module "streams-%s".
> > > 
> > > In 2.16.15 forward, if the module is not found, it is never loaded.
> > > 
> > > I'm patching back to the 2.16.14 lis_findmod.  I'll send a patch in
> > > a little while.
> > > 
> > > --brian
> > > 
> > > On Sun, 15 Feb 2004, John A. Boyd Jr. wrote:
> > > 
> > > 
> > >>Let me restate in the form of a suggestion - instead of clearing
> > >>the name, you might want to look at how to get the state change
> > >>to work, so as to prevent this problem.  The author apparently
> > >>intended clearing the _INITED state flag to have somewhat the
> > >>effect as your clearing of the name...
> > >>
> > >>-John
> > >>
> > >>Brian F. G. Bidulock wrote:
> > >>
> > >>>There is a module loading bug in head/mod.c  When a module
> > >>>is unregistered the f_name component is left alloing lis_findmod
> > >>>to find it an lis_loadmod will attempt to lock a destroyed
> > >>>semaphore.  The problem can be recreated by manually loading a
> > >>>streams kernel module (modprobe), unloading it (rmmod) and then
> > >>>demand loading it (e.g. I_PUSH).  The result is a kernel oops.
> > >>>
> > >>>The patch below fixes the problem (but may break other things).
> > >>>
> > >>>--brian
> > >>>
> > >>>Index: head/mod.c
> > >>>===================================================================
> > >>>RCS file: /home/common/cvsroot/LiSnew/head/mod.c,v
> > >>>retrieving revision 1.1.1.4
> > >>>diff -U3 -r1.1.1.4 mod.c
> > >>>--- head/mod.c   22 Nov 2003 23:01:43 -0000      1.1.1.4
> > >>>+++ head/mod.c   15 Feb 2004 18:05:31 -0000
> > >>>@@ -742,6 +742,7 @@
> > >>>     lis_up(&slot->f_sem) ;
> > >>>     lis_sem_destroy(&slot->f_sem) ;
> > >>>     slot->f_state &= ~LIS_MODSTATE_INITED ;
> > >>>+    slot->f_name[0] = '\0';
> > >>> 
> > >>>     printk("STREAMS module \"%s\" unregistered, id %d\n", name, id);
> > >>> 
> > >>>
> > >>
> > >>_______________________________________________
> > >>Linux-streams mailing list
> > >>[EMAIL PROTECTED]
> > >>http://gsyc.escet.urjc.es/mailman/listinfo/linux-streams
> > > 
> > > 
> > 
> > _______________________________________________
> > Linux-streams mailing list
> > [EMAIL PROTECTED]
> > http://gsyc.escet.urjc.es/mailman/listinfo/linux-streams
> 
> -- 
> Brian F. G. Bidulock    � The reasonable man adapts himself to the �
> [EMAIL PROTECTED]    � world; the unreasonable one persists in  �
> http://www.openss7.org/ � trying  to adapt the  world  to himself. �
>                         � Therefore  all  progress  depends on the �
>                         � unreasonable man. -- George Bernard Shaw �
> _______________________________________________
> Linux-streams mailing list
> [EMAIL PROTECTED]
> http://gsyc.escet.urjc.es/mailman/listinfo/linux-streams

-- 
Brian F. G. Bidulock    � The reasonable man adapts himself to the �
[EMAIL PROTECTED]    � world; the unreasonable one persists in  �
http://www.openss7.org/ � trying  to adapt the  world  to himself. �
                        � Therefore  all  progress  depends on the �
                        � unreasonable man. -- George Bernard Shaw �
_______________________________________________
Linux-streams mailing list
[EMAIL PROTECTED]
http://gsyc.escet.urjc.es/mailman/listinfo/linux-streams

Reply via email to