All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yanteng Si <siyanteng@loongson.cn>
To: corbet@lwn.net, alexs@kernel.org
Cc: Yanteng Si <siyanteng@loongson.cn>,
	chenhuacai@kernel.org, jiaxun.yang@flygoat.com,
	linux-doc@vger.kernel.org, realpuyuwang@gmail.com,
	bobwxc@email.cn, siyanteng01@gmail.com,
	huangjianghui@uniontech.com
Subject: [PATCH 2/2] docs/zh_CN: add core api local_ops.rst translation
Date: Tue, 18 May 2021 11:08:52 +0800	[thread overview]
Message-ID: <d3b3209a81bd225f6c6983c49b16a6ac8d93f054.1621255695.git.siyanteng@loongson.cn> (raw)
In-Reply-To: <cover.1621255695.git.siyanteng@loongson.cn>

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


  parent reply	other threads:[~2021-05-18  3:08 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 ` Yanteng Si [this message]
2021-05-19 18:11   ` [PATCH 2/2] docs/zh_CN: add core api local_ops.rst translation Wu X.C.
2021-05-21  1:53     ` yanteng si
2021-05-21  6:16       ` Wu X.C.

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d3b3209a81bd225f6c6983c49b16a6ac8d93f054.1621255695.git.siyanteng@loongson.cn \
    --to=siyanteng@loongson.cn \
    --cc=alexs@kernel.org \
    --cc=bobwxc@email.cn \
    --cc=chenhuacai@kernel.org \
    --cc=corbet@lwn.net \
    --cc=huangjianghui@uniontech.com \
    --cc=jiaxun.yang@flygoat.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=realpuyuwang@gmail.com \
    --cc=siyanteng01@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.