diff options
| author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-05-15 10:26:50 -0400 | 
|---|---|---|
| committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-05-15 10:26:50 -0400 | 
| commit | 12e04ffcd93b25dfd726d46338c2ee7d23de556e (patch) | |
| tree | f91479a62805619168994fd3ee55e3ffa23fc24e /kernel/trace/trace.h | |
| parent | 9eff37a8713939f218ab8bf0dc93f1d67af7b8b4 (diff) | |
| parent | f722406faae2d073cc1d01063d1123c35425939e (diff) | |
Merge tag 'v3.10-rc1' into stable/for-linus-3.10
Linux 3.10-rc1
* tag 'v3.10-rc1': (12273 commits)
  Linux 3.10-rc1
  [SCSI] qla2xxx: Update firmware link in Kconfig file.
  [SCSI] iscsi class, qla4xxx: fix sess/conn refcounting when find fns are used
  [SCSI] sas: unify the pointlessly separated enums sas_dev_type and sas_device_type
  [SCSI] pm80xx: thermal, sas controller config and error handling update
  [SCSI] pm80xx: NCQ error handling changes
  [SCSI] pm80xx: WWN Modification for PM8081/88/89 controllers
  [SCSI] pm80xx: Changed module name and debug messages update
  [SCSI] pm80xx: Firmware flash memory free fix, with addition of new memory region for it
  [SCSI] pm80xx: SPC new firmware changes for device id 0x8081 alone
  [SCSI] pm80xx: Added SPCv/ve specific hardware functionalities and relevant changes in common files
  [SCSI] pm80xx: MSI-X implementation for using 64 interrupts
  [SCSI] pm80xx: Updated common functions common for SPC and SPCv/ve
  [SCSI] pm80xx: Multiple inbound/outbound queue configuration
  [SCSI] pm80xx: Added SPCv/ve specific ids, variables and modify for SPC
  [SCSI] lpfc: fix up Kconfig dependencies
  [SCSI] Handle MLQUEUE busy response in scsi_send_eh_cmnd
  dm cache: set config value
  dm cache: move config fns
  dm thin: generate event when metadata threshold passed
  ...
Diffstat (limited to 'kernel/trace/trace.h')
| -rw-r--r-- | kernel/trace/trace.h | 149 | 
1 files changed, 122 insertions, 27 deletions
| diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 2081971367e..711ca7d3e7f 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -13,6 +13,11 @@  #include <linux/trace_seq.h>  #include <linux/ftrace_event.h> +#ifdef CONFIG_FTRACE_SYSCALLS +#include <asm/unistd.h>		/* For NR_SYSCALLS	     */ +#include <asm/syscall.h>	/* some archs define it here */ +#endif +  enum trace_type {  	__TRACE_FIRST_TYPE = 0, @@ -29,6 +34,7 @@ enum trace_type {  	TRACE_GRAPH_ENT,  	TRACE_USER_STACK,  	TRACE_BLK, +	TRACE_BPUTS,  	__TRACE_LAST_TYPE,  }; @@ -103,11 +109,6 @@ struct kretprobe_trace_entry_head {  	unsigned long		ret_ip;  }; -struct uprobe_trace_entry_head { -	struct trace_entry	ent; -	unsigned long		ip; -}; -  /*   * trace_flag_type is an enumeration that holds different   * states when a trace occurs. These are: @@ -127,12 +128,21 @@ enum trace_flag_type {  #define TRACE_BUF_SIZE		1024 +struct trace_array; + +struct trace_cpu { +	struct trace_array	*tr; +	struct dentry		*dir; +	int			cpu; +}; +  /*   * The CPU trace array - it consists of thousands of trace entries   * plus some other descriptor data: (for example which task started   * the trace, etc.)   */  struct trace_array_cpu { +	struct trace_cpu	trace_cpu;  	atomic_t		disabled;  	void			*buffer_page;	/* ring buffer spare */ @@ -151,20 +161,83 @@ struct trace_array_cpu {  	char			comm[TASK_COMM_LEN];  }; +struct tracer; + +struct trace_buffer { +	struct trace_array		*tr; +	struct ring_buffer		*buffer; +	struct trace_array_cpu __percpu	*data; +	cycle_t				time_start; +	int				cpu; +}; +  /*   * The trace array - an array of per-CPU trace arrays. This is the   * highest level data structure that individual tracers deal with.   * They have on/off state as well:   */  struct trace_array { -	struct ring_buffer	*buffer; -	int			cpu; +	struct list_head	list; +	char			*name; +	struct trace_buffer	trace_buffer; +#ifdef CONFIG_TRACER_MAX_TRACE +	/* +	 * The max_buffer is used to snapshot the trace when a maximum +	 * latency is reached, or when the user initiates a snapshot. +	 * Some tracers will use this to store a maximum trace while +	 * it continues examining live traces. +	 * +	 * The buffers for the max_buffer are set up the same as the trace_buffer +	 * When a snapshot is taken, the buffer of the max_buffer is swapped +	 * with the buffer of the trace_buffer and the buffers are reset for +	 * the trace_buffer so the tracing can continue. +	 */ +	struct trace_buffer	max_buffer; +	bool			allocated_snapshot; +#endif  	int			buffer_disabled; -	cycle_t			time_start; +	struct trace_cpu	trace_cpu;	/* place holder */ +#ifdef CONFIG_FTRACE_SYSCALLS +	int			sys_refcount_enter; +	int			sys_refcount_exit; +	DECLARE_BITMAP(enabled_enter_syscalls, NR_syscalls); +	DECLARE_BITMAP(enabled_exit_syscalls, NR_syscalls); +#endif +	int			stop_count; +	int			clock_id; +	struct tracer		*current_trace; +	unsigned int		flags; +	raw_spinlock_t		start_lock; +	struct dentry		*dir; +	struct dentry		*options; +	struct dentry		*percpu_dir; +	struct dentry		*event_dir; +	struct list_head	systems; +	struct list_head	events;  	struct task_struct	*waiter; -	struct trace_array_cpu	*data[NR_CPUS]; +	int			ref; +}; + +enum { +	TRACE_ARRAY_FL_GLOBAL	= (1 << 0)  }; +extern struct list_head ftrace_trace_arrays; + +/* + * The global tracer (top) should be the first trace array added, + * but we check the flag anyway. + */ +static inline struct trace_array *top_trace_array(void) +{ +	struct trace_array *tr; + +	tr = list_entry(ftrace_trace_arrays.prev, +			typeof(*tr), list); +	WARN_ON(!(tr->flags & TRACE_ARRAY_FL_GLOBAL)); +	return tr; +} +  #define FTRACE_CMP_TYPE(var, type) \  	__builtin_types_compatible_p(typeof(var), type *) @@ -200,6 +273,7 @@ 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 bputs_entry, TRACE_BPUTS);	\  		IF_ASSIGN(var, ent, struct trace_mmiotrace_rw,		\  			  TRACE_MMIO_RW);				\  		IF_ASSIGN(var, ent, struct trace_mmiotrace_map,		\ @@ -289,9 +363,10 @@ struct tracer {  	struct tracer		*next;  	struct tracer_flags	*flags;  	bool			print_max; -	bool			use_max_tr; -	bool			allocated_snapshot;  	bool			enabled; +#ifdef CONFIG_TRACER_MAX_TRACE +	bool			use_max_tr; +#endif  }; @@ -427,8 +502,6 @@ static __always_inline void trace_clear_recursion(int bit)  	current->trace_recursion = val;  } -#define TRACE_PIPE_ALL_CPU	-1 -  static inline struct ring_buffer_iter *  trace_buffer_iter(struct trace_iterator *iter, int cpu)  { @@ -439,10 +512,10 @@ trace_buffer_iter(struct trace_iterator *iter, int cpu)  int tracer_init(struct tracer *t, struct trace_array *tr);  int tracing_is_enabled(void); -void tracing_reset(struct trace_array *tr, int cpu); -void tracing_reset_online_cpus(struct trace_array *tr); +void tracing_reset(struct trace_buffer *buf, int cpu); +void tracing_reset_online_cpus(struct trace_buffer *buf);  void tracing_reset_current(int cpu); -void tracing_reset_current_online_cpus(void); +void tracing_reset_all_online_cpus(void);  int tracing_open_generic(struct inode *inode, struct file *filp);  struct dentry *trace_create_file(const char *name,  				 umode_t mode, @@ -450,6 +523,7 @@ struct dentry *trace_create_file(const char *name,  				 void *data,  				 const struct file_operations *fops); +struct dentry *tracing_init_dentry_tr(struct trace_array *tr);  struct dentry *tracing_init_dentry(void);  struct ring_buffer_event; @@ -583,7 +657,7 @@ extern int DYN_FTRACE_TEST_NAME(void);  #define DYN_FTRACE_TEST_NAME2 trace_selftest_dynamic_test_func2  extern int DYN_FTRACE_TEST_NAME2(void); -extern int ring_buffer_expanded; +extern bool ring_buffer_expanded;  extern bool tracing_selftest_disabled;  DECLARE_PER_CPU(int, ftrace_cpu_disabled); @@ -619,6 +693,8 @@ trace_array_vprintk(struct trace_array *tr,  		    unsigned long ip, const char *fmt, va_list args);  int trace_array_printk(struct trace_array *tr,  		       unsigned long ip, const char *fmt, ...); +int trace_array_printk_buf(struct ring_buffer *buffer, +			   unsigned long ip, const char *fmt, ...);  void trace_printk_seq(struct trace_seq *s);  enum print_line_t print_trace_line(struct trace_iterator *iter); @@ -786,6 +862,7 @@ enum trace_iterator_flags {  	TRACE_ITER_STOP_ON_FREE		= 0x400000,  	TRACE_ITER_IRQ_INFO		= 0x800000,  	TRACE_ITER_MARKERS		= 0x1000000, +	TRACE_ITER_FUNCTION		= 0x2000000,  };  /* @@ -832,8 +909,8 @@ enum {  struct ftrace_event_field {  	struct list_head	link; -	char			*name; -	char			*type; +	const char		*name; +	const char		*type;  	int			filter_type;  	int			offset;  	int			size; @@ -851,12 +928,19 @@ struct event_filter {  struct event_subsystem {  	struct list_head	list;  	const char		*name; -	struct dentry		*entry;  	struct event_filter	*filter; -	int			nr_events;  	int			ref_count;  }; +struct ftrace_subsystem_dir { +	struct list_head		list; +	struct event_subsystem		*subsystem; +	struct trace_array		*tr; +	struct dentry			*entry; +	int				ref_count; +	int				nr_events; +}; +  #define FILTER_PRED_INVALID	((unsigned short)-1)  #define FILTER_PRED_IS_RIGHT	(1 << 15)  #define FILTER_PRED_FOLD	(1 << 15) @@ -906,22 +990,20 @@ struct filter_pred {  	unsigned short		right;  }; -extern struct list_head ftrace_common_fields; -  extern enum regex_type  filter_parse_regex(char *buff, int len, char **search, int *not);  extern void print_event_filter(struct ftrace_event_call *call,  			       struct trace_seq *s);  extern int apply_event_filter(struct ftrace_event_call *call,  			      char *filter_string); -extern int apply_subsystem_event_filter(struct event_subsystem *system, +extern int apply_subsystem_event_filter(struct ftrace_subsystem_dir *dir,  					char *filter_string);  extern void print_subsystem_event_filter(struct event_subsystem *system,  					 struct trace_seq *s);  extern int filter_assign_type(const char *type); -struct list_head * -trace_get_fields(struct ftrace_event_call *event_call); +struct ftrace_event_field * +trace_find_event_field(struct ftrace_event_call *call, char *name);  static inline int  filter_check_discard(struct ftrace_event_call *call, void *rec, @@ -938,6 +1020,8 @@ filter_check_discard(struct ftrace_event_call *call, void *rec,  }  extern void trace_event_enable_cmd_record(bool enable); +extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr); +extern int event_trace_del_tracer(struct trace_array *tr);  extern struct mutex event_mutex;  extern struct list_head ftrace_events; @@ -948,7 +1032,18 @@ extern const char *__stop___trace_bprintk_fmt[];  void trace_printk_init_buffers(void);  void trace_printk_start_comm(void);  int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set); -int set_tracer_flag(unsigned int mask, int enabled); +int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled); + +/* + * Normal trace_printk() and friends allocates special buffers + * to do the manipulation, as well as saves the print formats + * into sections to display. But the trace infrastructure wants + * to use these without the added overhead at the price of being + * a bit slower (used mainly for warnings, where we don't care + * about performance). The internal_trace_puts() is for such + * a purpose. + */ +#define internal_trace_puts(str) __trace_puts(_THIS_IP_, str, strlen(str))  #undef FTRACE_ENTRY  #define FTRACE_ENTRY(call, struct_name, id, tstruct, print, filter)	\ | 
