[Cbe-oss-dev] [PATCH] OProfile fix call to kzalloc

Bob Nelson rrnelson at linux.vnet.ibm.com
Sat Jun 23 02:21:31 EST 2007


Fix OProfile kernel module to check pointer returned from kzalloc for 
success/failure.  Eliminated unnecessary cast.
Added some better error handling and cleanup in the related area of the 
code.

Signed-off-by: Bob Nelson <rrnelson at us.ibm.com

Index: linux-2.6.21-rc7/arch/powerpc/oprofile/cell/pr_util.h
===================================================================
--- linux-2.6.21-rc7.orig/arch/powerpc/oprofile/cell/pr_util.h
+++ linux-2.6.21-rc7/arch/powerpc/oprofile/cell/pr_util.h
@@ -70,7 +70,7 @@ void vma_map_free(struct vma_to_fileoffs
  * Entry point for SPU profiling.
  * cycles_reset is the SPU_CYCLES count value specified by the user.
  */
-void start_spu_profiling(unsigned int cycles_reset);
+int start_spu_profiling(unsigned int cycles_reset);
 
 void stop_spu_profiling(void);
 
Index: linux-2.6.21-rc7/arch/powerpc/oprofile/cell/spu_profiler.c
===================================================================
--- linux-2.6.21-rc7.orig/arch/powerpc/oprofile/cell/spu_profiler.c
+++ linux-2.6.21-rc7/arch/powerpc/oprofile/cell/spu_profiler.c
@@ -22,7 +22,7 @@
 #define TRACE_ARRAY_SIZE 1024
 #define SCALE_SHIFT 14
 
-static u32 * samples;
+static u32 * samples = 0;
 
 static int spu_prof_running = 0;
 static unsigned int profiling_interval = 0;
@@ -192,9 +192,10 @@ static struct hrtimer timer;
  * cycles_reset is the count value specified by the user when
  * setting up OProfile to count SPU_CYCLES.
  */
-void start_spu_profiling(unsigned int cycles_reset) {
+int start_spu_profiling(unsigned int cycles_reset) {
 
     ktime_t kt;
+    int ret = 0;
 
     pr_debug("timer resolution: %lu\n",
          TICK_NSEC);
@@ -204,17 +205,25 @@ void start_spu_profiling(unsigned int cy
     timer.function = profile_spus;
 
     /* Allocate arrays for collecting SPU PC samples */
-    samples = (u32 *) kzalloc(SPUS_PER_NODE *
-                  TRACE_ARRAY_SIZE * sizeof(u32), GFP_KERNEL);
+    samples = kzalloc(SPUS_PER_NODE *
+              TRACE_ARRAY_SIZE * sizeof(u32), GFP_KERNEL);
 
-    spu_prof_running = 1;
-    hrtimer_start(&timer, kt, HRTIMER_MODE_REL);
+    if (unlikely(samples == 0)) {
+        ret = -ENOMEM;
+    } else {
+        spu_prof_running = 1;
+        hrtimer_start(&timer, kt, HRTIMER_MODE_REL);
+    }
+
+        return ret;
 }
 
 void stop_spu_profiling(void)
 {
     spu_prof_running = 0;
     hrtimer_cancel(&timer);
-    kfree(samples);
+    if (samples != 0) {
+        kfree(samples);
+    }
     pr_debug("SPU_PROF: stop_spu_profiling issued\n");
 }
Index: linux-2.6.21-rc7/arch/powerpc/oprofile/op_model_cell.c
===================================================================
--- linux-2.6.21-rc7.orig/arch/powerpc/oprofile/op_model_cell.c
+++ linux-2.6.21-rc7/arch/powerpc/oprofile/op_model_cell.c
@@ -40,6 +40,8 @@
 #include "../platforms/cell/cbe_regs.h"
 #include "cell/pr_util.h"
 
+static void cell_global_stop_spu(void);
+
 /*
  * spu_cycle_reset is the number of cycles between samples.
  * This variable is used for SPU profiling and should ONLY be set
@@ -876,7 +878,7 @@ static struct notifier_block cpu_freq_no
 
 static int cell_global_start_spu(struct op_counter_config *ctr)
 {
-    int subfunc, rtn_value;
+    int subfunc;
     unsigned int lfsr_value;
     int cpu;
     int ret;
@@ -939,19 +941,24 @@ static int cell_global_start_spu(struct
         subfunc = 2;    /* 2 - activate SPU tracing, 3 - deactivate */
 
         /* start profiling */
-        rtn_value = rtas_call(spu_rtas_token, 3, 1, NULL, subfunc,
+        ret = rtas_call(spu_rtas_token, 3, 1, NULL, subfunc,
           cbe_cpu_to_node(cpu), lfsr_value);
 
-        if (unlikely(rtn_value != 0)) {
+        if (unlikely(ret != 0)) {
             printk(KERN_ERR
                    "%s: rtas call ibm,cbe-spu-perftools failed, return 
= %d\n",
-                   __FUNCTION__, rtn_value);
+                   __FUNCTION__, ret);
             rtas_error = -EIO;
             goto out;
         }
     }
 
-    start_spu_profiling(spu_cycle_reset);
+    ret = start_spu_profiling(spu_cycle_reset);
+    if (unlikely(ret != 0)) {
+        cell_global_stop_spu();        /* clean up the PMU/debug bus */
+        rtas_error = ret;
+        goto out;
+    }
 
     oprofile_running = 1;
     return 0;







More information about the cbe-oss-dev mailing list