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

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


Ok, try again without any Windows programs involved this time...

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