netdev
[Top] [All Lists]

Re: modular net drivers

To: Philipp Rumpf <prumpf@xxxxxxxx>
Subject: Re: modular net drivers
From: Andrew Morton <andrewm@xxxxxxxxxx>
Date: Sun, 25 Jun 2000 01:30:50 +1000
Cc: Rusty Russell <rusty@xxxxxxxxxxxxxxxx>, Keith Owens <kaos@xxxxxxxxxx>, Alan Cox <alan@xxxxxxxxxxxxxxxxxxx>, "netdev@xxxxxxxxxxx" <netdev@xxxxxxxxxxx>
References: <20000623164805.AA5BB8154@halfway> <3954262D.60BDEF41@uow.edu.au>, <3954262D.60BDEF41@uow.edu.au> <20000624080106.A25102@fruits.uzix.org>
Sender: owner-netdev@xxxxxxxxxxx
OK. I've flung together a prototype.

It doesn't immediately crash....
--- linux-official/kernel/module.c      Fri Jun  9 23:00:28 2000
+++ linux-akpm/kernel/module.c  Sun Jun 25 01:15:57 2000
@@ -365,17 +365,14 @@
        return res;
 }
 
-asmlinkage long
-sys_delete_module(const char *name_user)
+static long
+do_sys_delete_module(const char *name_user)
 {
        struct module *mod, *next;
        char *name;
        long error;
        int something_changed;
 
-       if (!capable(CAP_SYS_MODULE))
-               return -EPERM;
-
        lock_kernel();
        if (name_user) {
                if ((error = get_mod_name(name_user, &name)) < 0)
@@ -442,6 +439,75 @@
        unlock_kernel();
        return error;
 }
+
+#ifdef CONFIG_SMP
+static volatile int ice_block;
+static spinlock_t freeze_lock = SPIN_LOCK_UNLOCKED;
+
+static int
+antarctica(void *dummy)
+{
+       printk("start antarctica on %d\n", smp_processor_id());
+       while (ice_block)
+               ;
+       printk("stop antarctica on %d\n", smp_processor_id());
+       return 0;
+}
+
+static int
+freeze_other_cpus(void)
+{
+       int cpu, retval;
+
+       if (!spin_trylock(&freeze_lock))
+               return -EAGAIN;
+
+       printk("start freeze_other_cpus()\n");
+       ice_block = 1;
+       for (cpu = 0; cpu < smp_num_cpus - 1; cpu++) {
+               retval = kernel_thread(antarctica, (void *)0, 0);
+               if (retval < 0)
+                       goto out_melt;
+       }
+       printk("continue freeze_other_cpus()\n");
+       return 0;
+out_melt:
+       ice_block = 0;
+       spin_unlock(&freeze_lock);
+       return retval;
+}
+
+static void
+melt_other_cpus(void)
+{
+       printk("melt_other_cpus() starts\n");
+       ice_block = 0;
+       spin_unlock(&freeze_lock);
+       printk("melt_other_cpus() stops\n");
+}
+
+#else  /* CONFIG_SMP */
+
+#define freeze_other_cpus() 0
+#define melt_other_cpus() do { } while (0)
+#endif
+
+asmlinkage long
+sys_delete_module(const char *name_user)
+{
+       long ret;
+
+       if (!capable(CAP_SYS_MODULE))
+               return -EPERM;
+
+       if ((ret = freeze_other_cpus()))
+               return ret;
+
+       ret = do_sys_delete_module(name_user);
+       melt_other_cpus();
+       return ret;
+}
+
 
 /* Query various bits about modules.  */
 
<Prev in Thread] Current Thread [Next in Thread>