Re: owner field in `struct fs'

From: Philipp Rumpf (prumpf@uzix.org)
Date: Sat Jun 24 2000 - 14:28:04 EST


On Sun, Jun 25, 2000 at 02:33:30AM +1000, Rusty Russell wrote:
> That's easy to solve by (as posted on netdev) making sure all CPUs are
> running a `freeze' thread on module removal. If that's *all* it's

Well, all other CPUs. This way we get behaviour very similar to UP wrt
races.

> Philipp Rumpf has offered to supply the patch shortly,

Here it is (it compiles both for UP and SMP, I can't test it on SMP though).

--- linux/kernel/module.c Fri Jun 23 20:17:18 2000
+++ linux-prumpf/kernel/module.c Sat Jun 24 11:53:05 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 atomic_t freeze_count = ATOMIC_INIT(0);
+static volatile int ice_block;
+static spinlock_t freeze_lock = SPIN_LOCK_UNLOCKED;
+
+static int
+antarctica(void *atomic)
+{
+ atomic_inc(&freeze_count);
+ while (ice_block)
+ ;
+ atomic_dec(&freeze_count);
+ return 0;
+}
+
+static int
+freeze_other_cpus(void)
+{
+ int cpu, retval;
+
+ if (!spin_trylock(&freeze_lock))
+ return -EAGAIN;
+
+ 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;
+ }
+
+ while(atomic_read(&freeze_count) != smp_num_cpus - 1);
+ return 0;
+out_melt:
+ ice_block = 0;
+ spin_unlock(&freeze_lock);
+ return retval;
+}
+
+static void
+melt_other_cpus(void)
+{
+ ice_block = 0;
+ while(atomic_read(&freeze_count) != 0); /* this is paranoia */
+ spin_unlock(&freeze_lock);
+}
+
+#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. */
 

-
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/



This archive was generated by hypermail 2b29 : Mon Jun 26 2000 - 21:00:05 EST