From 0d046f205fa49c477bbf81b72cd038fb9f7e40d6 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 7 Jul 2015 12:24:37 -0400 Subject: [PATCH] TESTING: add spinlock to module.c rb latch tree Not-Signed-off-by: Mathieu Desnoyers --- kernel/module.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/kernel/module.c b/kernel/module.c index 3e0e197..eb99751 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -181,6 +181,9 @@ static struct mod_tree_root { #define module_addr_min mod_tree.addr_min #define module_addr_max mod_tree.addr_max +/* Fully serialize readers and updates to rb latch tree. */ +static DEFINE_SPINLOCK(test_rb_latch_lock); + static noinline void __mod_tree_insert(struct mod_tree_node *node) { latch_tree_insert(&node->node, &mod_tree.root, &mod_tree_ops); @@ -197,31 +200,50 @@ static void __mod_tree_remove(struct mod_tree_node *node) */ static void mod_tree_insert(struct module *mod) { + unsigned long flags; + + spin_lock_irqsave(&test_rb_latch_lock, flags); mod->mtn_core.mod = mod; mod->mtn_init.mod = mod; __mod_tree_insert(&mod->mtn_core); if (mod->init_size) __mod_tree_insert(&mod->mtn_init); + spin_unlock_irqrestore(&test_rb_latch_lock, flags); } static void mod_tree_remove_init(struct module *mod) { + unsigned long flags; + + spin_lock_irqsave(&test_rb_latch_lock, flags); if (mod->init_size) __mod_tree_remove(&mod->mtn_init); + spin_unlock_irqrestore(&test_rb_latch_lock, flags); } static void mod_tree_remove(struct module *mod) { + unsigned long flags; + + spin_lock_irqsave(&test_rb_latch_lock, flags); __mod_tree_remove(&mod->mtn_core); mod_tree_remove_init(mod); + spin_unlock_irqrestore(&test_rb_latch_lock, flags); } static struct module *mod_find(unsigned long addr) { struct latch_tree_node *ltn; + unsigned long flags; + if (in_nmi()) { + printk(KERN_ERR "mod_find called from NMI\n"); + return NULL; + } + spin_lock_irqsave(&test_rb_latch_lock, flags); ltn = latch_tree_find((void *)addr, &mod_tree.root, &mod_tree_ops); + spin_unlock_irqrestore(&test_rb_latch_lock, flags); if (!ltn) return NULL; -- 1.9.1