* [PATCH 0/2] docs/zh_CN:add core-api refcount-vs-atomic.rst and local_ops.rst translation. @ 2021-05-18 3:08 Yanteng Si 2021-05-18 3:08 ` [PATCH 1/2] docs/zh_CN:add core-api refcount-vs-atomic.rst translation Yanteng Si 2021-05-18 3:08 ` [PATCH 2/2] docs/zh_CN: add core api local_ops.rst translation Yanteng Si 0 siblings, 2 replies; 8+ messages in thread From: Yanteng Si @ 2021-05-18 3:08 UTC (permalink / raw) To: corbet, alexs Cc: Yanteng Si, chenhuacai, jiaxun.yang, linux-doc, realpuyuwang, bobwxc, siyanteng01, huangjianghui Translate Documentation/core-api/refcount-vs-atomic.rst and .../local_ops.rst into Chinese. Yanteng Si (2): docs/zh_CN:add core-api refcount-vs-atomic.rst translation. docs/zh_CN: add core api local_ops.rst translation .../translations/zh_CN/core-api/index.rst | 4 +- .../translations/zh_CN/core-api/local_ops.rst | 194 ++++++++++++++++++ .../zh_CN/core-api/refcount-vs-atomic.rst | 154 ++++++++++++++ 3 files changed, 350 insertions(+), 2 deletions(-) create mode 100644 Documentation/translations/zh_CN/core-api/local_ops.rst create mode 100644 Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst -- 2.27.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] docs/zh_CN:add core-api refcount-vs-atomic.rst translation. 2021-05-18 3:08 [PATCH 0/2] docs/zh_CN:add core-api refcount-vs-atomic.rst and local_ops.rst translation Yanteng Si @ 2021-05-18 3:08 ` Yanteng Si 2021-05-19 13:20 ` Wu X.C. 2021-05-18 3:08 ` [PATCH 2/2] docs/zh_CN: add core api local_ops.rst translation Yanteng Si 1 sibling, 1 reply; 8+ messages in thread From: Yanteng Si @ 2021-05-18 3:08 UTC (permalink / raw) To: corbet, alexs Cc: Yanteng Si, chenhuacai, jiaxun.yang, linux-doc, realpuyuwang, bobwxc, siyanteng01, huangjianghui Translate Documentation/core-api/refcount-vs-atomic.rst into Chinese. Signed-off-by: Yanteng Si <siyanteng@loongson.cn> --- .../translations/zh_CN/core-api/index.rst | 3 +- .../zh_CN/core-api/refcount-vs-atomic.rst | 154 ++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst index f1fa71e45c77..8f0b3fe8723d 100644 --- a/Documentation/translations/zh_CN/core-api/index.rst +++ b/Documentation/translations/zh_CN/core-api/index.rst @@ -58,10 +58,11 @@ Linux如何让一切同时发生。 详情请参阅 :maxdepth: 1 irq/index + refcount-vs-atomic + Todolist: - refcount-vs-atomic local_ops padata ../RCU/index diff --git a/Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst b/Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst new file mode 100644 index 000000000000..dabe0c1dae9a --- /dev/null +++ b/Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst @@ -0,0 +1,154 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/core-api/refcount-vs-atomic.rst +:Translator: Yanteng Si <siyanteng@loongson.cn> + +.. _cn_refcount-vs-atomic: + + +======================================= +与atomic_t相比,refcount_t的API是这样的 +======================================= + +.. contents:: :local: + +简介 +==== + +refcount_t API的目标是为实现对象的引用计数器提供一个最小的API。虽然来自 +lib/refcount.c的独立于架构的通用实现在下面使用了原子操作,但一些 ``refcount_*()`` +和 ``atomic_*()`` 函数在内存顺序保证方面有很多不同。本文档概述了这些差异,并 +提供了相应的例子,以帮助开发者根据这些内存顺序保证的变化来验证他们的代码。 + +本文档中使用的术语尽量遵循tools/memory-model/Documentation/explanation.txt +中定义的正式LKMM。 + +memory-barriers.txt和atomic_t.txt提供了更多关于内存顺序的背景,特别是 +对于原子操作。 + +内存顺序的相关类型 +================== + +.. note:: 下面的部分只涵盖了与原子操作和引用计数器有关的一些内存顺序类型,并 + 通过本文档使用。如果想了解更广泛的情况,请查阅memory-barriers.txt文件。 + +在没有任何内存顺序保证的情况下(即完全无序),atomics & refcounters只提供原 +子性和程序顺序(po)关系(在同一个CPU上)。它保证每个 ``atomic_* ()`` 和 ``refcount_*()`` +操作都是原子性的,指令在单个CPU上按程序顺序执行。这是用READ_ONCE()/WRITE_ONCE() +和比较——交换原语实现的。 + +强(全)内存顺序保证在同一CPU上的所有先前的加载和存储(所有po-earlier指令)在 +同一CPU上执行任何po-later指令之前完成。它还保证在同一CPU上的所有po-earlier存 +储和来自其他CPU的所有传播的存储必须在原CPU上执行任何po-later指令之前传播到所有 +其他CPU(A-累积属性)。这是用smp_mb()实现的。 + +一个RELEASE内存顺序保证了在同一CPU上所有先前的加载和存储(所有po-earlier指令) +在操作前完成。它还保证同一CPU上的所有po-earlier存储以及来自其他CPU的所有传播的 +存储必须在释放操作之前传播到所有其他CPU(A-累积属性)。这是用smp_store_release() +实现的。 + +ACQUIRE内存顺序保证了同一CPU上的所有后加载和存储(所有po-later指令)在获取操作 +之后完成。它还保证在获取操作执行后,同一CPU上的所有po-later存储必须传播到所有其 +他CPU。这是用smp_acquire__after_ctrl_dep()实现的。 + +对Refcounters的控制依赖(取决于成功)保证了如果一个对象的引用被成功获得(引用计数 +器的增量或增加行为发生了,函数返回true),那么进一步的存储是针对这个操作的命令。对存 +储的控制依赖没有使用任何明确的屏障来实现,而是依赖于CPU不对存储进行猜测。这只是 +一个单一的CPU关系,对其他CPU不提供任何保证。 + + +函数的比较 +========== + +情况1) - 非 "读/修改/写"(RMW)操作 +------------------------------------ + +函数变化: + + * atomic_set() --> refcount_set() + * atomic_read() --> refcount_read() + +内存顺序保证变化: + + * none (两者都是完全无序的) + + +情况2) - 基于增量的操作,不返回任何值 +-------------------------------------- + +函数变化: + + * atomic_inc() --> refcount_inc() + * atomic_add() --> refcount_add() + +内存顺序保证变化: + + * none (两者都是完全无序的) + +情况3) - 基于递减的RMW操作,没有返回值 +--------------------------------------- + +函数变化: + + * atomic_dec() --> refcount_dec() + +内存顺序保证变化: + + * 完全无序的 --> RELEASE顺序 + + +情况4) - 基于增量的RMW操作,返回一个值 +--------------------------------------- + +函数变化: + + * atomic_inc_not_zero() --> refcount_inc_not_zero() + * 无原子性对应函数 --> refcount_add_not_zero() + +内存顺序保证变化: + + * 完全有序的 --> 控制依赖于存储的成功 + +.. note:: 我们真的在这里假设,必要的顺序是作为获得对象指针的结果而提供的。 + + +情况 5) - 基于Dec/Sub递减的通用RMW操作,返回一个值 +--------------------------------------------------- + +函数变化: + + * atomic_dec_and_test() --> refcount_dec_and_test() + * atomic_sub_and_test() --> refcount_sub_and_test() + +内存顺序保证变化: + + * 完全有序的 --> RELEASE顺序 + 成功后ACQUIRE顺序 + + +情况6)其他基于递减的RMW操作,返回一个值 +---------------------------------------- + +函数变化: + + * 无原子性对应函数 --> refcount_dec_if_one() + * ``atomic_add_unless(&var, -1, 1)`` --> ``refcount_dec_not_one(&var)`` + +内存顺序保证变化: + + * 完全有序的 --> RELEASE顺序 + 控制依赖 + +.. note:: atomic_add_unless()只在执行成功时提供完整的顺序。 + + +情况7)--基于锁的RMW +-------------------- + +函数变化: + + * atomic_dec_and_lock() --> refcount_dec_and_lock() + * atomic_dec_and_mutex_lock() --> refcount_dec_and_mutex_lock() + +内存顺序保证变化: + + * 完全有序 --> RELEASE顺序 + 控制依赖 + 持有 + 成功后spin_lock() -- 2.27.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] docs/zh_CN:add core-api refcount-vs-atomic.rst translation. 2021-05-18 3:08 ` [PATCH 1/2] docs/zh_CN:add core-api refcount-vs-atomic.rst translation Yanteng Si @ 2021-05-19 13:20 ` Wu X.C. 2021-05-20 3:42 ` yanteng si 0 siblings, 1 reply; 8+ messages in thread From: Wu X.C. @ 2021-05-19 13:20 UTC (permalink / raw) To: Yanteng Si Cc: corbet, alexs, chenhuacai, jiaxun.yang, linux-doc, realpuyuwang, siyanteng01, huangjianghui [-- Attachment #1: Type: text/plain, Size: 8711 bytes --] On Tue, May 18, 2021 at 11:08:51AM +0800, Yanteng Si wrote: > Translate Documentation/core-api/refcount-vs-atomic.rst into Chinese. > > Signed-off-by: Yanteng Si <siyanteng@loongson.cn> > --- > .../translations/zh_CN/core-api/index.rst | 3 +- > .../zh_CN/core-api/refcount-vs-atomic.rst | 154 ++++++++++++++++++ > 2 files changed, 156 insertions(+), 1 deletion(-) > create mode 100644 Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst > > diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst > index f1fa71e45c77..8f0b3fe8723d 100644 > --- a/Documentation/translations/zh_CN/core-api/index.rst > +++ b/Documentation/translations/zh_CN/core-api/index.rst > @@ -58,10 +58,11 @@ Linux如何让一切同时发生。 详情请参阅 > :maxdepth: 1 > > irq/index > + refcount-vs-atomic > + > > Todolist: > > - refcount-vs-atomic > local_ops > padata > ../RCU/index > diff --git a/Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst b/Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst > new file mode 100644 > index 000000000000..dabe0c1dae9a > --- /dev/null > +++ b/Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst > @@ -0,0 +1,154 @@ > +.. include:: ../disclaimer-zh_CN.rst > + > +:Original: Documentation/core-api/refcount-vs-atomic.rst > +:Translator: Yanteng Si <siyanteng@loongson.cn> > + > +.. _cn_refcount-vs-atomic: > + > + > +======================================= > +与atomic_t相比,refcount_t的API是这样的 > +======================================= > + > +.. contents:: :local: > + > +简介 > +==== > + > +refcount_t API的目标是为实现对象的引用计数器提供一个最小的API。虽然来自 > +lib/refcount.c的独立于架构的通用实现在下面使用了原子操作,但一些 ``refcount_*()`` > +和 ``atomic_*()`` 函数在内存顺序保证方面有很多不同。本文档概述了这些差异,并 > +提供了相应的例子,以帮助开发者根据这些内存顺序保证的变化来验证他们的代码。 > + > +本文档中使用的术语尽量遵循tools/memory-model/Documentation/explanation.txt > +中定义的正式LKMM。 > + > +memory-barriers.txt和atomic_t.txt提供了更多关于内存顺序的背景,特别是 > +对于原子操作。 背景,包括通用的和针对原子操作的。 > + > +内存顺序的相关类型 > +================== > + > +.. note:: 下面的部分只涵盖了与原子操作和引用计数器有关的一些内存顺序类型,并 > + 通过本文档使用。如果想了解更广泛的情况,请查阅memory-barriers.txt文件。 只涵盖了本文使用的与原子操作和引用计数器有关的一些内存顺序类型。 > + > +在没有任何内存顺序保证的情况下(即完全无序),atomics & refcounters只提供原 atomics & refcounters是否翻译请统一 > +子性和程序顺序(po)关系(在同一个CPU上)。它保证每个 ``atomic_* ()`` 和 ``refcount_*()`` (program order, po) > +操作都是原子性的,指令在单个CPU上按程序顺序执行。这是用READ_ONCE()/WRITE_ONCE() > +和比较——交换原语实现的。 比较并交换? > + > +强(全)内存顺序保证在同一CPU上的所有先前的加载和存储(所有po-earlier指令)在 (完全) > +同一CPU上执行任何po-later指令之前完成。它还保证在同一CPU上的所有po-earlier存 > +储和来自其他CPU的所有传播的存储必须在原CPU上执行任何po-later指令之前传播到所有 > +其他CPU(A-累积属性)。这是用smp_mb()实现的。 maybe 强(完全)内存顺序保证在同一CPU上的所有较早加载和存储的指令(所有程序顺序较早 [po-earlier]指令)在执行任何程序顺序较后指令(po-later)之前完成。它还保证 同一CPU上储存的程序优先较早的指令和来自其他CPU传播的指令必须在该CPU执行任何 程序顺序较后指令之前传播到其他CPU(A-累积属性)。 > + > +一个RELEASE内存顺序保证了在同一CPU上所有先前的加载和存储(所有po-earlier指令) > +在操作前完成。它还保证同一CPU上的所有po-earlier存储以及来自其他CPU的所有传播的 > +存储必须在释放操作之前传播到所有其他CPU(A-累积属性)。这是用smp_store_release() > +实现的。 RELEASE内存顺序保证了在同一CPU上所有较早加载和存储的指令(所有程序顺序较早 指令)在此操作前完成。它还保证同一CPU上储存的程序优先较早的指令和来自其他CPU 传播的指令必须在释放(release)操作之前传播到所有其他CPU(A-累积属性)。这是用 smp_store_release()实现的。 > + > +ACQUIRE内存顺序保证了同一CPU上的所有后加载和存储(所有po-later指令)在获取操作 > +之后完成。它还保证在获取操作执行后,同一CPU上的所有po-later存储必须传播到所有其 > +他CPU。这是用smp_acquire__after_ctrl_dep()实现的。 ACQUIRE内存顺序保证了同一CPU上的所有后加载和存储的指令(所有程序顺序较后 指令)在获取(acquire)操作之后完成。它还保证在获取操作执行后,同一CPU上 储存的所有程序顺序较后指令必须传播到所有其他CPU。这是用 smp_acquire__after_ctrl_dep()实现的。 > + > +对Refcounters的控制依赖(取决于成功)保证了如果一个对象的引用被成功获得(引用计数 > +器的增量或增加行为发生了,函数返回true),那么进一步的存储是针对这个操作的命令。对存 > +储的控制依赖没有使用任何明确的屏障来实现,而是依赖于CPU不对存储进行猜测。这只是 > +一个单一的CPU关系,对其他CPU不提供任何保证。 > + > + > +函数的比较 > +========== > + > +情况1) - 非 "读/修改/写"(RMW)操作 “” > +------------------------------------ > + > +函数变化: > + > + * atomic_set() --> refcount_set() > + * atomic_read() --> refcount_read() > + > +内存顺序保证变化: > + > + * none (两者都是完全无序的) > + > + > +情况2) - 基于增量的操作,不返回任何值 > +-------------------------------------- > + > +函数变化: > + > + * atomic_inc() --> refcount_inc() > + * atomic_add() --> refcount_add() > + > +内存顺序保证变化: > + > + * none (两者都是完全无序的) > + > +情况3) - 基于递减的RMW操作,没有返回值 > +--------------------------------------- > + > +函数变化: > + > + * atomic_dec() --> refcount_dec() > + > +内存顺序保证变化: > + > + * 完全无序的 --> RELEASE顺序 > + > + > +情况4) - 基于增量的RMW操作,返回一个值 > +--------------------------------------- > + > +函数变化: > + > + * atomic_inc_not_zero() --> refcount_inc_not_zero() > + * 无原子性对应函数 --> refcount_add_not_zero() > + > +内存顺序保证变化: > + > + * 完全有序的 --> 控制依赖于存储的成功 > + > +.. note:: 我们真的在这里假设,必要的顺序是作为获得对象指针的结果而提供的。 how about 此处 **假设** 了, really表强调不好翻译 > + > + > +情况 5) - 基于Dec/Sub递减的通用RMW操作,返回一个值 > +--------------------------------------------------- > + > +函数变化: > + > + * atomic_dec_and_test() --> refcount_dec_and_test() > + * atomic_sub_and_test() --> refcount_sub_and_test() > + > +内存顺序保证变化: > + > + * 完全有序的 --> RELEASE顺序 + 成功后ACQUIRE顺序 > + > + > +情况6)其他基于递减的RMW操作,返回一个值 > +---------------------------------------- > + > +函数变化: > + > + * 无原子性对应函数 --> refcount_dec_if_one() > + * ``atomic_add_unless(&var, -1, 1)`` --> ``refcount_dec_not_one(&var)`` > + > +内存顺序保证变化: > + > + * 完全有序的 --> RELEASE顺序 + 控制依赖 > + > +.. note:: atomic_add_unless()只在执行成功时提供完整的顺序。 > + > + > +情况7)--基于锁的RMW > +-------------------- > + > +函数变化: > + > + * atomic_dec_and_lock() --> refcount_dec_and_lock() > + * atomic_dec_and_mutex_lock() --> refcount_dec_and_mutex_lock() > + > +内存顺序保证变化: > + > + * 完全有序 --> RELEASE顺序 + 控制依赖 + 持有 > + 成功后spin_lock() > -- > 2.27.0 Thanks, Wu X.C. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] docs/zh_CN:add core-api refcount-vs-atomic.rst translation. 2021-05-19 13:20 ` Wu X.C. @ 2021-05-20 3:42 ` yanteng si 0 siblings, 0 replies; 8+ messages in thread From: yanteng si @ 2021-05-20 3:42 UTC (permalink / raw) To: Wu X.C. Cc: Yanteng Si, Jonathan Corbet, Alex Shi, Huacai Chen, Jiaxun Yang, linux-doc, Puyu Wang, huangjianghui Wu X.C. <bobwxc@email.cn> 于2021年5月19日周三 下午9:20写道: > > On Tue, May 18, 2021 at 11:08:51AM +0800, Yanteng Si wrote: > > Translate Documentation/core-api/refcount-vs-atomic.rst into Chinese. > > > > Signed-off-by: Yanteng Si <siyanteng@loongson.cn> > > --- > > .../translations/zh_CN/core-api/index.rst | 3 +- > > .../zh_CN/core-api/refcount-vs-atomic.rst | 154 ++++++++++++++++++ > > 2 files changed, 156 insertions(+), 1 deletion(-) > > create mode 100644 Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst > > > > diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst > > index f1fa71e45c77..8f0b3fe8723d 100644 > > --- a/Documentation/translations/zh_CN/core-api/index.rst > > +++ b/Documentation/translations/zh_CN/core-api/index.rst > > @@ -58,10 +58,11 @@ Linux如何让一切同时发生。 详情请参阅 > > :maxdepth: 1 > > > > irq/index > > + refcount-vs-atomic > > + > > > > Todolist: > > > > - refcount-vs-atomic > > local_ops > > padata > > ../RCU/index > > diff --git a/Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst b/Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst > > new file mode 100644 > > index 000000000000..dabe0c1dae9a > > --- /dev/null > > +++ b/Documentation/translations/zh_CN/core-api/refcount-vs-atomic.rst > > @@ -0,0 +1,154 @@ > > +.. include:: ../disclaimer-zh_CN.rst > > + > > +:Original: Documentation/core-api/refcount-vs-atomic.rst > > +:Translator: Yanteng Si <siyanteng@loongson.cn> > > + > > +.. _cn_refcount-vs-atomic: > > + > > + > > +======================================= > > +与atomic_t相比,refcount_t的API是这样的 > > +======================================= > > + > > +.. contents:: :local: > > + > > +简介 > > +==== > > + > > +refcount_t API的目标是为实现对象的引用计数器提供一个最小的API。虽然来自 > > +lib/refcount.c的独立于架构的通用实现在下面使用了原子操作,但一些 ``refcount_*()`` > > +和 ``atomic_*()`` 函数在内存顺序保证方面有很多不同。本文档概述了这些差异,并 > > +提供了相应的例子,以帮助开发者根据这些内存顺序保证的变化来验证他们的代码。 > > + > > +本文档中使用的术语尽量遵循tools/memory-model/Documentation/explanation.txt > > +中定义的正式LKMM。 > > + > > +memory-barriers.txt和atomic_t.txt提供了更多关于内存顺序的背景,特别是 > > +对于原子操作。 > > 背景,包括通用的和针对原子操作的。 OK! > > > + > > +内存顺序的相关类型 > > +================== > > + > > +.. note:: 下面的部分只涵盖了与原子操作和引用计数器有关的一些内存顺序类型,并 > > + 通过本文档使用。如果想了解更广泛的情况,请查阅memory-barriers.txt文件。 > > 只涵盖了本文使用的与原子操作和引用计数器有关的一些内存顺序类型。 OK! > > > + > > +在没有任何内存顺序保证的情况下(即完全无序),atomics & refcounters只提供原 > > atomics & refcounters是否翻译请统一 atomics 和 refcounters > > > +子性和程序顺序(po)关系(在同一个CPU上)。它保证每个 ``atomic_* ()`` 和 ``refcount_*()`` > > (program order, po) OK! > > > +操作都是原子性的,指令在单个CPU上按程序顺序执行。这是用READ_ONCE()/WRITE_ONCE() > > +和比较——交换原语实现的。 > > 比较并交换? OK! > > > + > > +强(全)内存顺序保证在同一CPU上的所有先前的加载和存储(所有po-earlier指令)在 > > (完全) OK! > > > +同一CPU上执行任何po-later指令之前完成。它还保证在同一CPU上的所有po-earlier存 > > +储和来自其他CPU的所有传播的存储必须在原CPU上执行任何po-later指令之前传播到所有 > > +其他CPU(A-累积属性)。这是用smp_mb()实现的。 > > maybe > 强(完全)内存顺序保证在同一CPU上的所有较早加载和存储的指令(所有程序顺序较早 > [po-earlier]指令)在执行任何程序顺序较后指令(po-later)之前完成。它还保证 > 同一CPU上储存的程序优先较早的指令和来自其他CPU传播的指令必须在该CPU执行任何 > 程序顺序较后指令之前传播到其他CPU(A-累积属性)。 OK! > > > + > > +一个RELEASE内存顺序保证了在同一CPU上所有先前的加载和存储(所有po-earlier指令) > > +在操作前完成。它还保证同一CPU上的所有po-earlier存储以及来自其他CPU的所有传播的 > > +存储必须在释放操作之前传播到所有其他CPU(A-累积属性)。这是用smp_store_release() > > +实现的。 > > RELEASE内存顺序保证了在同一CPU上所有较早加载和存储的指令(所有程序顺序较早 > 指令)在此操作前完成。它还保证同一CPU上储存的程序优先较早的指令和来自其他CPU > 传播的指令必须在释放(release)操作之前传播到所有其他CPU(A-累积属性)。这是用 > smp_store_release()实现的。 OK! > > > + > > +ACQUIRE内存顺序保证了同一CPU上的所有后加载和存储(所有po-later指令)在获取操作 > > +之后完成。它还保证在获取操作执行后,同一CPU上的所有po-later存储必须传播到所有其 > > +他CPU。这是用smp_acquire__after_ctrl_dep()实现的。 > > ACQUIRE内存顺序保证了同一CPU上的所有后加载和存储的指令(所有程序顺序较后 > 指令)在获取(acquire)操作之后完成。它还保证在获取操作执行后,同一CPU上 > 储存的所有程序顺序较后指令必须传播到所有其他CPU。这是用 > smp_acquire__after_ctrl_dep()实现的。 OK! > > > + > > +对Refcounters的控制依赖(取决于成功)保证了如果一个对象的引用被成功获得(引用计数 > > +器的增量或增加行为发生了,函数返回true),那么进一步的存储是针对这个操作的命令。对存 > > +储的控制依赖没有使用任何明确的屏障来实现,而是依赖于CPU不对存储进行猜测。这只是 > > +一个单一的CPU关系,对其他CPU不提供任何保证。 > > + > > + > > +函数的比较 > > +========== > > + > > +情况1) - 非 "读/修改/写"(RMW)操作 > > “” OK! > > > +------------------------------------ > > + > > +函数变化: > > + > > + * atomic_set() --> refcount_set() > > + * atomic_read() --> refcount_read() > > + > > +内存顺序保证变化: > > + > > + * none (两者都是完全无序的) > > + > > + > > +情况2) - 基于增量的操作,不返回任何值 > > +-------------------------------------- > > + > > +函数变化: > > + > > + * atomic_inc() --> refcount_inc() > > + * atomic_add() --> refcount_add() > > + > > +内存顺序保证变化: > > + > > + * none (两者都是完全无序的) > > + > > +情况3) - 基于递减的RMW操作,没有返回值 > > +--------------------------------------- > > + > > +函数变化: > > + > > + * atomic_dec() --> refcount_dec() > > + > > +内存顺序保证变化: > > + > > + * 完全无序的 --> RELEASE顺序 > > + > > + > > +情况4) - 基于增量的RMW操作,返回一个值 > > +--------------------------------------- > > + > > +函数变化: > > + > > + * atomic_inc_not_zero() --> refcount_inc_not_zero() > > + * 无原子性对应函数 --> refcount_add_not_zero() > > + > > +内存顺序保证变化: > > + > > + * 完全有序的 --> 控制依赖于存储的成功 > > + > > +.. note:: 我们真的在这里假设,必要的顺序是作为获得对象指针的结果而提供的。 > how about > 此处 **假设** 了, > > really表强调不好翻译 OK! > > > + > > + > > +情况 5) - 基于Dec/Sub递减的通用RMW操作,返回一个值 > > +--------------------------------------------------- > > + > > +函数变化: > > + > > + * atomic_dec_and_test() --> refcount_dec_and_test() > > + * atomic_sub_and_test() --> refcount_sub_and_test() > > + > > +内存顺序保证变化: > > + > > + * 完全有序的 --> RELEASE顺序 + 成功后ACQUIRE顺序 > > + > > + > > +情况6)其他基于递减的RMW操作,返回一个值 > > +---------------------------------------- > > + > > +函数变化: > > + > > + * 无原子性对应函数 --> refcount_dec_if_one() > > + * ``atomic_add_unless(&var, -1, 1)`` --> ``refcount_dec_not_one(&var)`` > > + > > +内存顺序保证变化: > > + > > + * 完全有序的 --> RELEASE顺序 + 控制依赖 > > + > > +.. note:: atomic_add_unless()只在执行成功时提供完整的顺序。 > > + > > + > > +情况7)--基于锁的RMW > > +-------------------- > > + > > +函数变化: > > + > > + * atomic_dec_and_lock() --> refcount_dec_and_lock() > > + * atomic_dec_and_mutex_lock() --> refcount_dec_and_mutex_lock() > > + > > +内存顺序保证变化: > > + > > + * 完全有序 --> RELEASE顺序 + 控制依赖 + 持有 > > + 成功后spin_lock() > > -- > > 2.27.0 > > Thanks, > > Wu X.C. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/2] docs/zh_CN: add core api local_ops.rst translation 2021-05-18 3:08 [PATCH 0/2] docs/zh_CN:add core-api refcount-vs-atomic.rst and local_ops.rst translation Yanteng Si 2021-05-18 3:08 ` [PATCH 1/2] docs/zh_CN:add core-api refcount-vs-atomic.rst translation Yanteng Si @ 2021-05-18 3:08 ` Yanteng Si 2021-05-19 18:11 ` Wu X.C. 1 sibling, 1 reply; 8+ messages in thread From: Yanteng Si @ 2021-05-18 3:08 UTC (permalink / raw) To: corbet, alexs Cc: Yanteng Si, chenhuacai, jiaxun.yang, linux-doc, realpuyuwang, bobwxc, siyanteng01, huangjianghui Translate Documentation/core-api/local_ops.rst into Chinese. Signed-off-by: Yanteng Si <siyanteng@loongson.cn> --- .../translations/zh_CN/core-api/index.rst | 3 +- .../translations/zh_CN/core-api/local_ops.rst | 194 ++++++++++++++++++ 2 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 Documentation/translations/zh_CN/core-api/local_ops.rst diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst index 8f0b3fe8723d..c7a004bf2bd6 100644 --- a/Documentation/translations/zh_CN/core-api/index.rst +++ b/Documentation/translations/zh_CN/core-api/index.rst @@ -59,11 +59,10 @@ Linux如何让一切同时发生。 详情请参阅 irq/index refcount-vs-atomic - + local_ops Todolist: - local_ops padata ../RCU/index diff --git a/Documentation/translations/zh_CN/core-api/local_ops.rst b/Documentation/translations/zh_CN/core-api/local_ops.rst new file mode 100644 index 000000000000..1294cc1864ff --- /dev/null +++ b/Documentation/translations/zh_CN/core-api/local_ops.rst @@ -0,0 +1,194 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/core-api/local_ops.rst +:Translator: Yanteng Si <siyanteng@loongson.cn> + +.. _cn_local_ops: + + +======================== +本地原子操作的语义和行为 +======================== + +:作者: Mathieu Desnoyers + + +本文解释了本地原子操作的目的,如何为任何给定的架构实现这些操作,并说明 +如何正确使用这些操作。它还强调了在内存写入顺序很重要的情况下,跨CPU读取 +这些本地变量时必须采取的预防措施。 + +.. note:: + + 注意,基于 ``local_t`` 的操作不建议在通用的内核中使用。请使用 ``this_cpu`` + 操作来代替使用,除非真的有特殊目的。大多数内核中使用的 ``local_t`` 已 + 经被 ``this_cpu`` 操作所取代。 ``this_cpu`` 操作在一条指令中结合了重 + 定位和类似 ``local_t`` 的语义,产生了更紧凑和更快的执行代码。 + + +本地原子操作的目的 +================== + +本地原子操作的目的是提供快速和高度可重入的每CPU计数器。它们通过移除LOCK前 +缀和通常需要在CPU间同步的内存屏障,将标准原子操作的性能成本降到最低。 + +在许多情况下,拥有快速的每CPU原子计数器是很有趣的:它不需要禁用中断来保护中 +断处理程序,它允许在NMI处理程序中使用连贯的计数器。它对追踪目的和各种性能监 +测计数器特别有用。 + +本地原子操作只保证在拥有数据的CPU上的变量修改的原子性。因此,必须注意确保只 +有一个CPU写到 ``local_t`` 的数据。这是通过使用每CPU的数据来实现的,并确 +保我们在一个抢占式安全上下文中修改它。然而,从任何一个CPU读取 ``local_t`` +数据都是允许的:这样它就会显得与所有者CPU的其他内存写入顺序不一致。 + + +针对特定架构的实现 +================== + +这可以通过稍微修改标准的原子操作来实现:只有它们的UP变体必须被保留。这通常 +意味着删除LOCK前缀(在i386和x86_64上)和任何SMP同步屏障。如果架构在 SMP +和UP之间没有不同的行为,在你的架构的 ``local.h`` 中包括 ``asm-generic/local.h`` +就足够了。 + +通过在一个结构中嵌入一个 ``atomic_long_t`` , ``local_t`` 类型被定义为 +一个不透明的 ``signed long`` 字符串。这样做的目的是为了使从这个类型到 +``long`` 的转换失败。该定义看起来像:: + + typedef struct { atomic_long_t a; } local_t; + + +使用本地原子操作时应遵循的规则 +============================== + +* 被本地操作触及的变量必须是每cpu的变量。 + +* 只有这些变量的CPU所有者才可以写入这些变量。 + +* 这个CPU可以从任何上下文(进程、中断、软中断、nmi...)中使用本地操作来更新 + 它的local_t变量。 + +* 当在进程上下文中使用本地操作时,必须禁用抢占(或中断),以确保进程在获得每 + CPU变量和进行实际的本地操作之间不会被迁移到不同的CPU。 + +* 当在中断上下文中使用本地操作时,在主线内核上不需要特别注意,因为它们将在局 + 部CPU上运行,并且已经禁用了抢占。然而,我建议无论如何都要明确地禁用抢占, + 以确保它在-rt内核上仍能正确工作。 + +* 读取本地cpu变量将提供该变量的当前拷贝。 + +* 对这些变量的读取可以从任何CPU进行,因为对 “ ``long`` ”,对齐的变量的更新 + 总是原子的。由于写程序的CPU没有进行内存同步,所以在读取其他cpu的变量时,可 + 以读取该变量的过期副本。 + + +如何使用本地原子操作 +==================== + +:: + + #include <linux/percpu.h> + #include <asm/local.h> + + static DEFINE_PER_CPU(local_t, counters) = LOCAL_INIT(0); + + +计数器 +====== + +计数是在一个signed long的所有位上进行的。 + +在可抢占的上下文中,围绕本地原子操作使用 ``get_cpu_var()`` 和 +``put_cpu_var()`` :它确保在对每个cpu变量进行写访问时,抢占被禁用。比如 +说:: + + local_inc(&get_cpu_var(counters)); + put_cpu_var(counters); + +如果你已经在一个抢占式安全上下文中,你可以使用 ``this_cpu_ptr()`` 代替:: + + local_inc(this_cpu_ptr(&counters)); + + + +读取计数器 +========== + +那些本地计数器可以从外部的CPU中读取,以求得计数的总和。请注意,local_read +所看到的跨CPU的数据必须被认为是相对于拥有该数据的CPU上发生的其他内存写入来 +说不符合顺序的。:: + + long sum = 0; + for_each_online_cpu(cpu) + sum += local_read(&per_cpu(counters, cpu)); + +如果你想使用远程local_read来同步CPU之间对资源的访问,必须在写入者和读取者 +的CPU上分别使用显式的 ``smp_wmb()`` 和 ``smp_rmb()`` 内存屏障。如果你使 +用 ``local_t`` 变量作为写在缓冲区中的字节的计数器,就会出现这种情况:在缓 +冲区写和计数器增量之间应该有一个 ``smp_wmb()`` ,在计数器读和缓冲区读之间 +也应有一个 ``smp_rmb()`` 。 + +下面是一个使用 ``local.h`` 实现每个cpu基本计数器的示例模块:: + + /* test-local.c + * + * Sample module for local.h usage. + */ + + + #include <asm/local.h> + #include <linux/module.h> + #include <linux/timer.h> + + static DEFINE_PER_CPU(local_t, counters) = LOCAL_INIT(0); + + static struct timer_list test_timer; + + /* IPI called on each CPU. */ + static void test_each(void *info) + { + /* Increment the counter from a non preemptible context */ + printk("Increment on cpu %d\n", smp_processor_id()); + local_inc(this_cpu_ptr(&counters)); + + /* This is what incrementing the variable would look like within a + * preemptible context (it disables preemption) : + * + * local_inc(&get_cpu_var(counters)); + * put_cpu_var(counters); + */ + } + + static void do_test_timer(unsigned long data) + { + int cpu; + + /* Increment the counters */ + on_each_cpu(test_each, NULL, 1); + /* Read all the counters */ + printk("Counters read from CPU %d\n", smp_processor_id()); + for_each_online_cpu(cpu) { + printk("Read : CPU %d, count %ld\n", cpu, + local_read(&per_cpu(counters, cpu))); + } + mod_timer(&test_timer, jiffies + 1000); + } + + static int __init test_init(void) + { + /* initialize the timer that will increment the counter */ + timer_setup(&test_timer, do_test_timer, 0); + mod_timer(&test_timer, jiffies + 1); + + return 0; + } + + static void __exit test_exit(void) + { + del_timer_sync(&test_timer); + } + + module_init(test_init); + module_exit(test_exit); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Mathieu Desnoyers"); + MODULE_DESCRIPTION("Local Atomic Ops"); -- 2.27.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] docs/zh_CN: add core api local_ops.rst translation 2021-05-18 3:08 ` [PATCH 2/2] docs/zh_CN: add core api local_ops.rst translation Yanteng Si @ 2021-05-19 18:11 ` Wu X.C. 2021-05-21 1:53 ` yanteng si 0 siblings, 1 reply; 8+ messages in thread From: Wu X.C. @ 2021-05-19 18:11 UTC (permalink / raw) To: Yanteng Si Cc: corbet, alexs, chenhuacai, jiaxun.yang, linux-doc, realpuyuwang, siyanteng01, huangjianghui [-- Attachment #1: Type: text/plain, Size: 9562 bytes --] On Tue, May 18, 2021 at 11:08:52AM +0800, Yanteng Si wrote: > Translate Documentation/core-api/local_ops.rst into Chinese. > > Signed-off-by: Yanteng Si <siyanteng@loongson.cn> > --- > .../translations/zh_CN/core-api/index.rst | 3 +- > .../translations/zh_CN/core-api/local_ops.rst | 194 ++++++++++++++++++ > 2 files changed, 195 insertions(+), 2 deletions(-) > create mode 100644 Documentation/translations/zh_CN/core-api/local_ops.rst > > diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst > index 8f0b3fe8723d..c7a004bf2bd6 100644 > --- a/Documentation/translations/zh_CN/core-api/index.rst > +++ b/Documentation/translations/zh_CN/core-api/index.rst > @@ -59,11 +59,10 @@ Linux如何让一切同时发生。 详情请参阅 > > irq/index > refcount-vs-atomic > - > + local_ops > > Todolist: > > - local_ops > padata > ../RCU/index > > diff --git a/Documentation/translations/zh_CN/core-api/local_ops.rst b/Documentation/translations/zh_CN/core-api/local_ops.rst > new file mode 100644 > index 000000000000..1294cc1864ff > --- /dev/null > +++ b/Documentation/translations/zh_CN/core-api/local_ops.rst > @@ -0,0 +1,194 @@ > +.. include:: ../disclaimer-zh_CN.rst > + > +:Original: Documentation/core-api/local_ops.rst > +:Translator: Yanteng Si <siyanteng@loongson.cn> > + > +.. _cn_local_ops: > + > + Which is better for "local" in this article, 局部 or 本地? Seems not much different > +======================== > +本地原子操作的语义和行为 > +======================== > + > +:作者: Mathieu Desnoyers > + > + > +本文解释了本地原子操作的目的,如何为任何给定的架构实现这些操作,并说明 说明了 or 展示了 > +如何正确使用这些操作。它还强调了在内存写入顺序很重要的情况下,跨CPU读取 > +这些本地变量时必须采取的预防措施。 > + > +.. note:: > + > + 注意,基于 ``local_t`` 的操作不建议在通用的内核中使用。请使用 ``this_cpu`` 不建议用于一般内核操作 > + 操作来代替使用,除非真的有特殊目的。大多数内核中使用的 ``local_t`` 已 > + 经被 ``this_cpu`` 操作所取代。 ``this_cpu`` 操作在一条指令中结合了重 > + 定位和类似 ``local_t`` 的语义,产生了更紧凑和更快的执行代码。 > + > + > +本地原子操作的目的 > +================== > + > +本地原子操作的目的是提供快速和高度可重入的每CPU计数器。它们通过移除LOCK前 > +缀和通常需要在CPU间同步的内存屏障,将标准原子操作的性能成本降到最低。 > + > +在许多情况下,拥有快速的每CPU原子计数器是很有趣的:它不需要禁用中断来保护中 s/有趣/有吸引力/ > +断处理程序,它允许在NMI处理程序中使用连贯的计数器。它对追踪目的和各种性能监 (Non Maskable Interrupt) > +测计数器特别有用。 > + > +本地原子操作只保证在拥有数据的CPU上的变量修改的原子性。因此,必须注意确保只 > +有一个CPU写到 ``local_t`` 的数据。这是通过使用每CPU的数据来实现的,并确 > +保我们在一个抢占式安全上下文中修改它。然而,从任何一个CPU读取 ``local_t`` > +数据都是允许的:这样它就会显得与所有者CPU的其他内存写入顺序不一致。 > + > + > +针对特定架构的实现 > +================== > + > +这可以通过稍微修改标准的原子操作来实现:只有它们的UP变体必须被保留。这通常 > +意味着删除LOCK前缀(在i386和x86_64上)和任何SMP同步屏障。如果架构在 SMP ----------------------------------------------------------------------^ a space > +和UP之间没有不同的行为,在你的架构的 ``local.h`` 中包括 ``asm-generic/local.h`` > +就足够了。 > + > +通过在一个结构中嵌入一个 ``atomic_long_t`` , ``local_t`` 类型被定义为 结构体 > +一个不透明的 ``signed long`` 字符串。这样做的目的是为了使从这个类型到 字符串 确定么? > +``long`` 的转换失败。该定义看起来像:: > + > + typedef struct { atomic_long_t a; } local_t; > + > + > +使用本地原子操作时应遵循的规则 > +============================== > + > +* 被本地操作触及的变量必须是每cpu的变量。 > + > +* 只有这些变量的CPU所有者才可以写入这些变量。 *只有* > + > +* 这个CPU可以从任何上下文(进程、中断、软中断、nmi...)中使用本地操作来更新 > + 它的local_t变量。 > + > +* 当在进程上下文中使用本地操作时,必须禁用抢占(或中断),以确保进程在获得每 > + CPU变量和进行实际的本地操作之间不会被迁移到不同的CPU。 > + > +* 当在中断上下文中使用本地操作时,在主线内核上不需要特别注意,因为它们将在局 > + 部CPU上运行,并且已经禁用了抢占。然而,我建议无论如何都要明确地禁用抢占, > + 以确保它在-rt内核上仍能正确工作。 > + > +* 读取本地cpu变量将提供该变量的当前拷贝。 > + > +* 对这些变量的读取可以从任何CPU进行,因为对 “ ``long`` ”,对齐的变量的更新 > + 总是原子的。由于写程序的CPU没有进行内存同步,所以在读取其他cpu的变量时,可 s/写程序/写入程序/ *其他* > + 以读取该变量的过期副本。 > + > + > +如何使用本地原子操作 > +==================== > + > +:: > + > + #include <linux/percpu.h> > + #include <asm/local.h> > + > + static DEFINE_PER_CPU(local_t, counters) = LOCAL_INIT(0); > + > + > +计数器 > +====== > + > +计数是在一个signed long的所有位上进行的。 > + > +在可抢占的上下文中,围绕本地原子操作使用 ``get_cpu_var()`` 和 > +``put_cpu_var()`` :它确保在对每个cpu变量进行写访问时,抢占被禁用。比如 > +说:: > + > + local_inc(&get_cpu_var(counters)); > + put_cpu_var(counters); > + > +如果你已经在一个抢占式安全上下文中,你可以使用 ``this_cpu_ptr()`` 代替:: remove 式 ? > + > + local_inc(this_cpu_ptr(&counters)); > + > + > + > +读取计数器 > +========== > + > +那些本地计数器可以从外部的CPU中读取,以求得计数的总和。请注意,local_read > +所看到的跨CPU的数据必须被认为是相对于拥有该数据的CPU上发生的其他内存写入来 > +说不符合顺序的。:: remove 。 > + > + long sum = 0; > + for_each_online_cpu(cpu) > + sum += local_read(&per_cpu(counters, cpu)); > + > +如果你想使用远程local_read来同步CPU之间对资源的访问,必须在写入者和读取者 > +的CPU上分别使用显式的 ``smp_wmb()`` 和 ``smp_rmb()`` 内存屏障。如果你使 > +用 ``local_t`` 变量作为写在缓冲区中的字节的计数器,就会出现这种情况:在缓 > +冲区写和计数器增量之间应该有一个 ``smp_wmb()`` ,在计数器读和缓冲区读之间 > +也应有一个 ``smp_rmb()`` 。 > + > +下面是一个使用 ``local.h`` 实现每个cpu基本计数器的示例模块:: > + > + /* test-local.c > + * > + * Sample module for local.h usage. > + */ > + > + > + #include <asm/local.h> > + #include <linux/module.h> > + #include <linux/timer.h> > + > + static DEFINE_PER_CPU(local_t, counters) = LOCAL_INIT(0); > + > + static struct timer_list test_timer; > + > + /* IPI called on each CPU. */ > + static void test_each(void *info) > + { > + /* Increment the counter from a non preemptible context */ > + printk("Increment on cpu %d\n", smp_processor_id()); > + local_inc(this_cpu_ptr(&counters)); > + > + /* This is what incrementing the variable would look like within a > + * preemptible context (it disables preemption) : > + * > + * local_inc(&get_cpu_var(counters)); > + * put_cpu_var(counters); > + */ > + } > + > + static void do_test_timer(unsigned long data) > + { > + int cpu; > + > + /* Increment the counters */ > + on_each_cpu(test_each, NULL, 1); > + /* Read all the counters */ > + printk("Counters read from CPU %d\n", smp_processor_id()); > + for_each_online_cpu(cpu) { > + printk("Read : CPU %d, count %ld\n", cpu, > + local_read(&per_cpu(counters, cpu))); > + } > + mod_timer(&test_timer, jiffies + 1000); > + } > + > + static int __init test_init(void) > + { > + /* initialize the timer that will increment the counter */ > + timer_setup(&test_timer, do_test_timer, 0); > + mod_timer(&test_timer, jiffies + 1); > + > + return 0; > + } > + > + static void __exit test_exit(void) > + { > + del_timer_sync(&test_timer); > + } > + > + module_init(test_init); > + module_exit(test_exit); > + > + MODULE_LICENSE("GPL"); > + MODULE_AUTHOR("Mathieu Desnoyers"); > + MODULE_DESCRIPTION("Local Atomic Ops"); > -- > 2.27.0 Thanks! Wu X.C. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] docs/zh_CN: add core api local_ops.rst translation 2021-05-19 18:11 ` Wu X.C. @ 2021-05-21 1:53 ` yanteng si 2021-05-21 6:16 ` Wu X.C. 0 siblings, 1 reply; 8+ messages in thread From: yanteng si @ 2021-05-21 1:53 UTC (permalink / raw) To: Wu X.C. Cc: Yanteng Si, Jonathan Corbet, Alex Shi, Huacai Chen, Jiaxun Yang, linux-doc, Puyu Wang, huangjianghui Wu X.C. <bobwxc@email.cn> 于2021年5月20日周四 上午2:11写道: > > On Tue, May 18, 2021 at 11:08:52AM +0800, Yanteng Si wrote: > > Translate Documentation/core-api/local_ops.rst into Chinese. > > > > Signed-off-by: Yanteng Si <siyanteng@loongson.cn> > > --- > > .../translations/zh_CN/core-api/index.rst | 3 +- > > .../translations/zh_CN/core-api/local_ops.rst | 194 ++++++++++++++++++ > > 2 files changed, 195 insertions(+), 2 deletions(-) > > create mode 100644 Documentation/translations/zh_CN/core-api/local_ops.rst > > > > diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst > > index 8f0b3fe8723d..c7a004bf2bd6 100644 > > --- a/Documentation/translations/zh_CN/core-api/index.rst > > +++ b/Documentation/translations/zh_CN/core-api/index.rst > > @@ -59,11 +59,10 @@ Linux如何让一切同时发生。 详情请参阅 > > > > irq/index > > refcount-vs-atomic > > - > > + local_ops > > > > Todolist: > > > > - local_ops > > padata > > ../RCU/index > > > > diff --git a/Documentation/translations/zh_CN/core-api/local_ops.rst b/Documentation/translations/zh_CN/core-api/local_ops.rst > > new file mode 100644 > > index 000000000000..1294cc1864ff > > --- /dev/null > > +++ b/Documentation/translations/zh_CN/core-api/local_ops.rst > > @@ -0,0 +1,194 @@ > > +.. include:: ../disclaimer-zh_CN.rst > > + > > +:Original: Documentation/core-api/local_ops.rst > > +:Translator: Yanteng Si <siyanteng@loongson.cn> > > + > > +.. _cn_local_ops: > > + > > + > > Which is better for "local" in this article, 局部 or 本地? > Seems not much different “本地” is better. If you want to use “局部", The word "local" should accompany the word "global" in the context. > > > +======================== > > +本地原子操作的语义和行为 > > +======================== > > + > > +:作者: Mathieu Desnoyers > > + > > + > > +本文解释了本地原子操作的目的,如何为任何给定的架构实现这些操作,并说明 > > 说明了 or 展示了 说明了 > > > +如何正确使用这些操作。它还强调了在内存写入顺序很重要的情况下,跨CPU读取 > > +这些本地变量时必须采取的预防措施。 > > + > > +.. note:: > > + > > + 注意,基于 ``local_t`` 的操作不建议在通用的内核中使用。请使用 ``this_cpu`` > > 不建议用于一般内核操作 OK! > > > + 操作来代替使用,除非真的有特殊目的。大多数内核中使用的 ``local_t`` 已 > > + 经被 ``this_cpu`` 操作所取代。 ``this_cpu`` 操作在一条指令中结合了重 > > + 定位和类似 ``local_t`` 的语义,产生了更紧凑和更快的执行代码。 > > + > > + > > +本地原子操作的目的 > > +================== > > + > > +本地原子操作的目的是提供快速和高度可重入的每CPU计数器。它们通过移除LOCK前 > > +缀和通常需要在CPU间同步的内存屏障,将标准原子操作的性能成本降到最低。 > > + > > +在许多情况下,拥有快速的每CPU原子计数器是很有趣的:它不需要禁用中断来保护中 > > s/有趣/有吸引力/ OK! > > > +断处理程序,它允许在NMI处理程序中使用连贯的计数器。它对追踪目的和各种性能监 > > (Non Maskable Interrupt) OK! > > > +测计数器特别有用。 > > + > > +本地原子操作只保证在拥有数据的CPU上的变量修改的原子性。因此,必须注意确保只 > > +有一个CPU写到 ``local_t`` 的数据。这是通过使用每CPU的数据来实现的,并确 > > +保我们在一个抢占式安全上下文中修改它。然而,从任何一个CPU读取 ``local_t`` > > +数据都是允许的:这样它就会显得与所有者CPU的其他内存写入顺序不一致。 > > + > > + > > +针对特定架构的实现 > > +================== > > + > > +这可以通过稍微修改标准的原子操作来实现:只有它们的UP变体必须被保留。这通常 > > +意味着删除LOCK前缀(在i386和x86_64上)和任何SMP同步屏障。如果架构在 SMP > ----------------------------------------------------------------------^ > a space del > > > +和UP之间没有不同的行为,在你的架构的 ``local.h`` 中包括 ``asm-generic/local.h`` > > +就足够了。 > > + > > +通过在一个结构中嵌入一个 ``atomic_long_t`` , ``local_t`` 类型被定义为 > > 结构体 OK > > > +一个不透明的 ``signed long`` 字符串。这样做的目的是为了使从这个类型到 > > 字符串 确定么? del 字符串 > > > +``long`` 的转换失败。该定义看起来像:: > > + > > + typedef struct { atomic_long_t a; } local_t; > > + > > + > > +使用本地原子操作时应遵循的规则 > > +============================== > > + > > +* 被本地操作触及的变量必须是每cpu的变量。 > > + > > +* 只有这些变量的CPU所有者才可以写入这些变量。 > > *只有* OK! > > > + > > +* 这个CPU可以从任何上下文(进程、中断、软中断、nmi...)中使用本地操作来更新 > > + 它的local_t变量。 > > + > > +* 当在进程上下文中使用本地操作时,必须禁用抢占(或中断),以确保进程在获得每 > > + CPU变量和进行实际的本地操作之间不会被迁移到不同的CPU。 > > + > > +* 当在中断上下文中使用本地操作时,在主线内核上不需要特别注意,因为它们将在局 > > + 部CPU上运行,并且已经禁用了抢占。然而,我建议无论如何都要明确地禁用抢占, > > + 以确保它在-rt内核上仍能正确工作。 > > + > > +* 读取本地cpu变量将提供该变量的当前拷贝。 > > + > > +* 对这些变量的读取可以从任何CPU进行,因为对 “ ``long`` ”,对齐的变量的更新 > > + 总是原子的。由于写程序的CPU没有进行内存同步,所以在读取其他cpu的变量时,可 > > s/写程序/写入程序/ > *其他* OK! > > > + 以读取该变量的过期副本。 > > + > > + > > +如何使用本地原子操作 > > +==================== > > + > > +:: > > + > > + #include <linux/percpu.h> > > + #include <asm/local.h> > > + > > + static DEFINE_PER_CPU(local_t, counters) = LOCAL_INIT(0); > > + > > + > > +计数器 > > +====== > > + > > +计数是在一个signed long的所有位上进行的。 > > + > > +在可抢占的上下文中,围绕本地原子操作使用 ``get_cpu_var()`` 和 > > +``put_cpu_var()`` :它确保在对每个cpu变量进行写访问时,抢占被禁用。比如 > > +说:: > > + > > + local_inc(&get_cpu_var(counters)); > > + put_cpu_var(counters); > > + > > +如果你已经在一个抢占式安全上下文中,你可以使用 ``this_cpu_ptr()`` 代替:: > > remove 式 ? OK! > > > + > > + local_inc(this_cpu_ptr(&counters)); > > + > > + > > + > > +读取计数器 > > +========== > > + > > +那些本地计数器可以从外部的CPU中读取,以求得计数的总和。请注意,local_read > > +所看到的跨CPU的数据必须被认为是相对于拥有该数据的CPU上发生的其他内存写入来 > > +说不符合顺序的。:: > > remove 。 OK!>_< > > > + > > + long sum = 0; > > + for_each_online_cpu(cpu) > > + sum += local_read(&per_cpu(counters, cpu)); > > + > > +如果你想使用远程local_read来同步CPU之间对资源的访问,必须在写入者和读取者 > > +的CPU上分别使用显式的 ``smp_wmb()`` 和 ``smp_rmb()`` 内存屏障。如果你使 > > +用 ``local_t`` 变量作为写在缓冲区中的字节的计数器,就会出现这种情况:在缓 > > +冲区写和计数器增量之间应该有一个 ``smp_wmb()`` ,在计数器读和缓冲区读之间 > > +也应有一个 ``smp_rmb()`` 。 > > + > > +下面是一个使用 ``local.h`` 实现每个cpu基本计数器的示例模块:: > > + > > + /* test-local.c > > + * > > + * Sample module for local.h usage. > > + */ > > + > > + > > + #include <asm/local.h> > > + #include <linux/module.h> > > + #include <linux/timer.h> > > + > > + static DEFINE_PER_CPU(local_t, counters) = LOCAL_INIT(0); > > + > > + static struct timer_list test_timer; > > + > > + /* IPI called on each CPU. */ > > + static void test_each(void *info) > > + { > > + /* Increment the counter from a non preemptible context */ > > + printk("Increment on cpu %d\n", smp_processor_id()); > > + local_inc(this_cpu_ptr(&counters)); > > + > > + /* This is what incrementing the variable would look like within a > > + * preemptible context (it disables preemption) : > > + * > > + * local_inc(&get_cpu_var(counters)); > > + * put_cpu_var(counters); > > + */ > > + } > > + > > + static void do_test_timer(unsigned long data) > > + { > > + int cpu; > > + > > + /* Increment the counters */ > > + on_each_cpu(test_each, NULL, 1); > > + /* Read all the counters */ > > + printk("Counters read from CPU %d\n", smp_processor_id()); > > + for_each_online_cpu(cpu) { > > + printk("Read : CPU %d, count %ld\n", cpu, > > + local_read(&per_cpu(counters, cpu))); > > + } > > + mod_timer(&test_timer, jiffies + 1000); > > + } > > + > > + static int __init test_init(void) > > + { > > + /* initialize the timer that will increment the counter */ > > + timer_setup(&test_timer, do_test_timer, 0); > > + mod_timer(&test_timer, jiffies + 1); > > + > > + return 0; > > + } > > + > > + static void __exit test_exit(void) > > + { > > + del_timer_sync(&test_timer); > > + } > > + > > + module_init(test_init); > > + module_exit(test_exit); > > + > > + MODULE_LICENSE("GPL"); > > + MODULE_AUTHOR("Mathieu Desnoyers"); > > + MODULE_DESCRIPTION("Local Atomic Ops"); > > -- > > 2.27.0 > > Thanks! > > Wu X.C. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] docs/zh_CN: add core api local_ops.rst translation 2021-05-21 1:53 ` yanteng si @ 2021-05-21 6:16 ` Wu X.C. 0 siblings, 0 replies; 8+ messages in thread From: Wu X.C. @ 2021-05-21 6:16 UTC (permalink / raw) To: yanteng si Cc: Yanteng Si, Jonathan Corbet, Alex Shi, Huacai Chen, Jiaxun Yang, linux-doc, Puyu Wang, huangjianghui [-- Attachment #1: Type: text/plain, Size: 2016 bytes --] On Fri, May 21, 2021 at 09:53:08AM +0800, yanteng si wrote: > Wu X.C. <bobwxc@email.cn> 于2021年5月20日周四 上午2:11写道: > > > > On Tue, May 18, 2021 at 11:08:52AM +0800, Yanteng Si wrote: > > > Translate Documentation/core-api/local_ops.rst into Chinese. > > > > > > Signed-off-by: Yanteng Si <siyanteng@loongson.cn> > > > --- > > > .../translations/zh_CN/core-api/index.rst | 3 +- > > > .../translations/zh_CN/core-api/local_ops.rst | 194 ++++++++++++++++++ > > > 2 files changed, 195 insertions(+), 2 deletions(-) > > > create mode 100644 Documentation/translations/zh_CN/core-api/local_ops.rst > > > > > > diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst > > > index 8f0b3fe8723d..c7a004bf2bd6 100644 > > > --- a/Documentation/translations/zh_CN/core-api/index.rst > > > +++ b/Documentation/translations/zh_CN/core-api/index.rst > > > @@ -59,11 +59,10 @@ Linux如何让一切同时发生。 详情请参阅 > > > > > > irq/index > > > refcount-vs-atomic > > > - > > > + local_ops > > > > > > Todolist: > > > > > > - local_ops > > > padata > > > ../RCU/index > > > > > > diff --git a/Documentation/translations/zh_CN/core-api/local_ops.rst b/Documentation/translations/zh_CN/core-api/local_ops.rst > > > new file mode 100644 > > > index 000000000000..1294cc1864ff > > > --- /dev/null > > > +++ b/Documentation/translations/zh_CN/core-api/local_ops.rst > > > @@ -0,0 +1,194 @@ > > > +.. include:: ../disclaimer-zh_CN.rst > > > + > > > +:Original: Documentation/core-api/local_ops.rst > > > +:Translator: Yanteng Si <siyanteng@loongson.cn> > > > + > > > +.. _cn_local_ops: > > > + > > > + > > > > Which is better for "local" in this article, 局部 or 本地? > > Seems not much different > “本地” is better. > If you want to use “局部", The word "local" should accompany the word > "global" in the context. Agree. Thanks, Wu X.C. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-05-21 6:16 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-05-18 3:08 [PATCH 0/2] docs/zh_CN:add core-api refcount-vs-atomic.rst and local_ops.rst translation Yanteng Si 2021-05-18 3:08 ` [PATCH 1/2] docs/zh_CN:add core-api refcount-vs-atomic.rst translation Yanteng Si 2021-05-19 13:20 ` Wu X.C. 2021-05-20 3:42 ` yanteng si 2021-05-18 3:08 ` [PATCH 2/2] docs/zh_CN: add core api local_ops.rst translation Yanteng Si 2021-05-19 18:11 ` Wu X.C. 2021-05-21 1:53 ` yanteng si 2021-05-21 6:16 ` Wu X.C.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.