diff for duplicates of <20171005163154.GH11088@arm.com> diff --git a/a/1.txt b/N1/1.txt index 2afdca9..8567066 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -29,397 +29,3 @@ Ok, full patch below. Will --->8 - -From 15956d0cc6b37208d8542b1858a8d8b64227acf4 Mon Sep 17 00:00:00 2001 -From: Will Deacon <will.deacon@arm.com> -Date: Thu, 5 Oct 2017 16:57:36 +0100 -Subject: [PATCH] locking/barriers: Kill lockless_dereference - -lockless_dereference is a nice idea, but it's gained little traction in -kernel code since it's introduction three years ago. This is partly -because it's a pain to type, but also because using READ_ONCE instead -will work correctly on all architectures apart from Alpha, which is a -fully supported but somewhat niche architecture these days. - -This patch moves smp_read_barrier_depends() (a NOP on all architectures -other than Alpha) from lockless_dereference into READ_ONCE, converts -the few actual users over to READ_ONCE and then finally removes -lockless_dereference altogether. - -Signed-off-by: Will Deacon <will.deacon@arm.com> ---- - Documentation/memory-barriers.txt | 12 ------------ - .../translations/ko_KR/memory-barriers.txt | 12 ------------ - arch/x86/events/core.c | 2 +- - arch/x86/include/asm/mmu_context.h | 4 ++-- - arch/x86/kernel/ldt.c | 2 +- - drivers/md/dm-mpath.c | 20 ++++++++++---------- - fs/dcache.c | 4 ++-- - fs/overlayfs/ovl_entry.h | 2 +- - fs/overlayfs/readdir.c | 2 +- - include/linux/compiler.h | 21 +-------------------- - include/linux/rculist.h | 4 ++-- - include/linux/rcupdate.h | 4 ++-- - kernel/events/core.c | 4 ++-- - kernel/seccomp.c | 2 +- - kernel/task_work.c | 2 +- - mm/slab.h | 2 +- - 16 files changed, 28 insertions(+), 71 deletions(-) - -diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt -index b759a60624fd..470a682f3fa4 100644 ---- a/Documentation/memory-barriers.txt -+++ b/Documentation/memory-barriers.txt -@@ -1886,18 +1886,6 @@ There are some more advanced barrier functions: - See Documentation/atomic_{t,bitops}.txt for more information. - - -- (*) lockless_dereference(); -- -- This can be thought of as a pointer-fetch wrapper around the -- smp_read_barrier_depends() data-dependency barrier. -- -- This is also similar to rcu_dereference(), but in cases where -- object lifetime is handled by some mechanism other than RCU, for -- example, when the objects removed only when the system goes down. -- In addition, lockless_dereference() is used in some data structures -- that can be used both with and without RCU. -- -- - (*) dma_wmb(); - (*) dma_rmb(); - -diff --git a/Documentation/translations/ko_KR/memory-barriers.txt b/Documentation/translations/ko_KR/memory-barriers.txt -index a7a813258013..ec3b46e27b7a 100644 ---- a/Documentation/translations/ko_KR/memory-barriers.txt -+++ b/Documentation/translations/ko_KR/memory-barriers.txt -@@ -1858,18 +1858,6 @@ Mandatory 배리어들은 SMP 시스템에서도 UP 시스템에서도 SMP 효 - 참고하세요. - - -- (*) lockless_dereference(); -- -- 이 함수는 smp_read_barrier_depends() 데이터 의존성 배리어를 사용하는 -- 포인터 읽어오기 래퍼(wrapper) 함수로 생각될 수 있습니다. -- -- 객체의 라이프타임이 RCU 외의 메커니즘으로 관리된다는 점을 제외하면 -- rcu_dereference() 와도 유사한데, 예를 들면 객체가 시스템이 꺼질 때에만 -- 제거되는 경우 등입니다. 또한, lockless_dereference() 은 RCU 와 함께 -- 사용될수도, RCU 없이 사용될 수도 있는 일부 데이터 구조에 사용되고 -- 있습니다. -- -- - (*) dma_wmb(); - (*) dma_rmb(); - -diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c -index 80534d3c2480..589af1eec7c1 100644 ---- a/arch/x86/events/core.c -+++ b/arch/x86/events/core.c -@@ -2371,7 +2371,7 @@ static unsigned long get_segment_base(unsigned int segment) - struct ldt_struct *ldt; - - /* IRQs are off, so this synchronizes with smp_store_release */ -- ldt = lockless_dereference(current->active_mm->context.ldt); -+ ldt = READ_ONCE(current->active_mm->context.ldt); - if (!ldt || idx >= ldt->nr_entries) - return 0; - -diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h -index c120b5db178a..9037a4e546e8 100644 ---- a/arch/x86/include/asm/mmu_context.h -+++ b/arch/x86/include/asm/mmu_context.h -@@ -72,8 +72,8 @@ static inline void load_mm_ldt(struct mm_struct *mm) - #ifdef CONFIG_MODIFY_LDT_SYSCALL - struct ldt_struct *ldt; - -- /* lockless_dereference synchronizes with smp_store_release */ -- ldt = lockless_dereference(mm->context.ldt); -+ /* READ_ONCE synchronizes with smp_store_release */ -+ ldt = READ_ONCE(mm->context.ldt); - - /* - * Any change to mm->context.ldt is followed by an IPI to all -diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c -index f0e64db18ac8..0a21390642c4 100644 ---- a/arch/x86/kernel/ldt.c -+++ b/arch/x86/kernel/ldt.c -@@ -101,7 +101,7 @@ static void finalize_ldt_struct(struct ldt_struct *ldt) - static void install_ldt(struct mm_struct *current_mm, - struct ldt_struct *ldt) - { -- /* Synchronizes with lockless_dereference in load_mm_ldt. */ -+ /* Synchronizes with READ_ONCE in load_mm_ldt. */ - smp_store_release(¤t_mm->context.ldt, ldt); - - /* Activate the LDT for all CPUs using current_mm. */ -diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c -index 11f273d2f018..3f88c9d32f7e 100644 ---- a/drivers/md/dm-mpath.c -+++ b/drivers/md/dm-mpath.c -@@ -366,7 +366,7 @@ static struct pgpath *choose_path_in_pg(struct multipath *m, - - pgpath = path_to_pgpath(path); - -- if (unlikely(lockless_dereference(m->current_pg) != pg)) { -+ if (unlikely(READ_ONCE(m->current_pg) != pg)) { - /* Only update current_pgpath if pg changed */ - spin_lock_irqsave(&m->lock, flags); - m->current_pgpath = pgpath; -@@ -390,7 +390,7 @@ static struct pgpath *choose_pgpath(struct multipath *m, size_t nr_bytes) - } - - /* Were we instructed to switch PG? */ -- if (lockless_dereference(m->next_pg)) { -+ if (READ_ONCE(m->next_pg)) { - spin_lock_irqsave(&m->lock, flags); - pg = m->next_pg; - if (!pg) { -@@ -406,7 +406,7 @@ static struct pgpath *choose_pgpath(struct multipath *m, size_t nr_bytes) - - /* Don't change PG until it has no remaining paths */ - check_current_pg: -- pg = lockless_dereference(m->current_pg); -+ pg = READ_ONCE(m->current_pg); - if (pg) { - pgpath = choose_path_in_pg(m, pg, nr_bytes); - if (!IS_ERR_OR_NULL(pgpath)) -@@ -473,7 +473,7 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq, - struct request *clone; - - /* Do we need to select a new pgpath? */ -- pgpath = lockless_dereference(m->current_pgpath); -+ pgpath = READ_ONCE(m->current_pgpath); - if (!pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags)) - pgpath = choose_pgpath(m, nr_bytes); - -@@ -535,7 +535,7 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio, struct dm_m - bool queue_io; - - /* Do we need to select a new pgpath? */ -- pgpath = lockless_dereference(m->current_pgpath); -+ pgpath = READ_ONCE(m->current_pgpath); - queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags); - if (!pgpath || !queue_io) - pgpath = choose_pgpath(m, nr_bytes); -@@ -1804,7 +1804,7 @@ static int multipath_prepare_ioctl(struct dm_target *ti, - struct pgpath *current_pgpath; - int r; - -- current_pgpath = lockless_dereference(m->current_pgpath); -+ current_pgpath = READ_ONCE(m->current_pgpath); - if (!current_pgpath) - current_pgpath = choose_pgpath(m, 0); - -@@ -1826,7 +1826,7 @@ static int multipath_prepare_ioctl(struct dm_target *ti, - } - - if (r == -ENOTCONN) { -- if (!lockless_dereference(m->current_pg)) { -+ if (!READ_ONCE(m->current_pg)) { - /* Path status changed, redo selection */ - (void) choose_pgpath(m, 0); - } -@@ -1895,9 +1895,9 @@ static int multipath_busy(struct dm_target *ti) - return (m->queue_mode != DM_TYPE_MQ_REQUEST_BASED); - - /* Guess which priority_group will be used at next mapping time */ -- pg = lockless_dereference(m->current_pg); -- next_pg = lockless_dereference(m->next_pg); -- if (unlikely(!lockless_dereference(m->current_pgpath) && next_pg)) -+ pg = READ_ONCE(m->current_pg); -+ next_pg = READ_ONCE(m->next_pg); -+ if (unlikely(!READ_ONCE(m->current_pgpath) && next_pg)) - pg = next_pg; - - if (!pg) { -diff --git a/fs/dcache.c b/fs/dcache.c -index f90141387f01..34c852af215c 100644 ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -231,7 +231,7 @@ static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *c - { - /* - * Be careful about RCU walk racing with rename: -- * use 'lockless_dereference' to fetch the name pointer. -+ * use 'READ_ONCE' to fetch the name pointer. - * - * NOTE! Even if a rename will mean that the length - * was not loaded atomically, we don't care. The -@@ -245,7 +245,7 @@ static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *c - * early because the data cannot match (there can - * be no NUL in the ct/tcount data) - */ -- const unsigned char *cs = lockless_dereference(dentry->d_name.name); -+ const unsigned char *cs = READ_ONCE(dentry->d_name.name); - - return dentry_string_cmp(cs, ct, tcount); - } -diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h -index 878a750986dd..0f6809fa6628 100644 ---- a/fs/overlayfs/ovl_entry.h -+++ b/fs/overlayfs/ovl_entry.h -@@ -74,5 +74,5 @@ static inline struct ovl_inode *OVL_I(struct inode *inode) - - static inline struct dentry *ovl_upperdentry_dereference(struct ovl_inode *oi) - { -- return lockless_dereference(oi->__upperdentry); -+ return READ_ONCE(oi->__upperdentry); - } -diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c -index 62e9b22a2077..0b389d330613 100644 ---- a/fs/overlayfs/readdir.c -+++ b/fs/overlayfs/readdir.c -@@ -754,7 +754,7 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end, - if (!od->is_upper && OVL_TYPE_UPPER(ovl_path_type(dentry))) { - struct inode *inode = file_inode(file); - -- realfile = lockless_dereference(od->upperfile); -+ realfile = READ_ONCE(od->upperfile); - if (!realfile) { - struct path upperpath; - -diff --git a/include/linux/compiler.h b/include/linux/compiler.h -index e95a2631e545..f260ff39f90f 100644 ---- a/include/linux/compiler.h -+++ b/include/linux/compiler.h -@@ -340,6 +340,7 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s - __read_once_size(&(x), __u.__c, sizeof(x)); \ - else \ - __read_once_size_nocheck(&(x), __u.__c, sizeof(x)); \ -+ smp_read_barrier_depends(); /* Enforce dependency ordering from x */ \ - __u.__val; \ - }) - #define READ_ONCE(x) __READ_ONCE(x, 1) -@@ -604,24 +605,4 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s - (volatile typeof(x) *)&(x); }) - #define ACCESS_ONCE(x) (*__ACCESS_ONCE(x)) - --/** -- * lockless_dereference() - safely load a pointer for later dereference -- * @p: The pointer to load -- * -- * Similar to rcu_dereference(), but for situations where the pointed-to -- * object's lifetime is managed by something other than RCU. That -- * "something other" might be reference counting or simple immortality. -- * -- * The seemingly unused variable ___typecheck_p validates that @p is -- * indeed a pointer type by using a pointer to typeof(*p) as the type. -- * Taking a pointer to typeof(*p) again is needed in case p is void *. -- */ --#define lockless_dereference(p) \ --({ \ -- typeof(p) _________p1 = READ_ONCE(p); \ -- typeof(*(p)) *___typecheck_p __maybe_unused; \ -- smp_read_barrier_depends(); /* Dependency order vs. p above. */ \ -- (_________p1); \ --}) -- - #endif /* __LINUX_COMPILER_H */ -diff --git a/include/linux/rculist.h b/include/linux/rculist.h -index b1fd8bf85fdc..3a2bb7d8ed4d 100644 ---- a/include/linux/rculist.h -+++ b/include/linux/rculist.h -@@ -274,7 +274,7 @@ static inline void list_splice_tail_init_rcu(struct list_head *list, - * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock(). - */ - #define list_entry_rcu(ptr, type, member) \ -- container_of(lockless_dereference(ptr), type, member) -+ container_of(READ_ONCE(ptr), type, member) - - /** - * Where are list_empty_rcu() and list_first_entry_rcu()? -@@ -367,7 +367,7 @@ static inline void list_splice_tail_init_rcu(struct list_head *list, - * example is when items are added to the list, but never deleted. - */ - #define list_entry_lockless(ptr, type, member) \ -- container_of((typeof(ptr))lockless_dereference(ptr), type, member) -+ container_of((typeof(ptr))READ_ONCE(ptr), type, member) - - /** - * list_for_each_entry_lockless - iterate over rcu list of given type -diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h -index de50d8a4cf41..380a3aeb09d7 100644 ---- a/include/linux/rcupdate.h -+++ b/include/linux/rcupdate.h -@@ -346,7 +346,7 @@ static inline void rcu_preempt_sleep_check(void) { } - #define __rcu_dereference_check(p, c, space) \ - ({ \ - /* Dependency order vs. p above. */ \ -- typeof(*p) *________p1 = (typeof(*p) *__force)lockless_dereference(p); \ -+ typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \ - RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \ - rcu_dereference_sparse(p, space); \ - ((typeof(*p) __force __kernel *)(________p1)); \ -@@ -360,7 +360,7 @@ static inline void rcu_preempt_sleep_check(void) { } - #define rcu_dereference_raw(p) \ - ({ \ - /* Dependency order vs. p above. */ \ -- typeof(p) ________p1 = lockless_dereference(p); \ -+ typeof(p) ________p1 = READ_ONCE(p); \ - ((typeof(*p) __force __kernel *)(________p1)); \ - }) - -diff --git a/kernel/events/core.c b/kernel/events/core.c -index 6bc21e202ae4..417812ce0099 100644 ---- a/kernel/events/core.c -+++ b/kernel/events/core.c -@@ -4231,7 +4231,7 @@ static void perf_remove_from_owner(struct perf_event *event) - * indeed free this event, otherwise we need to serialize on - * owner->perf_event_mutex. - */ -- owner = lockless_dereference(event->owner); -+ owner = READ_ONCE(event->owner); - if (owner) { - /* - * Since delayed_put_task_struct() also drops the last -@@ -4328,7 +4328,7 @@ int perf_event_release_kernel(struct perf_event *event) - * Cannot change, child events are not migrated, see the - * comment with perf_event_ctx_lock_nested(). - */ -- ctx = lockless_dereference(child->ctx); -+ ctx = READ_ONCE(child->ctx); - /* - * Since child_mutex nests inside ctx::mutex, we must jump - * through hoops. We start by grabbing a reference on the ctx. -diff --git a/kernel/seccomp.c b/kernel/seccomp.c -index bb3a38005b9c..1daa8b61a268 100644 ---- a/kernel/seccomp.c -+++ b/kernel/seccomp.c -@@ -189,7 +189,7 @@ static u32 seccomp_run_filters(const struct seccomp_data *sd, - u32 ret = SECCOMP_RET_ALLOW; - /* Make sure cross-thread synced filter points somewhere sane. */ - struct seccomp_filter *f = -- lockless_dereference(current->seccomp.filter); -+ READ_ONCE(current->seccomp.filter); - - /* Ensure unexpected behavior doesn't result in failing open. */ - if (unlikely(WARN_ON(f == NULL))) -diff --git a/kernel/task_work.c b/kernel/task_work.c -index 836a72a66fba..9a9f262fc53d 100644 ---- a/kernel/task_work.c -+++ b/kernel/task_work.c -@@ -67,7 +67,7 @@ task_work_cancel(struct task_struct *task, task_work_func_t func) - * we raced with task_work_run(), *pprev == NULL/exited. - */ - raw_spin_lock_irqsave(&task->pi_lock, flags); -- while ((work = lockless_dereference(*pprev))) { -+ while ((work = READ_ONCE(*pprev))) { - if (work->func != func) - pprev = &work->next; - else if (cmpxchg(pprev, work, work->next) == work) -diff --git a/mm/slab.h b/mm/slab.h -index 073362816acc..8894f811a89d 100644 ---- a/mm/slab.h -+++ b/mm/slab.h -@@ -258,7 +258,7 @@ cache_from_memcg_idx(struct kmem_cache *s, int idx) - * memcg_caches issues a write barrier to match this (see - * memcg_create_kmem_cache()). - */ -- cachep = lockless_dereference(arr->entries[idx]); -+ cachep = READ_ONCE(arr->entries[idx]); - rcu_read_unlock(); - - return cachep; --- -2.1.4 diff --git a/a/content_digest b/N1/content_digest index 8b3c6aa..96d7bd3 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -57,400 +57,6 @@ "\n" "Will\n" "\n" - "--->8\n" - "\n" - "From 15956d0cc6b37208d8542b1858a8d8b64227acf4 Mon Sep 17 00:00:00 2001\n" - "From: Will Deacon <will.deacon@arm.com>\n" - "Date: Thu, 5 Oct 2017 16:57:36 +0100\n" - "Subject: [PATCH] locking/barriers: Kill lockless_dereference\n" - "\n" - "lockless_dereference is a nice idea, but it's gained little traction in\n" - "kernel code since it's introduction three years ago. This is partly\n" - "because it's a pain to type, but also because using READ_ONCE instead\n" - "will work correctly on all architectures apart from Alpha, which is a\n" - "fully supported but somewhat niche architecture these days.\n" - "\n" - "This patch moves smp_read_barrier_depends() (a NOP on all architectures\n" - "other than Alpha) from lockless_dereference into READ_ONCE, converts\n" - "the few actual users over to READ_ONCE and then finally removes\n" - "lockless_dereference altogether.\n" - "\n" - "Signed-off-by: Will Deacon <will.deacon@arm.com>\n" - "---\n" - " Documentation/memory-barriers.txt | 12 ------------\n" - " .../translations/ko_KR/memory-barriers.txt | 12 ------------\n" - " arch/x86/events/core.c | 2 +-\n" - " arch/x86/include/asm/mmu_context.h | 4 ++--\n" - " arch/x86/kernel/ldt.c | 2 +-\n" - " drivers/md/dm-mpath.c | 20 ++++++++++----------\n" - " fs/dcache.c | 4 ++--\n" - " fs/overlayfs/ovl_entry.h | 2 +-\n" - " fs/overlayfs/readdir.c | 2 +-\n" - " include/linux/compiler.h | 21 +--------------------\n" - " include/linux/rculist.h | 4 ++--\n" - " include/linux/rcupdate.h | 4 ++--\n" - " kernel/events/core.c | 4 ++--\n" - " kernel/seccomp.c | 2 +-\n" - " kernel/task_work.c | 2 +-\n" - " mm/slab.h | 2 +-\n" - " 16 files changed, 28 insertions(+), 71 deletions(-)\n" - "\n" - "diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt\n" - "index b759a60624fd..470a682f3fa4 100644\n" - "--- a/Documentation/memory-barriers.txt\n" - "+++ b/Documentation/memory-barriers.txt\n" - "@@ -1886,18 +1886,6 @@ There are some more advanced barrier functions:\n" - " See Documentation/atomic_{t,bitops}.txt for more information.\n" - " \n" - " \n" - "- (*) lockless_dereference();\n" - "-\n" - "- This can be thought of as a pointer-fetch wrapper around the\n" - "- smp_read_barrier_depends() data-dependency barrier.\n" - "-\n" - "- This is also similar to rcu_dereference(), but in cases where\n" - "- object lifetime is handled by some mechanism other than RCU, for\n" - "- example, when the objects removed only when the system goes down.\n" - "- In addition, lockless_dereference() is used in some data structures\n" - "- that can be used both with and without RCU.\n" - "-\n" - "-\n" - " (*) dma_wmb();\n" - " (*) dma_rmb();\n" - " \n" - "diff --git a/Documentation/translations/ko_KR/memory-barriers.txt b/Documentation/translations/ko_KR/memory-barriers.txt\n" - "index a7a813258013..ec3b46e27b7a 100644\n" - "--- a/Documentation/translations/ko_KR/memory-barriers.txt\n" - "+++ b/Documentation/translations/ko_KR/memory-barriers.txt\n" - "@@ -1858,18 +1858,6 @@ Mandatory \353\260\260\353\246\254\354\226\264\353\223\244\354\235\200 SMP \354\213\234\354\212\244\355\205\234\354\227\220\354\204\234\353\217\204 UP \354\213\234\354\212\244\355\205\234\354\227\220\354\204\234\353\217\204 SMP \355\232\250\n" - " \354\260\270\352\263\240\355\225\230\354\204\270\354\232\224.\n" - " \n" - " \n" - "- (*) lockless_dereference();\n" - "-\n" - "- \354\235\264 \355\225\250\354\210\230\353\212\224 smp_read_barrier_depends() \353\215\260\354\235\264\355\204\260 \354\235\230\354\241\264\354\204\261 \353\260\260\353\246\254\354\226\264\353\245\274 \354\202\254\354\232\251\355\225\230\353\212\224\n" - "- \355\217\254\354\235\270\355\204\260 \354\235\275\354\226\264\354\230\244\352\270\260 \353\236\230\355\215\274(wrapper) \355\225\250\354\210\230\353\241\234 \354\203\235\352\260\201\353\220\240 \354\210\230 \354\236\210\354\212\265\353\213\210\353\213\244.\n" - "-\n" - "- \352\260\235\354\262\264\354\235\230 \353\235\274\354\235\264\355\224\204\355\203\200\354\236\204\354\235\264 RCU \354\231\270\354\235\230 \353\251\224\354\273\244\353\213\210\354\246\230\354\234\274\353\241\234 \352\264\200\353\246\254\353\220\234\353\213\244\353\212\224 \354\240\220\354\235\204 \354\240\234\354\231\270\355\225\230\353\251\264\n" - "- rcu_dereference() \354\231\200\353\217\204 \354\234\240\354\202\254\355\225\234\353\215\260, \354\230\210\353\245\274 \353\223\244\353\251\264 \352\260\235\354\262\264\352\260\200 \354\213\234\354\212\244\355\205\234\354\235\264 \352\272\274\354\247\210 \353\225\214\354\227\220\353\247\214\n" - "- \354\240\234\352\261\260\353\220\230\353\212\224 \352\262\275\354\232\260 \353\223\261\354\236\205\353\213\210\353\213\244. \353\230\220\355\225\234, lockless_dereference() \354\235\200 RCU \354\231\200 \355\225\250\352\273\230\n" - "- \354\202\254\354\232\251\353\220\240\354\210\230\353\217\204, RCU \354\227\206\354\235\264 \354\202\254\354\232\251\353\220\240 \354\210\230\353\217\204 \354\236\210\353\212\224 \354\235\274\353\266\200 \353\215\260\354\235\264\355\204\260 \352\265\254\354\241\260\354\227\220 \354\202\254\354\232\251\353\220\230\352\263\240\n" - "- \354\236\210\354\212\265\353\213\210\353\213\244.\n" - "-\n" - "-\n" - " (*) dma_wmb();\n" - " (*) dma_rmb();\n" - " \n" - "diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c\n" - "index 80534d3c2480..589af1eec7c1 100644\n" - "--- a/arch/x86/events/core.c\n" - "+++ b/arch/x86/events/core.c\n" - "@@ -2371,7 +2371,7 @@ static unsigned long get_segment_base(unsigned int segment)\n" - " \t\tstruct ldt_struct *ldt;\n" - " \n" - " \t\t/* IRQs are off, so this synchronizes with smp_store_release */\n" - "-\t\tldt = lockless_dereference(current->active_mm->context.ldt);\n" - "+\t\tldt = READ_ONCE(current->active_mm->context.ldt);\n" - " \t\tif (!ldt || idx >= ldt->nr_entries)\n" - " \t\t\treturn 0;\n" - " \n" - "diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h\n" - "index c120b5db178a..9037a4e546e8 100644\n" - "--- a/arch/x86/include/asm/mmu_context.h\n" - "+++ b/arch/x86/include/asm/mmu_context.h\n" - "@@ -72,8 +72,8 @@ static inline void load_mm_ldt(struct mm_struct *mm)\n" - " #ifdef CONFIG_MODIFY_LDT_SYSCALL\n" - " \tstruct ldt_struct *ldt;\n" - " \n" - "-\t/* lockless_dereference synchronizes with smp_store_release */\n" - "-\tldt = lockless_dereference(mm->context.ldt);\n" - "+\t/* READ_ONCE synchronizes with smp_store_release */\n" - "+\tldt = READ_ONCE(mm->context.ldt);\n" - " \n" - " \t/*\n" - " \t * Any change to mm->context.ldt is followed by an IPI to all\n" - "diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c\n" - "index f0e64db18ac8..0a21390642c4 100644\n" - "--- a/arch/x86/kernel/ldt.c\n" - "+++ b/arch/x86/kernel/ldt.c\n" - "@@ -101,7 +101,7 @@ static void finalize_ldt_struct(struct ldt_struct *ldt)\n" - " static void install_ldt(struct mm_struct *current_mm,\n" - " \t\t\tstruct ldt_struct *ldt)\n" - " {\n" - "-\t/* Synchronizes with lockless_dereference in load_mm_ldt. */\n" - "+\t/* Synchronizes with READ_ONCE in load_mm_ldt. */\n" - " \tsmp_store_release(¤t_mm->context.ldt, ldt);\n" - " \n" - " \t/* Activate the LDT for all CPUs using current_mm. */\n" - "diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c\n" - "index 11f273d2f018..3f88c9d32f7e 100644\n" - "--- a/drivers/md/dm-mpath.c\n" - "+++ b/drivers/md/dm-mpath.c\n" - "@@ -366,7 +366,7 @@ static struct pgpath *choose_path_in_pg(struct multipath *m,\n" - " \n" - " \tpgpath = path_to_pgpath(path);\n" - " \n" - "-\tif (unlikely(lockless_dereference(m->current_pg) != pg)) {\n" - "+\tif (unlikely(READ_ONCE(m->current_pg) != pg)) {\n" - " \t\t/* Only update current_pgpath if pg changed */\n" - " \t\tspin_lock_irqsave(&m->lock, flags);\n" - " \t\tm->current_pgpath = pgpath;\n" - "@@ -390,7 +390,7 @@ static struct pgpath *choose_pgpath(struct multipath *m, size_t nr_bytes)\n" - " \t}\n" - " \n" - " \t/* Were we instructed to switch PG? */\n" - "-\tif (lockless_dereference(m->next_pg)) {\n" - "+\tif (READ_ONCE(m->next_pg)) {\n" - " \t\tspin_lock_irqsave(&m->lock, flags);\n" - " \t\tpg = m->next_pg;\n" - " \t\tif (!pg) {\n" - "@@ -406,7 +406,7 @@ static struct pgpath *choose_pgpath(struct multipath *m, size_t nr_bytes)\n" - " \n" - " \t/* Don't change PG until it has no remaining paths */\n" - " check_current_pg:\n" - "-\tpg = lockless_dereference(m->current_pg);\n" - "+\tpg = READ_ONCE(m->current_pg);\n" - " \tif (pg) {\n" - " \t\tpgpath = choose_path_in_pg(m, pg, nr_bytes);\n" - " \t\tif (!IS_ERR_OR_NULL(pgpath))\n" - "@@ -473,7 +473,7 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq,\n" - " \tstruct request *clone;\n" - " \n" - " \t/* Do we need to select a new pgpath? */\n" - "-\tpgpath = lockless_dereference(m->current_pgpath);\n" - "+\tpgpath = READ_ONCE(m->current_pgpath);\n" - " \tif (!pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags))\n" - " \t\tpgpath = choose_pgpath(m, nr_bytes);\n" - " \n" - "@@ -535,7 +535,7 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio, struct dm_m\n" - " \tbool queue_io;\n" - " \n" - " \t/* Do we need to select a new pgpath? */\n" - "-\tpgpath = lockless_dereference(m->current_pgpath);\n" - "+\tpgpath = READ_ONCE(m->current_pgpath);\n" - " \tqueue_io = test_bit(MPATHF_QUEUE_IO, &m->flags);\n" - " \tif (!pgpath || !queue_io)\n" - " \t\tpgpath = choose_pgpath(m, nr_bytes);\n" - "@@ -1804,7 +1804,7 @@ static int multipath_prepare_ioctl(struct dm_target *ti,\n" - " \tstruct pgpath *current_pgpath;\n" - " \tint r;\n" - " \n" - "-\tcurrent_pgpath = lockless_dereference(m->current_pgpath);\n" - "+\tcurrent_pgpath = READ_ONCE(m->current_pgpath);\n" - " \tif (!current_pgpath)\n" - " \t\tcurrent_pgpath = choose_pgpath(m, 0);\n" - " \n" - "@@ -1826,7 +1826,7 @@ static int multipath_prepare_ioctl(struct dm_target *ti,\n" - " \t}\n" - " \n" - " \tif (r == -ENOTCONN) {\n" - "-\t\tif (!lockless_dereference(m->current_pg)) {\n" - "+\t\tif (!READ_ONCE(m->current_pg)) {\n" - " \t\t\t/* Path status changed, redo selection */\n" - " \t\t\t(void) choose_pgpath(m, 0);\n" - " \t\t}\n" - "@@ -1895,9 +1895,9 @@ static int multipath_busy(struct dm_target *ti)\n" - " \t\treturn (m->queue_mode != DM_TYPE_MQ_REQUEST_BASED);\n" - " \n" - " \t/* Guess which priority_group will be used at next mapping time */\n" - "-\tpg = lockless_dereference(m->current_pg);\n" - "-\tnext_pg = lockless_dereference(m->next_pg);\n" - "-\tif (unlikely(!lockless_dereference(m->current_pgpath) && next_pg))\n" - "+\tpg = READ_ONCE(m->current_pg);\n" - "+\tnext_pg = READ_ONCE(m->next_pg);\n" - "+\tif (unlikely(!READ_ONCE(m->current_pgpath) && next_pg))\n" - " \t\tpg = next_pg;\n" - " \n" - " \tif (!pg) {\n" - "diff --git a/fs/dcache.c b/fs/dcache.c\n" - "index f90141387f01..34c852af215c 100644\n" - "--- a/fs/dcache.c\n" - "+++ b/fs/dcache.c\n" - "@@ -231,7 +231,7 @@ static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *c\n" - " {\n" - " \t/*\n" - " \t * Be careful about RCU walk racing with rename:\n" - "-\t * use 'lockless_dereference' to fetch the name pointer.\n" - "+\t * use 'READ_ONCE' to fetch the name pointer.\n" - " \t *\n" - " \t * NOTE! Even if a rename will mean that the length\n" - " \t * was not loaded atomically, we don't care. The\n" - "@@ -245,7 +245,7 @@ static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *c\n" - " \t * early because the data cannot match (there can\n" - " \t * be no NUL in the ct/tcount data)\n" - " \t */\n" - "-\tconst unsigned char *cs = lockless_dereference(dentry->d_name.name);\n" - "+\tconst unsigned char *cs = READ_ONCE(dentry->d_name.name);\n" - " \n" - " \treturn dentry_string_cmp(cs, ct, tcount);\n" - " }\n" - "diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h\n" - "index 878a750986dd..0f6809fa6628 100644\n" - "--- a/fs/overlayfs/ovl_entry.h\n" - "+++ b/fs/overlayfs/ovl_entry.h\n" - "@@ -74,5 +74,5 @@ static inline struct ovl_inode *OVL_I(struct inode *inode)\n" - " \n" - " static inline struct dentry *ovl_upperdentry_dereference(struct ovl_inode *oi)\n" - " {\n" - "-\treturn lockless_dereference(oi->__upperdentry);\n" - "+\treturn READ_ONCE(oi->__upperdentry);\n" - " }\n" - "diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c\n" - "index 62e9b22a2077..0b389d330613 100644\n" - "--- a/fs/overlayfs/readdir.c\n" - "+++ b/fs/overlayfs/readdir.c\n" - "@@ -754,7 +754,7 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end,\n" - " \tif (!od->is_upper && OVL_TYPE_UPPER(ovl_path_type(dentry))) {\n" - " \t\tstruct inode *inode = file_inode(file);\n" - " \n" - "-\t\trealfile = lockless_dereference(od->upperfile);\n" - "+\t\trealfile = READ_ONCE(od->upperfile);\n" - " \t\tif (!realfile) {\n" - " \t\t\tstruct path upperpath;\n" - " \n" - "diff --git a/include/linux/compiler.h b/include/linux/compiler.h\n" - "index e95a2631e545..f260ff39f90f 100644\n" - "--- a/include/linux/compiler.h\n" - "+++ b/include/linux/compiler.h\n" - "@@ -340,6 +340,7 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s\n" - " \t\t__read_once_size(&(x), __u.__c, sizeof(x));\t\t\\\n" - " \telse\t\t\t\t\t\t\t\t\\\n" - " \t\t__read_once_size_nocheck(&(x), __u.__c, sizeof(x));\t\\\n" - "+\tsmp_read_barrier_depends(); /* Enforce dependency ordering from x */ \\\n" - " \t__u.__val;\t\t\t\t\t\t\t\\\n" - " })\n" - " #define READ_ONCE(x) __READ_ONCE(x, 1)\n" - "@@ -604,24 +605,4 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s\n" - " \t(volatile typeof(x) *)&(x); })\n" - " #define ACCESS_ONCE(x) (*__ACCESS_ONCE(x))\n" - " \n" - "-/**\n" - "- * lockless_dereference() - safely load a pointer for later dereference\n" - "- * @p: The pointer to load\n" - "- *\n" - "- * Similar to rcu_dereference(), but for situations where the pointed-to\n" - "- * object's lifetime is managed by something other than RCU. That\n" - "- * \"something other\" might be reference counting or simple immortality.\n" - "- *\n" - "- * The seemingly unused variable ___typecheck_p validates that @p is\n" - "- * indeed a pointer type by using a pointer to typeof(*p) as the type.\n" - "- * Taking a pointer to typeof(*p) again is needed in case p is void *.\n" - "- */\n" - "-#define lockless_dereference(p) \\\n" - "-({ \\\n" - "-\ttypeof(p) _________p1 = READ_ONCE(p); \\\n" - "-\ttypeof(*(p)) *___typecheck_p __maybe_unused; \\\n" - "-\tsmp_read_barrier_depends(); /* Dependency order vs. p above. */ \\\n" - "-\t(_________p1); \\\n" - "-})\n" - "-\n" - " #endif /* __LINUX_COMPILER_H */\n" - "diff --git a/include/linux/rculist.h b/include/linux/rculist.h\n" - "index b1fd8bf85fdc..3a2bb7d8ed4d 100644\n" - "--- a/include/linux/rculist.h\n" - "+++ b/include/linux/rculist.h\n" - "@@ -274,7 +274,7 @@ static inline void list_splice_tail_init_rcu(struct list_head *list,\n" - " * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().\n" - " */\n" - " #define list_entry_rcu(ptr, type, member) \\\n" - "-\tcontainer_of(lockless_dereference(ptr), type, member)\n" - "+\tcontainer_of(READ_ONCE(ptr), type, member)\n" - " \n" - " /**\n" - " * Where are list_empty_rcu() and list_first_entry_rcu()?\n" - "@@ -367,7 +367,7 @@ static inline void list_splice_tail_init_rcu(struct list_head *list,\n" - " * example is when items are added to the list, but never deleted.\n" - " */\n" - " #define list_entry_lockless(ptr, type, member) \\\n" - "-\tcontainer_of((typeof(ptr))lockless_dereference(ptr), type, member)\n" - "+\tcontainer_of((typeof(ptr))READ_ONCE(ptr), type, member)\n" - " \n" - " /**\n" - " * list_for_each_entry_lockless - iterate over rcu list of given type\n" - "diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h\n" - "index de50d8a4cf41..380a3aeb09d7 100644\n" - "--- a/include/linux/rcupdate.h\n" - "+++ b/include/linux/rcupdate.h\n" - "@@ -346,7 +346,7 @@ static inline void rcu_preempt_sleep_check(void) { }\n" - " #define __rcu_dereference_check(p, c, space) \\\n" - " ({ \\\n" - " \t/* Dependency order vs. p above. */ \\\n" - "-\ttypeof(*p) *________p1 = (typeof(*p) *__force)lockless_dereference(p); \\\n" - "+\ttypeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \\\n" - " \tRCU_LOCKDEP_WARN(!(c), \"suspicious rcu_dereference_check() usage\"); \\\n" - " \trcu_dereference_sparse(p, space); \\\n" - " \t((typeof(*p) __force __kernel *)(________p1)); \\\n" - "@@ -360,7 +360,7 @@ static inline void rcu_preempt_sleep_check(void) { }\n" - " #define rcu_dereference_raw(p) \\\n" - " ({ \\\n" - " \t/* Dependency order vs. p above. */ \\\n" - "-\ttypeof(p) ________p1 = lockless_dereference(p); \\\n" - "+\ttypeof(p) ________p1 = READ_ONCE(p); \\\n" - " \t((typeof(*p) __force __kernel *)(________p1)); \\\n" - " })\n" - " \n" - "diff --git a/kernel/events/core.c b/kernel/events/core.c\n" - "index 6bc21e202ae4..417812ce0099 100644\n" - "--- a/kernel/events/core.c\n" - "+++ b/kernel/events/core.c\n" - "@@ -4231,7 +4231,7 @@ static void perf_remove_from_owner(struct perf_event *event)\n" - " \t * indeed free this event, otherwise we need to serialize on\n" - " \t * owner->perf_event_mutex.\n" - " \t */\n" - "-\towner = lockless_dereference(event->owner);\n" - "+\towner = READ_ONCE(event->owner);\n" - " \tif (owner) {\n" - " \t\t/*\n" - " \t\t * Since delayed_put_task_struct() also drops the last\n" - "@@ -4328,7 +4328,7 @@ int perf_event_release_kernel(struct perf_event *event)\n" - " \t\t * Cannot change, child events are not migrated, see the\n" - " \t\t * comment with perf_event_ctx_lock_nested().\n" - " \t\t */\n" - "-\t\tctx = lockless_dereference(child->ctx);\n" - "+\t\tctx = READ_ONCE(child->ctx);\n" - " \t\t/*\n" - " \t\t * Since child_mutex nests inside ctx::mutex, we must jump\n" - " \t\t * through hoops. We start by grabbing a reference on the ctx.\n" - "diff --git a/kernel/seccomp.c b/kernel/seccomp.c\n" - "index bb3a38005b9c..1daa8b61a268 100644\n" - "--- a/kernel/seccomp.c\n" - "+++ b/kernel/seccomp.c\n" - "@@ -189,7 +189,7 @@ static u32 seccomp_run_filters(const struct seccomp_data *sd,\n" - " \tu32 ret = SECCOMP_RET_ALLOW;\n" - " \t/* Make sure cross-thread synced filter points somewhere sane. */\n" - " \tstruct seccomp_filter *f =\n" - "-\t\t\tlockless_dereference(current->seccomp.filter);\n" - "+\t\t\tREAD_ONCE(current->seccomp.filter);\n" - " \n" - " \t/* Ensure unexpected behavior doesn't result in failing open. */\n" - " \tif (unlikely(WARN_ON(f == NULL)))\n" - "diff --git a/kernel/task_work.c b/kernel/task_work.c\n" - "index 836a72a66fba..9a9f262fc53d 100644\n" - "--- a/kernel/task_work.c\n" - "+++ b/kernel/task_work.c\n" - "@@ -67,7 +67,7 @@ task_work_cancel(struct task_struct *task, task_work_func_t func)\n" - " \t * we raced with task_work_run(), *pprev == NULL/exited.\n" - " \t */\n" - " \traw_spin_lock_irqsave(&task->pi_lock, flags);\n" - "-\twhile ((work = lockless_dereference(*pprev))) {\n" - "+\twhile ((work = READ_ONCE(*pprev))) {\n" - " \t\tif (work->func != func)\n" - " \t\t\tpprev = &work->next;\n" - " \t\telse if (cmpxchg(pprev, work, work->next) == work)\n" - "diff --git a/mm/slab.h b/mm/slab.h\n" - "index 073362816acc..8894f811a89d 100644\n" - "--- a/mm/slab.h\n" - "+++ b/mm/slab.h\n" - "@@ -258,7 +258,7 @@ cache_from_memcg_idx(struct kmem_cache *s, int idx)\n" - " \t * memcg_caches issues a write barrier to match this (see\n" - " \t * memcg_create_kmem_cache()).\n" - " \t */\n" - "-\tcachep = lockless_dereference(arr->entries[idx]);\n" - "+\tcachep = READ_ONCE(arr->entries[idx]);\n" - " \trcu_read_unlock();\n" - " \n" - " \treturn cachep;\n" - "-- \n" - 2.1.4 + --->8 -e0cc695fc5f0e00f58d88f1ae491bea721e9604511e27deca3ad2e35ce647bcb +f4f21637dc69168f9fb74ea6661a483d67769e5739aefa7ecee61051266c9eb8
diff --git a/a/1.txt b/N2/1.txt index 2afdca9..886ff50 100644 --- a/a/1.txt +++ b/N2/1.txt @@ -30,7 +30,7 @@ Will --->8 -From 15956d0cc6b37208d8542b1858a8d8b64227acf4 Mon Sep 17 00:00:00 2001 +>From 15956d0cc6b37208d8542b1858a8d8b64227acf4 Mon Sep 17 00:00:00 2001 From: Will Deacon <will.deacon@arm.com> Date: Thu, 5 Oct 2017 16:57:36 +0100 Subject: [PATCH] locking/barriers: Kill lockless_dereference diff --git a/a/content_digest b/N2/content_digest index 8b3c6aa..336292d 100644 --- a/a/content_digest +++ b/N2/content_digest @@ -59,7 +59,7 @@ "\n" "--->8\n" "\n" - "From 15956d0cc6b37208d8542b1858a8d8b64227acf4 Mon Sep 17 00:00:00 2001\n" + ">From 15956d0cc6b37208d8542b1858a8d8b64227acf4 Mon Sep 17 00:00:00 2001\n" "From: Will Deacon <will.deacon@arm.com>\n" "Date: Thu, 5 Oct 2017 16:57:36 +0100\n" "Subject: [PATCH] locking/barriers: Kill lockless_dereference\n" @@ -453,4 +453,4 @@ "-- \n" 2.1.4 -e0cc695fc5f0e00f58d88f1ae491bea721e9604511e27deca3ad2e35ce647bcb +91b7667a0942cf44e0c7bb8e9d633d5db56db42d9ba86e439e427d0e2977e1cf
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.