Merge branch 'tracing-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 11 Sep 2009 20:24:03 +0000 (13:24 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 11 Sep 2009 20:24:03 +0000 (13:24 -0700)
* 'tracing-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (105 commits)
  ring-buffer: only enable ring_buffer_swap_cpu when needed
  ring-buffer: check for swapped buffers in start of committing
  tracing: report error in trace if we fail to swap latency buffer
  tracing: add trace_array_printk for internal tracers to use
  tracing: pass around ring buffer instead of tracer
  tracing: make tracing_reset safe for external use
  tracing: use timestamp to determine start of latency traces
  tracing: Remove mentioning of legacy latency_trace file from documentation
  tracing/filters: Defer pred allocation, fix memory leak
  tracing: remove users of tracing_reset
  tracing: disable buffers and synchronize_sched before resetting
  tracing: disable update max tracer while reading trace
  tracing: print out start and stop in latency traces
  ring-buffer: disable all cpu buffers when one finds a problem
  ring-buffer: do not count discarded events
  ring-buffer: remove ring_buffer_event_discard
  ring-buffer: fix ring_buffer_read crossing pages
  ring-buffer: remove unnecessary cpu_relax
  ring-buffer: do not swap buffers during a commit
  ring-buffer: do not reset while in a commit
  ...

1  2 
arch/s390/Kconfig
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/x86/Kconfig
include/linux/perf_counter.h
include/trace/events/sched.h
kernel/kmod.c
tools/perf/util/parse-events.c

diff --combined arch/s390/Kconfig
@@@ -84,7 -84,7 +84,7 @@@ config S39
        select HAVE_FUNCTION_TRACER
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_FTRACE_MCOUNT_RECORD
-       select HAVE_FTRACE_SYSCALLS
+       select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_DEFAULT_NO_SPIN_MUTEXES
@@@ -95,6 -95,7 +95,6 @@@
        select HAVE_ARCH_TRACEHOOK
        select INIT_ALL_POSSIBLE
        select HAVE_PERF_COUNTERS
 -      select GENERIC_ATOMIC64 if !64BIT
  
  config SCHED_OMIT_FRAME_POINTER
        bool
@@@ -480,6 -481,13 +480,6 @@@ config CMM_IUC
          Select this option to enable the special message interface to
          the cooperative memory management.
  
 -config PAGE_STATES
 -      bool "Unused page notification"
 -      help
 -        This enables the notification of unused pages to the
 -        hypervisor. The ESSA instruction is used to do the states
 -        changes between a page that has content and the unused state.
 -
  config APPLDATA_BASE
        bool "Linux - VM Monitor Stream, base infrastructure"
        depends on PROC_FS
diff --combined arch/s390/kernel/entry.S
@@@ -54,7 -54,7 +54,7 @@@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF
  _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
                 _TIF_MCCK_PENDING)
  _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
-               _TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8)
+               _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8)
  
  STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
  STACK_SIZE  = 1 << STACK_SHIFT
@@@ -278,8 -278,7 +278,8 @@@ sysc_return
        bnz     BASED(sysc_work)  # there is work to do (signals etc.)
  sysc_restore:
  #ifdef CONFIG_TRACE_IRQFLAGS
 -      la      %r1,BASED(sysc_restore_trace_psw)
 +      la      %r1,BASED(sysc_restore_trace_psw_addr)
 +      l       %r1,0(%r1)
        lpsw    0(%r1)
  sysc_restore_trace:
        TRACE_IRQS_CHECK
@@@ -290,15 -289,10 +290,15 @@@ sysc_leave
  sysc_done:
  
  #ifdef CONFIG_TRACE_IRQFLAGS
 +sysc_restore_trace_psw_addr:
 +      .long sysc_restore_trace_psw
 +
 +      .section .data,"aw",@progbits
        .align  8
        .globl  sysc_restore_trace_psw
  sysc_restore_trace_psw:
        .long   0, sysc_restore_trace + 0x80000000
 +      .previous
  #endif
  
  #
@@@ -612,8 -606,7 +612,8 @@@ io_return
        bnz     BASED(io_work)          # there is work to do (signals etc.)
  io_restore:
  #ifdef CONFIG_TRACE_IRQFLAGS
 -      la      %r1,BASED(io_restore_trace_psw)
 +      la      %r1,BASED(io_restore_trace_psw_addr)
 +      l       %r1,0(%r1)
        lpsw    0(%r1)
  io_restore_trace:
        TRACE_IRQS_CHECK
@@@ -624,15 -617,10 +624,15 @@@ io_leave
  io_done:
  
  #ifdef CONFIG_TRACE_IRQFLAGS
 +io_restore_trace_psw_addr:
 +      .long io_restore_trace_psw
 +
 +      .section .data,"aw",@progbits
        .align  8
        .globl  io_restore_trace_psw
  io_restore_trace_psw:
        .long   0, io_restore_trace + 0x80000000
 +      .previous
  #endif
  
  #
@@@ -57,7 -57,7 +57,7 @@@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF
  _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
                 _TIF_MCCK_PENDING)
  _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
-               _TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8)
+               _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8)
  
  #define BASED(name) name-system_call(%r13)
  
@@@ -284,12 -284,10 +284,12 @@@ sysc_leave
  sysc_done:
  
  #ifdef CONFIG_TRACE_IRQFLAGS
 +      .section .data,"aw",@progbits
        .align  8
        .globl sysc_restore_trace_psw
  sysc_restore_trace_psw:
        .quad   0, sysc_restore_trace
 +      .previous
  #endif
  
  #
@@@ -597,12 -595,10 +597,12 @@@ io_leave
  io_done:
  
  #ifdef CONFIG_TRACE_IRQFLAGS
 +      .section .data,"aw",@progbits
        .align  8
        .globl io_restore_trace_psw
  io_restore_trace_psw:
        .quad   0, io_restore_trace
 +      .previous
  #endif
  
  #
diff --combined arch/x86/Kconfig
@@@ -38,7 -38,7 +38,7 @@@ config X8
        select HAVE_FUNCTION_GRAPH_FP_TEST
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
-       select HAVE_FTRACE_SYSCALLS
+       select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_KVM
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_TRACEHOOK
@@@ -586,6 -586,7 +586,6 @@@ config GART_IOMM
        bool "GART IOMMU support" if EMBEDDED
        default y
        select SWIOTLB
 -      select AGP
        depends on X86_64 && PCI
        ---help---
          Support for full DMA access of devices with 32bit memory access only
@@@ -216,7 -216,6 +216,7 @@@ struct perf_counter_attr 
  #define PERF_COUNTER_IOC_REFRESH      _IO ('$', 2)
  #define PERF_COUNTER_IOC_RESET                _IO ('$', 3)
  #define PERF_COUNTER_IOC_PERIOD               _IOW('$', 4, u64)
 +#define PERF_COUNTER_IOC_SET_OUTPUT   _IO ('$', 5)
  
  enum perf_counter_ioc_flags {
        PERF_IOC_FLAG_GROUP             = 1U << 0,
@@@ -416,9 -415,6 +416,9 @@@ enum perf_callchain_context 
        PERF_CONTEXT_MAX                = (__u64)-4095,
  };
  
 +#define PERF_FLAG_FD_NO_GROUP (1U << 0)
 +#define PERF_FLAG_FD_OUTPUT   (1U << 1)
 +
  #ifdef __KERNEL__
  /*
   * Kernel-internal data types and definitions:
@@@ -540,7 -536,6 +540,7 @@@ struct perf_counter 
        struct list_head                sibling_list;
        int                             nr_siblings;
        struct perf_counter             *group_leader;
 +      struct perf_counter             *output;
        const struct pmu                *pmu;
  
        enum perf_counter_active_state  state;
@@@ -766,6 -761,8 +766,8 @@@ extern int sysctl_perf_counter_mlock
  extern int sysctl_perf_counter_sample_rate;
  
  extern void perf_counter_init(void);
+ extern void perf_tpcounter_event(int event_id, u64 addr, u64 count,
+                                void *record, int entry_size);
  
  #ifndef perf_misc_flags
  #define perf_misc_flags(regs) (user_mode(regs) ? PERF_EVENT_MISC_USER : \
@@@ -94,6 -94,7 +94,7 @@@ TRACE_EVENT(sched_wakeup
                __field(        pid_t,  pid                     )
                __field(        int,    prio                    )
                __field(        int,    success                 )
+               __field(        int,    cpu                     )
        ),
  
        TP_fast_assign(
                __entry->pid            = p->pid;
                __entry->prio           = p->prio;
                __entry->success        = success;
+               __entry->cpu            = task_cpu(p);
        ),
  
-       TP_printk("task %s:%d [%d] success=%d",
+       TP_printk("task %s:%d [%d] success=%d [%03d]",
                  __entry->comm, __entry->pid, __entry->prio,
-                 __entry->success)
+                 __entry->success, __entry->cpu)
  );
  
  /*
@@@ -125,6 -127,7 +127,7 @@@ TRACE_EVENT(sched_wakeup_new
                __field(        pid_t,  pid                     )
                __field(        int,    prio                    )
                __field(        int,    success                 )
+               __field(        int,    cpu                     )
        ),
  
        TP_fast_assign(
                __entry->pid            = p->pid;
                __entry->prio           = p->prio;
                __entry->success        = success;
+               __entry->cpu            = task_cpu(p);
        ),
  
-       TP_printk("task %s:%d [%d] success=%d",
+       TP_printk("task %s:%d [%d] success=%d [%03d]",
                  __entry->comm, __entry->pid, __entry->prio,
-                 __entry->success)
+                 __entry->success, __entry->cpu)
  );
  
  /*
@@@ -340,101 -344,6 +344,101 @@@ TRACE_EVENT(sched_signal_send
                  __entry->sig, __entry->comm, __entry->pid)
  );
  
 +/*
 + * XXX the below sched_stat tracepoints only apply to SCHED_OTHER/BATCH/IDLE
 + *     adding sched_stat support to SCHED_FIFO/RR would be welcome.
 + */
 +
 +/*
 + * Tracepoint for accounting wait time (time the task is runnable
 + * but not actually running due to scheduler contention).
 + */
 +TRACE_EVENT(sched_stat_wait,
 +
 +      TP_PROTO(struct task_struct *tsk, u64 delay),
 +
 +      TP_ARGS(tsk, delay),
 +
 +      TP_STRUCT__entry(
 +              __array( char,  comm,   TASK_COMM_LEN   )
 +              __field( pid_t, pid                     )
 +              __field( u64,   delay                   )
 +      ),
 +
 +      TP_fast_assign(
 +              memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
 +              __entry->pid    = tsk->pid;
 +              __entry->delay  = delay;
 +      )
 +      TP_perf_assign(
 +              __perf_count(delay);
 +      ),
 +
 +      TP_printk("task: %s:%d wait: %Lu [ns]",
 +                      __entry->comm, __entry->pid,
 +                      (unsigned long long)__entry->delay)
 +);
 +
 +/*
 + * Tracepoint for accounting sleep time (time the task is not runnable,
 + * including iowait, see below).
 + */
 +TRACE_EVENT(sched_stat_sleep,
 +
 +      TP_PROTO(struct task_struct *tsk, u64 delay),
 +
 +      TP_ARGS(tsk, delay),
 +
 +      TP_STRUCT__entry(
 +              __array( char,  comm,   TASK_COMM_LEN   )
 +              __field( pid_t, pid                     )
 +              __field( u64,   delay                   )
 +      ),
 +
 +      TP_fast_assign(
 +              memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
 +              __entry->pid    = tsk->pid;
 +              __entry->delay  = delay;
 +      )
 +      TP_perf_assign(
 +              __perf_count(delay);
 +      ),
 +
 +      TP_printk("task: %s:%d sleep: %Lu [ns]",
 +                      __entry->comm, __entry->pid,
 +                      (unsigned long long)__entry->delay)
 +);
 +
 +/*
 + * Tracepoint for accounting iowait time (time the task is not runnable
 + * due to waiting on IO to complete).
 + */
 +TRACE_EVENT(sched_stat_iowait,
 +
 +      TP_PROTO(struct task_struct *tsk, u64 delay),
 +
 +      TP_ARGS(tsk, delay),
 +
 +      TP_STRUCT__entry(
 +              __array( char,  comm,   TASK_COMM_LEN   )
 +              __field( pid_t, pid                     )
 +              __field( u64,   delay                   )
 +      ),
 +
 +      TP_fast_assign(
 +              memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
 +              __entry->pid    = tsk->pid;
 +              __entry->delay  = delay;
 +      )
 +      TP_perf_assign(
 +              __perf_count(delay);
 +      ),
 +
 +      TP_printk("task: %s:%d iowait: %Lu [ns]",
 +                      __entry->comm, __entry->pid,
 +                      (unsigned long long)__entry->delay)
 +);
 +
  #endif /* _TRACE_SCHED_H */
  
  /* This part must be outside protection */
diff --combined kernel/kmod.c
@@@ -37,6 -37,8 +37,8 @@@
  #include <linux/suspend.h>
  #include <asm/uaccess.h>
  
+ #include <trace/events/module.h>
  extern int max_threads;
  
  static struct workqueue_struct *khelper_wq;
@@@ -78,10 -80,6 +80,10 @@@ int __request_module(bool wait, const c
  #define MAX_KMOD_CONCURRENT 50        /* Completely arbitrary value - KAO */
        static int kmod_loop_msg;
  
 +      ret = security_kernel_module_request();
 +      if (ret)
 +              return ret;
 +
        va_start(args, fmt);
        ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
        va_end(args);
                return -ENOMEM;
        }
  
+       trace_module_request(module_name, wait, _RET_IP_);
        ret = call_usermodehelper(modprobe_path, argv, envp,
                        wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC);
        atomic_dec(&kmod_concurrent);
@@@ -466,7 -466,6 +470,7 @@@ int call_usermodehelper_exec(struct sub
        int retval = 0;
  
        BUG_ON(atomic_read(&sub_info->cred->usage) != 1);
 +      validate_creds(sub_info->cred);
  
        helper_lock();
        if (sub_info->path[0] == '\0')
@@@ -1,21 -1,23 +1,21 @@@
  
 -#include "../perf.h"
  #include "util.h"
 +#include "../perf.h"
  #include "parse-options.h"
  #include "parse-events.h"
  #include "exec_cmd.h"
  #include "string.h"
  #include "cache.h"
  
 -extern char *strcasestr(const char *haystack, const char *needle);
 -
  int                                   nr_counters;
  
  struct perf_counter_attr              attrs[MAX_COUNTERS];
  
  struct event_symbol {
 -      u8      type;
 -      u64     config;
 -      char    *symbol;
 -      char    *alias;
 +      u8              type;
 +      u64             config;
 +      const char      *symbol;
 +      const char      *alias;
  };
  
  char debugfs_path[MAXPATHLEN];
@@@ -49,7 -51,7 +49,7 @@@ static struct event_symbol event_symbol
  #define PERF_COUNTER_TYPE(config)     __PERF_COUNTER_FIELD(config, TYPE)
  #define PERF_COUNTER_ID(config)               __PERF_COUNTER_FIELD(config, EVENT)
  
 -static char *hw_event_names[] = {
 +static const char *hw_event_names[] = {
        "cycles",
        "instructions",
        "cache-references",
@@@ -59,7 -61,7 +59,7 @@@
        "bus-cycles",
  };
  
 -static char *sw_event_names[] = {
 +static const char *sw_event_names[] = {
        "cpu-clock-msecs",
        "task-clock-msecs",
        "page-faults",
@@@ -71,7 -73,7 +71,7 @@@
  
  #define MAX_ALIASES 8
  
 -static char *hw_cache[][MAX_ALIASES] = {
 +static const char *hw_cache[][MAX_ALIASES] = {
   { "L1-dcache",       "l1-d",         "l1d",          "L1-data",              },
   { "L1-icache",       "l1-i",         "l1i",          "L1-instruction",       },
   { "LLC",     "L2"                                                    },
   { "branch",  "branches",     "bpu",          "btb",          "bpc",  },
  };
  
 -static char *hw_cache_op[][MAX_ALIASES] = {
 +static const char *hw_cache_op[][MAX_ALIASES] = {
   { "load",    "loads",        "read",                                 },
   { "store",   "stores",       "write",                                },
   { "prefetch",        "prefetches",   "speculative-read", "speculative-load", },
  };
  
 -static char *hw_cache_result[][MAX_ALIASES] = {
 +static const char *hw_cache_result[][MAX_ALIASES] = {
   { "refs",    "Reference",    "ops",          "access",               },
   { "misses",  "miss",                                                 },
  };
@@@ -111,9 -113,11 +111,9 @@@ static unsigned long hw_cache_stat[C(MA
   [C(BPU)]     = (CACHE_READ),
  };
  
 -#define for_each_subsystem(sys_dir, sys_dirent, sys_next, file, st)          \
 +#define for_each_subsystem(sys_dir, sys_dirent, sys_next)            \
        while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next)        \
 -      if (snprintf(file, MAXPATHLEN, "%s/%s", debugfs_path,                  \
 -                      sys_dirent.d_name) &&                                  \
 -         (!stat(file, &st)) && (S_ISDIR(st.st_mode)) &&                      \
 +      if (sys_dirent.d_type == DT_DIR &&                                     \
           (strcmp(sys_dirent.d_name, ".")) &&                                 \
           (strcmp(sys_dirent.d_name, "..")))
  
@@@ -132,9 -136,11 +132,9 @@@ static int tp_event_has_id(struct diren
        return 0;
  }
  
 -#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, file, st)    \
 +#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next)            \
        while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next)        \
 -      if (snprintf(file, MAXPATHLEN, "%s/%s/%s", debugfs_path,               \
 -                   sys_dirent.d_name, evt_dirent.d_name) &&                  \
 -         (!stat(file, &st)) && (S_ISDIR(st.st_mode)) &&                      \
 +      if (evt_dirent.d_type == DT_DIR &&                                     \
           (strcmp(evt_dirent.d_name, ".")) &&                                 \
           (strcmp(evt_dirent.d_name, "..")) &&                                \
           (!tp_event_has_id(&sys_dirent, &evt_dirent)))
@@@ -152,39 -158,34 +152,39 @@@ int valid_debugfs_mount(const char *deb
        return 0;
  }
  
 -static char *tracepoint_id_to_name(u64 config)
 +struct tracepoint_path *tracepoint_id_to_path(u64 config)
  {
 -      static char tracepoint_name[2 * MAX_EVENT_LENGTH];
 +      struct tracepoint_path *path = NULL;
        DIR *sys_dir, *evt_dir;
        struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
 -      struct stat st;
        char id_buf[4];
 -      int fd;
 +      int sys_dir_fd, fd;
        u64 id;
        char evt_path[MAXPATHLEN];
  
        if (valid_debugfs_mount(debugfs_path))
 -              return "unkown";
 +              return NULL;
  
        sys_dir = opendir(debugfs_path);
        if (!sys_dir)
                goto cleanup;
 -
 -      for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) {
 -              evt_dir = opendir(evt_path);
 -              if (!evt_dir)
 -                      goto cleanup;
 -              for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next,
 -                                                              evt_path, st) {
 -                      snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id",
 -                               debugfs_path, sys_dirent.d_name,
 +      sys_dir_fd = dirfd(sys_dir);
 +
 +      for_each_subsystem(sys_dir, sys_dirent, sys_next) {
 +              int dfd = openat(sys_dir_fd, sys_dirent.d_name,
 +                               O_RDONLY|O_DIRECTORY), evt_dir_fd;
 +              if (dfd == -1)
 +                      continue;
 +              evt_dir = fdopendir(dfd);
 +              if (!evt_dir) {
 +                      close(dfd);
 +                      continue;
 +              }
 +              evt_dir_fd = dirfd(evt_dir);
 +              for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
 +                      snprintf(evt_path, MAXPATHLEN, "%s/id",
                                 evt_dirent.d_name);
 -                      fd = open(evt_path, O_RDONLY);
 +                      fd = openat(evt_dir_fd, evt_path, O_RDONLY);
                        if (fd < 0)
                                continue;
                        if (read(fd, id_buf, sizeof(id_buf)) < 0) {
                        if (id == config) {
                                closedir(evt_dir);
                                closedir(sys_dir);
 -                              snprintf(tracepoint_name, 2 * MAX_EVENT_LENGTH,
 -                                      "%s:%s", sys_dirent.d_name,
 -                                      evt_dirent.d_name);
 -                              return tracepoint_name;
 +                              path = calloc(1, sizeof(path));
 +                              path->system = malloc(MAX_EVENT_LENGTH);
 +                              if (!path->system) {
 +                                      free(path);
 +                                      return NULL;
 +                              }
 +                              path->name = malloc(MAX_EVENT_LENGTH);
 +                              if (!path->name) {
 +                                      free(path->system);
 +                                      free(path);
 +                                      return NULL;
 +                              }
 +                              strncpy(path->system, sys_dirent.d_name,
 +                                      MAX_EVENT_LENGTH);
 +                              strncpy(path->name, evt_dirent.d_name,
 +                                      MAX_EVENT_LENGTH);
 +                              return path;
                        }
                }
                closedir(evt_dir);
  
  cleanup:
        closedir(sys_dir);
 -      return "unkown";
 +      return NULL;
 +}
 +
 +#define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1)
 +static const char *tracepoint_id_to_name(u64 config)
 +{
 +      static char buf[TP_PATH_LEN];
 +      struct tracepoint_path *path;
 +
 +      path = tracepoint_id_to_path(config);
 +      if (path) {
 +              snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name);
 +              free(path->name);
 +              free(path->system);
 +              free(path);
 +      } else
 +              snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown");
 +
 +      return buf;
  }
  
  static int is_cache_op_valid(u8 cache_type, u8 cache_op)
@@@ -265,7 -235,7 +265,7 @@@ static char *event_cache_name(u8 cache_
        return name;
  }
  
 -char *event_name(int counter)
 +const char *event_name(int counter)
  {
        u64 config = attrs[counter].config;
        int type = attrs[counter].type;
        return __event_name(type, config);
  }
  
 -char *__event_name(int type, u64 config)
 +const char *__event_name(int type, u64 config)
  {
        static char buf[32];
  
        return "unknown";
  }
  
 -static int parse_aliases(const char **str, char *names[][MAX_ALIASES], int size)
 +static int parse_aliases(const char **str, const char *names[][MAX_ALIASES], int size)
  {
        int i, j;
        int n, longest = -1;
@@@ -628,7 -598,7 +628,7 @@@ static void print_tracepoint_events(voi
  {
        DIR *sys_dir, *evt_dir;
        struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
 -      struct stat st;
 +      int sys_dir_fd;
        char evt_path[MAXPATHLEN];
  
        if (valid_debugfs_mount(debugfs_path))
        sys_dir = opendir(debugfs_path);
        if (!sys_dir)
                goto cleanup;
 -
 -      for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) {
 -              evt_dir = opendir(evt_path);
 -              if (!evt_dir)
 -                      goto cleanup;
 -              for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next,
 -                                                              evt_path, st) {
 +      sys_dir_fd = dirfd(sys_dir);
 +
 +      for_each_subsystem(sys_dir, sys_dirent, sys_next) {
 +              int dfd = openat(sys_dir_fd, sys_dirent.d_name,
 +                               O_RDONLY|O_DIRECTORY), evt_dir_fd;
 +              if (dfd == -1)
 +                      continue;
 +              evt_dir = fdopendir(dfd);
 +              if (!evt_dir) {
 +                      close(dfd);
 +                      continue;
 +              }
 +              evt_dir_fd = dirfd(evt_dir);
 +              for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
                        snprintf(evt_path, MAXPATHLEN, "%s:%s",
                                 sys_dirent.d_name, evt_dirent.d_name);
-                       fprintf(stderr, "  %-40s [%s]\n", evt_path,
+                       fprintf(stderr, "  %-42s [%s]\n", evt_path,
                                event_type_descriptors[PERF_TYPE_TRACEPOINT+1]);
                }
                closedir(evt_dir);
@@@ -687,7 -650,7 +687,7 @@@ void print_events(void
                        sprintf(name, "%s OR %s", syms->symbol, syms->alias);
                else
                        strcpy(name, syms->symbol);
-               fprintf(stderr, "  %-40s [%s]\n", name,
+               fprintf(stderr, "  %-42s [%s]\n", name,
                        event_type_descriptors[type]);
  
                prev_type = type;
                                continue;
  
                        for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
-                               fprintf(stderr, "  %-40s [%s]\n",
+                               fprintf(stderr, "  %-42s [%s]\n",
                                        event_cache_name(type, op, i),
                                        event_type_descriptors[4]);
                        }
        }
  
        fprintf(stderr, "\n");
-       fprintf(stderr, "  %-40s [raw hardware event descriptor]\n",
+       fprintf(stderr, "  %-42s [raw hardware event descriptor]\n",
                "rNNN");
        fprintf(stderr, "\n");