]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dtrace: fix cyclic allocation
authorKris Van Hees <kris.van.hees@oracle.com>
Thu, 3 Nov 2011 17:59:00 +0000 (13:59 -0400)
committerNick Alcock <nick.alcock@oracle.com>
Mon, 29 Jun 2015 21:39:56 +0000 (22:39 +0100)
Fixed the allocation of cyclics that was the cause of some obscure crashes
during the testsuite execution.  Problem was that cyclics were being allocated
in chunks, with a new array being allocated as (prev-size + chink-size), and
then the old entries being copied over.  However, because the hrtimer struct is
embedded in the cyclic struct, this meant that hrtimer structs were being moved
outside the hrtimer code.

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
kernel/dtrace/dtrace_os.c

index c97d2202bc895297043dad1a6b58f61f00fbf7f2..d8b5f088785c8f34d4e0c2b18e07243f535e0bc5 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/dtrace_os.h>
 #include <linux/hrtimer.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <asm/stacktrace.h>
 
@@ -53,55 +54,6 @@ union cyclic {
        cyclic_t                *nxt;
 };
 
-static cyclic_t                *cyc_arr = NULL;
-static cyclic_t                *cyc_flst = NULL;
-static unsigned long   cyc_size = 0;
-
-#define CHUNKSIZE      12
-
-DEFINE_MUTEX(cyclic_lock);
-
-/*
- * Find a free cyclic slot.  Returns NULL in out-of-memory conditions.
- */
-static cyclic_t *cyc_alloc(void)
-{
-       cyclic_t        *np;
-
-       mutex_lock(&cyclic_lock);
-
-       if (cyc_flst == NULL) {
-               unsigned long   nsize = cyc_size + CHUNKSIZE;
-               unsigned long   idx = nsize;
-               cyclic_t        *narr;
-
-               if (!(narr = (cyclic_t *)vmalloc(nsize * sizeof(cyclic_t)))) {
-                       mutex_unlock(&cyclic_lock);
-                       return NULL;
-               }
-
-               memcpy(narr, cyc_arr, cyc_size * sizeof(cyclic_t));
-               vfree(cyc_arr);
-               cyc_arr = narr;
-
-               idx = nsize;
-               cyc_flst = &cyc_arr[cyc_size];
-               cyc_arr[--idx].nxt = NULL;
-               while (idx-- > cyc_size)
-                       cyc_arr[idx].nxt = &cyc_arr[idx + 1];
-
-               cyc_size = nsize;
-       }
-
-       np = cyc_flst;
-       cyc_flst = cyc_flst->nxt;
-
-       mutex_unlock(&cyclic_lock);
-
-       np->cyc.hdlr.cyh_func = NULL;
-       return np;
-}
-
 static enum hrtimer_restart cyclic_fire_fn(struct hrtimer *timr)
 {
        cyclic_t        *cyc = container_of(timr, cyclic_t, cyc.timr);
@@ -124,7 +76,7 @@ cyclic_id_t cyclic_add(cyc_handler_t *hdlr, cyc_time_t *when)
        if (hdlr == NULL || when == NULL)
                return CYCLIC_NONE;
 
-       if ((cyc = cyc_alloc()) == NULL)
+       if ((cyc = kmalloc(sizeof(cyclic_t), GFP_KERNEL)) == NULL)
                return CYCLIC_NONE;
 
        cyc->cyc.when = *when;
@@ -165,12 +117,7 @@ void cyclic_remove(cyclic_id_t id)
 
        hrtimer_cancel(&cyc->cyc.timr);
 
-       mutex_lock(&cyclic_lock);
-
-       cyc->nxt = cyc_flst;
-       cyc_flst = cyc;
-
-       mutex_unlock(&cyclic_lock);
+       kfree(cyc);
 }
 EXPORT_SYMBOL(cyclic_remove);