Merge tag 'arc-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc
[cascardo/linux.git] / tools / perf / util / evsel.c
index 645dc18..52c7d88 100644 (file)
@@ -226,7 +226,8 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
                perf_evsel__init(evsel, attr, idx);
 
        if (perf_evsel__is_bpf_output(evsel)) {
-               evsel->attr.sample_type |= PERF_SAMPLE_RAW;
+               evsel->attr.sample_type |= (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
+                                           PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD),
                evsel->attr.sample_period = 1;
        }
 
@@ -561,10 +562,9 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
        return ret;
 }
 
-static void
-perf_evsel__config_callgraph(struct perf_evsel *evsel,
-                            struct record_opts *opts,
-                            struct callchain_param *param)
+void perf_evsel__config_callchain(struct perf_evsel *evsel,
+                                 struct record_opts *opts,
+                                 struct callchain_param *param)
 {
        bool function = perf_evsel__is_function_event(evsel);
        struct perf_event_attr *attr = &evsel->attr;
@@ -704,7 +704,7 @@ static void apply_config_terms(struct perf_evsel *evsel,
 
                /* set perf-event callgraph */
                if (param.enabled)
-                       perf_evsel__config_callgraph(evsel, opts, &param);
+                       perf_evsel__config_callchain(evsel, opts, &param);
        }
 }
 
@@ -736,7 +736,8 @@ static void apply_config_terms(struct perf_evsel *evsel,
  *     enable/disable events specifically, as there's no
  *     initial traced exec call.
  */
-void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
+void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
+                       struct callchain_param *callchain)
 {
        struct perf_evsel *leader = evsel->leader;
        struct perf_event_attr *attr = &evsel->attr;
@@ -811,8 +812,8 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
        if (perf_evsel__is_function_event(evsel))
                evsel->attr.exclude_callchain_user = 1;
 
-       if (callchain_param.enabled && !evsel->no_aux_samples)
-               perf_evsel__config_callgraph(evsel, opts, &callchain_param);
+       if (callchain && callchain->enabled && !evsel->no_aux_samples)
+               perf_evsel__config_callchain(evsel, opts, callchain);
 
        if (opts->sample_intr_regs) {
                attr->sample_regs_intr = opts->sample_intr_regs;
@@ -826,7 +827,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
                perf_evsel__set_sample_bit(evsel, PERIOD);
 
        /*
-        * When the user explicitely disabled time don't force it here.
+        * When the user explicitly disabled time don't force it here.
         */
        if (opts->sample_time &&
            (!perf_missing_features.sample_id_all &&
@@ -1230,6 +1231,21 @@ static void __p_sample_type(char *buf, size_t size, u64 value)
        __p_bits(buf, size, value, bits);
 }
 
+static void __p_branch_sample_type(char *buf, size_t size, u64 value)
+{
+#define bit_name(n) { PERF_SAMPLE_BRANCH_##n, #n }
+       struct bit_names bits[] = {
+               bit_name(USER), bit_name(KERNEL), bit_name(HV), bit_name(ANY),
+               bit_name(ANY_CALL), bit_name(ANY_RETURN), bit_name(IND_CALL),
+               bit_name(ABORT_TX), bit_name(IN_TX), bit_name(NO_TX),
+               bit_name(COND), bit_name(CALL_STACK), bit_name(IND_JUMP),
+               bit_name(CALL), bit_name(NO_FLAGS), bit_name(NO_CYCLES),
+               { .name = NULL, }
+       };
+#undef bit_name
+       __p_bits(buf, size, value, bits);
+}
+
 static void __p_read_format(char *buf, size_t size, u64 value)
 {
 #define bit_name(n) { PERF_FORMAT_##n, #n }
@@ -1248,6 +1264,7 @@ static void __p_read_format(char *buf, size_t size, u64 value)
 #define p_unsigned(val)                snprintf(buf, BUF_SIZE, "%"PRIu64, (uint64_t)(val))
 #define p_signed(val)          snprintf(buf, BUF_SIZE, "%"PRId64, (int64_t)(val))
 #define p_sample_type(val)     __p_sample_type(buf, BUF_SIZE, val)
+#define p_branch_sample_type(val) __p_branch_sample_type(buf, BUF_SIZE, val)
 #define p_read_format(val)     __p_read_format(buf, BUF_SIZE, val)
 
 #define PRINT_ATTRn(_n, _f, _p)                                \
@@ -1299,12 +1316,13 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
        PRINT_ATTRf(comm_exec, p_unsigned);
        PRINT_ATTRf(use_clockid, p_unsigned);
        PRINT_ATTRf(context_switch, p_unsigned);
+       PRINT_ATTRf(write_backward, p_unsigned);
 
        PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events, p_unsigned);
        PRINT_ATTRf(bp_type, p_unsigned);
        PRINT_ATTRn("{ bp_addr, config1 }", bp_addr, p_hex);
        PRINT_ATTRn("{ bp_len, config2 }", bp_len, p_hex);
-       PRINT_ATTRf(branch_sample_type, p_unsigned);
+       PRINT_ATTRf(branch_sample_type, p_branch_sample_type);
        PRINT_ATTRf(sample_regs_user, p_hex);
        PRINT_ATTRf(sample_stack_user, p_unsigned);
        PRINT_ATTRf(clockid, p_signed);
@@ -2253,95 +2271,6 @@ u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample,
        return 0;
 }
 
-static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
-{
-       va_list args;
-       int ret = 0;
-
-       if (!*first) {
-               ret += fprintf(fp, ",");
-       } else {
-               ret += fprintf(fp, ":");
-               *first = false;
-       }
-
-       va_start(args, fmt);
-       ret += vfprintf(fp, fmt, args);
-       va_end(args);
-       return ret;
-}
-
-static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
-{
-       return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
-}
-
-int perf_evsel__fprintf(struct perf_evsel *evsel,
-                       struct perf_attr_details *details, FILE *fp)
-{
-       bool first = true;
-       int printed = 0;
-
-       if (details->event_group) {
-               struct perf_evsel *pos;
-
-               if (!perf_evsel__is_group_leader(evsel))
-                       return 0;
-
-               if (evsel->nr_members > 1)
-                       printed += fprintf(fp, "%s{", evsel->group_name ?: "");
-
-               printed += fprintf(fp, "%s", perf_evsel__name(evsel));
-               for_each_group_member(pos, evsel)
-                       printed += fprintf(fp, ",%s", perf_evsel__name(pos));
-
-               if (evsel->nr_members > 1)
-                       printed += fprintf(fp, "}");
-               goto out;
-       }
-
-       printed += fprintf(fp, "%s", perf_evsel__name(evsel));
-
-       if (details->verbose) {
-               printed += perf_event_attr__fprintf(fp, &evsel->attr,
-                                                   __print_attr__fprintf, &first);
-       } else if (details->freq) {
-               const char *term = "sample_freq";
-
-               if (!evsel->attr.freq)
-                       term = "sample_period";
-
-               printed += comma_fprintf(fp, &first, " %s=%" PRIu64,
-                                        term, (u64)evsel->attr.sample_freq);
-       }
-
-       if (details->trace_fields) {
-               struct format_field *field;
-
-               if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
-                       printed += comma_fprintf(fp, &first, " (not a tracepoint)");
-                       goto out;
-               }
-
-               field = evsel->tp_format->format.fields;
-               if (field == NULL) {
-                       printed += comma_fprintf(fp, &first, " (no trace field)");
-                       goto out;
-               }
-
-               printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name);
-
-               field = field->next;
-               while (field) {
-                       printed += comma_fprintf(fp, &first, "%s", field->name);
-                       field = field->next;
-               }
-       }
-out:
-       fputc('\n', fp);
-       return ++printed;
-}
-
 bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
                          char *msg, size_t msgsize)
 {
@@ -2416,10 +2345,18 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
                         "Probably the maximum number of open file descriptors has been reached.\n"
                         "Hint: Try again after reducing the number of events.\n"
                         "Hint: Try increasing the limit with 'ulimit -n <limit>'");
+       case ENOMEM:
+               if ((evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) != 0 &&
+                   access("/proc/sys/kernel/perf_event_max_stack", F_OK) == 0)
+                       return scnprintf(msg, size,
+                                        "Not enough memory to setup event with callchain.\n"
+                                        "Hint: Try tweaking /proc/sys/kernel/perf_event_max_stack\n"
+                                        "Hint: Current value: %d", sysctl_perf_event_max_stack);
+               break;
        case ENODEV:
                if (target->cpu_list)
                        return scnprintf(msg, size, "%s",
-        "No such device - did you specify an out-of-range profile CPU?\n");
+        "No such device - did you specify an out-of-range profile CPU?");
                break;
        case EOPNOTSUPP:
                if (evsel->attr.precise_ip)
@@ -2451,7 +2388,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
        return scnprintf(msg, size,
        "The sys_perf_event_open() syscall returned with %d (%s) for event (%s).\n"
        "/bin/dmesg may provide additional information.\n"
-       "No CONFIG_PERF_EVENTS=y kernel support configured?\n",
+       "No CONFIG_PERF_EVENTS=y kernel support configured?",
                         err, strerror_r(err, sbuf, sizeof(sbuf)),
                         perf_evsel__name(evsel));
 }