]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge commit 'v2.6.35' into perf/core
authorIngo Molnar <mingo@elte.hu>
Mon, 2 Aug 2010 06:29:56 +0000 (08:29 +0200)
committerIngo Molnar <mingo@elte.hu>
Mon, 2 Aug 2010 06:31:54 +0000 (08:31 +0200)
Conflicts:
tools/perf/Makefile
tools/perf/util/hist.c

Merge reason: Resolve the conflicts and update to latest upstream.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
1  2 
MAINTAINERS
Makefile
drivers/cpufreq/cpufreq.c
include/asm-generic/vmlinux.lds.h
include/linux/sched.h
scripts/package/Makefile
tools/perf/util/hist.c
tools/perf/util/symbol.c

diff --combined MAINTAINERS
index b7f6a88ce12902a787bf891908403f266fa0f781,02f75fccac20915ae4c7aad6b333ed0061f90e44..5d5f9e2617fcd34f3d4a1a214bb32d2e8abe6c47
@@@ -3380,6 -3380,13 +3380,6 @@@ F:     include/linux/kmemleak.
  F:    mm/kmemleak.c
  F:    mm/kmemleak-test.c
  
 -KMEMTRACE
 -M:    Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
 -S:    Maintained
 -F:    Documentation/trace/kmemtrace.txt
 -F:    include/linux/kmemtrace.h
 -F:    kernel/trace/kmemtrace.c
 -
  KPROBES
  M:    Ananth N Mavinakayanahalli <ananth@in.ibm.com>
  M:    Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
@@@ -5647,7 -5654,7 +5647,7 @@@ TRACIN
  M:    Steven Rostedt <rostedt@goodmis.org>
  M:    Frederic Weisbecker <fweisbec@gmail.com>
  M:    Ingo Molnar <mingo@redhat.com>
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git tracing/core
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git perf/core
  S:    Maintained
  F:    Documentation/trace/ftrace.txt
  F:    arch/*/*/*/ftrace.h
@@@ -6236,6 -6243,8 +6236,8 @@@ F:      drivers/mmc/host/wbsd.
  
  WATCHDOG DEVICE DRIVERS
  M:    Wim Van Sebroeck <wim@iguana.be>
+ L:    linux-watchdog@vger.kernel.org
+ W:    http://www.linux-watchdog.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog.git
  S:    Maintained
  F:    Documentation/watchdog/
diff --combined Makefile
index f5787e2e150453a762774b62705e7185cfa7e24d,141da26fda4b87870ba19237f61ced915d0cebcb..85a14f5b74e971825e344b80bb1a4129c82d7167
+++ b/Makefile
@@@ -1,7 -1,7 +1,7 @@@
  VERSION = 2
  PATCHLEVEL = 6
  SUBLEVEL = 35
- EXTRAVERSION = -rc5
+ EXTRAVERSION =
  NAME = Sheep on Meth
  
  # *DOCUMENTATION*
@@@ -414,7 -414,7 +414,7 @@@ endi
  no-dot-config-targets := clean mrproper distclean \
                         cscope TAGS tags help %docs check% \
                         include/linux/version.h headers_% \
 -                       kernelrelease kernelversion
 +                       kernelrelease kernelversion %src-pkg
  
  config-targets := 0
  mixed-targets  := 0
@@@ -1158,8 -1158,6 +1158,8 @@@ distclean: mrprope
  # rpm target kept for backward compatibility
  package-dir   := $(srctree)/scripts/package
  
 +%src-pkg: FORCE
 +      $(Q)$(MAKE) $(build)=$(package-dir) $@
  %pkg: include/config/kernel.release FORCE
        $(Q)$(MAKE) $(build)=$(package-dir) $@
  rpm: include/config/kernel.release FORCE
index 4ed665725cc51080e17a0d2f023e1ebe672edfc1,938b74ea9ffbee8e6c195baa2eae97520c7a07cb..e59cb470914aaf2393080ad6c704f3a0d6cdeda3
@@@ -29,8 -29,6 +29,8 @@@
  #include <linux/completion.h>
  #include <linux/mutex.h>
  
 +#include <trace/events/power.h>
 +
  #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, \
                                                "cpufreq-core", msg)
  
@@@ -356,7 -354,6 +356,7 @@@ void cpufreq_notify_transition(struct c
  
        case CPUFREQ_POSTCHANGE:
                adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
 +                trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
                srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
                                CPUFREQ_POSTCHANGE, freqs);
                if (likely(policy) && likely(policy->cpu == freqs->cpu))
@@@ -1080,6 -1077,7 +1080,7 @@@ err_out_unregister
  
  err_unlock_policy:
        unlock_policy_rwsem_write(cpu);
+       free_cpumask_var(policy->related_cpus);
  err_free_cpumask:
        free_cpumask_var(policy->cpus);
  err_free_policy:
@@@ -1765,17 -1763,8 +1766,8 @@@ static int __cpufreq_set_policy(struct 
                        dprintk("governor switch\n");
  
                        /* end old governor */
-                       if (data->governor) {
-                               /*
-                                * Need to release the rwsem around governor
-                                * stop due to lock dependency between
-                                * cancel_delayed_work_sync and the read lock
-                                * taken in the delayed work handler.
-                                */
-                               unlock_policy_rwsem_write(data->cpu);
+                       if (data->governor)
                                __cpufreq_governor(data, CPUFREQ_GOV_STOP);
-                               lock_policy_rwsem_write(data->cpu);
-                       }
  
                        /* start new governor */
                        data->governor = policy->governor;
index 415b1a9118e784cca843f34ba691e1b64827a092,030a954ed292a59feae0bbf8437f370127b22bd6..853aa871fc6cac42bc183b1f539d7d73a1e986fc
  /* Align . to a 8 byte boundary equals to maximum function alignment. */
  #define ALIGN_FUNCTION()  . = ALIGN(8)
  
+ /*
+  * Align to a 32 byte boundary equal to the
+  * alignment gcc 4.5 uses for a struct
+  */
+ #define STRUCT_ALIGN() . = ALIGN(32)
  /* The actual configuration determine if the init/exit sections
   * are handled as text/data or they can be discarded (which
   * often happens at runtime)
        CPU_KEEP(exit.data)                                             \
        MEM_KEEP(init.data)                                             \
        MEM_KEEP(exit.data)                                             \
 -      . = ALIGN(8);                                                   \
 -      VMLINUX_SYMBOL(__start___markers) = .;                          \
 -      *(__markers)                                                    \
 -      VMLINUX_SYMBOL(__stop___markers) = .;                           \
        . = ALIGN(32);                                                  \
        VMLINUX_SYMBOL(__start___tracepoints) = .;                      \
        *(__tracepoints)                                                \
        LIKELY_PROFILE()                                                \
        BRANCH_PROFILE()                                                \
        TRACE_PRINTKS()                                                 \
+                                                                       \
+       STRUCT_ALIGN();                                                 \
        FTRACE_EVENTS()                                                 \
+                                                                       \
+       STRUCT_ALIGN();                                                 \
        TRACE_SYSCALLS()
  
  /*
   */
  #define INIT_TASK_DATA_SECTION(align)                                 \
        . = ALIGN(align);                                               \
-       .data..init_task : {                                            \
+       .data..init_task :  AT(ADDR(.data..init_task) - LOAD_OFFSET) {  \
                INIT_TASK_DATA(align)                                   \
        }
  
diff --combined include/linux/sched.h
index f751ea9dcb7b9faae49db446ce475d722f597db5,0478888c6899d3c59a1649d38dfdd58030f14918..7b6ec63cb74fa7f7d83520b2712b772a09c89ecf
@@@ -214,6 -214,7 +214,7 @@@ extern char ___assert_task_state[1 - 2*
  
  #define task_is_traced(task)  ((task->state & __TASK_TRACED) != 0)
  #define task_is_stopped(task) ((task->state & __TASK_STOPPED) != 0)
+ #define task_is_dead(task)    ((task)->exit_state != 0)
  #define task_is_stopped_or_traced(task)       \
                        ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0)
  #define task_contributes_to_load(task)        \
@@@ -2434,6 -2435,18 +2435,6 @@@ static inline void set_task_cpu(struct 
  
  #endif /* CONFIG_SMP */
  
 -#ifdef CONFIG_TRACING
 -extern void
 -__trace_special(void *__tr, void *__data,
 -              unsigned long arg1, unsigned long arg2, unsigned long arg3);
 -#else
 -static inline void
 -__trace_special(void *__tr, void *__data,
 -              unsigned long arg1, unsigned long arg2, unsigned long arg3)
 -{
 -}
 -#endif
 -
  extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask);
  extern long sched_getaffinity(pid_t pid, struct cpumask *mask);
  
diff --combined scripts/package/Makefile
index cea12744a6712541ae42e1ec6c27d2e2d0054cf1,d2c29b63addaa04dbd3df94d1adbfa9bc3ff8518..d0b931b994fccebc025c1c281c8cfd1573b7f64b
@@@ -44,7 -44,7 +44,7 @@@ rpm-pkg rpm: $(objtree)/kernel.spec FOR
        fi
        $(MAKE) clean
        $(PREV) ln -sf $(srctree) $(KERNELPATH)
-       $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion --scm-only > $(objtree)/.scmversion
+       $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion --save-scmversion
        $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/.
        $(PREV) rm $(KERNELPATH)
        rm -f $(objtree)/.scmversion
@@@ -111,38 -111,13 +111,38 @@@ tar%pkg: FORC
  clean-dirs += $(objtree)/tar-install/
  
  
 +# perf-pkg - generate a source tarball with perf source
 +# ---------------------------------------------------------------------------
 +
 +perf-tar=perf-$(KERNELVERSION)
 +
 +quiet_cmd_perf_tar = TAR
 +      cmd_perf_tar = \
 +git archive --prefix=$(perf-tar)/ HEAD^{tree}                       \
 +      $$(cat $(srctree)/tools/perf/MANIFEST) -o $(perf-tar).tar;  \
 +mkdir -p $(perf-tar);                                               \
 +git rev-parse HEAD > $(perf-tar)/HEAD;                              \
 +tar rf $(perf-tar).tar $(perf-tar)/HEAD;                            \
 +rm -r $(perf-tar);                                                  \
 +$(if $(findstring tar-src,$@),,                                     \
 +$(if $(findstring bz2,$@),bzip2,                                    \
 +$(if $(findstring gz,$@),gzip,                                      \
 +$(error unknown target $@)))                                       \
 +      -f -9 $(perf-tar).tar)
 +
 +perf-%pkg: FORCE
 +      $(call cmd,perf_tar)
 +
  # Help text displayed when executing 'make help'
  # ---------------------------------------------------------------------------
  help: FORCE
 -      @echo '  rpm-pkg         - Build both source and binary RPM kernel packages'
 -      @echo '  binrpm-pkg      - Build only the binary kernel package'
 -      @echo '  deb-pkg         - Build the kernel as an deb package'
 -      @echo '  tar-pkg         - Build the kernel as an uncompressed tarball'
 -      @echo '  targz-pkg       - Build the kernel as a gzip compressed tarball'
 -      @echo '  tarbz2-pkg      - Build the kernel as a bzip2 compressed tarball'
 +      @echo '  rpm-pkg             - Build both source and binary RPM kernel packages'
 +      @echo '  binrpm-pkg          - Build only the binary kernel package'
 +      @echo '  deb-pkg             - Build the kernel as an deb package'
 +      @echo '  tar-pkg             - Build the kernel as an uncompressed tarball'
 +      @echo '  targz-pkg           - Build the kernel as a gzip compressed tarball'
 +      @echo '  tarbz2-pkg          - Build the kernel as a bzip2 compressed tarball'
 +      @echo '  perf-tar-src-pkg    - Build $(perf-tar).tar source tarball'
 +      @echo '  perf-targz-src-pkg  - Build $(perf-tar).tar.gz source tarball'
 +      @echo '  perf-tarbz2-src-pkg - Build $(perf-tar).tar.bz2 source tarball'
  
diff --combined tools/perf/util/hist.c
index d0f07f7bdf16bd2fb8d161b031c586b0b97c968d,784ee0bdda7754f329428e40fa790a22dd331568..a6cea2894d12a5261519ebf40ce4af83787dce98
@@@ -5,61 -5,11 +5,61 @@@
  #include "sort.h"
  #include <math.h>
  
 +enum hist_filter {
 +      HIST_FILTER__DSO,
 +      HIST_FILTER__THREAD,
 +      HIST_FILTER__PARENT,
 +};
 +
  struct callchain_param        callchain_param = {
        .mode   = CHAIN_GRAPH_REL,
        .min_percent = 0.5
  };
  
 +u16 hists__col_len(struct hists *self, enum hist_column col)
 +{
 +      return self->col_len[col];
 +}
 +
 +void hists__set_col_len(struct hists *self, enum hist_column col, u16 len)
 +{
 +      self->col_len[col] = len;
 +}
 +
 +bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len)
 +{
 +      if (len > hists__col_len(self, col)) {
 +              hists__set_col_len(self, col, len);
 +              return true;
 +      }
 +      return false;
 +}
 +
 +static void hists__reset_col_len(struct hists *self)
 +{
 +      enum hist_column col;
 +
 +      for (col = 0; col < HISTC_NR_COLS; ++col)
 +              hists__set_col_len(self, col, 0);
 +}
 +
 +static void hists__calc_col_len(struct hists *self, struct hist_entry *h)
 +{
 +      u16 len;
 +
 +      if (h->ms.sym)
 +              hists__new_col_len(self, HISTC_SYMBOL, h->ms.sym->namelen);
 +
 +      len = thread__comm_len(h->thread);
 +      if (hists__new_col_len(self, HISTC_COMM, len))
 +              hists__set_col_len(self, HISTC_THREAD, len + 6);
 +
 +      if (h->ms.map) {
 +              len = dso__name_len(h->ms.map->dso);
 +              hists__new_col_len(self, HISTC_DSO, len);
 +      }
 +}
 +
  static void hist_entry__add_cpumode_period(struct hist_entry *self,
                                           unsigned int cpumode, u64 period)
  {
@@@ -100,19 -50,11 +100,19 @@@ static struct hist_entry *hist_entry__n
        return self;
  }
  
 -static void hists__inc_nr_entries(struct hists *self, struct hist_entry *entry)
 +static void hists__inc_nr_entries(struct hists *self, struct hist_entry *h)
  {
 -      if (entry->ms.sym && self->max_sym_namelen < entry->ms.sym->namelen)
 -              self->max_sym_namelen = entry->ms.sym->namelen;
 -      ++self->nr_entries;
 +      if (!h->filtered) {
 +              hists__calc_col_len(self, h);
 +              ++self->nr_entries;
 +      }
 +}
 +
 +static u8 symbol__parent_filter(const struct symbol *parent)
 +{
 +      if (symbol_conf.exclude_other && parent == NULL)
 +              return 1 << HIST_FILTER__PARENT;
 +      return 0;
  }
  
  struct hist_entry *__hists__add_entry(struct hists *self,
                        .map    = al->map,
                        .sym    = al->sym,
                },
 +              .cpu    = al->cpu,
                .ip     = al->addr,
                .level  = al->level,
                .period = period,
                .parent = sym_parent,
 +              .filtered = symbol__parent_filter(sym_parent),
        };
        int cmp;
  
@@@ -251,7 -191,7 +251,7 @@@ void hists__collapse_resort(struct hist
        tmp = RB_ROOT;
        next = rb_first(&self->entries);
        self->nr_entries = 0;
 -      self->max_sym_namelen = 0;
 +      hists__reset_col_len(self);
  
        while (next) {
                n = rb_entry(next, struct hist_entry, rb_node);
@@@ -308,7 -248,7 +308,7 @@@ void hists__output_resort(struct hists 
        next = rb_first(&self->entries);
  
        self->nr_entries = 0;
 -      self->max_sym_namelen = 0;
 +      hists__reset_col_len(self);
  
        while (next) {
                n = rb_entry(next, struct hist_entry, rb_node);
@@@ -575,9 -515,8 +575,9 @@@ static size_t hist_entry_callchain__fpr
  }
  
  int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
 -                       struct hists *pair_hists, bool show_displacement,
 -                       long displacement, bool color, u64 session_total)
 +                       struct hists *hists, struct hists *pair_hists,
 +                       bool show_displacement, long displacement,
 +                       bool color, u64 session_total)
  {
        struct sort_entry *se;
        u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us;
  
                ret += snprintf(s + ret, size - ret, "%s", sep ?: "  ");
                ret += se->se_snprintf(self, s + ret, size - ret,
 -                                     se->se_width ? *se->se_width : 0);
 +                                     hists__col_len(hists, se->se_width_idx));
        }
  
        return ret;
  }
  
 -int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
 -                      bool show_displacement, long displacement, FILE *fp,
 -                      u64 session_total)
 +int hist_entry__fprintf(struct hist_entry *self, struct hists *hists,
 +                      struct hists *pair_hists, bool show_displacement,
 +                      long displacement, FILE *fp, u64 session_total)
  {
        char bf[512];
 -      int ret;
 -
 -      ret = hist_entry__snprintf(self, bf, sizeof(bf), pair_hists,
 -                                 show_displacement, displacement,
 -                                 true, session_total);
 -      if (!ret)
 -              return 0;
 -
 +      hist_entry__snprintf(self, bf, sizeof(bf), hists, pair_hists,
 +                           show_displacement, displacement,
 +                           true, session_total);
        return fprintf(fp, "%s\n", bf);
  }
  
 -static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
 +static size_t hist_entry__fprintf_callchain(struct hist_entry *self,
 +                                          struct hists *hists, FILE *fp,
                                            u64 session_total)
  {
        int left_margin = 0;
        if (sort__first_dimension == SORT_COMM) {
                struct sort_entry *se = list_first_entry(&hist_entry__sort_list,
                                                         typeof(*se), list);
 -              left_margin = se->se_width ? *se->se_width : 0;
 +              left_margin = hists__col_len(hists, se->se_width_idx);
                left_margin -= thread__comm_len(self->thread);
        }
  
@@@ -778,17 -721,17 +778,17 @@@ size_t hists__fprintf(struct hists *sel
                        continue;
                }
                width = strlen(se->se_header);
 -              if (se->se_width) {
 -                      if (symbol_conf.col_width_list_str) {
 -                              if (col_width) {
 -                                      *se->se_width = atoi(col_width);
 -                                      col_width = strchr(col_width, ',');
 -                                      if (col_width)
 -                                              ++col_width;
 -                              }
 +              if (symbol_conf.col_width_list_str) {
 +                      if (col_width) {
 +                              hists__set_col_len(self, se->se_width_idx,
 +                                                 atoi(col_width));
 +                              col_width = strchr(col_width, ',');
 +                              if (col_width)
 +                                      ++col_width;
                        }
 -                      width = *se->se_width = max(*se->se_width, width);
                }
 +              if (!hists__new_col_len(self, se->se_width_idx, width))
 +                      width = hists__col_len(self, se->se_width_idx);
                fprintf(fp, "  %*s", width, se->se_header);
        }
        fprintf(fp, "\n");
                        continue;
  
                fprintf(fp, "  ");
 -              if (se->se_width)
 -                      width = *se->se_width;
 -              else
 +              width = hists__col_len(self, se->se_width_idx);
 +              if (width == 0)
                        width = strlen(se->se_header);
                for (i = 0; i < width; i++)
                        fprintf(fp, ".");
  print_entries:
        for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
 -              int cnt;
  
                if (show_displacement) {
                        if (h->pair != NULL)
                                displacement = 0;
                        ++position;
                }
 -              cnt = hist_entry__fprintf(h, pair, show_displacement,
 -                                        displacement, fp, self->stats.total_period);
 -              /* Ignore those that didn't match the parent filter */
 -              if (!cnt)
 -                      continue;
 -
 -              ret += cnt;
 +              ret += hist_entry__fprintf(h, self, pair, show_displacement,
 +                                         displacement, fp, self->stats.total_period);
  
                if (symbol_conf.use_callchain)
 -                      ret += hist_entry__fprintf_callchain(h, fp, self->stats.total_period);
 -
 +                      ret += hist_entry__fprintf_callchain(h, self, fp,
 +                                                           self->stats.total_period);
                if (h->ms.map == NULL && verbose > 1) {
                        __map_groups__fprintf_maps(&h->thread->mg,
                                                   MAP__FUNCTION, verbose, fp);
        return ret;
  }
  
 -enum hist_filter {
 -      HIST_FILTER__DSO,
 -      HIST_FILTER__THREAD,
 -};
 +/*
 + * See hists__fprintf to match the column widths
 + */
 +unsigned int hists__sort_list_width(struct hists *self)
 +{
 +      struct sort_entry *se;
 +      int ret = 9; /* total % */
 +
 +      if (symbol_conf.show_cpu_utilization) {
 +              ret += 7; /* count_sys % */
 +              ret += 6; /* count_us % */
 +              if (perf_guest) {
 +                      ret += 13; /* count_guest_sys % */
 +                      ret += 12; /* count_guest_us % */
 +              }
 +      }
 +
 +      if (symbol_conf.show_nr_samples)
 +              ret += 11;
 +
 +      list_for_each_entry(se, &hist_entry__sort_list, list)
 +              if (!se->elide)
 +                      ret += 2 + hists__col_len(self, se->se_width_idx);
 +
 +      return ret;
 +}
 +
 +static void hists__remove_entry_filter(struct hists *self, struct hist_entry *h,
 +                                     enum hist_filter filter)
 +{
 +      h->filtered &= ~(1 << filter);
 +      if (h->filtered)
 +              return;
 +
 +      ++self->nr_entries;
 +      if (h->ms.unfolded)
 +              self->nr_entries += h->nr_rows;
 +      h->row_offset = 0;
 +      self->stats.total_period += h->period;
 +      self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
 +
 +      hists__calc_col_len(self, h);
 +}
  
  void hists__filter_by_dso(struct hists *self, const struct dso *dso)
  {
  
        self->nr_entries = self->stats.total_period = 0;
        self->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
 -      self->max_sym_namelen = 0;
 +      hists__reset_col_len(self);
  
        for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
                        continue;
                }
  
 -              h->filtered &= ~(1 << HIST_FILTER__DSO);
 -              if (!h->filtered) {
 -                      ++self->nr_entries;
 -                      self->stats.total_period += h->period;
 -                      self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
 -                      if (h->ms.sym &&
 -                          self->max_sym_namelen < h->ms.sym->namelen)
 -                              self->max_sym_namelen = h->ms.sym->namelen;
 -              }
 +              hists__remove_entry_filter(self, h, HIST_FILTER__DSO);
        }
  }
  
@@@ -923,7 -842,7 +923,7 @@@ void hists__filter_by_thread(struct his
  
        self->nr_entries = self->stats.total_period = 0;
        self->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
 -      self->max_sym_namelen = 0;
 +      hists__reset_col_len(self);
  
        for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
                        h->filtered |= (1 << HIST_FILTER__THREAD);
                        continue;
                }
 -              h->filtered &= ~(1 << HIST_FILTER__THREAD);
 -              if (!h->filtered) {
 -                      ++self->nr_entries;
 -                      self->stats.total_period += h->period;
 -                      self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
 -                      if (h->ms.sym &&
 -                          self->max_sym_namelen < h->ms.sym->namelen)
 -                              self->max_sym_namelen = h->ms.sym->namelen;
 -              }
 +
 +              hists__remove_entry_filter(self, h, HIST_FILTER__THREAD);
        }
  }
  
@@@ -1050,13 -976,17 +1050,17 @@@ static int hist_entry__parse_objdump_li
                 * Parse hexa addresses followed by ':'
                 */
                line_ip = strtoull(tmp, &tmp2, 16);
-               if (*tmp2 != ':' || tmp == tmp2)
+               if (*tmp2 != ':' || tmp == tmp2 || tmp2[1] == '\0')
                        line_ip = -1;
        }
  
        if (line_ip != -1) {
-               u64 start = map__rip_2objdump(self->ms.map, sym->start);
+               u64 start = map__rip_2objdump(self->ms.map, sym->start),
+                   end = map__rip_2objdump(self->ms.map, sym->end);
                offset = line_ip - start;
+               if (offset < 0 || (u64)line_ip > end)
+                       offset = -1;
        }
  
        objdump_line = objdump_line__new(offset, line);
@@@ -1122,7 -1052,7 +1126,7 @@@ fallback
                 dso, dso->long_name, sym, sym->name);
  
        snprintf(command, sizeof(command),
 -               "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s|expand",
 +               "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS -C %s|grep -v %s|expand",
                 map__rip_2objdump(map, sym->start),
                 map__rip_2objdump(map, sym->end),
                 filename, filename);
diff --combined tools/perf/util/symbol.c
index 94cdf68440cd6533a760a366c70a6768b35ce77a,5b276833e2bfea3bae9115f2555b32e3a3b8b628..3b8c00506672da55a9de1e577fe5443ec4f361c6
@@@ -12,7 -12,6 +12,7 @@@
  #include <fcntl.h>
  #include <unistd.h>
  #include "build-id.h"
 +#include "debug.h"
  #include "symbol.h"
  #include "strlist.h"
  
@@@ -26,8 -25,6 +26,8 @@@
  #define NT_GNU_BUILD_ID 3
  #endif
  
 +static bool dso__build_id_equal(const struct dso *self, u8 *build_id);
 +static int elf_read_build_id(Elf *elf, void *bf, size_t size);
  static void dsos__add(struct list_head *head, struct dso *dso);
  static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
  static int dso__load_kernel_sym(struct dso *self, struct map *map,
@@@ -43,14 -40,6 +43,14 @@@ struct symbol_conf symbol_conf = 
        .try_vmlinux_path = true,
  };
  
 +int dso__name_len(const struct dso *self)
 +{
 +      if (verbose)
 +              return self->long_name_len;
 +
 +      return self->short_name_len;
 +}
 +
  bool dso__loaded(const struct dso *self, enum map_type type)
  {
        return self->loaded & (1 << type);
@@@ -226,9 -215,7 +226,9 @@@ void dso__delete(struct dso *self
        int i;
        for (i = 0; i < MAP__NR_TYPES; ++i)
                symbols__delete(&self->symbols[i]);
 -      if (self->long_name != self->name)
 +      if (self->sname_alloc)
 +              free((char *)self->short_name);
 +      if (self->lname_alloc)
                free(self->long_name);
        free(self);
  }
@@@ -946,28 -933,8 +946,28 @@@ static bool elf_sec__is_a(GElf_Shdr *se
        }
  }
  
 +static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
 +{
 +      Elf_Scn *sec = NULL;
 +      GElf_Shdr shdr;
 +      size_t cnt = 1;
 +
 +      while ((sec = elf_nextscn(elf, sec)) != NULL) {
 +              gelf_getshdr(sec, &shdr);
 +
 +              if ((addr >= shdr.sh_addr) &&
 +                  (addr < (shdr.sh_addr + shdr.sh_size)))
 +                      return cnt;
 +
 +              ++cnt;
 +      }
 +
 +      return -1;
 +}
 +
  static int dso__load_sym(struct dso *self, struct map *map, const char *name,
 -                       int fd, symbol_filter_t filter, int kmodule)
 +                       int fd, symbol_filter_t filter, int kmodule,
 +                       int want_symtab)
  {
        struct kmap *kmap = self->kernel ? map__kmap(map) : NULL;
        struct map *curr_map = map;
        int err = -1;
        uint32_t idx;
        GElf_Ehdr ehdr;
 -      GElf_Shdr shdr;
 -      Elf_Data *syms;
 +      GElf_Shdr shdr, opdshdr;
 +      Elf_Data *syms, *opddata = NULL;
        GElf_Sym sym;
 -      Elf_Scn *sec, *sec_strndx;
 +      Elf_Scn *sec, *sec_strndx, *opdsec;
        Elf *elf;
        int nr = 0;
 +      size_t opdidx = 0;
  
        elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
        if (elf == NULL) {
 -              pr_err("%s: cannot read %s ELF file.\n", __func__, name);
 +              pr_debug("%s: cannot read %s ELF file.\n", __func__, name);
                goto out_close;
        }
  
        if (gelf_getehdr(elf, &ehdr) == NULL) {
 -              pr_err("%s: cannot get elf header.\n", __func__);
 +              pr_debug("%s: cannot get elf header.\n", __func__);
                goto out_elf_end;
        }
  
 +      /* Always reject images with a mismatched build-id: */
 +      if (self->has_build_id) {
 +              u8 build_id[BUILD_ID_SIZE];
 +
 +              if (elf_read_build_id(elf, build_id,
 +                                    BUILD_ID_SIZE) != BUILD_ID_SIZE)
 +                      goto out_elf_end;
 +
 +              if (!dso__build_id_equal(self, build_id))
 +                      goto out_elf_end;
 +      }
 +
        sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
        if (sec == NULL) {
 +              if (want_symtab)
 +                      goto out_elf_end;
 +
                sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
                if (sec == NULL)
                        goto out_elf_end;
        }
  
 +      opdsec = elf_section_by_name(elf, &ehdr, &opdshdr, ".opd", &opdidx);
 +      if (opdsec)
 +              opddata = elf_rawdata(opdsec, NULL);
 +
        syms = elf_getdata(sec, NULL);
        if (syms == NULL)
                goto out_elf_end;
                if (!is_label && !elf_sym__is_a(&sym, map->type))
                        continue;
  
 +              if (opdsec && sym.st_shndx == opdidx) {
 +                      u32 offset = sym.st_value - opdshdr.sh_addr;
 +                      u64 *opd = opddata->d_buf + offset;
 +                      sym.st_value = *opd;
 +                      sym.st_shndx = elf_addr_to_index(elf, sym.st_value);
 +              }
 +
                sec = elf_getscn(elf, sym.st_shndx);
                if (!sec)
                        goto out_elf_end;
@@@ -1211,26 -1151,37 +1211,26 @@@ bool __dsos__read_build_ids(struct list
   */
  #define NOTE_ALIGN(n) (((n) + 3) & -4U)
  
 -int filename__read_build_id(const char *filename, void *bf, size_t size)
 +static int elf_read_build_id(Elf *elf, void *bf, size_t size)
  {
 -      int fd, err = -1;
 +      int err = -1;
        GElf_Ehdr ehdr;
        GElf_Shdr shdr;
        Elf_Data *data;
        Elf_Scn *sec;
        Elf_Kind ek;
        void *ptr;
 -      Elf *elf;
  
        if (size < BUILD_ID_SIZE)
                goto out;
  
 -      fd = open(filename, O_RDONLY);
 -      if (fd < 0)
 -              goto out;
 -
 -      elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
 -      if (elf == NULL) {
 -              pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
 -              goto out_close;
 -      }
 -
        ek = elf_kind(elf);
        if (ek != ELF_K_ELF)
 -              goto out_elf_end;
 +              goto out;
  
        if (gelf_getehdr(elf, &ehdr) == NULL) {
                pr_err("%s: cannot get elf header.\n", __func__);
 -              goto out_elf_end;
 +              goto out;
        }
  
        sec = elf_section_by_name(elf, &ehdr, &shdr,
                sec = elf_section_by_name(elf, &ehdr, &shdr,
                                          ".notes", NULL);
                if (sec == NULL)
 -                      goto out_elf_end;
 +                      goto out;
        }
  
        data = elf_getdata(sec, NULL);
        if (data == NULL)
 -              goto out_elf_end;
 +              goto out;
  
        ptr = data->d_buf;
        while (ptr < (data->d_buf + data->d_size)) {
                }
                ptr += descsz;
        }
 -out_elf_end:
 +
 +out:
 +      return err;
 +}
 +
 +int filename__read_build_id(const char *filename, void *bf, size_t size)
 +{
 +      int fd, err = -1;
 +      Elf *elf;
 +
 +      if (size < BUILD_ID_SIZE)
 +              goto out;
 +
 +      fd = open(filename, O_RDONLY);
 +      if (fd < 0)
 +              goto out;
 +
 +      elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
 +      if (elf == NULL) {
 +              pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
 +              goto out_close;
 +      }
 +
 +      err = elf_read_build_id(elf, bf, size);
 +
        elf_end(elf);
  out_close:
        close(fd);
@@@ -1366,11 -1293,11 +1366,11 @@@ int dso__load(struct dso *self, struct 
  {
        int size = PATH_MAX;
        char *name;
 -      u8 build_id[BUILD_ID_SIZE];
        int ret = -1;
        int fd;
        struct machine *machine;
        const char *root_dir;
 +      int want_symtab;
  
        dso__set_loaded(self, map->type);
  
                return ret;
        }
  
 -      self->origin = DSO__ORIG_BUILD_ID_CACHE;
 -      if (dso__build_id_filename(self, name, size) != NULL)
 -              goto open_file;
 -more:
 -      do {
 -              self->origin++;
 +      /* Iterate over candidate debug images.
 +       * On the first pass, only load images if they have a full symtab.
 +       * Failing that, do a second pass where we accept .dynsym also
 +       */
 +      for (self->origin = DSO__ORIG_BUILD_ID_CACHE, want_symtab = 1;
 +           self->origin != DSO__ORIG_NOT_FOUND;
 +           self->origin++) {
                switch (self->origin) {
 +              case DSO__ORIG_BUILD_ID_CACHE:
 +                      if (dso__build_id_filename(self, name, size) == NULL)
 +                              continue;
 +                      break;
                case DSO__ORIG_FEDORA:
                        snprintf(name, size, "/usr/lib/debug%s.debug",
                                 self->long_name);
                        snprintf(name, size, "/usr/lib/debug%s",
                                 self->long_name);
                        break;
 -              case DSO__ORIG_BUILDID:
 -                      if (filename__read_build_id(self->long_name, build_id,
 -                                                  sizeof(build_id))) {
 -                              char build_id_hex[BUILD_ID_SIZE * 2 + 1];
 -                              build_id__sprintf(build_id, sizeof(build_id),
 -                                                build_id_hex);
 -                              snprintf(name, size,
 -                                       "/usr/lib/debug/.build-id/%.2s/%s.debug",
 -                                      build_id_hex, build_id_hex + 2);
 -                              if (self->has_build_id)
 -                                      goto compare_build_id;
 -                              break;
 +              case DSO__ORIG_BUILDID: {
 +                      char build_id_hex[BUILD_ID_SIZE * 2 + 1];
 +
 +                      if (!self->has_build_id)
 +                              continue;
 +
 +                      build_id__sprintf(self->build_id,
 +                                        sizeof(self->build_id),
 +                                        build_id_hex);
 +                      snprintf(name, size,
 +                               "/usr/lib/debug/.build-id/%.2s/%s.debug",
 +                               build_id_hex, build_id_hex + 2);
                        }
 -                      self->origin++;
 -                      /* Fall thru */
 +                      break;
                case DSO__ORIG_DSO:
                        snprintf(name, size, "%s", self->long_name);
                        break;
                        break;
  
                default:
 -                      goto out;
 +                      /*
 +                       * If we wanted a full symtab but no image had one,
 +                       * relax our requirements and repeat the search.
 +                       */
 +                      if (want_symtab) {
 +                              want_symtab = 0;
 +                              self->origin = DSO__ORIG_BUILD_ID_CACHE;
 +                      } else
 +                              continue;
                }
  
 -              if (self->has_build_id) {
 -                      if (filename__read_build_id(name, build_id,
 -                                                  sizeof(build_id)) < 0)
 -                              goto more;
 -compare_build_id:
 -                      if (!dso__build_id_equal(self, build_id))
 -                              goto more;
 -              }
 -open_file:
 +              /* Name is now the name of the next image to try */
                fd = open(name, O_RDONLY);
 -      } while (fd < 0);
 +              if (fd < 0)
 +                      continue;
  
 -      ret = dso__load_sym(self, map, name, fd, filter, 0);
 -      close(fd);
 +              ret = dso__load_sym(self, map, name, fd, filter, 0,
 +                                  want_symtab);
 +              close(fd);
  
 -      /*
 -       * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
 -       */
 -      if (!ret)
 -              goto more;
 +              /*
 +               * Some people seem to have debuginfo files _WITHOUT_ debug
 +               * info!?!?
 +               */
 +              if (!ret)
 +                      continue;
  
 -      if (ret > 0) {
 -              int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
 -              if (nr_plt > 0)
 -                      ret += nr_plt;
 +              if (ret > 0) {
 +                      int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
 +                      if (nr_plt > 0)
 +                              ret += nr_plt;
 +                      break;
 +              }
        }
 -out:
 +
        free(name);
        if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
                return 0;
@@@ -1525,6 -1443,7 +1525,7 @@@ static int map_groups__set_modules_path
  {
        struct dirent *dent;
        DIR *dir = opendir(dir_name);
+       int ret = 0;
  
        if (!dir) {
                pr_debug("%s: cannot open %s dir\n", __func__, dir_name);
  
                        snprintf(path, sizeof(path), "%s/%s",
                                 dir_name, dent->d_name);
-                       if (map_groups__set_modules_path_dir(self, path) < 0)
-                               goto failure;
+                       ret = map_groups__set_modules_path_dir(self, path);
+                       if (ret < 0)
+                               goto out;
                } else {
                        char *dot = strrchr(dent->d_name, '.'),
                             dso_name[PATH_MAX];
                                 dir_name, dent->d_name);
  
                        long_name = strdup(path);
-                       if (long_name == NULL)
-                               goto failure;
+                       if (long_name == NULL) {
+                               ret = -1;
+                               goto out;
+                       }
                        dso__set_long_name(map->dso, long_name);
 +                      map->dso->lname_alloc = 1;
                        dso__kernel_module_get_build_id(map->dso, "");
                }
        }
  
-       return 0;
- failure:
+ out:
        closedir(dir);
-       return -1;
+       return ret;
  }
  
  static char *get_kernel_version(const char *root_dir)
@@@ -1736,12 -1656,36 +1739,12 @@@ static int dso__load_vmlinux(struct ds
  {
        int err = -1, fd;
  
 -      if (self->has_build_id) {
 -              u8 build_id[BUILD_ID_SIZE];
 -
 -              if (filename__read_build_id(vmlinux, build_id,
 -                                          sizeof(build_id)) < 0) {
 -                      pr_debug("No build_id in %s, ignoring it\n", vmlinux);
 -                      return -1;
 -              }
 -              if (!dso__build_id_equal(self, build_id)) {
 -                      char expected_build_id[BUILD_ID_SIZE * 2 + 1],
 -                           vmlinux_build_id[BUILD_ID_SIZE * 2 + 1];
 -
 -                      build_id__sprintf(self->build_id,
 -                                        sizeof(self->build_id),
 -                                        expected_build_id);
 -                      build_id__sprintf(build_id, sizeof(build_id),
 -                                        vmlinux_build_id);
 -                      pr_debug("build_id in %s is %s while expected is %s, "
 -                               "ignoring it\n", vmlinux, vmlinux_build_id,
 -                               expected_build_id);
 -                      return -1;
 -              }
 -      }
 -
        fd = open(vmlinux, O_RDONLY);
        if (fd < 0)
                return -1;
  
        dso__set_loaded(self, map->type);
 -      err = dso__load_sym(self, map, vmlinux, fd, filter, 0);
 +      err = dso__load_sym(self, map, vmlinux, fd, filter, 0, 0);
        close(fd);
  
        if (err > 0)
@@@ -2245,15 -2189,6 +2248,15 @@@ out_free_comm_list
        return -1;
  }
  
 +void symbol__exit(void)
 +{
 +      strlist__delete(symbol_conf.sym_list);
 +      strlist__delete(symbol_conf.dso_list);
 +      strlist__delete(symbol_conf.comm_list);
 +      vmlinux_path__exit();
 +      symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
 +}
 +
  int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
  {
        struct machine *machine = machines__findnew(self, pid);