Re: Re: [PATCH 2/9] docs/zh_CN: core-api: Update the translation of cpu_hotplug.rst to 5.19-rc2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi xiangcheng:

> -----原始邮件-----
&gt; 发件人: "Wu XiangCheng" <bobwxc@xxxxxxxx>
&gt; 发送时间: 2022-06-16 08:21:38 (星期四)
&gt; 收件人: "Binbin Zhou" <zhoubinbin@xxxxxxxxxxx>
&gt; 抄送: "Wu X.C." <bobwxc@xxxxxxxx>, alexs@xxxxxxxxxx, siyanteng@xxxxxxxxxxx, corbet@xxxxxxx, chenhuacai@xxxxxxxxxxx, linux-doc@xxxxxxxxxxxxxxx
&gt; 主题: Re: [PATCH 2/9] docs/zh_CN: core-api: Update the translation of cpu_hotplug.rst to 5.19-rc2
&gt; 
&gt; From: "Wu X.C." <bobwxc@xxxxxxxx>
&gt; 
&gt; Hi Binbin,
&gt; 
&gt; On Wed, Jun 15, 2022 at 05:24:25PM +0800, Binbin Zhou wrote:
&gt; &gt; Synchronous translation from upstream commit c9871c800f65
&gt; &gt; ("Documentation: core-api/cpuhotplug: Rewrite the API section")
&gt; &gt; 
&gt; &gt; Signed-off-by: Binbin Zhou <zhoubinbin@xxxxxxxxxxx>
&gt; &gt; ---
&gt; &gt;  .../zh_CN/core-api/cpu_hotplug.rst            | 435 +++++++++++++++---
&gt; &gt;  1 file changed, 377 insertions(+), 58 deletions(-)
&gt; &gt; 
&gt; &gt; diff --git a/Documentation/translations/zh_CN/core-api/cpu_hotplug.rst b/Documentation/translations/zh_CN/core-api/cpu_hotplug.rst
&gt; &gt; index 85a264287426..007a58f8086d 100644
&gt; &gt; --- a/Documentation/translations/zh_CN/core-api/cpu_hotplug.rst
&gt; &gt; +++ b/Documentation/translations/zh_CN/core-api/cpu_hotplug.rst
&gt; &gt; @@ -4,6 +4,7 @@
&gt; &gt;  :翻译:
&gt; &gt;  
&gt; &gt;   司延腾 Yanteng Si <siyanteng@xxxxxxxxxxx>
&gt; &gt; + 周彬彬 Binbin Zhou <zhoubinbin@xxxxxxxxxxx>
&gt; &gt;  
&gt; &gt;  :校译:
&gt; &gt;  
&gt; &gt; @@ -15,12 +16,13 @@
&gt; &gt;  内核中的CPU热拔插
&gt; &gt;  =================
&gt; &gt;  
&gt; &gt; -:时间: 2016年12月
&gt; &gt; +:时间: 2021年9月
&gt; &gt;  :作者: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>,
&gt; &gt; -          Rusty Russell <rusty@xxxxxxxxxxxxxxx>,
&gt; &gt; -          Srivatsa Vaddagiri <vatsa@xxxxxxxxxx>,
&gt; &gt; -          Ashok Raj <ashok.raj@xxxxxxxxx>,
&gt; &gt; -          Joel Schopp <jschopp@xxxxxxxxxxxxxx>
&gt; &gt; +       Rusty Russell <rusty@xxxxxxxxxxxxxxx>,
&gt; &gt; +       Srivatsa Vaddagiri <vatsa@xxxxxxxxxx>,
&gt; &gt; +       Ashok Raj <ashok.raj@xxxxxxxxx>,
&gt; &gt; +       Joel Schopp <jschopp@xxxxxxxxxxxxxx>,
&gt; &gt; +       Thomas Gleixner <tglx@xxxxxxxxxxxxx>
&gt; &gt;  
&gt; &gt;  简介
&gt; &gt;  ====
&gt; &gt; @@ -139,7 +141,7 @@ CPU的热拔插协作
&gt; &gt;  下线情况
&gt; &gt;  --------
&gt; &gt;  
&gt; &gt; -一旦CPU被逻辑关闭,注册的热插拔状态的清除回调将被调用,从 ``CPUHP_ONLINE`` 开始,在
&gt; &gt; +一旦CPU被逻辑关闭,注册的热插拔状态的清除回调将被调用,从 ``CPUHP_ONLINE`` 开始,到
&gt; &gt;  ``CPUHP_OFFLINE`` 状态结束。这包括:
&gt; &gt;  
&gt; &gt;  * 如果任务因暂停操作而被冻结,那么 *cpuhp_tasks_frozen* 将被设置为true。
&gt; &gt; @@ -154,82 +156,399 @@ CPU的热拔插协作
&gt; &gt;  * 一旦所有的服务被迁移,内核会调用一个特定的例程 ``__cpu_disable()`` 来进行特定的清
&gt; &gt;    理。
&gt; &gt;  
&gt; &gt; -使用热插拔API
&gt; &gt; --------------
&gt; &gt; +CPU热插拔API
&gt; &gt; +============
&gt; &gt; +
&gt; &gt; +CPU热拔插状态机
&gt; &gt; +---------------
&gt; &gt; +
&gt; &gt; +CPU热插拔使用一个从CPUHP_OFFLINE到CPUHP_ONLINE的线性状态空间的普通状态机。每个状态都
&gt; &gt; +有一个startup和teardown的回调。
&gt; &gt; +
&gt; &gt; +当一个CPU上线时,将按顺序调用startup回调,直到达到CPUHP_ONLINE状态。当设置状态的回调
&gt; &gt; +或将实例添加到多实例状态时,也可以调用它们。
&gt; &gt; +
&gt; &gt; +当一个CPU下线时,将按相反的顺序依次调用teardown回调,直到达到CPUHP_OFFLINE状态。当删
&gt; &gt; +除状态的回调或从多实例状态中删除实例时,也可以调用它们。
&gt; &gt; +
&gt; &gt; +如果某个使用场景只需要一个方向的热插拔操作回调(CPU上线或CPU下线),则在设置状态时,
&gt; &gt; +可以将另一个不需要的回调设置为NULL。
&gt; &gt; +
&gt; &gt; +状态空间被划分成三个阶段:
&gt; &gt; +
&gt; &gt; +* PREPARE阶段
&gt; &gt; +
&gt; &gt; +  PREPARE阶段涵盖了从CPUHP_OFFLINE到CPUHP_BRINGUP_CPU之间的状态空间。
&gt; &gt; +
&gt; &gt; +  在该阶段中,startup回调在CPU上线操作启动CPU之前被调用,teardown回调在CPU下线操作使
&gt; &gt; +  CPU功能失调之后被调用。
&gt; 
&gt; dysfunctional -&gt; 失效 ?
&gt; 功能失调 is quite strange, if you agree, repalce all 'dysfunctional'.

Yes,“失效“ is a better translation.
&gt; 
&gt; &gt; +
&gt; &gt; +  这些回调是在控制CPU上调用的,因为它们显然不能在热插拔的CPU上运行,此时热插拔的CPU要
&gt; &gt; +  么还没有启动,要么已经功能失调。
&gt; &gt; +
&gt; &gt; +  startup回调用于设置CPU成功上线所需要的资源。teardown回调用于释放资源或在热插拔的CPU
&gt; &gt; +  不能正常工作后,将待处理的工作转移到在线的CPU上。
&gt; &gt; +
&gt; &gt; +  允许startup回调失败。如果回调失败,CPU上线操作被中止,CPU将再次被降到之前的状态(通
&gt; &gt; +  常是CPUHP_OFFLINE)。
&gt; &gt; +
&gt; &gt; +  本阶段中的teardown回调不允许失败。
&gt; &gt; +
&gt; &gt; +* STARTING阶段
&gt; &gt; +
&gt; &gt; +  STARTING阶段涵盖了CPUHP_BRINGUP_CPU + 1到CPUHP_AP_ONLINE之间的状态空间。
&gt; &gt; +
&gt; &gt; +  该阶段中的startup回调是在早期CPU设置代码中的CPU上线操作期间,禁用中断的情况下在热拔
&gt; &gt; +  插的CPU上被调用。teardown回调是在CPU完全关闭前不久的CPU下线操作期间,禁用中断的情况
&gt; &gt; +  下在热拔插的CPU上被调用。
&gt; &gt; +
&gt; &gt; +  该阶段中的回调不允许失败。
&gt; &gt; +
&gt; &gt; +  回调用于低级别的硬件初始化/关机和核心子系统。
&gt; &gt; +
&gt; &gt; +* ONLINE阶段
&gt; &gt; +
&gt; &gt; +  ONLINE阶段涵盖了CPUHP_AP_ONLINE + 1到CPUHP_ONLINE之间的状态空间。
&gt; &gt; +
&gt; &gt; +  该阶段中的startup回调是在CPU上线时在热插拔的CPU上调用的。teardown回调是在CPU下线操
&gt; &gt; +  作时在热插拔CPU上调用的。
&gt; &gt; +
&gt; &gt; +  回调是在每个CPU热插拔线程的上下文中调用的,该线程绑定在热插拔的CPU上。回调是在启用
&gt; &gt; +  中断和抢占的情况下调用的。
&gt; &gt; +
&gt; &gt; +  允许回调失败。如果回调失败,CPU热插拔操作被中止,CPU将恢复到之前的状态。
&gt; &gt; +
&gt; &gt; +CPU 上线/下线操作
&gt; &gt; +-----------------
&gt; &gt; +
&gt; &gt; +一个成功的上线操作如下::
&gt; &gt; +
&gt; &gt; +  [CPUHP_OFFLINE]
&gt; &gt; +  [CPUHP_OFFLINE + 1]-&gt;startup()       -&gt; 成功
&gt; &gt; +  [CPUHP_OFFLINE + 2]-&gt;startup()       -&gt; 成功
&gt; &gt; +  [CPUHP_OFFLINE + 3]                  -&gt; 略过,因为startup == NULL
&gt; &gt; +  ...
&gt; &gt; +  [CPUHP_BRINGUP_CPU]-&gt;startup()       -&gt; 成功
&gt; &gt; +  === PREPARE阶段结束
&gt; &gt; +  [CPUHP_BRINGUP_CPU + 1]-&gt;startup()   -&gt; 成功
&gt; &gt; +  ...
&gt; &gt; +  [CPUHP_AP_ONLINE]-&gt;startup()         -&gt; 成功
&gt; &gt; +  === STARTUP阶段结束
&gt; &gt; +  [CPUHP_AP_ONLINE + 1]-&gt;startup()     -&gt; 成功
&gt; &gt; +  ...
&gt; &gt; +  [CPUHP_ONLINE - 1]-&gt;startup()        -&gt; 成功
&gt; &gt; +  [CPUHP_ONLINE]
&gt; &gt; +
&gt; &gt; +一个成功的下线操作如下::
&gt; &gt; +
&gt; &gt; +  [CPUHP_ONLINE]
&gt; &gt; +  [CPUHP_ONLINE - 1]-&gt;teardown()       -&gt; 成功
&gt; &gt; +  ...
&gt; &gt; +  [CPUHP_AP_ONLINE + 1]-&gt;teardown()    -&gt; 成功
&gt; &gt; +  === STARTUP阶段开始
&gt; &gt; +  [CPUHP_AP_ONLINE]-&gt;teardown()        -&gt; 成功
&gt; &gt; +  ...
&gt; &gt; +  [CPUHP_BRINGUP_ONLINE - 1]-&gt;teardown()
&gt; &gt; +  ...
&gt; &gt; +  === PREPARE阶段开始
&gt; &gt; +  [CPUHP_BRINGUP_CPU]-&gt;teardown()
&gt; &gt; +  [CPUHP_OFFLINE + 3]-&gt;teardown()
&gt; &gt; +  [CPUHP_OFFLINE + 2]                  -&gt; 略过,因为teardown == NULL
&gt; &gt; +  [CPUHP_OFFLINE + 1]-&gt;teardown()
&gt; &gt; +  [CPUHP_OFFLINE]
&gt; &gt; +
&gt; &gt; +一个失败的上线操作如下::
&gt; &gt; +
&gt; &gt; +  [CPUHP_OFFLINE]
&gt; &gt; +  [CPUHP_OFFLINE + 1]-&gt;startup()       -&gt; 成功
&gt; &gt; +  [CPUHP_OFFLINE + 2]-&gt;startup()       -&gt; 成功
&gt; &gt; +  [CPUHP_OFFLINE + 3]                  -&gt; 略过,因为startup == NULL
&gt; &gt; +  ...
&gt; &gt; +  [CPUHP_BRINGUP_CPU]-&gt;startup()       -&gt; 成功
&gt; &gt; +  === PREPARE阶段结束
&gt; &gt; +  [CPUHP_BRINGUP_CPU + 1]-&gt;startup()   -&gt; 成功
&gt; &gt; +  ...
&gt; &gt; +  [CPUHP_AP_ONLINE]-&gt;startup()         -&gt; 成功
&gt; &gt; +  === STARTUP阶段结束
&gt; &gt; +  [CPUHP_AP_ONLINE + 1]-&gt;startup()     -&gt; 成功
&gt; &gt; +  ---
&gt; &gt; +  [CPUHP_AP_ONLINE + N]-&gt;startup()     -&gt; 失败
&gt; &gt; +  [CPUHP_AP_ONLINE + (N - 1)]-&gt;teardown()
&gt; &gt; +  ...
&gt; &gt; +  [CPUHP_AP_ONLINE + 1]-&gt;teardown()
&gt; &gt; +  === STARTUP阶段开始
&gt; &gt; +  [CPUHP_AP_ONLINE]-&gt;teardown()
&gt; &gt; +  ...
&gt; &gt; +  [CPUHP_BRINGUP_ONLINE - 1]-&gt;teardown()
&gt; &gt; +  ...
&gt; &gt; +  === PREPARE阶段开始
&gt; &gt; +  [CPUHP_BRINGUP_CPU]-&gt;teardown()
&gt; &gt; +  [CPUHP_OFFLINE + 3]-&gt;teardown()
&gt; &gt; +  [CPUHP_OFFLINE + 2]                  -&gt; 略过,因为teardown == NULL
&gt; &gt; +  [CPUHP_OFFLINE + 1]-&gt;teardown()
&gt; &gt; +  [CPUHP_OFFLINE]
&gt; &gt; +
&gt; &gt; +一个失败的下线操作如下::
&gt; &gt; +
&gt; &gt; +  [CPUHP_ONLINE]
&gt; &gt; +  [CPUHP_ONLINE - 1]-&gt;teardown()       -&gt; 成功
&gt; &gt; +  ...
&gt; &gt; +  [CPUHP_ONLINE - N]-&gt;teardown()       -&gt; 失败
&gt; &gt; +  [CPUHP_ONLINE - (N - 1)]-&gt;startup()
&gt; &gt; +  ...
&gt; &gt; +  [CPUHP_ONLINE - 1]-&gt;startup()
&gt; &gt; +  [CPUHP_ONLINE]
&gt; &gt; +
&gt; &gt; +递归失败不能被合理地处理。
&gt; &gt; +请看下面的例子,由于下线操作失败而导致的递归失败: ::
&gt; &gt; +
&gt; &gt; +  [CPUHP_ONLINE]
&gt; &gt; +  [CPUHP_ONLINE - 1]-&gt;teardown()       -&gt; 成功
&gt; &gt; +  ...
&gt; &gt; +  [CPUHP_ONLINE - N]-&gt;teardown()       -&gt; 失败
&gt; &gt; +  [CPUHP_ONLINE - (N - 1)]-&gt;startup()  -&gt; 成功
&gt; &gt; +  [CPUHP_ONLINE - (N - 2)]-&gt;startup()  -&gt; 失败
&gt; &gt; +
&gt; &gt; +CPU热插拔状态机在此停止,并不试图再次回滚,因为这可能会导致无尽的循环::
&gt; 
&gt; 且不再尝试回滚
&gt; 
&gt; 无尽的循环 -&gt; 死循环 ?

Agress!

&gt; 
&gt; &gt; +
&gt; &gt; +  [CPUHP_ONLINE - (N - 1)]-&gt;teardown() -&gt; 成功
&gt; &gt; +  [CPUHP_ONLINE - N]-&gt;teardown()       -&gt; 失败
&gt; &gt; +  [CPUHP_ONLINE - (N - 1)]-&gt;startup()  -&gt; 成功
&gt; &gt; +  [CPUHP_ONLINE - (N - 2)]-&gt;startup()  -&gt; 失败
&gt; &gt; +  [CPUHP_ONLINE - (N - 1)]-&gt;teardown() -&gt; 成功
&gt; &gt; +  [CPUHP_ONLINE - N]-&gt;teardown()       -&gt; 失败
&gt; &gt; +
&gt; &gt; +擦洗,冲洗,重复。在这种情况下,CPU留在该状态中::
&gt; 
&gt; Lather, rinse and repeat.
&gt; 可意译成 周而复始,不断重复

Perfact!

&gt; 
&gt; &gt; +
&gt; &gt; +  [CPUHP_ONLINE - (N - 1)]
&gt; &gt; +
&gt; &gt; +这至少可以让系统取得进展,让用户有机会进行调试,甚至解决这个问题。
&gt; &gt; +
&gt; &gt; +分配一个状态
&gt; &gt; +------------
&gt; &gt; +
&gt; &gt; +有两种方式分配一个CPU热插拔状态:
&gt; &gt; +
&gt; &gt; +* 静态分配
&gt; &gt; +
&gt; &gt; +  当子系统或驱动程序有相对于其他CPU热插拔状态的排序要求时,必须使用静态分配。例如,
&gt; &gt; +  在CPU上线操作期间,PERF核心startup回调必须在PERF驱动startup回调之前被调用。在CPU
&gt; &gt; +  下线操作中,驱动teardown回调必须在核心teardown回调之前调用。静态分配的状态由
&gt; &gt; +  cpuhp_state枚举中的常量描述,可以在include/linux/cpuhotplug.h中找到。
&gt; &gt; +
&gt; &gt; +  在适当的位置将状态插入枚举中,这样就满足了排序要求。状态常量必须被用于状态的设置
&gt; &gt; +  和移除。
&gt; &gt; +
&gt; &gt; +  当状态回调不是在运行时设置的,并且是kernel/cpu.c中CPU热插拔状态数组初始化的一部分
&gt; &gt; +  时,也需要静态分配。
&gt; &gt; +
&gt; &gt; +* 动态分配
&gt; &gt; +
&gt; &gt; +  当对状态回调没有排序要求时,动态分配是首选方法。状态编号由setup函数分配,并在成功
&gt; &gt; +  后返回给调用者。
&gt; &gt; +
&gt; &gt; +  只有PREPARE和ONLINE阶段提供了一个动态分配范围。STARTING阶段则没有,因为该部分的大多
&gt; &gt; +  数回调都有明确的排序要求。
&gt; &gt; +
&gt; &gt; +CPU热插拔状态的设置
&gt; &gt; +-------------------
&gt; &gt; +
&gt; &gt; +核心代码提供了以下函数用来设置状态:
&gt; &gt; +
&gt; &gt; +* cpuhp_setup_state(state, name, startup, teardown)
&gt; &gt; +* cpuhp_setup_state_nocalls(state, name, startup, teardown)
&gt; &gt; +* cpuhp_setup_state_cpuslocked(state, name, startup, teardown)
&gt; &gt; +* cpuhp_setup_state_nocalls_cpuslocked(state, name, startup, teardown)
&gt; &gt; +
&gt; &gt; +对于一个驱动程序或子系统有多个实例,并且每个实例都需要调用相同的CPU hotplug状态回
&gt; &gt; +调的情况,CPU hotplug核心提供多实例支持。与驱动程序特定的实例列表相比,其优势在于
&gt; &gt; +与实例相关的函数完全针对CPU hotplug操作进行序列化,并在添加和删除时提供状态回调的
&gt; &gt; +自动调用。要设置这样一个多实例状态,可以使用以下函数:
&gt; &gt; +
&gt; &gt; +* cpuhp_setup_state_multi(state, name, startup, teardown)
&gt; &gt; +
&gt; &gt; +@state参数要么是静态分配的状态,要么是动态分配状态(PUHP_PREPARE_DYN,CPUHP_ONLINE_DYN)
&gt; &gt; +的常量之一, 具体取决于应该分配动态状态的状态阶段(PREPARE,ONLINE)。
&gt; &gt; +
&gt; &gt; +@name参数用于sysfs输出和检测。命名惯例是"subsys:mode"或"subsys/driver:mode",
&gt; &gt; +例如 "perf:mode"或"perf/x86:mode"。常见的mode名称有:
&gt; &gt; +
&gt; &gt; +======== ============================================
&gt; &gt; +prepare  对应PREPARE阶段中的状态
&gt; &gt; +
&gt; &gt; +dead     对应PREPARE阶段中不提供startup回调的状态
&gt; &gt; +
&gt; &gt; +starting 对应STARTING阶段中的状态
&gt; &gt; +
&gt; &gt; +dying    对应STARTING阶段中不提供startup回调的状态
&gt; &gt; +
&gt; &gt; +online   对应ONLINE阶段中的状态
&gt; &gt; +
&gt; &gt; +offline  对应ONLINE阶段中不提供startup回调的状态
&gt; &gt; +======== ============================================
&gt; &gt; +
&gt; &gt; +由于@name参数只用于sysfs和检测,如果其他mode描述符比常见的描述符更好地描述状态的性质,
&gt; &gt; +也可以使用。
&gt; &gt; +
&gt; &gt; +@name参数的示例:"perf/online", "perf/x86:prepare", "RCU/tree:dying", "sched/waitempty"
&gt; &gt; +
&gt; &gt; +@startup参数是一个指向回调的函数指针,在CPU上线操作时被调用。若应用不需要startup
&gt; &gt; +回调,则将该指针设为NULL。
&gt; &gt; +
&gt; &gt; +@teardown参数是一个指向回调的函数指针,在CPU下线操作时调用。若应用不需要teardown
&gt; &gt; +回调,则将该指针设为NULL。
&gt; &gt; +
&gt; &gt; +这些函数在处理已注册回调的方式上有所不同:
&gt; &gt; +
&gt; &gt; +  * cpuhp_setup_state_nocalls(), cpuhp_setup_state_nocalls_cpuslocked()和
&gt; &gt; +    cpuhp_setup_state_multi()只注册回调。
&gt; &gt; +
&gt; &gt; +  * cpuhp_setup_state()和cpuhp_setup_state_cpuslocked()注册回调,并对当前状态大于新
&gt; &gt; +    安装状态的所有在线CPU调用@startup回调(如果不是NULL)。根据状态阶段,回调要么在
&gt; &gt; +    当前的CPU上调用(PREPARE阶段),要么在CPU的热插拔线程中调用每个在线CPU(ONLINE阶段)。
&gt; &gt; +
&gt; &gt; +    如果CPU N的回调失败,那么CPU 0...N-1的teardown回调被调用以回滚操作。状态设置失败,
&gt; &gt; +    状态的回调没有被注册,在动态分配的情况下,分配的状态被释放。
&gt; &gt; +
&gt; &gt; +状态设置和回调调用是针对CPU热拔插操作进行序列化的。如果设置函数必须从CPU热插拔的读
&gt; &gt; +锁定区域调用,那么必须使用_cpuslocked()变体。这些函数不能在CPU热拔插回调中使用。
&gt; &gt; +
&gt; &gt; +函数返回值:
&gt; &gt; +  ======== ==========================================================
&gt; &gt; +  0        静态分配的状态设置成功
&gt; &gt; +
&gt; &gt; +  &gt;0       动态分配的状态设置成功
&gt; &gt; +
&gt; &gt; +           返回的数值是被分配的状态编号。如果状态回调后来必须被移除,
&gt; &gt; +           例如模块移除,那么这个数值必须由调用者保存,并作为状态移
&gt; &gt; +           除函数的@state参数。对于多实例状态,动态分配的状态编号也
&gt; &gt; +           需要作为实例添加/删除操作的@state参数。
&gt; &gt; +
&gt; &gt; +  &lt;0	   操作失败
&gt; &gt; +  ======== ==========================================================
&gt; &gt; +
&gt; &gt; +移除CPU热拔插状态
&gt; &gt; +-----------------
&gt; &gt; +
&gt; &gt; +为了移除一个之前设置好的状态,提供了如下函数:
&gt; &gt; +
&gt; &gt; +* cpuhp_remove_state(state)
&gt; &gt; +* cpuhp_remove_state_nocalls(state)
&gt; &gt; +* cpuhp_remove_state_nocalls_cpuslocked(state)
&gt; &gt; +* cpuhp_remove_multi_state(state)
&gt; &gt; +
&gt; &gt; +@state参数要么是静态分配的状态,要么是由cpuhp_setup_state*()在动态范围内分配
&gt; &gt; +的状态编号。如果状态在动态范围内,则状态编号被释放,可再次进行动态分配。
&gt; &gt; +
&gt; &gt; +这些函数在处理已注册回调的方式上有所不同:
&gt; &gt; +
&gt; &gt; +  * cpuhp_remove_state_nocalls(), cpuhp_remove_state_nocalls_cpuslocked()
&gt; &gt; +    和 cpuhp_remove_multi_state()只删除回调。
&gt; &gt; +
&gt; &gt; +  * cpuhp_remove_state()删除回调,并调用所有当前状态大于被删除状态的在线CPU的
&gt; &gt; +    teardown回调(如果不是NULL)。根据状态阶段,回调要么在当前的CPU上调用
&gt; &gt; +    (PREPARE阶段),要么在CPU的热插拔线程中调用每个在线CPU(ONLINE阶段)。
&gt; &gt; +
&gt; &gt; +    为了完成移除工作,teardown回调不能失败。
&gt; &gt; +
&gt; &gt; +状态移除和回调调用是针对CPU热拔插操作进行序列化的。如果移除函数必须从CPU hotplug
&gt; &gt; +读取锁定区域调用,那么必须使用_cpuslocked()变体。这些函数不能从CPU热插拔的回调中使用。
&gt; &gt; +
&gt; &gt; +如果一个多实例的状态被移除,那么调用者必须先移除所有的实例。
&gt; &gt; +
&gt; &gt; +多实例状态实例管理
&gt; &gt; +------------------
&gt; &gt; +
&gt; &gt; +一旦多实例状态被建立,实例就可以被添加到状态中:
&gt; &gt;  
&gt; &gt; -一旦一个CPU下线或上线,就有可能收到通知。这对某些需要根据可用CPU数量执行某种设置或清
&gt; &gt; -理功能的驱动程序来说可能很重要::
&gt; &gt; +  * cpuhp_state_add_instance(state, node)
&gt; &gt; +  * cpuhp_state_add_instance_nocalls(state, node)
&gt; &gt;  
&gt; &gt; -  #include <linux cpuhotplug.h="">
&gt; &gt; +@state参数是一个静态分配的状态或由cpuhp_setup_state_multi()在动态范围内分配的状
&gt; &gt; +态编号。
&gt; &gt;  
&gt; &gt; -  ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "X/Y:online",
&gt; &gt; -                          Y_online, Y_prepare_down);
&gt; &gt; +@node参数是一个指向hlist_node的指针,它被嵌入到实例的数据结构中。这个指针被交给
&gt; &gt; +多实例状态的回调,可以被回调用来通过container_of()检索到实例。
&gt; &gt;  
&gt; &gt; -*X* 是子系统, *Y* 是特定的驱动程序。 *Y_online* 回调将在所有在线CPU的注册过程中被调用。
&gt; &gt; -如果在线回调期间发生错误, *Y_prepare_down*  回调将在所有之前调用过在线回调的CPU上调
&gt; &gt; -用。注册完成后,一旦有CPU上线, *Y_online* 回调将被调用,当CPU关闭时, *Y_prepare_down*
&gt; &gt; -将被调用。所有之前在 *Y_online* 中分配的资源都应该在 *Y_prepare_down* 中释放。如果在
&gt; &gt; -注册过程中发生错误,返回值 *ret* 为负值。否则会返回一个正值,其中包含动态分配状态
&gt; &gt; -( *CPUHP_AP_ONLINE_DYN* )的分配热拔插。对于预定义的状态,它将返回0。
&gt; &gt; +这些函数在处理已注册回调的方式上有所不同:
&gt; &gt;  
&gt; &gt; -该回调可以通过调用 ``cpuhp_remove_state()`` 来删除。如果是动态分配的状态
&gt; &gt; -( *CPUHP_AP_ONLINE_DYN* ),则使用返回的状态。在移除热插拔状态的过程中,将调用拆解回调。
&gt; &gt; +  * cpuhp_state_add_instance_nocalls()只将实例添加到多实例状态的节点列表中。
&gt; &gt;  
&gt; &gt; -多个实例
&gt; &gt; -~~~~~~~~
&gt; &gt; +  * cpuhp_state_add_instance()为所有当前状态大于@state的在线CPU添加实例并调用与
&gt; &gt; +    @state相关的startup回调(如果不是NULL)。该回调只对将要添加的实例进行调用。
&gt; &gt; +    根据状态阶段,回调要么在当前的CPU上调用(PREPARE阶段),要么在CPU的热插拔线
&gt; &gt; +    程中调用每个在线CPU(ONLINE阶段)。
&gt; &gt;  
&gt; &gt; -如果一个驱动程序有多个实例,并且每个实例都需要独立执行回调,那么很可能应该使用
&gt; &gt; -``multi-state`` 。首先需要注册一个多状态的状态::
&gt; &gt; +    如果CPU N的回调失败,那么CPU 0 ... N-1的teardown回调被调用以回滚操作,该函数
&gt; &gt; +    失败,实例不会被添加到多实例状态的节点列表中。
&gt; &gt;  
&gt; &gt; -  ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "X/Y:online,
&gt; &gt; -                                Y_online, Y_prepare_down);
&gt; &gt; -  Y_hp_online = ret;
&gt; &gt; +要从状态的节点列表中删除一个实例,可以使用这些函数:
&gt; &gt;  
&gt; &gt; -``cpuhp_setup_state_multi()`` 的行为与 ``cpuhp_setup_state()`` 类似,只是它
&gt; &gt; -为多状态准备了回调,但不调用回调。这是一个一次性的设置。
&gt; &gt; -一旦分配了一个新的实例,你需要注册这个新实例::
&gt; &gt; +  * cpuhp_state_remove_instance(state, node)
&gt; &gt; +  * cpuhp_state_remove_instance_nocalls(state, node)
&gt; &gt;  
&gt; &gt; -  ret = cpuhp_state_add_instance(Y_hp_online, &amp;d-&gt;node);
&gt; &gt; +参数与上述cpuhp_state_add_instance*()变体相同。
&gt; &gt;  
&gt; &gt; -这个函数将把这个实例添加到你先前分配的 ``Y_hp_online`` 状态,并在所有在线的
&gt; &gt; -CPU上调用先前注册的回调( ``Y_online`` )。 *node* 元素是你的每个实例数据结构
&gt; &gt; -中的一个 ``struct hlist_node`` 成员。
&gt; &gt; +这些函数在处理已注册回调的方式上有所不同:
&gt; &gt;  
&gt; &gt; -在移除该实例时::
&gt; &gt; +  * cpuhp_state_remove_instance_nocalls()只从状态的节点列表中删除实例。
&gt; &gt;  
&gt; &gt; -  cpuhp_state_remove_instance(Y_hp_online, &amp;d-&gt;node)
&gt; &gt; +  * cpuhp_state_remove_instance()删除实例并调用与@state相关的回调(如果不是NULL),
&gt; &gt; +    用于所有当前状态大于@state的在线CPU。 该回调只对将要被移除的实例进行调用。
&gt; &gt; +    根据状态阶段,回调要么在当前的CPU上调用(PREPARE阶段),要么在CPU的热插拔
&gt; &gt; +    线程中调用每个在线CPU(ONLINE阶段)。
&gt; &gt;  
&gt; &gt; -应该被调用,这将在所有在线CPU上调用拆分回调。
&gt; &gt; +    为了完成移除工作,teardown回调不能失败。
&gt; &gt;  
&gt; &gt; -手动设置
&gt; &gt; -~~~~~~~~
&gt; &gt; +节点列表的添加/删除操作和回调调用是针对CPU热拔插操作进行序列化。这些函数不能在
&gt; &gt; +CPU hotplug回调和CPU hotplug读取锁定区域内使用。
&gt; &gt;  
&gt; &gt; -通常情况下,在注册或移除状态时调用setup和teamdown回调是很方便的,因为通常在CPU上线
&gt; &gt; -(下线)和驱动的初始设置(关闭)时需要执行该操作。然而,每个注册和删除功能也有一个
&gt; &gt; -_nocalls的后缀,如果不希望调用回调,则不调用所提供的回调。在手动设置(或关闭)期间,
&gt; &gt; -应该使用 ``get_online_cpus()`` 和 ``put_online_cpus()`` 函数来抑制CPU热插拔操作。
&gt; &gt; +例证
&gt; 
&gt; 例子 or 样例

“样例“ maybe the better choice.

&gt; 
&gt; &gt; +----
&gt; &gt;  
&gt; &gt; +在STARTING阶段设置和取消静态分配的状态,以获取上线和下线操作的通知::
&gt; &gt;  
&gt; &gt; -事件的顺序
&gt; &gt; -----------
&gt; &gt; +   ret = cpuhp_setup_state(CPUHP_SUBSYS_STARTING, "subsys:starting", subsys_cpu_starting, subsys_cpu_dying);
&gt; &gt; +   if (ret &lt; 0)
&gt; &gt; +        return ret;
&gt; &gt; +   ....
&gt; &gt; +   cpuhp_remove_state(CPUHP_SUBSYS_STARTING);
&gt; &gt;  
&gt; &gt; -热插拔状态被定义在 ``include/linux/cpuhotplug.h``:
&gt; &gt; +在ONLINE阶段设置和取消动态分配的状态,以获取下线操作的通知::
&gt; &gt;  
&gt; &gt; -* ``CPUHP_OFFLINE`` ... ``CPUHP_AP_OFFLINE`` 状态是在CPU启动前调用的。
&gt; &gt; +   state = cpuhp_setup_state(CPUHP_ONLINE_DYN, "subsys:offline", NULL, subsys_cpu_offline);
&gt; &gt; +   if (state &lt; 0)
&gt; &gt; +       return state;
&gt; &gt; +   ....
&gt; &gt; +   cpuhp_remove_state(state);
&gt; &gt;  
&gt; &gt; -* ``CPUHP_AP_OFFLINE`` ... ``CPUHP_AP_ONLINE`` 状态是在CPU被启动后被调用的。
&gt; &gt; -  中断是关闭的,调度程序还没有在这个CPU上活动。从 ``CPUHP_AP_OFFLINE`` 开始,
&gt; &gt; -  回调被调用到目标CPU上。
&gt; &gt; +在ONLINE阶段设置和取消动态分配的状态,以获取有关上线操作的通知,而无需调用回调::
&gt; &gt;  
&gt; &gt; -* ``CPUHP_AP_ONLINE_DYN`` 和 ``CPUHP_AP_ONLINE_DYN_END`` 之间的状态被保留
&gt; &gt; -  给动态分配。
&gt; &gt; +   state = cpuhp_setup_state_nocalls(CPUHP_ONLINE_DYN, "subsys:online", subsys_cpu_online, NULL);
&gt; &gt; +   if (state &lt; 0)
&gt; &gt; +       return state;
&gt; &gt; +   ....
&gt; &gt; +   cpuhp_remove_state_nocalls(state);
&gt; &gt;  
&gt; &gt; -* 这些状态在CPU关闭时以相反的顺序调用,从 ``CPUHP_ONLINE`` 开始,在 ``CPUHP_OFFLINE``
&gt; &gt; -  停止。这里的回调是在将被关闭的CPU上调用的,直到 ``CPUHP_AP_OFFLINE`` 。
&gt; &gt; +在ONLINE阶段设置、使用和取消动态分配的多实例状态,以获得上线和下线操作的通知::
&gt; &gt;  
&gt; &gt; -通过 ``CPUHP_AP_ONLINE_DYN`` 动态分配的状态通常已经足够了。然而,如果在启动或关闭
&gt; &gt; -期间需要更早的调用,那么应该获得一个显式状态。如果热拔插事件需要相对于另一个热拔插事
&gt; &gt; -件的特定排序,也可能需要一个显式状态。
&gt; &gt; +   state = cpuhp_setup_state_multi(CPUHP_ONLINE_DYN, "subsys:online", subsys_cpu_online, subsys_cpu_offline);
&gt; &gt; +   if (state &lt; 0)
&gt; &gt; +       return state;
&gt; &gt; +   ....
&gt; &gt; +   ret = cpuhp_state_add_instance(state, &amp;inst1-&gt;node);
&gt; &gt; +   if (ret)
&gt; &gt; +        return ret;
&gt; &gt; +   ....
&gt; &gt; +   ret = cpuhp_state_add_instance(state, &amp;inst2-&gt;node);
&gt; &gt; +   if (ret)
&gt; &gt; +        return ret;
&gt; &gt; +   ....
&gt; &gt; +   cpuhp_remove_instance(state, &amp;inst1-&gt;node);
&gt; &gt; +   ....
&gt; &gt; +   cpuhp_remove_instance(state, &amp;inst2-&gt;node);
&gt; &gt; +   ....
&gt; &gt; +   remove_multi_state(state);
&gt; &gt;  
&gt; &gt;  测试热拔插状态
&gt; &gt;  ==============
&gt; &gt; -- 
&gt; &gt; 2.20.1
&gt; 
&gt; Good job, thanks!
&gt;         Wu

Thanks your review!

Binbin</linux></tglx@xxxxxxxxxxxxx></jschopp@xxxxxxxxxxxxxx></ashok.raj@xxxxxxxxx></vatsa@xxxxxxxxxx></rusty@xxxxxxxxxxxxxxx></jschopp@xxxxxxxxxxxxxx></ashok.raj@xxxxxxxxx></vatsa@xxxxxxxxxx></rusty@xxxxxxxxxxxxxxx></bigeasy@xxxxxxxxxxxxx></zhoubinbin@xxxxxxxxxxx></siyanteng@xxxxxxxxxxx></zhoubinbin@xxxxxxxxxxx></bobwxc@xxxxxxxx></bobwxc@xxxxxxxx></zhoubinbin@xxxxxxxxxxx></bobwxc@xxxxxxxx>

本邮件及其附件含有龙芯中科的商业秘密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制或散发)本邮件及其附件中的信息。如果您错收本邮件,请您立即电话或邮件通知发件人并删除本邮件。 
This email and its attachments contain confidential information from Loongson Technology , which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this email in error, please notify the sender by phone or email immediately and delete it. 




[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux