--- kerneltop.c.old 2008-12-11 15:34:58.000000000 -0500 +++ kerneltop.c 2008-12-11 16:06:28.000000000 -0500 @@ -62,15 +62,31 @@ # define __NR_perf_counter_open 333 #endif +/* + * Hardware event to monitor via a performance monitoring counter: + */ +struct perf_counter_hw_event { + int64_t type; + + u_int64_t irq_period; + u_int32_t record_type; + + u_int32_t disabled : 1, /* off by default */ + nmi : 1, /* NMI sampling */ + raw : 1, /* raw event type */ + __reserved_1 : 29; + + u_int64_t __reserved_2; +}; + int -perf_counter_open(int hw_event_type, - unsigned int hw_event_period, - unsigned int record_type, +perf_counter_open(struct perf_counter_hw_event *hw_event_uptr, pid_t pid, - int cpu) + int cpu, + int group_fd) { - return syscall(__NR_perf_counter_open, hw_event_type, hw_event_period, - record_type, pid, cpu); + return syscall(__NR_perf_counter_open, hw_event_uptr, + pid, cpu, group_fd); } enum hw_event_types { @@ -82,10 +98,6 @@ PERF_COUNT_BRANCH_MISSES, PERF_COUNT_MAX, - /* - * If this bit is set in the type, then trigger NMI sampling: - */ - PERF_COUNT_NMI = (1 << 30), }; const char *event_types [] = { @@ -616,14 +628,14 @@ { struct pollfd event_array[MAX_NR_CPUS][MAX_COUNTERS]; int fd[MAX_NR_CPUS][MAX_COUNTERS]; - unsigned int nmi_flag = 0; - unsigned int flags, cpu; + unsigned int cpu; int i, counter; uint64_t ip; ssize_t res; #if USE_POLL int ret; #endif + struct perf_counter_hw_event hw_event; process_options(argc, argv); @@ -633,18 +645,18 @@ assert(nr_cpus <= MAX_NR_CPUS); - if (nmi) - nmi_flag |= PERF_COUNT_NMI; - for (i = 0; i < nr_cpus; i++) { for (counter = 0; counter < nr_counters; counter++) { - flags = event_id[counter] | nmi_flag; - cpu = profile_cpu; if (tid == -1 && profile_cpu == -1) cpu = i; - - fd[i][counter] = perf_counter_open(flags, event_count[counter], 1, tid, cpu); + hw_event.type = event_id[counter]; + hw_event.irq_period = event_count[counter]; + hw_event.record_type = 1; + hw_event.nmi = nmi ? 1 : 0; + + fd[i][counter] = perf_counter_open(&hw_event, tid, + cpu, -1 ); if (fd[i][counter] < 0) { printf("kerneltop error: syscall returned with %d (%s)\n", fd[i][counter], strerror(-fd[i][counter]));