On Saturday 15 January 2005 23:01, Andi Kleen wrote:
> > Based on the comment it is understood that suddenly this pointer points
> > to userspace, because the module got unloaded.
> > I wonder why we can rely on the same address now the module got unloaded
> > - we may risk this virtual address is taken over by someone else?
>
> The address is not user space; you would be lying.
>
> Perhaps it's best to get rid of the hack completely. Turn
> kmem_cache_t->name into an array and copy the name instead of storing the
> pointer, then it wouldn't be needed at all.

Those are just bugs from the time before there was kmem_cache_destroy. I 
checked the 2.6.11-rc1-mm1 tree: every kmem_cache_create in modules seems to 
destroyed properly except in decnet, and decnet module unloading currently is 
disabled. The attached patch fixes the decnet case, puts the slab name in a 
static array, and removes the name accessibilty check.

Regards,
-- 
Andreas Gruenbacher <[EMAIL PROTECTED]>
SUSE Labs, SUSE LINUX PRODUCTS GMBH
From: Andreas Gruenbacher <[EMAIL PROTECTED]>
Subject: Missing kmem_cache_destroy()s in decnet; remove dead-slab check

Decnet is not destroying two of the slabs it creates. Put slab names into
struct kmem_cache_s, and remove the name accessibility hack.

Signed-off-by: Andreas Gruenbacher <[EMAIL PROTECTED]>

Index: linux-2.6.11-rc1-mm1/net/decnet/dn_table.c
===================================================================
--- linux-2.6.11-rc1-mm1.orig/net/decnet/dn_table.c
+++ linux-2.6.11-rc1-mm1/net/decnet/dn_table.c
@@ -820,6 +820,7 @@ void __exit dn_fib_table_cleanup(void)
 
        for (i = RT_TABLE_MIN; i <= RT_TABLE_MAX; ++i)
                dn_fib_del_tree(i);
+       kmem_cache_destroy(dn_hash_kmem);
 
        return;
 }
Index: linux-2.6.11-rc1-mm1/net/decnet/dn_route.c
===================================================================
--- linux-2.6.11-rc1-mm1.orig/net/decnet/dn_route.c
+++ linux-2.6.11-rc1-mm1/net/decnet/dn_route.c
@@ -1835,6 +1835,7 @@ void __exit dn_route_cleanup(void)
 {
        del_timer(&dn_route_timer);
        dn_run_flush(0);
+       kmem_cache_destroy(dn_dst_ops.kmem_cachep);
 
        proc_net_remove("decnet_cache");
 }
Index: linux-2.6.11-rc1-mm1/mm/slab.c
===================================================================
--- linux-2.6.11-rc1-mm1.orig/mm/slab.c
+++ linux-2.6.11-rc1-mm1/mm/slab.c
@@ -334,7 +334,7 @@ struct kmem_cache_s {
        void (*dtor)(void *, kmem_cache_t *, unsigned long);
 
 /* 4) cache creation/removal */
-       const char              *name;
+       char                    name[32];
        struct list_head        next;
 
 /* 5) statistics */
@@ -1419,7 +1419,7 @@ next:
                cachep->slabp_cache = kmem_find_general_cachep(slab_size,0);
        cachep->ctor = ctor;
        cachep->dtor = dtor;
-       cachep->name = name;
+       strlcpy(cachep->name, name, sizeof(cachep->name));
 
        /* Don't let CPUs to come and go */
        lock_cpu_hotplug();
@@ -1465,15 +1465,6 @@ next:
                set_fs(KERNEL_DS);
                list_for_each(p, &cache_chain) {
                        kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
-                       char tmp;
-                       /* This happens when the module gets unloaded and 
doesn't
-                          destroy its slab cache and noone else reuses the 
vmalloc
-                          area of the module. Print a warning. */
-                       if (__get_user(tmp,pc->name)) { 
-                               printk("SLAB: cache with size %d has lost its 
name\n", 
-                                       pc->objsize); 
-                               continue; 
-                       }       
                        if (!strcmp(pc->name,name)) { 
                                printk("kmem_cache_create: duplicate cache 
%s\n",name); 
                                up(&cache_chain_sem); 

Reply via email to