All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Gunthorpe <jgg@nvidia.com>
To: Alistair Popple <apopple@nvidia.com>
Cc: <linux-mm@kvack.org>, <nouveau@lists.freedesktop.org>,
	<bskeggs@redhat.com>, <akpm@linux-foundation.org>,
	<linux-doc@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<dri-devel@lists.freedesktop.org>, <jhubbard@nvidia.com>,
	<rcampbell@nvidia.com>, <jglisse@redhat.com>, <hch@infradead.org>,
	<daniel@ffwll.ch>
Subject: Re: [PATCH v3 3/8] mm/rmap: Split try_to_munlock from try_to_unmap
Date: Mon, 1 Mar 2021 12:10:49 -0400	[thread overview]
Message-ID: <20210301161049.GJ4247@nvidia.com> (raw)
In-Reply-To: <20210226071832.31547-4-apopple@nvidia.com>

On Fri, Feb 26, 2021 at 06:18:27PM +1100, Alistair Popple wrote:
> The behaviour of try_to_unmap_one() is difficult to follow because it
> performs different operations based on a fairly large set of flags used
> in different combinations.
> 
> TTU_MUNLOCK is one such flag. However it is exclusively used by
> try_to_munlock() which specifies no other flags. Therefore rather than
> overload try_to_unmap_one() with unrelated behaviour split this out into
> it's own function and remove the flag.
> 
> Signed-off-by: Alistair Popple <apopple@nvidia.com>
> 
> 
> Given the comments on not needing to hold mmap_lock it was not 100% clear
> to me if it is safe to check vma->vma_flags & VM_LOCKED and if re-checking
> under the ptl was significant. I left the extra check in case it was, but
> it seems one of the checks is redunant as either the first check is racey
> or the second check is unneccsary.

The rmap doesn't hold the mmap_lock so I think both of these cases are
racey.

eg 

apply_vma_lock_flags()

	vma = find_vma(current->mm, start);
	if (!vma || vma->vm_start > start)
		return -ENOMEM;

	prev = vma->vm_prev;
	if (start > vma->vm_start)
		prev = vma;

	for (nstart = start ; ; ) {
		vm_flags_t newflags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;

		newflags |= flags;
 [...]
mlock_fixup()
	/*
	 * vm_flags is protected by the mmap_lock held in write mode.
	 * It's okay if try_to_unmap_one unmaps a page just after we
	 * set VM_LOCKED, populate_vma_page_range will bring it back.
	 */

	if (lock)
		vma->vm_flags = newflags;
	else
               	vma->vm_flags &= VM_LOCKED_CLEAR_MASK;

Which is only done under the mmap_sem

> +static bool try_to_munlock_one(struct page *page, struct vm_area_struct *vma,
> +		     unsigned long address, void *arg)
> +{
> +	struct page_vma_mapped_walk pvmw = {
> +		.page = page,
> +		.vma = vma,
> +		.address = address,
> +	};
> +	bool ret = true;
> +
> +	/* munlock has nothing to gain from examining un-locked vmas */
> +	if (!(vma->vm_flags & VM_LOCKED))
> +		return true;

The mmap_sem can't be obtained in the rmap walkers due to lock
ordering, the various rmap locks are nested under the mmap_sem

So, when reading data that is not locked it should be written as:

   READ_ONCE(vma->vm_flags) & VM_LOCKED

> +	while (page_vma_mapped_walk(&pvmw)) {
> +		/*
> +		 * If the page is mlock()d, we cannot swap it out.
> +		 * If it's recently referenced (perhaps page_referenced
> +		 * skipped over this mm) then we should reactivate it.
> +		 */
> +		if (vma->vm_flags & VM_LOCKED) {

And since we write the data without holding the PTLs this looks
pointless, unless there is some other VM_LOCKED manipulation

Jason

WARNING: multiple messages have this Message-ID (diff)
From: Jason Gunthorpe <jgg@nvidia.com>
To: Alistair Popple <apopple@nvidia.com>
Cc: rcampbell@nvidia.com, linux-doc@vger.kernel.org,
	nouveau@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	dri-devel@lists.freedesktop.org, hch@infradead.org,
	linux-mm@kvack.org, bskeggs@redhat.com, daniel@ffwll.ch,
	akpm@linux-foundation.org
Subject: Re: [Nouveau] [PATCH v3 3/8] mm/rmap: Split try_to_munlock from try_to_unmap
Date: Mon, 1 Mar 2021 12:10:49 -0400	[thread overview]
Message-ID: <20210301161049.GJ4247@nvidia.com> (raw)
In-Reply-To: <20210226071832.31547-4-apopple@nvidia.com>

On Fri, Feb 26, 2021 at 06:18:27PM +1100, Alistair Popple wrote:
> The behaviour of try_to_unmap_one() is difficult to follow because it
> performs different operations based on a fairly large set of flags used
> in different combinations.
> 
> TTU_MUNLOCK is one such flag. However it is exclusively used by
> try_to_munlock() which specifies no other flags. Therefore rather than
> overload try_to_unmap_one() with unrelated behaviour split this out into
> it's own function and remove the flag.
> 
> Signed-off-by: Alistair Popple <apopple@nvidia.com>
> 
> 
> Given the comments on not needing to hold mmap_lock it was not 100% clear
> to me if it is safe to check vma->vma_flags & VM_LOCKED and if re-checking
> under the ptl was significant. I left the extra check in case it was, but
> it seems one of the checks is redunant as either the first check is racey
> or the second check is unneccsary.

The rmap doesn't hold the mmap_lock so I think both of these cases are
racey.

eg 

apply_vma_lock_flags()

	vma = find_vma(current->mm, start);
	if (!vma || vma->vm_start > start)
		return -ENOMEM;

	prev = vma->vm_prev;
	if (start > vma->vm_start)
		prev = vma;

	for (nstart = start ; ; ) {
		vm_flags_t newflags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;

		newflags |= flags;
 [...]
mlock_fixup()
	/*
	 * vm_flags is protected by the mmap_lock held in write mode.
	 * It's okay if try_to_unmap_one unmaps a page just after we
	 * set VM_LOCKED, populate_vma_page_range will bring it back.
	 */

	if (lock)
		vma->vm_flags = newflags;
	else
               	vma->vm_flags &= VM_LOCKED_CLEAR_MASK;

Which is only done under the mmap_sem

> +static bool try_to_munlock_one(struct page *page, struct vm_area_struct *vma,
> +		     unsigned long address, void *arg)
> +{
> +	struct page_vma_mapped_walk pvmw = {
> +		.page = page,
> +		.vma = vma,
> +		.address = address,
> +	};
> +	bool ret = true;
> +
> +	/* munlock has nothing to gain from examining un-locked vmas */
> +	if (!(vma->vm_flags & VM_LOCKED))
> +		return true;

The mmap_sem can't be obtained in the rmap walkers due to lock
ordering, the various rmap locks are nested under the mmap_sem

So, when reading data that is not locked it should be written as:

   READ_ONCE(vma->vm_flags) & VM_LOCKED

> +	while (page_vma_mapped_walk(&pvmw)) {
> +		/*
> +		 * If the page is mlock()d, we cannot swap it out.
> +		 * If it's recently referenced (perhaps page_referenced
> +		 * skipped over this mm) then we should reactivate it.
> +		 */
> +		if (vma->vm_flags & VM_LOCKED) {

And since we write the data without holding the PTLs this looks
pointless, unless there is some other VM_LOCKED manipulation

Jason
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

WARNING: multiple messages have this Message-ID (diff)
From: Jason Gunthorpe <jgg@nvidia.com>
To: Alistair Popple <apopple@nvidia.com>
Cc: rcampbell@nvidia.com, linux-doc@vger.kernel.org,
	nouveau@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	dri-devel@lists.freedesktop.org, hch@infradead.org,
	linux-mm@kvack.org, jglisse@redhat.com, bskeggs@redhat.com,
	jhubbard@nvidia.com, akpm@linux-foundation.org
Subject: Re: [PATCH v3 3/8] mm/rmap: Split try_to_munlock from try_to_unmap
Date: Mon, 1 Mar 2021 12:10:49 -0400	[thread overview]
Message-ID: <20210301161049.GJ4247@nvidia.com> (raw)
In-Reply-To: <20210226071832.31547-4-apopple@nvidia.com>

On Fri, Feb 26, 2021 at 06:18:27PM +1100, Alistair Popple wrote:
> The behaviour of try_to_unmap_one() is difficult to follow because it
> performs different operations based on a fairly large set of flags used
> in different combinations.
> 
> TTU_MUNLOCK is one such flag. However it is exclusively used by
> try_to_munlock() which specifies no other flags. Therefore rather than
> overload try_to_unmap_one() with unrelated behaviour split this out into
> it's own function and remove the flag.
> 
> Signed-off-by: Alistair Popple <apopple@nvidia.com>
> 
> 
> Given the comments on not needing to hold mmap_lock it was not 100% clear
> to me if it is safe to check vma->vma_flags & VM_LOCKED and if re-checking
> under the ptl was significant. I left the extra check in case it was, but
> it seems one of the checks is redunant as either the first check is racey
> or the second check is unneccsary.

The rmap doesn't hold the mmap_lock so I think both of these cases are
racey.

eg 

apply_vma_lock_flags()

	vma = find_vma(current->mm, start);
	if (!vma || vma->vm_start > start)
		return -ENOMEM;

	prev = vma->vm_prev;
	if (start > vma->vm_start)
		prev = vma;

	for (nstart = start ; ; ) {
		vm_flags_t newflags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;

		newflags |= flags;
 [...]
mlock_fixup()
	/*
	 * vm_flags is protected by the mmap_lock held in write mode.
	 * It's okay if try_to_unmap_one unmaps a page just after we
	 * set VM_LOCKED, populate_vma_page_range will bring it back.
	 */

	if (lock)
		vma->vm_flags = newflags;
	else
               	vma->vm_flags &= VM_LOCKED_CLEAR_MASK;

Which is only done under the mmap_sem

> +static bool try_to_munlock_one(struct page *page, struct vm_area_struct *vma,
> +		     unsigned long address, void *arg)
> +{
> +	struct page_vma_mapped_walk pvmw = {
> +		.page = page,
> +		.vma = vma,
> +		.address = address,
> +	};
> +	bool ret = true;
> +
> +	/* munlock has nothing to gain from examining un-locked vmas */
> +	if (!(vma->vm_flags & VM_LOCKED))
> +		return true;

The mmap_sem can't be obtained in the rmap walkers due to lock
ordering, the various rmap locks are nested under the mmap_sem

So, when reading data that is not locked it should be written as:

   READ_ONCE(vma->vm_flags) & VM_LOCKED

> +	while (page_vma_mapped_walk(&pvmw)) {
> +		/*
> +		 * If the page is mlock()d, we cannot swap it out.
> +		 * If it's recently referenced (perhaps page_referenced
> +		 * skipped over this mm) then we should reactivate it.
> +		 */
> +		if (vma->vm_flags & VM_LOCKED) {

And since we write the data without holding the PTLs this looks
pointless, unless there is some other VM_LOCKED manipulation

Jason
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2021-03-01 16:16 UTC|newest]

Thread overview: 92+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-26  7:18 [PATCH v3 0/8] Add support for SVM atomics in Nouveau Alistair Popple
2021-02-26  7:18 ` Alistair Popple
2021-02-26  7:18 ` [Nouveau] " Alistair Popple
2021-02-26  7:18 ` [PATCH v3 1/8] mm: Remove special swap entry functions Alistair Popple
2021-02-26  7:18   ` Alistair Popple
2021-02-26  7:18   ` [Nouveau] " Alistair Popple
2021-02-26 15:59   ` Christoph Hellwig
2021-02-26 15:59     ` [Nouveau] " Christoph Hellwig
2021-03-02  8:52     ` Alistair Popple
2021-03-02  8:52       ` Alistair Popple
2021-03-02  8:52       ` [Nouveau] " Alistair Popple
2021-03-02 12:02       ` Alistair Popple
2021-03-02 12:02         ` Alistair Popple
2021-03-02 12:02         ` [Nouveau] " Alistair Popple
2021-03-01 17:46   ` Jason Gunthorpe
2021-03-01 17:46     ` Jason Gunthorpe
2021-03-01 17:46     ` [Nouveau] " Jason Gunthorpe
2021-03-02  0:21     ` Alistair Popple
2021-03-02  0:21       ` Alistair Popple
2021-03-02  0:21       ` [Nouveau] " Alistair Popple
2021-02-26  7:18 ` [PATCH v3 2/8] mm/swapops: Rework swap entry manipulation code Alistair Popple
2021-02-26  7:18   ` Alistair Popple
2021-02-26  7:18   ` [Nouveau] " Alistair Popple
2021-02-26 16:00   ` Christoph Hellwig
2021-02-26 16:00     ` [Nouveau] " Christoph Hellwig
2021-03-01 17:47   ` Jason Gunthorpe
2021-03-01 17:47     ` Jason Gunthorpe
2021-03-01 17:47     ` [Nouveau] " Jason Gunthorpe
2021-02-26  7:18 ` [PATCH v3 3/8] mm/rmap: Split try_to_munlock from try_to_unmap Alistair Popple
2021-02-26  7:18   ` Alistair Popple
2021-02-26  7:18   ` [Nouveau] " Alistair Popple
2021-02-26 16:01   ` Christoph Hellwig
2021-02-26 16:01     ` [Nouveau] " Christoph Hellwig
2021-03-01 16:10   ` Jason Gunthorpe [this message]
2021-03-01 16:10     ` Jason Gunthorpe
2021-03-01 16:10     ` [Nouveau] " Jason Gunthorpe
2021-03-04  4:27     ` Alistair Popple
2021-03-04  4:27       ` Alistair Popple
2021-03-04  4:27       ` [Nouveau] " Alistair Popple
2021-02-26  7:18 ` [PATCH v3 4/8] mm/rmap: Split migration into its own function Alistair Popple
2021-02-26  7:18   ` Alistair Popple
2021-02-26  7:18   ` [Nouveau] " Alistair Popple
2021-02-26 16:03   ` Christoph Hellwig
2021-02-26 16:03     ` [Nouveau] " Christoph Hellwig
2021-03-02 22:08   ` Zi Yan
2021-03-02 22:08     ` Zi Yan
2021-03-02 22:08     ` [Nouveau] " Zi Yan
2021-03-04 23:54     ` Alistair Popple
2021-03-04 23:54       ` Alistair Popple
2021-03-04 23:54       ` [Nouveau] " Alistair Popple
2021-02-26  7:18 ` [PATCH v3 5/8] mm: Device exclusive memory access Alistair Popple
2021-02-26  7:18   ` Alistair Popple
2021-02-26  7:18   ` [Nouveau] " Alistair Popple
2021-03-01 17:54   ` Jason Gunthorpe
2021-03-01 17:54     ` Jason Gunthorpe
2021-03-01 17:54     ` [Nouveau] " Jason Gunthorpe
2021-03-01 22:55   ` Ralph Campbell
2021-03-01 22:55     ` Ralph Campbell
2021-03-01 22:55     ` [Nouveau] " Ralph Campbell
2021-03-02  0:05   ` Jason Gunthorpe
2021-03-02  0:05     ` Jason Gunthorpe
2021-03-02  0:05     ` [Nouveau] " Jason Gunthorpe
2021-03-02  8:57     ` Alistair Popple
2021-03-02  8:57       ` Alistair Popple
2021-03-02  8:57       ` [Nouveau] " Alistair Popple
2021-03-02 12:41       ` Jason Gunthorpe
2021-03-02 12:41         ` Jason Gunthorpe
2021-03-02 12:41         ` [Nouveau] " Jason Gunthorpe
2021-03-04  5:20         ` Alistair Popple
2021-03-04  5:20           ` Alistair Popple
2021-03-04  5:20           ` [Nouveau] " Alistair Popple
2021-02-26  7:18 ` [PATCH v3 6/8] mm: Selftests for exclusive device memory Alistair Popple
2021-02-26  7:18   ` Alistair Popple
2021-02-26  7:18   ` [Nouveau] " Alistair Popple
2021-03-01 17:55   ` Jason Gunthorpe
2021-03-01 17:55     ` Jason Gunthorpe
2021-03-01 17:55     ` [Nouveau] " Jason Gunthorpe
2021-03-01 18:07     ` Ralph Campbell
2021-03-01 18:07       ` Ralph Campbell
2021-03-01 18:07       ` [Nouveau] " Ralph Campbell
2021-03-01 23:14   ` Ralph Campbell
2021-03-01 23:14     ` Ralph Campbell
2021-03-01 23:14     ` [Nouveau] " Ralph Campbell
2021-03-02  9:12     ` Alistair Popple
2021-03-02  9:12       ` Alistair Popple
2021-03-02  9:12       ` [Nouveau] " Alistair Popple
2021-02-26  7:18 ` [PATCH v3 7/8] nouveau/svm: Refactor nouveau_range_fault Alistair Popple
2021-02-26  7:18   ` Alistair Popple
2021-02-26  7:18   ` [Nouveau] " Alistair Popple
2021-02-26  7:18 ` [PATCH v3 8/8] nouveau/svm: Implement atomic SVM access Alistair Popple
2021-02-26  7:18   ` Alistair Popple
2021-02-26  7:18   ` [Nouveau] " Alistair Popple

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=20210301161049.GJ4247@nvidia.com \
    --to=jgg@nvidia.com \
    --cc=akpm@linux-foundation.org \
    --cc=apopple@nvidia.com \
    --cc=bskeggs@redhat.com \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hch@infradead.org \
    --cc=jglisse@redhat.com \
    --cc=jhubbard@nvidia.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=nouveau@lists.freedesktop.org \
    --cc=rcampbell@nvidia.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.