怕网页关了.....
:)
#define unlikely
后面那个是
void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect)
{
tarce_likely_condition(f, var, expect); /*同一文件中,先分析跟踪条件 */.
if(val == expect) /*如果通过层层分析,猜中就correct++*/
f->correct ++
else
f->incorrect++; /*如果没有命中,就不正确加1*/
}
EXPORT_SYMBOL(ftrace_likely_update);
static inline void trace_likely_condition(struct ftrace_branch_data *f, int val ,int expect)
{
if (!branch_tracing_enable) /*不允跟踪变量(此时为变量)*/
return;
probe_likely_condition(f, val, expect); /*同一文件,这里是很有可能跟踪*/
}
static void probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
{
struct ftrace_event_call *call = &event_branch; /*linux/ftrace_event.h*/
struct trace_array *tr = branch_tracer;
struct ring_buffer_event *event; /* include/types.h */
struct ring_buffer *buffer; /*ring_buffer */
unsigned long flags;
int cpu, pc;
const char *p;
if (unlikely ( !try))
return;
local_irq_save(flags);
cpu = raw_smp_processor_id();
if (atomic_inc_return ( &return rt->data[cpu]->disable) != 1)
goto out;
pc = preempt_count();
buffer = tr->buffer;
event = trace_buffer_lock_reserve(buffer, TRACE_BRANCH, sizeof(*entry), flags, pc);
if (!event)
goto out;
entry = ring_buffer_event_data(event);
/*Strip off the path, only save the file,削去路径*/
p = f->file + strlen(f->file);
while(p >= f->file && *p != '/')
p--;
p++;
strncpy(entry->func, f->func, TRACE_FUNC_SIZE);
strncpy(entry->file, p, TRACE_FILE_SIZE);
entry->func[TRACE_FUNC_SIZE] = 0;
entry->file[TRACE_FILE_SIZE] =0;
entry->line = f->line;
entry->correct = val == expect;
if (! filter_check_discard(call, entry, buffer, event))
ring_buffer_unlock_commit(buffer,event);
out:
atomic_dec (&tr->data[cpu]->disable);
local_irq_restore(flags);
}
struct ftrace_event_call {
struct list_head list; /*链入队列*/
struct ftrace_event_class *class; /*in the same file */
char * name;
struct dentry *dir; /*I eventually find the familiar stuff 0.0 */
struct trace_event event; /*in the same file*/
const char *print_fmt;
struct event_filter *filter;
void *mod;
void *data;
unsigned int flags;
#define CONFIG_FERF_EVENTS
int perf_refcount;
struct hlist_head __percpu *perf_event;
#endif
};
struct ftrace_event_class {
char *system;
void *probe;
#ifdef CONFIG_FERE_EVENTS
void *perf_probe;
#endif
int (*reg)(struct ftrace_event_call *event, enum trace_reg type);
int (*define_fields) (struct ftrace_event_call *);
struct list_head *(*get_fields) (struct ftrace_event_call *);
struct list_head filed;
}
struct trace_event {
struct hlist_node node; /*linux/types.h*/
struct list_head list;
int type;
struct trace_event_functions *funcs;}
__________________________________________________________________
struct hlist_node {
struct hlist_node *next, **pprev; /*这里的**prev便于在某个前面插入节点*/
};
struct list_head {
struct list_head *next, *prev;
};
两个不同是:list_head 是创建单向后方插入*/
_______________________________________________________________________________
struct trace_event_functions {
trace_print_func trace; /*function name*/
trace_print_func raw;
trace_print_func hex;
trace_print_func binary;
};
typedef enum print_line_t (*trace_print_func) (struct trace_interator *itemr \
int flags, struct trace_event *event);
返回为 enum的值*/
________________________________________________________________________________
struct event_filter { /*过滤器*/
int n_preds;
int a_preds;
struct filter_pred *preds; /*
struct filter_pred *root; /*.................I have come to the desert,even goole gets little*/
char *filter_string ; /*.................*/
}
struct filter_pred {
filter_pred_fn_t fn; /*function poiter */
u64 val;
struct regex regex; /*in the same file*/
/*leaf nodes use field_name, ops is used by AND and OR nodes. */
union {
char *field_name;
unsigned short *ops;
};
int offset;
int not;
int op;
unsigned short index;
unsigned short parent;
unsigned short left;
unsigned short right;
};
struct regex {
char patter[MAX_FILTER_STR_VAL];
int len;
int field_len;
regex_match_func match; /*same file*/
};
typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void * event);
typedef int (*register_match_func) (char *str, regex *r, int len);
这里对我来说,资料和能力有限。有证据时回来分析
__________________________________________________________________________________
接着前面的
static inline unsigned long __raw_spin_lock_irqsave(raw_spinlock_t *lock)
先见到的是
I go the wrong path, so get the alpha or sparc arch.......#define local_irq_save(flags)
do { \
raw_lock_irq_save(flags); \ /*In the same file*/
}while ( 0 )
____________----->
#define raw_local_irq_save(flags) \
do { \
typecheck(unsigned long, flags); \ /*类型检查,见第一个*/
flags = arch_local_irq_save() ; \
}while (0)
_____________---->
static inline unsigned long arch_local_irq_save(void)
{
unsigned long flags = swpipl(LPL_MAX); /*LPL_MAX 7 就是swpipl( 7 )*/
barrier ();
return flags;
}
First the swpipl is in the asm-alpha or asm-sparc's subdir system.h
in the linux/asm-alhpa/system.h
____---->
#define cli() = swpipl( 7 ) /*这是alpha 汇编指令对应格式 ,走远了.
#define swpipl(__new_ip1) \
({ unsigned long __old_ip1; \
__asm__ __volitile__ ( \
"bis %1 , %1, $16, \n\t" \
".long 53 \n \t" \
"bis $0, $0, %0 " \n
: " =r " (__old_ip1) \
:"r" (__new_ip1) \
:"$0", "$1", "$16", "$22", "$23","$24","$25"); \
__old_ip1;})
_______________________________________________________________________x86 platformstatic inline unsigned long arch_local_irq_save(void )
{
unsigned long flags = arch_local_save_flags(); /*arch/x86/include/asm/irqflags.h
*/
arch_local_irq_disable(); /*arch/x86/include/asm/irqflags.h*/_____---->
return flags;
}
static inline unsigned long arch_local_save_flags (void)
{
return native_save_fl(); /*起到了保存flags作用*/
}
/*The last step often uses the assemble*/
static inline unsigned long native_save_fl(void )
{
unsigned long flags;
asm volitile("# __raw_save_flags \n \t"
"pushf ; pop %0 "
: "=rm" (flags) /*理解为将flags地址装入m或者装入r,前面pushf将flags装入堆栈,然后pop%0,分别装入内存m或者r,起到了保存flags作用。*/
: /*no input */
:"memory ");
return flags;
}
static inline notrace void arch_local_irq_disable(void)
{
PVOP_VCALLEEO(pv_irq_ops.irq_disable);
}
#define PVOP_VCALLEEO(op)
__PVOP_VCALLEESAVE(op, " ", " ") /* In the same file */
#define __PVOP_VCALLEESAVE(op, pre, post, ...)
____PVOP_VCALL(op.func, CLOBBERS, , pre, post, ##__VA_ARGS__)
______________________------------>
#define ____PVOP_VCALL(op, clbr, call_clbr, extra_clbr, pre, post, ...)
( { \
PVOP_VCALL_ARGS; \
PVOP_TEST_NULL(op); \
asm volatile (pre \
paravirt_alt (PARAVITE_CALL) \
post \
: call_clbr \
: paravirt_type( op ), \
paravirt_clobber(clbr) , \
##__VA_ARGS__ \
:"memory", "cc" extra_clbr); \
})
__________________---------------------->
#define paravirt_alt(insn_string)
_paravirt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]")
___________________-------------------->
#define _paravirt_alt(insn_string, type, clobber) \
"771 : \n \t" insn_string "\n" "772 : \n" \
".pushsection .parainstructions , \"a \n" \n" \
"_ASM_ALAIN " \n" \
".btye " type "\n" \
".byte 772b-771b \n " \
".short " clobber " \n" \
".popsection \n"