linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Hillf Danton <hdanton@sina.com>
To: Liam Howlett <liam.howlett@oracle.com>
Cc: "maple-tree@lists.infradead.org" <maple-tree@lists.infradead.org>,
	"linux-mm@kvack.org" <linux-mm@kvack.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Michel Lespinasse <walken.cr@gmail.com>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [PATCH v2 10/61] kernel/fork: Use maple tree for dup_mmap() during forking
Date: Thu, 19 Aug 2021 10:01:05 +0800	[thread overview]
Message-ID: <20210819020105.3756-1-hdanton@sina.com> (raw)
In-Reply-To: <20210818145420.hoieffhzxnxc64qr@revolver>

On Wed, 18 Aug 2021 14:54:29 +0000 Liam R. Howlett wrote:
>* Hillf Danton <hdanton@sina.com> [210818 04:36]:
>> On Tue, 17 Aug 2021 15:47:11 +0000 Liam R. Howlett wrote:
>> >
>> >  static inline void mmget(struct mm_struct *mm)
>> >  {
>> > +	mt_set_in_rcu(&mm->mm_mt);
>> >  	atomic_inc(&mm->mm_users);
>> >  }
>> >
>> >  static inline bool mmget_not_zero(struct mm_struct *mm)
>> >  {
>> > +	/*
>> > +	 * There is a race below during task tear down that can cause the maple
>> > +	 * tree to enter rcu mode with only a single user.  If this race
>> > +	 * happens, the result would be that the maple tree nodes would remain
>> > +	 * active for an extra RCU read cycle.
>> > +	 */
>> > +	mt_set_in_rcu(&mm->mm_mt);
>> >  	return atomic_inc_not_zero(&mm->mm_users);
>> >  }
>>
>> Nit, leave the mm with zero refcount intact.
>>
>>  	if (atomic_inc_not_zero(&mm->mm_users)) {
>> 		mt_set_in_rcu(&mm->mm_mt);
>> 		return true;
>> 	}
>> 	return false;
>
>Thanks for looking at this.
>
>I thought about that, but came up with the following scenario:
>
>thread 1	thread 2
>mmget(mm)
>		mmget_not_zero() enter..
>		atomic_inc_not_zero(&mm->mm_users)
>mmput(mm)
>		mt_set_in_rcu(&mm->mm_mt);
>		return true;
>

At first glance, given the above mmget, mmput will not hurt anyone.

>
>So I think the above does not remove the race, but does add instructions

If the mm refcount drops to one after mmput then it is one before
atomic_inc_not_zero() which only ensures the mm is stable afterwards
until mmput again.

>to each call to mmget_not_zero().  I thought the race of having nodes
>sitting around for an rcu read cycle was worth the trade off.

Is one ounce of the mm stability worth two pounds? Or three?


WARNING: multiple messages have this Message-ID
From: Hillf Danton <hdanton@sina.com>
To: Liam Howlett <liam.howlett@oracle.com>
Cc: "maple-tree@lists.infradead.org" <maple-tree@lists.infradead.org>,
	"linux-mm@kvack.org" <linux-mm@kvack.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Michel Lespinasse <walken.cr@gmail.com>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [PATCH v2 10/61] kernel/fork: Use maple tree for dup_mmap() during forking
Date: Fri, 20 Aug 2021 12:04:55 +0800	[thread overview]
Message-ID: <20210819020105.3756-1-hdanton@sina.com> (raw)
Message-ID: <20210820040455.IbdxzebONQFn78zC2laYiGypGDbupzjrjgaMNoEGRs4@z> (raw)

On Thu, 19 Aug 2021 13:32:58 +0000 Liam R. Howlett wrote:
>* Hillf Danton <hdanton@sina.com> [210818 22:01]:
>> On Wed, 18 Aug 2021 14:54:29 +0000 Liam R. Howlett wrote:
>> >* Hillf Danton <hdanton@sina.com> [210818 04:36]:
>> >> On Tue, 17 Aug 2021 15:47:11 +0000 Liam R. Howlett wrote:
>> >> >
>> >> >  static inline void mmget(struct mm_struct *mm)
>> >> >  {
>> >> > +	mt_set_in_rcu(&mm->mm_mt);
>> >> >  	atomic_inc(&mm->mm_users);
>> >> >  }
>> >> >
>> >> >  static inline bool mmget_not_zero(struct mm_struct *mm)
>> >> >  {
>> >> > +	/*
>> >> > +	 * There is a race below during task tear down that can cause the =
>maple
>> >> > +	 * tree to enter rcu mode with only a single user.  If this race
>> >> > +	 * happens, the result would be that the maple tree nodes would re=
>main
>> >> > +	 * active for an extra RCU read cycle.
>> >> > +	 */
>> >> > +	mt_set_in_rcu(&mm->mm_mt);
>> >> >  	return atomic_inc_not_zero(&mm->mm_users);
>> >> >  }
>> >>
>> >> Nit, leave the mm with zero refcount intact.
>> >>
>> >>  	if (atomic_inc_not_zero(&mm->mm_users)) {
>> >> 		mt_set_in_rcu(&mm->mm_mt);
>> >> 		return true;
>> >> 	}
>> >> 	return false;
>> >
>> >Thanks for looking at this.
>> >
>> >I thought about that, but came up with the following scenario:
>> >
>> >thread 1	thread 2
>> >mmget(mm)
>> >		mmget_not_zero() enter..
>> >		atomic_inc_not_zero(&mm->mm_users)
>> >mmput(mm)
>> >		mt_set_in_rcu(&mm->mm_mt);
>> >		return true;
>> >
>>=20
>> At first glance, given the above mmget, mmput will not hurt anyone.
>
>In the case above, the maple tree enters RCU mode with a single user.
>This will have the result of nodes being freed in RCU mode which is the
>same result as what happens as it is written, except the racing thread
>wins (in this case).  I thought this was what you were trying to fix?
>
>>=20
>> >
>> >So I think the above does not remove the race, but does add instructions
>>=20
>> If the mm refcount drops to one after mmput then it is one before
>> atomic_inc_not_zero() which only ensures the mm is stable afterwards
>> until mmput again.
>
>Right.  The race we are worried about is the zero referenced mm.  If
>mm->mm_users is safe, then mm->mm_mt is also safe.
>
>>=20
>> >to each call to mmget_not_zero().  I thought the race of having nodes
>> >sitting around for an rcu read cycle was worth the trade off.
>>=20
>> Is one ounce of the mm stability worth two pounds? Or three?
>
>I don't see a stability problem with the way it is written.

On the maple tree side, I see in
 [PATCH v2 05/61] Maple Tree: Add new data structure

+ * MAPLE_USE_RCU	Operate in read/copy/update mode for multi-readers

<...>

+/**
+ * mt_set_in_rcu() - Switch the tree to RCU safe mode.
+ */
+static inline void mt_set_in_rcu(struct maple_tree *mt)
+{
+	if (mt_in_rcu(mt))
+		return;
+
+	mtree_lock(mt);
+	mt->ma_flags |= MAPLE_USE_RCU;
+	mtree_unlock(mt);
+}

and on the mm side, however, if atomic_inc_not_zero(&mm->mm_users) fails
then who can be the "RCU multi-readers"?

>Your change does not remove the race.

If atomic_inc_not_zero() fails then there is no pre-condition in any form
for race; if it succeeds then the race window is slammed.

>Can you explain how the stability is affected negatively by the way it
>is written?

Hard to find the correct answer without knowing why you prefer to update
the flags for mm->mm_mt with mm->mm_users dropping down to ground.


  reply	other threads:[~2021-08-19  2:01 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-17 15:47 [PATCH v2 00/61] Introducing the Maple Tree Liam Howlett
2021-08-17 15:47 ` [PATCH v2 01/61] radix tree test suite: Add pr_err define Liam Howlett
2021-08-17 15:47 ` [PATCH v2 02/61] radix tree test suite: Add kmem_cache_set_non_kernel() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 04/61] radix tree test suite: Add support for slab bulk APIs Liam Howlett
2021-08-17 15:47 ` [PATCH v2 03/61] radix tree test suite: Add allocation counts and size to kmem_cache Liam Howlett
2021-08-17 15:47 ` [PATCH v2 06/61] mm: Start tracking VMAs with maple tree Liam Howlett
2021-08-17 15:47 ` [PATCH v2 07/61] mm/mmap: Use the maple tree in find_vma() instead of the rbtree Liam Howlett
2021-08-17 15:47 ` [PATCH v2 05/61] Maple Tree: Add new data structure Liam Howlett
2021-08-17 15:47 ` [PATCH v2 10/61] kernel/fork: Use maple tree for dup_mmap() during forking Liam Howlett
2021-08-18  8:36   ` Hillf Danton
2021-08-18 14:54     ` Liam Howlett
2021-08-19  2:01       ` Hillf Danton [this message]
2021-08-19 13:32         ` Liam Howlett
2021-08-20  4:04         ` Hillf Danton
2021-08-20 17:45         ` Liam Howlett
2021-08-17 15:47 ` [PATCH v2 09/61] mm/mmap: Use maple tree for unmapped_area{_topdown} Liam Howlett
2021-08-17 15:47 ` [PATCH v2 08/61] mm/mmap: Use the maple tree for find_vma_prev() instead of the rbtree Liam Howlett
2021-08-17 15:47 ` [PATCH v2 13/61] mm: Optimize find_exact_vma() to use vma_lookup() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 12/61] xen/privcmd: Optimized privcmd_ioctl_mmap() by using vma_lookup() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 11/61] mm: Remove rb tree Liam Howlett
2021-08-23  9:49   ` David Hildenbrand
2021-08-31 14:40     ` Liam Howlett
2021-08-17 15:47 ` [PATCH v2 17/61] mm/mmap: Use advanced maple tree API for mmap_region() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 14/61] mm/khugepaged: Optimize collapse_pte_mapped_thp() by using vma_lookup() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 15/61] mm/mmap: Change do_brk_flags() to expand existing VMA and add do_brk_munmap() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 16/61] mm: Use maple tree operations for find_vma_intersection() and find_vma() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 19/61] mm/mmap: Move mmap_region() below do_munmap() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 18/61] mm: Remove vmacache Liam Howlett
2021-08-17 15:47 ` [PATCH v2 22/61] mm/mmap: Change do_brk_munmap() to use do_mas_align_munmap() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 21/61] mm/mmap: Reorganize munmap to use maple states Liam Howlett
2021-08-17 15:47 ` [PATCH v2 20/61] mm/mmap: Convert count_vma_pages_range() to use ma_state Liam Howlett
2021-08-17 15:47 ` [PATCH v2 25/61] arch/parisc: Remove mmap linked list from kernel/cache Liam Howlett
2021-08-17 15:47 ` [PATCH v2 23/61] mm: Introduce vma_next() and vma_prev() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 26/61] arch/powerpc: Remove mmap linked list from mm/book3s32/tlb Liam Howlett
2021-08-17 15:47 ` [PATCH v2 24/61] arch/arm64: Remove mmap linked list from vdso Liam Howlett
2021-08-17 15:47 ` [PATCH v2 27/61] arch/powerpc: Remove mmap linked list from mm/book3s64/subpage_prot Liam Howlett
2021-08-17 15:47 ` [PATCH v2 28/61] arch/s390: Use maple tree iterators instead of linked list Liam Howlett
2021-08-17 15:47 ` [PATCH v2 30/61] arch/xtensa: Use maple tree iterators for unmapped area Liam Howlett
2021-08-17 15:47 ` [PATCH v2 31/61] drivers/misc/cxl: Use maple tree iterators for cxl_prefault_vma() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 29/61] arch/x86: Use maple tree iterators for vdso/vma Liam Howlett
2021-08-17 15:47 ` [PATCH v2 32/61] drivers/tee/optee: Use maple tree iterators for __check_mem_type() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 34/61] fs/coredump: Use maple tree iterators in place of linked list Liam Howlett
2021-08-17 15:47 ` [PATCH v2 33/61] fs/binfmt_elf: Use maple tree iterators for fill_files_note() Liam Howlett
2021-08-17 15:47 ` [PATCH v2 37/61] fs/proc/task_mmu: Stop using linked list and highest_vm_end Liam Howlett
2021-08-17 15:47 ` [PATCH v2 35/61] fs/exec: Use vma_next() instead of linked list Liam Howlett
2021-08-17 15:47 ` [PATCH v2 38/61] fs/userfaultfd: Stop using vma " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 36/61] fs/proc/base: Use maple tree iterators in place of " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 39/61] ipc/shm: Stop using the vma " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 40/61] kernel/acct: Use maple tree iterators instead of " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 41/61] kernel/events/core: " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 43/61] kernel/sched/fair: " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 42/61] kernel/events/uprobes: " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 44/61] kernel/sys: " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 45/61] arch/um/kernel/tlb: Stop using " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 48/61] mm/khugepaged: Use maple tree iterators instead of vma " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 47/61] mm/gup: Use maple tree navigation instead of " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 46/61] bpf: Remove VMA " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 52/61] mm/mempolicy: Use maple tree iterators instead of vma " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 50/61] mm/madvise: Use vma_next " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 51/61] mm/memcontrol: Stop using mm->highest_vm_end Liam Howlett
2021-08-17 15:47 ` [PATCH v2 49/61] mm/ksm: Use maple tree iterators instead of vma linked list Liam Howlett
2021-08-17 15:47 ` [PATCH v2 55/61] mm/mremap: Use vma_next() " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 53/61] mm/mlock: Use maple tree iterators " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 54/61] mm/mprotect: Use maple tree navigation " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 56/61] mm/msync: Use vma_next() " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 57/61] mm/oom_kill: Use maple tree iterators " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 58/61] mm/pagewalk: Use vma_next() " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 59/61] mm/swapfile: Use maple tree iterator " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 60/61] mm: Remove the " Liam Howlett
2021-08-17 15:47 ` [PATCH v2 61/61] mm/mmap: Drop range_has_overlap() function Liam Howlett

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=20210819020105.3756-1-hdanton@sina.com \
    --to=hdanton@sina.com \
    --cc=akpm@linux-foundation.org \
    --cc=liam.howlett@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=maple-tree@lists.infradead.org \
    --cc=peterz@infradead.org \
    --cc=walken.cr@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox