tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Modularizing net80211 (was: link_set info needed)



On Fri, 27 Apr 2012, Joerg Sonnenberger wrote:

On Fri, Apr 27, 2012 at 06:34:40AM -0700, Paul Goyette wrote:
On Fri, 27 Apr 2012, Joerg Sonnenberger wrote:

On Fri, Apr 27, 2012 at 05:51:30AM -0700, Paul Goyette wrote:
3. Replacing the use of link_set with direct calls to all of the
  crypto/auth initializers.

I believe this to a noticable regression due to bugs in the module
framework. It should support either link sets or _init sections.
If the latter is supposed to be the way forward, current linkset usage
should be adjusted and an appropiate place in the kernel for calling all
static initializers be found.

Thanks for the feedback.  I am not familiar with the "_init
sections" stuff - can you provide a reference or example?

That's effectively how __attribute__((constructor)) or the corrsponding
C++ functionality is implemented. The necessary clue in userland is
crt*.o, would wouldn't be that hard to adopt for kernel usage.

I took a look at this, at it seems to be fairly straight-forward to allow constructors/destructors in modules. The attached patch will invoke a module's constructors immediately before the xxx_modcmd(INIT) call, and the destructors will be called immediately after the xxx_modcmd(FINI).

This mechanism only works for modules that are "separate" from the kernel (loaded via "boot" or from "filesys"). "builtin" modules still need to use the link_set mechanism.



-------------------------------------------------------------------------
| Paul Goyette     | PGP Key fingerprint:     | E-mail addresses:       |
| Customer Service | FA29 0E3B 35AF E8AE 6651 | paul at whooppee.com    |
| Network Engineer | 0786 F758 55DE 53BA 7731 | pgoyette at juniper.net |
| Kernel Developer |                          | pgoyette at netbsd.org  |
-------------------------------------------------------------------------
Index: kern_module.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_module.c,v
retrieving revision 1.86
diff -u -p -r1.86 kern_module.c
--- kern_module.c       4 Dec 2011 19:24:59 -0000       1.86
+++ kern_module.c       28 Apr 2012 14:20:56 -0000
@@ -98,6 +98,8 @@ static void   module_enqueue(module_t *);
 
 static bool    module_merge_dicts(prop_dictionary_t, const prop_dictionary_t);
 
+static void    module_do_tors(const char *, module_t *);
+
 static void    sysctl_module_setup(void);
 
 /*
@@ -1055,6 +1057,11 @@ module_do_load(const char *name, bool is
                        goto fail;
                }
        }
+       /*
+        * If module has constructors, call them now
+        */
+       module_do_tors(".ctors", mod);
+
        prev_active = module_active;
        module_active = mod;
        error = (*mi->mi_modcmd)(MODULE_CMD_INIT, filedict ? filedict : props);
@@ -1145,6 +1152,11 @@ module_do_unload(const char *name, bool 
                    error);
                return error;
        }
+       /*
+        * If module has destructors, call them
+        */
+       module_do_tors(".dtors", mod);
+
        module_count--;
        TAILQ_REMOVE(&module_list, mod, mod_chain);
        for (i = 0; i < mod->mod_nrequired; i++) {
@@ -1431,3 +1443,26 @@ out:
 
        return !error;
 }
+
+/*
+ * Call the list of contructors/destructors, if any
+ */
+
+typedef void (*tor_func_t)(void);
+
+static void
+module_do_tors(const char *section, module_t *mod)
+{
+       tor_func_t f, *s_addr;
+       size_t s_size;
+
+       if (kobj_find_section(mod->mod_kobj, section, (void **)&s_addr, &s_size)
+                   != 0)
+               return;
+       KASSERT(s_size % sizeof(f) == 0);
+       while (s_size > 0) {
+               f = *(s_addr++);
+               s_size -= sizeof(f);
+               (*f)();
+       }
+}


Home | Main Index | Thread Index | Old Index