From: Thomas Gleixner tglx@linutronix.de
mainline inclusion from mainline-v6.2-rc1 commit 87bdd932e85881895d4720255b40ac28749c4e32 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7R8WG
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
Adjust to the new preferred function names.
Suggested-by: Steven Rostedt rostedt@goodmis.org Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Jacob Keller jacob.e.keller@intel.com Reviewed-by: Anna-Maria Behnsen anna-maria@linutronix.de Link: https://lore.kernel.org/r/20221123201625.075320635@linutronix.de
Conflicts: Documentation/RCU/Design/Requirements/Requirements.rst Documentation/translations/zh_CN/core-api/local_ops.rst Signed-off-by: Yu Liao liaoyu15@huawei.com --- .../RCU/Design/Requirements/Requirements.rst | 2 +- Documentation/core-api/local_ops.rst | 2 +- Documentation/kernel-hacking/locking.rst | 11 +- Documentation/timers/hrtimers.rst | 2 +- .../it_IT/kernel-hacking/locking.rst | 10 +- .../translations/zh_CN/core-api/local_ops.rst | 196 ++++++++++++++++++ 6 files changed, 209 insertions(+), 14 deletions(-) create mode 100644 Documentation/translations/zh_CN/core-api/local_ops.rst
diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst index 1ae79a10a8de..ad2cc20131ec 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.rst +++ b/Documentation/RCU/Design/Requirements/Requirements.rst @@ -1858,7 +1858,7 @@ unloaded. After a given module has been unloaded, any attempt to call one of its functions results in a segmentation fault. The module-unload functions must therefore cancel any delayed calls to loadable-module functions, for example, any outstanding ``mod_timer()`` must be dealt -with via ``del_timer_sync()`` or similar. +with via ``timer_delete_sync()`` or similar.
Unfortunately, there is no way to cancel an RCU callback; once you invoke ``call_rcu()``, the callback function is eventually going to be diff --git a/Documentation/core-api/local_ops.rst b/Documentation/core-api/local_ops.rst index 2ac3f9f29845..a84f8b0c7ab2 100644 --- a/Documentation/core-api/local_ops.rst +++ b/Documentation/core-api/local_ops.rst @@ -191,7 +191,7 @@ Here is a sample module which implements a basic per cpu counter using
static void __exit test_exit(void) { - del_timer_sync(&test_timer); + timer_delete_sync(&test_timer); }
module_init(test_init); diff --git a/Documentation/kernel-hacking/locking.rst b/Documentation/kernel-hacking/locking.rst index d5ad37467d0c..20710efa0322 100644 --- a/Documentation/kernel-hacking/locking.rst +++ b/Documentation/kernel-hacking/locking.rst @@ -976,7 +976,7 @@ you might do the following::
while (list) { struct foo *next = list->next; - del_timer(&list->timer); + timer_delete(&list->timer); kfree(list); list = next; } @@ -990,7 +990,7 @@ the lock after we spin_unlock_bh(), and then try to free the element (which has already been freed!).
This can be avoided by checking the result of -del_timer(): if it returns 1, the timer has been deleted. +timer_delete(): if it returns 1, the timer has been deleted. If 0, it means (in this case) that it is currently running, so we can do::
@@ -999,7 +999,7 @@ do::
while (list) { struct foo *next = list->next; - if (!del_timer(&list->timer)) { + if (!timer_delete(&list->timer)) { /* Give timer a chance to delete this */ spin_unlock_bh(&list_lock); goto retry; @@ -1014,8 +1014,7 @@ do:: Another common problem is deleting timers which restart themselves (by calling add_timer() at the end of their timer function). Because this is a fairly common case which is prone to races, you should -use del_timer_sync() (``include/linux/timer.h``) to -handle this case. +use timer_delete_sync() (``include/linux/timer.h``) to handle this case.
Locking Speed ============= @@ -1343,7 +1342,7 @@ lock.
- kfree()
-- add_timer() and del_timer() +- add_timer() and timer_delete()
Mutex API reference =================== diff --git a/Documentation/timers/hrtimers.rst b/Documentation/timers/hrtimers.rst index c1c20a693e8f..7ac448908d1f 100644 --- a/Documentation/timers/hrtimers.rst +++ b/Documentation/timers/hrtimers.rst @@ -118,7 +118,7 @@ existing timer wheel code, as it is mature and well suited. Sharing code was not really a win, due to the different data structures. Also, the hrtimer functions now have clearer behavior and clearer names - such as hrtimer_try_to_cancel() and hrtimer_cancel() [which are roughly -equivalent to del_timer() and del_timer_sync()] - so there's no direct +equivalent to timer_delete() and timer_delete_sync()] - so there's no direct 1:1 mapping between them on the algorithmic level, and thus no real potential for code sharing either.
diff --git a/Documentation/translations/it_IT/kernel-hacking/locking.rst b/Documentation/translations/it_IT/kernel-hacking/locking.rst index 587ae37d2ee9..955864af913a 100644 --- a/Documentation/translations/it_IT/kernel-hacking/locking.rst +++ b/Documentation/translations/it_IT/kernel-hacking/locking.rst @@ -1000,7 +1000,7 @@ potreste fare come segue::
while (list) { struct foo *next = list->next; - del_timer(&list->timer); + timer_delete(&list->timer); kfree(list); list = next; } @@ -1013,7 +1013,7 @@ e prender�� il *lock* solo dopo spin_unlock_bh(), e cercher�� di eliminare il suo oggetto (che per�� �� gi�� stato eliminato).
Questo pu�� essere evitato controllando il valore di ritorno di -del_timer(): se ritorna 1, il temporizzatore �� stato gi�� +timer_delete(): se ritorna 1, il temporizzatore �� stato gi�� rimosso. Se 0, significa (in questo caso) che il temporizzatore �� in esecuzione, quindi possiamo fare come segue::
@@ -1022,7 +1022,7 @@ esecuzione, quindi possiamo fare come segue::
while (list) { struct foo *next = list->next; - if (!del_timer(&list->timer)) { + if (!timer_delete(&list->timer)) { /* Give timer a chance to delete this */ spin_unlock_bh(&list_lock); goto retry; @@ -1036,7 +1036,7 @@ esecuzione, quindi possiamo fare come segue:: Un altro problema �� l'eliminazione dei temporizzatori che si riavviano da soli (chiamando add_timer() alla fine della loro esecuzione). Dato che questo �� un problema abbastanza comune con una propensione -alle corse critiche, dovreste usare del_timer_sync() +alle corse critiche, dovreste usare timer_delete_sync() (``include/linux/timer.h``) per gestire questo caso.
Velocit�� della sincronizzazione @@ -1384,7 +1384,7 @@ contesto, o trattenendo un qualsiasi *lock*.
- kfree()
-- add_timer() e del_timer() +- add_timer() e timer_delete()
Riferimento per l'API dei Mutex =============================== 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..22493b9b829c --- /dev/null +++ b/Documentation/translations/zh_CN/core-api/local_ops.rst @@ -0,0 +1,196 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/core-api/local_ops.rst + +:������: + + ��������� 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���Non Maskable Interrupt��������������������������������������������� +��������������������������������������������������������������� + +���������������������������������������������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) + { + timer_delete_sync(&test_timer); + } + + module_init(test_init); + module_exit(test_exit); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Mathieu Desnoyers"); + MODULE_DESCRIPTION("Local Atomic Ops");