Ok, how about this.  If the simple form of objcache_create is used
    we install simple_objsize and allow M_ZERO.  Otherwise we panic if
    M_ZERO is specified.

    I let the second layer case fall through... if the allocator happens
    to be malloc, then M_ZERO will work.  If it doesn't, then the problem
    will be caught later on when the first layer has cached objects and
    the caller tries to get a new object.  Not perfect but it should catch
    any problems.

                                                -Matt

Index: kern_objcache.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_objcache.c,v
retrieving revision 1.12
diff -u -r1.12 kern_objcache.c
--- kern_objcache.c     20 Nov 2006 22:19:54 -0000      1.12
+++ kern_objcache.c     29 Nov 2006 23:33:00 -0000
@@ -129,6 +129,7 @@
        objcache_alloc_fn       *alloc;
        objcache_free_fn        *free;
        void                    *allocator_args;
+       size_t                  simple_objsize;
 
        SLIST_ENTRY(objcache)   oc_next;
 
@@ -228,6 +229,12 @@
                             null_ctor, null_dtor, NULL,
                             objcache_malloc_alloc, objcache_malloc_free,
                             margs);
+
+       /*
+        * This indicates that we are a simple objcache and allows
+        * objcache_get() calls with M_ZERO.
+        */
+       oc->simple_objsize = objsize;
        return (oc);
 }
 
@@ -264,7 +271,14 @@
        loadedmag = cpucache->loaded_magazine;
        if (MAGAZINE_NOTEMPTY(loadedmag)) {
                obj = loadedmag->objects[--loadedmag->rounds];
+done:
                crit_exit();
+               if (ocflags & M_ZERO) {
+                       if (oc->simple_objsize)
+                               bzero(obj, oc->simple_objsize);
+                       else
+                               panic("objcache_get(): M_ZERO illegal here");
+               }
                return (obj);
        }
 
@@ -275,8 +289,7 @@
                swap(cpucache->loaded_magazine, cpucache->previous_magazine);
                loadedmag = cpucache->loaded_magazine;
                obj = loadedmag->objects[--loadedmag->rounds];
-               crit_exit();
-               return (obj);
+               goto done;
        }
 
        /*
@@ -284,6 +297,8 @@
         * move one of the empty ones to the depot.
         *
         * Obtain the depot spinlock.
+        *
+        * NOTE: Beyond this point, M_ZERO is handled via oc->alloc()
         */
        depot = &oc->depot[myclusterid];
        spin_lock_wr(&depot->spin);

Reply via email to