• rcu的学习记录


    crash> p rcu_sched_state.node[0]
    $13 = {
      lock = {
        raw_lock = {
          slock = 748760225
        }
      },
      gpnum = 21141468,
      completed = 21141467,
      qsmask = 1,
      expmask = 0,
      wakemask = {
        counter = 0
      },
      qsmaskinit = 1,
      grpmask = 0,
      grplo = 0,
      grphi = 4095,
      grpnum = 0 '00',
      level = 0 '00',---------------来自灵魂的拷问,你的level编号,root是0级
      parent = 0x0,
      blkd_tasks = {
        next = 0xffffffff81a28e58,
        prev = 0xffffffff81a28e58
      },
      gp_tasks = 0x0,
      exp_tasks = 0x0,
      node_kthread_task = 0x0,
      node_kthread_status = 0
    }
    crash> p rcu_sched_state.node[1]
    $14 = {
      lock = {
        raw_lock = {
          slock = 2634718474
        }
      },
      gpnum = 21141468,
      completed = 21141467,
      qsmask = 1073741823,
      expmask = 0,
      wakemask = {
        counter = 0
      },
      qsmaskinit = 4294967295,
      grpmask = 1,-------------常量
      grplo = 0,
      grphi = 63,
      grpnum = 0 '00',
      level = 1 '01',
      parent = 0xffffffff81a28e00,------这个就是node[0]的地址
      blkd_tasks = {
        next = 0xffffffff81a28f58,
        prev = 0xffffffff81a28f58
      },
      gp_tasks = 0x0,
      exp_tasks = 0x0,
      node_kthread_task = 0x0,
      node_kthread_status = 0
    }
    crash> p &rcu_sched_state.node[0]
    $15 = (struct rcu_node *) 0xffffffff81a28e00

     4还会记录gp的历史最大值,即gp_max,

    p rcu_sched_state
    rcu_sched_state = $22 = {


    struct rcu_node node[65]-----省略
    level = {0xffffffff81a28e00, 0xffffffff81a28f00}, levelcnt = {1, 64, 4096, 0, 0}, levelspread = "@@", rda = 0xce00, signaled = 2 '02', fqs_active = 0 '00', fqs_need_gp = 0 '00', boost = 0 '00', gpnum = 21141468, completed = 21141467, onofflock = { raw_lock = { slock = 2569574696 } }, fqslock = { raw_lock = { slock = 659040072 } }, jiffies_force_qs = 4447515504, n_force_qs = 36185678, n_force_qs_lh = 219254, n_force_qs_ngp = 7, gp_start = 4447515501, jiffies_stall = 4447530501, gp_max = 54, name = 0xffffffff8178a4e7 "rcu_sched_state" }
    /*
     * Dynticks per-CPU state.
     */
    struct rcu_dynticks {
        int dynticks_nesting;    /* Track irq/process nesting level. */
        int dynticks_nmi_nesting; /* Track NMI nesting level. */
        atomic_t dynticks;    /* 偶数代表处于dyntick-idle*/
    };
    crash> rcu_sched_data
    PER-CPU DATA TYPE:
      struct rcu_data rcu_sched_data;
    PER-CPU ADDRESSES:
      [0]: ffff88207fc0ce00
      [1]: ffff88207fc2ce00
      [2]: ffff88207fc4ce00
      [3]: ffff88207fc6ce00
      [4]: ffff88207fc8ce00
      [5]: ffff88207fcace00
      [6]: ffff88207fccce00
      [7]: ffff88207fcece00
      [8]: ffff88407fc0ce00
      [9]: ffff88407fc2ce00
      [10]: ffff88407fc4ce00
      [11]: ffff88407fc6ce00
      [12]: ffff88407fc8ce00
      [13]: ffff88407fcace00
      [14]: ffff88407fccce00
      [15]: ffff88407fcece00
      [16]: ffff88207fd0ce00
      [17]: ffff88207fd2ce00
      [18]: ffff88207fd4ce00
      [19]: ffff88207fd6ce00
      [20]: ffff88207fd8ce00
      [21]: ffff88207fdace00
      [22]: ffff88207fdcce00
      [23]: ffff88207fdece00
      [24]: ffff88407fd0ce00
      [25]: ffff88407fd2ce00
      [26]: ffff88407fd4ce00
      [27]: ffff88407fd6ce00
      [28]: ffff88407fd8ce00
      [29]: ffff88407fdace00
      [30]: ffff88407fdcce00
      [31]: ffff88407fdece00
    crash> rcu_data ffff88407fd0ce00
    struct rcu_data {
      completed = 21141467,
      gpnum = 21141468,
      passed_quiesc_completed = 21141466,
      passed_quiesc = false,
      qs_pending = true,
      beenonline = true,
      preemptible = false,
      mynode = 0xffffffff81a28f00,
      grpmask = 16777216,
      nxtlist = 0xffff8831017b1280,
      nxttail = {0xffff88407fd0ce30, 0xffff88407fd0ce30, 0xffff88055065ab48, 0xffff88055065ab48},
      qlen = 0,
      qlen_last_fqs_check = 0,
      n_cbs_invoked = 292196490,
      n_cbs_orphaned = 0,
      n_cbs_adopted = 0,
      n_force_qs_snap = 0,
      blimit = 10,
      dynticks = 0xffff88407fd0cde0,
      dynticks_snap = 834727793,
      dynticks_fqs = 1555945,
      offline_fqs = 0,
      resched_ipi = 1016,
      n_rcu_pending = 130520066,
      n_rp_qs_pending = 24570,
      n_rp_report_qs = 19693251,
      n_rp_cb_ready = 8253,
      n_rp_cpu_needs_gp = 270805,
      n_rp_gp_completed = 19229197,
      n_rp_gp_started = 124913,
      n_rp_need_fqs = 16071,
      n_rp_need_nothing = 91177576,
      cpu = 24
    }
    crash> struct rcu_dynticks 0xffff88407fd0cde0
    struct rcu_dynticks {
      dynticks_nesting = 2,
      dynticks_nmi_nesting = 0,
      dynticks = {
        counter = 834728091--------奇数
      }
    }

    对于level的个数和node的个数:

    crash> !grep CONFIG_RCU_FANOUT  /boot/config-3.0.101-0.47.90-default
    CONFIG_RCU_FANOUT=64

    CONFIG_RCU_FANOUT_LEAF没有设置,则走代码默认设置

    给定由RCU_FANOUT 和RCU_FANOUT_LEAF指定的扇出的情况下,第21-24行分别计算单级(包含单个rcu_node结构),两级,三级和四级rcu_node支持的最大CPU数量这些数量的CPU分别保留在RCU_FANOUT_1, RCU_FANOUT_2, RCU_FANOUT_3和 RCU_FANOUT_4 C预处理器变量中。

    心得:

    在rcu的回调中,一般是引用计数为0再挂rcu,然后在执行rcu的时候,用bugon判断一下计数。

    static void release_tgcred(struct cred *cred)
    {
    #ifdef CONFIG_KEYS
        struct thread_group_cred *tgcred = cred->tgcred;
    
        if (atomic_dec_and_test(&tgcred->usage))
            call_rcu(&tgcred->rcu, release_tgcred_rcu);
    #endif
    }

    如上,可以见到 atomic_dec_and_test ,这通过将引用计数-1然后和0比较,如果相等,则返回1,否则返回0,那么其实就是原子判断引用计数是否为1,

    然后在rcu的回调中,通过BUG_ON的方式,确定是可以释放的,这样可以保证资源释放的时候,不会有其他的人在用这块内存了。这是一个好的编码习惯,减少了内存踩来踩去

    的风险。

    static void release_tgcred_rcu(struct rcu_head *rcu)
    {
        struct thread_group_cred *tgcred =
            container_of(rcu, struct thread_group_cred, rcu);
    
        BUG_ON(atomic_read(&tgcred->usage) != 0);
    
        key_put(tgcred->session_keyring);
        key_put(tgcred->process_keyring);
        kfree(tgcred);
    }

    rcu的嵌套问题,后面补充。

    水平有限,如果有错误,请帮忙提醒我。如果您觉得本文对您有帮助,可以点击下面的 推荐 支持一下我。版权所有,需要转发请带上本文源地址,博客一直在更新,欢迎 关注 。
  • 相关阅读:
    学习笔记
    核心网概要学习
    python基础知识
    python_基础知识_py运算符
    python_基础知识
    将博客搬至CSDN
    poj1182测试数据过了,但A不了,暂时放在这,以后再看
    score——3354
    杭电1241
    杭电1010(WA)
  • 原文地址:https://www.cnblogs.com/10087622blog/p/11142849.html
Copyright © 2020-2023  润新知