Hi,

The appended patch seems to fix the problem.
With the patch I get

    tarte:~# opcontrol --start
    Using default event: CPU_CLK_UNHALTED:100000:0:1:1
    Using 2.6+ OProfile kernel interface.
    Using log file /var/lib/oprofile/oprofiled.log
    Daemon started.
    Profiler running.

and samples are collected.

I hope this helps,
Jochen
-- 
http://seehuhn.de/
diff -ur oprofile-0.9.2-3/debian/changelog oprofile-0.9.2-3.1/debian/changelog
--- oprofile-0.9.2-3/debian/changelog	2007-02-17 20:05:21.000000000 +0000
+++ oprofile-0.9.2-3.1/debian/changelog	2007-02-17 20:06:27.000000000 +0000
@@ -1,3 +1,11 @@
+oprofile (0.9.2-3.1) unstable; urgency=low
+
+  * Apply the patches from http://lkml.org/lkml/2006/11/22/170
+    and http://lkml.org/lkml/2006/11/22/172 to make oprofile
+    work on newer kernels.
+
+ -- Jochen Voss <[EMAIL PROTECTED]>  Sat, 17 Feb 2007 19:54:00 +0000
+
 oprofile (0.9.2-3) unstable; urgency=low
 
   * Closes: bug#396749 -- FTBFS: no suitably configured kernel include tree
diff -ur oprofile-0.9.2-3/libop/op_alloc_counter.c oprofile-0.9.2-3.1/libop/op_alloc_counter.c
--- oprofile-0.9.2-3/libop/op_alloc_counter.c	2003-10-01 22:53:46.000000000 +0100
+++ oprofile-0.9.2-3.1/libop/op_alloc_counter.c	2007-02-17 20:06:27.000000000 +0000
@@ -12,6 +12,8 @@
  */
 
 #include <stdlib.h>
+#include <ctype.h>
+#include <dirent.h>
 
 #include "op_events.h"
 #include "op_libiberty.h"
@@ -54,7 +56,7 @@
 		list_init(&ctr_arc[i].next);
 		for (j = 0; mask; ++j) {
 			if (mask & (1 << j)) {
-				counter_arc * arc = 
+				counter_arc * arc =
 					xmalloc(sizeof(counter_arc));
 				arc->counter = j;
 				/* we are looping by increasing counter number,
@@ -130,13 +132,13 @@
 		counter_arc const * arc = list_entry(pos, counter_arc, next);
 
 		if (allocated_mask & (1 << arc->counter))
-			return 0;
+			continue;
 
 		counter_map[depth] = arc->counter;
 
 		if (allocate_counter(ctr_arc, max_depth, depth + 1,
-		                     allocated_mask | (1 << arc->counter),
-		                     counter_map))
+				     allocated_mask | (1 << arc->counter),
+				     counter_map))
 			return 1;
 	}
 
@@ -144,14 +146,54 @@
 }
 
 
+/* determine which directories are counter directories
+ */
+static int perfcounterdir(const struct dirent * entry)
+{
+	return (isdigit(entry->d_name[0]));
+}
+
+
+/**
+ * @param mask pointer where to place bit mask of unavailable counters
+ *
+ * return >= 0 number of counters that are available
+ * < 0 could not determine number of counters
+ *
+ */
+static int op_get_counter_mask(u32 * mask)
+{
+	struct dirent **counterlist;
+	int count, i;
+	/* assume nothing is available */
+	u32 available=0;
+
+	count = scandir("/dev/oprofile", &counterlist, perfcounterdir,
+			alphasort);
+	if (count < 0)
+		/* unable to determine bit mask */
+		return -1;
+	/* convert to bit map (0 where counter exists) */
+	for (i=0; i<count; ++i) {
+		available |= 1 << atoi(counterlist[i]->d_name);
+		free(counterlist[i]);
+	}
+	*mask=~available;
+	free(counterlist);
+	return count;
+}
+
 size_t * map_event_to_counter(struct op_event const * pev[], int nr_events,
-                              op_cpu cpu_type)
+			      op_cpu cpu_type)
 {
 	counter_arc_head * ctr_arc;
 	size_t * counter_map;
 	int nr_counters;
+	u32 unavailable_counters = 0;
 
-	nr_counters = op_get_nr_counters(cpu_type);
+	nr_counters = op_get_counter_mask(&unavailable_counters);
+	if (nr_counters < 0)
+		nr_counters = op_get_nr_counters(cpu_type);
 	if (nr_counters < nr_events)
 		return 0;
 
@@ -159,7 +201,8 @@
 
 	counter_map = xmalloc(nr_counters * sizeof(size_t));
 
-	if (!allocate_counter(ctr_arc, nr_events, 0, 0, counter_map)) {
+	if (!allocate_counter(ctr_arc, nr_events, 0, unavailable_counters,
+			      counter_map)) {
 		free(counter_map);
 		counter_map = 0;
 	}

Reply via email to