• tracer ftrace笔记(9)—— TRACE_EVENT 初始化 Hello


    基于Linux-5.10

    一、内核启动时遍历 trace_event_call 初始化流程

    1. TRACE_EVENT()多次展开定义了各种实现函数以后,最终把本 event 的所有的函数和数据存放在一个类型为 struct trace_event_call 的顶层变量中,并且会把指针存放到 section(“_ftrace_events”) 中。在 trace_events 初始化时会逐个遍历 section("_ftrace_events") 中的指针来添加静态的 events。

    TRACE_EVENT(sched_blocked_reason, ...) 宏解析后:

    static struct trace_event_call __used __section("_ftrace_events") 
        *__event_sched_blocked_reason = &event_sched_blocked_reason;

    链接脚本 include/asm-generic/vmlinux.lds.h

    #define FTRACE_EVENTS()    . = ALIGN(8);    \
        __start_ftrace_events = .;            \
        KEEP(*(_ftrace_events))                \
        __stop_ftrace_events = .;            \

    函数调用路径:

    trace_init //trace/trace.c
        trace_event_init //trace/trace_events.c
            event_trace_enable //trace/trace_events.c

    event_trace_enable() 函数:

    static __init int event_trace_enable(void) //trace/trace_events.c
    {
        struct trace_event_call **iter, *call;
        int ret;
        ...
    
        /*
         * 从 section("_ftrace_events") 逐个拿出使用 TRACE_EVENT() 宏定义的
         * trace_event_call 指针,并进行初始化
        */
        for_each_event(iter, __start_ftrace_events, __stop_ftrace_events) {
            call = *iter;
            /* 初始化trace_event_call */
            ret = event_init(call);
            if (!ret)
                /* 挂到全局 ftrace_events 链表上 */
                list_add(&call->list, &ftrace_events);
        }
        ...
    
        return 0;
    }

    event_init() 函数:

    static int event_init(struct trace_event_call *call)
    {
        int ret = 0;
        const char *name;
    
        /* TRACE_EVENT()定义的就是第一个参数 name 成员 */
        name = trace_event_name(call);
        if (WARN_ON(!name))
            return -EINVAL;
    
        /* TRACE_EVENT()定义的就是 trace_event_raw_init() */
        if (call->class->raw_init) {
            /* 初始化后注册trace event,就是放在全局hash表 event_hash[key] 上 */
            ret = call->class->raw_init(call);
            if (ret < 0 && ret != -ENOSYS)
                pr_warn("Could not initialize trace events/%s\n", name);
        }
    
        return ret;
    }

    参考:

    深入理解Linux ftrace 之 trace event: https://mp.weixin.qq.com/s/1A02qv5SIEgTEvsN1DWzqQ

  • 相关阅读:
    获取系统信息
    Spring下获取项目根路径--good
    Java 获取webapp,Root,classpath,项目等路径工具类
    并发与并行的区别
    享元模式的简单使用
    mysql 分库分表(水平切割和垂直切割)
    sql随机筛选几条记录
    创建表
    sql字段组合唯一
    Jobject 使用
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/16779654.html
Copyright © 2020-2023  润新知