Merge branch 'tip/perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
Ingo Molnar [Fri, 23 Jul 2010 07:10:29 +0000 (09:10 +0200)]
1  2 
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_output.c

diff --combined kernel/trace/trace.c
@@@ -344,7 -344,7 +344,7 @@@ static DECLARE_WAIT_QUEUE_HEAD(trace_wa
  /* trace_flags holds trace_options default values */
  unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |
        TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME |
-       TRACE_ITER_GRAPH_TIME;
+       TRACE_ITER_GRAPH_TIME | TRACE_ITER_RECORD_CMD;
  
  static int trace_stop_count;
  static DEFINE_SPINLOCK(tracing_start_lock);
@@@ -428,6 -428,7 +428,7 @@@ static const char *trace_options[] = 
        "latency-format",
        "sleep-time",
        "graph-time",
+       "record-cmd",
        NULL
  };
  
@@@ -659,6 -660,10 +660,10 @@@ update_max_tr(struct trace_array *tr, s
                return;
  
        WARN_ON_ONCE(!irqs_disabled());
+       if (!current_trace->use_max_tr) {
+               WARN_ON_ONCE(1);
+               return;
+       }
        arch_spin_lock(&ftrace_max_lock);
  
        tr->buffer = max_tr.buffer;
@@@ -685,6 -690,11 +690,11 @@@ update_max_tr_single(struct trace_arra
                return;
  
        WARN_ON_ONCE(!irqs_disabled());
+       if (!current_trace->use_max_tr) {
+               WARN_ON_ONCE(1);
+               return;
+       }
        arch_spin_lock(&ftrace_max_lock);
  
        ftrace_disable_cpu();
@@@ -729,7 -739,7 +739,7 @@@ __acquires(kernel_lock
                return -1;
        }
  
-       if (strlen(type->name) > MAX_TRACER_SIZE) {
+       if (strlen(type->name) >= MAX_TRACER_SIZE) {
                pr_info("Tracer has a name longer than %d\n", MAX_TRACER_SIZE);
                return -1;
        }
@@@ -1331,6 -1341,61 +1341,6 @@@ static void __trace_userstack(struct tr
  
  #endif /* CONFIG_STACKTRACE */
  
 -static void
 -ftrace_trace_special(void *__tr,
 -                   unsigned long arg1, unsigned long arg2, unsigned long arg3,
 -                   int pc)
 -{
 -      struct ftrace_event_call *call = &event_special;
 -      struct ring_buffer_event *event;
 -      struct trace_array *tr = __tr;
 -      struct ring_buffer *buffer = tr->buffer;
 -      struct special_entry *entry;
 -
 -      event = trace_buffer_lock_reserve(buffer, TRACE_SPECIAL,
 -                                        sizeof(*entry), 0, pc);
 -      if (!event)
 -              return;
 -      entry   = ring_buffer_event_data(event);
 -      entry->arg1                     = arg1;
 -      entry->arg2                     = arg2;
 -      entry->arg3                     = arg3;
 -
 -      if (!filter_check_discard(call, entry, buffer, event))
 -              trace_buffer_unlock_commit(buffer, event, 0, pc);
 -}
 -
 -void
 -__trace_special(void *__tr, void *__data,
 -              unsigned long arg1, unsigned long arg2, unsigned long arg3)
 -{
 -      ftrace_trace_special(__tr, arg1, arg2, arg3, preempt_count());
 -}
 -
 -void
 -ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3)
 -{
 -      struct trace_array *tr = &global_trace;
 -      struct trace_array_cpu *data;
 -      unsigned long flags;
 -      int cpu;
 -      int pc;
 -
 -      if (tracing_disabled)
 -              return;
 -
 -      pc = preempt_count();
 -      local_irq_save(flags);
 -      cpu = raw_smp_processor_id();
 -      data = tr->data[cpu];
 -
 -      if (likely(atomic_inc_return(&data->disabled) == 1))
 -              ftrace_trace_special(tr, arg1, arg2, arg3, pc);
 -
 -      atomic_dec(&data->disabled);
 -      local_irq_restore(flags);
 -}
 -
  /**
   * trace_vbprintk - write binary msg to tracing buffer
   *
@@@ -2338,7 -2403,6 +2348,7 @@@ static const struct file_operations sho
        .open           = show_traces_open,
        .read           = seq_read,
        .release        = seq_release,
 +      .llseek         = seq_lseek,
  };
  
  /*
@@@ -2432,7 -2496,6 +2442,7 @@@ static const struct file_operations tra
        .open           = tracing_open_generic,
        .read           = tracing_cpumask_read,
        .write          = tracing_cpumask_write,
 +      .llseek         = generic_file_llseek,
  };
  
  static int tracing_trace_options_show(struct seq_file *m, void *v)
@@@ -2508,6 -2571,9 +2518,9 @@@ static void set_tracer_flags(unsigned i
                trace_flags |= mask;
        else
                trace_flags &= ~mask;
+       if (mask == TRACE_ITER_RECORD_CMD)
+               trace_event_enable_cmd_record(enabled);
  }
  
  static ssize_t
@@@ -2599,7 -2665,6 +2612,7 @@@ tracing_readme_read(struct file *filp, 
  static const struct file_operations tracing_readme_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_readme_read,
 +      .llseek         = generic_file_llseek,
  };
  
  static ssize_t
@@@ -2650,7 -2715,6 +2663,7 @@@ tracing_saved_cmdlines_read(struct fil
  static const struct file_operations tracing_saved_cmdlines_fops = {
      .open       = tracing_open_generic,
      .read       = tracing_saved_cmdlines_read,
 +    .llseek   = generic_file_llseek,
  };
  
  static ssize_t
@@@ -2746,6 -2810,9 +2759,9 @@@ static int tracing_resize_ring_buffer(u
        if (ret < 0)
                return ret;
  
+       if (!current_trace->use_max_tr)
+               goto out;
        ret = ring_buffer_resize(max_tr.buffer, size);
        if (ret < 0) {
                int r;
                return ret;
        }
  
+       max_tr.entries = size;
+  out:
        global_trace.entries = size;
  
        return ret;
  }
  
  /**
   * tracing_update_buffers - used by tracing facility to expand ring buffers
   *
@@@ -2838,12 -2908,26 +2857,26 @@@ static int tracing_set_tracer(const cha
        trace_branch_disable();
        if (current_trace && current_trace->reset)
                current_trace->reset(tr);
+       if (current_trace && current_trace->use_max_tr) {
+               /*
+                * We don't free the ring buffer. instead, resize it because
+                * The max_tr ring buffer has some state (e.g. ring->clock) and
+                * we want preserve it.
+                */
+               ring_buffer_resize(max_tr.buffer, 1);
+               max_tr.entries = 1;
+       }
        destroy_trace_option_files(topts);
  
        current_trace = t;
  
        topts = create_trace_option_files(current_trace);
+       if (current_trace->use_max_tr) {
+               ret = ring_buffer_resize(max_tr.buffer, global_trace.entries);
+               if (ret < 0)
+                       goto out;
+               max_tr.entries = global_trace.entries;
+       }
  
        if (t->init) {
                ret = tracer_init(t, tr);
@@@ -2980,7 -3064,6 +3013,7 @@@ static int tracing_open_pipe(struct ino
        if (iter->trace->pipe_open)
                iter->trace->pipe_open(iter);
  
 +      nonseekable_open(inode, filp);
  out:
        mutex_unlock(&trace_types_lock);
        return ret;
@@@ -3426,7 -3509,6 +3459,6 @@@ tracing_entries_write(struct file *filp
        }
  
        tracing_start();
-       max_tr.entries = global_trace.entries;
        mutex_unlock(&trace_types_lock);
  
        return cnt;
@@@ -3539,21 -3621,18 +3571,21 @@@ static const struct file_operations tra
        .open           = tracing_open_generic,
        .read           = tracing_max_lat_read,
        .write          = tracing_max_lat_write,
 +      .llseek         = generic_file_llseek,
  };
  
  static const struct file_operations tracing_ctrl_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_ctrl_read,
        .write          = tracing_ctrl_write,
 +      .llseek         = generic_file_llseek,
  };
  
  static const struct file_operations set_tracer_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_set_trace_read,
        .write          = tracing_set_trace_write,
 +      .llseek         = generic_file_llseek,
  };
  
  static const struct file_operations tracing_pipe_fops = {
        .read           = tracing_read_pipe,
        .splice_read    = tracing_splice_read_pipe,
        .release        = tracing_release_pipe,
 +      .llseek         = no_llseek,
  };
  
  static const struct file_operations tracing_entries_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_entries_read,
        .write          = tracing_entries_write,
 +      .llseek         = generic_file_llseek,
  };
  
  static const struct file_operations tracing_mark_fops = {
        .open           = tracing_open_generic,
        .write          = tracing_mark_write,
 +      .llseek         = generic_file_llseek,
  };
  
  static const struct file_operations trace_clock_fops = {
@@@ -3881,7 -3957,6 +3913,7 @@@ tracing_stats_read(struct file *filp, c
  static const struct file_operations tracing_stats_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_stats_read,
 +      .llseek         = generic_file_llseek,
  };
  
  #ifdef CONFIG_DYNAMIC_FTRACE
@@@ -3918,7 -3993,6 +3950,7 @@@ tracing_read_dyn_info(struct file *filp
  static const struct file_operations tracing_dyn_info_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_read_dyn_info,
 +      .llseek         = generic_file_llseek,
  };
  #endif
  
@@@ -4072,7 -4146,6 +4104,7 @@@ static const struct file_operations tra
        .open = tracing_open_generic,
        .read = trace_options_read,
        .write = trace_options_write,
 +      .llseek = generic_file_llseek,
  };
  
  static ssize_t
@@@ -4124,7 -4197,6 +4156,7 @@@ static const struct file_operations tra
        .open = tracing_open_generic,
        .read = trace_options_core_read,
        .write = trace_options_core_write,
 +      .llseek = generic_file_llseek,
  };
  
  struct dentry *trace_create_file(const char *name,
@@@ -4314,6 -4386,9 +4346,6 @@@ static __init int tracer_init_debugfs(v
        trace_create_file("dyn_ftrace_total_info", 0444, d_tracer,
                        &ftrace_update_tot_cnt, &tracing_dyn_info_fops);
  #endif
 -#ifdef CONFIG_SYSPROF_TRACER
 -      init_tracer_sysprof_debugfs(d_tracer);
 -#endif
  
        create_trace_options_dir();
  
@@@ -4531,16 -4606,14 +4563,14 @@@ __init static int tracer_alloc_buffers(
  
  
  #ifdef CONFIG_TRACER_MAX_TRACE
-       max_tr.buffer = ring_buffer_alloc(ring_buf_size,
-                                            TRACE_BUFFER_FLAGS);
+       max_tr.buffer = ring_buffer_alloc(1, TRACE_BUFFER_FLAGS);
        if (!max_tr.buffer) {
                printk(KERN_ERR "tracer: failed to allocate max ring buffer!\n");
                WARN_ON(1);
                ring_buffer_free(global_trace.buffer);
                goto out_free_cpumask;
        }
-       max_tr.entries = ring_buffer_size(max_tr.buffer);
-       WARN_ON(max_tr.entries != global_trace.entries);
+       max_tr.entries = 1;
  #endif
  
        /* Allocate the first page for all buffers */
diff --combined kernel/trace/trace.h
@@@ -22,6 -22,7 +22,6 @@@ enum trace_type 
        TRACE_STACK,
        TRACE_PRINT,
        TRACE_BPRINT,
 -      TRACE_SPECIAL,
        TRACE_MMIO_RW,
        TRACE_MMIO_MAP,
        TRACE_BRANCH,
@@@ -188,6 -189,7 +188,6 @@@ extern void __ftrace_bad_type(void)
                IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\
                IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT);   \
                IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \
 -              IF_ASSIGN(var, ent, struct special_entry, 0);           \
                IF_ASSIGN(var, ent, struct trace_mmiotrace_rw,          \
                          TRACE_MMIO_RW);                               \
                IF_ASSIGN(var, ent, struct trace_mmiotrace_map,         \
@@@ -274,6 -276,7 +274,7 @@@ struct tracer 
        struct tracer           *next;
        int                     print_max;
        struct tracer_flags     *flags;
+       int                     use_max_tr;
  };
  
  
@@@ -294,6 -297,7 +295,6 @@@ struct dentry *trace_create_file(const 
                                 const struct file_operations *fops);
  
  struct dentry *tracing_init_dentry(void);
 -void init_tracer_sysprof_debugfs(struct dentry *d_tracer);
  
  struct ring_buffer_event;
  
@@@ -330,6 -334,11 +331,6 @@@ void tracing_sched_wakeup_trace(struct 
                                struct task_struct *wakee,
                                struct task_struct *cur,
                                unsigned long flags, int pc);
 -void trace_special(struct trace_array *tr,
 -                 struct trace_array_cpu *data,
 -                 unsigned long arg1,
 -                 unsigned long arg2,
 -                 unsigned long arg3, int pc);
  void trace_function(struct trace_array *tr,
                    unsigned long ip,
                    unsigned long parent_ip,
@@@ -420,6 -429,8 +421,6 @@@ extern int trace_selftest_startup_nop(s
                                         struct trace_array *tr);
  extern int trace_selftest_startup_sched_switch(struct tracer *trace,
                                               struct trace_array *tr);
 -extern int trace_selftest_startup_sysprof(struct tracer *trace,
 -                                             struct trace_array *tr);
  extern int trace_selftest_startup_branch(struct tracer *trace,
                                         struct trace_array *tr);
  #endif /* CONFIG_FTRACE_STARTUP_TEST */
@@@ -581,6 -592,7 +582,7 @@@ enum trace_iterator_flags 
        TRACE_ITER_LATENCY_FMT          = 0x20000,
        TRACE_ITER_SLEEP_TIME           = 0x40000,
        TRACE_ITER_GRAPH_TIME           = 0x80000,
+       TRACE_ITER_RECORD_CMD           = 0x100000,
  };
  
  /*
@@@ -713,6 -725,8 +715,8 @@@ filter_check_discard(struct ftrace_even
        return 0;
  }
  
+ extern void trace_event_enable_cmd_record(bool enable);
  extern struct mutex event_mutex;
  extern struct list_head ftrace_events;
  
@@@ -16,9 -16,6 +16,6 @@@
  
  DECLARE_RWSEM(trace_event_mutex);
  
- DEFINE_PER_CPU(struct trace_seq, ftrace_event_seq);
- EXPORT_PER_CPU_SYMBOL(ftrace_event_seq);
  static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
  
  static int next_event_type = __TRACE_LAST_TYPE + 1;
@@@ -1069,6 -1066,65 +1066,6 @@@ static struct trace_event trace_wake_ev
        .funcs          = &trace_wake_funcs,
  };
  
 -/* TRACE_SPECIAL */
 -static enum print_line_t trace_special_print(struct trace_iterator *iter,
 -                                           int flags, struct trace_event *event)
 -{
 -      struct special_entry *field;
 -
 -      trace_assign_type(field, iter->ent);
 -
 -      if (!trace_seq_printf(&iter->seq, "# %ld %ld %ld\n",
 -                            field->arg1,
 -                            field->arg2,
 -                            field->arg3))
 -              return TRACE_TYPE_PARTIAL_LINE;
 -
 -      return TRACE_TYPE_HANDLED;
 -}
 -
 -static enum print_line_t trace_special_hex(struct trace_iterator *iter,
 -                                         int flags, struct trace_event *event)
 -{
 -      struct special_entry *field;
 -      struct trace_seq *s = &iter->seq;
 -
 -      trace_assign_type(field, iter->ent);
 -
 -      SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
 -      SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
 -      SEQ_PUT_HEX_FIELD_RET(s, field->arg3);
 -
 -      return TRACE_TYPE_HANDLED;
 -}
 -
 -static enum print_line_t trace_special_bin(struct trace_iterator *iter,
 -                                         int flags, struct trace_event *event)
 -{
 -      struct special_entry *field;
 -      struct trace_seq *s = &iter->seq;
 -
 -      trace_assign_type(field, iter->ent);
 -
 -      SEQ_PUT_FIELD_RET(s, field->arg1);
 -      SEQ_PUT_FIELD_RET(s, field->arg2);
 -      SEQ_PUT_FIELD_RET(s, field->arg3);
 -
 -      return TRACE_TYPE_HANDLED;
 -}
 -
 -static struct trace_event_functions trace_special_funcs = {
 -      .trace          = trace_special_print,
 -      .raw            = trace_special_print,
 -      .hex            = trace_special_hex,
 -      .binary         = trace_special_bin,
 -};
 -
 -static struct trace_event trace_special_event = {
 -      .type           = TRACE_SPECIAL,
 -      .funcs          = &trace_special_funcs,
 -};
 -
  /* TRACE_STACK */
  
  static enum print_line_t trace_stack_print(struct trace_iterator *iter,
  
  static struct trace_event_functions trace_stack_funcs = {
        .trace          = trace_stack_print,
 -      .raw            = trace_special_print,
 -      .hex            = trace_special_hex,
 -      .binary         = trace_special_bin,
  };
  
  static struct trace_event trace_stack_event = {
@@@ -1132,6 -1191,9 +1129,6 @@@ static enum print_line_t trace_user_sta
  
  static struct trace_event_functions trace_user_stack_funcs = {
        .trace          = trace_user_stack_print,
 -      .raw            = trace_special_print,
 -      .hex            = trace_special_hex,
 -      .binary         = trace_special_bin,
  };
  
  static struct trace_event trace_user_stack_event = {
@@@ -1249,6 -1311,7 +1246,6 @@@ static struct trace_event *events[] __i
        &trace_fn_event,
        &trace_ctx_event,
        &trace_wake_event,
 -      &trace_special_event,
        &trace_stack_event,
        &trace_user_stack_event,
        &trace_bprint_event,