All of lore.kernel.org
 help / color / mirror / Atom feed
From: jglisse@redhat.com
To: dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org
Cc: "Jérôme Glisse" <jglisse@redhat.com>,
	linux-mm@kvack.org, "John Hubbard" <jhubbard@nvidia.com>,
	"Evgeny Baskakov" <ebaskakov@nvidia.com>,
	"Ralph Campbell" <rcampbell@nvidia.com>,
	"Ben Skeggs" <bskeggs@redhat.com>
Subject: [RFC PATCH 01/13] drm/nouveau/vmm: enable page table iterator over non populated range
Date: Fri,  9 Mar 2018 22:21:29 -0500	[thread overview]
Message-ID: <20180310032141.6096-2-jglisse@redhat.com> (raw)
In-Reply-To: <20180310032141.6096-1-jglisse@redhat.com>

From: JA(C)rA'me Glisse <jglisse@redhat.com>

This patch modify the page table iterator to support empty range when
unmaping a range (ie when it is not trying to populate the range).

Signed-off-by: JA(C)rA'me Glisse <jglisse@redhat.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 75 ++++++++++++++++++---------
 1 file changed, 51 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
index 93946dcee319..20d31526ba8f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
@@ -75,6 +75,7 @@ struct nvkm_vmm_iter {
 	struct nvkm_vmm *vmm;
 	u64 cnt;
 	u16 max, lvl;
+	u64 start, addr;
 	u32 pte[NVKM_VMM_LEVELS_MAX];
 	struct nvkm_vmm_pt *pt[NVKM_VMM_LEVELS_MAX];
 	int flush;
@@ -485,6 +486,23 @@ nvkm_vmm_ref_swpt(struct nvkm_vmm_iter *it, struct nvkm_vmm_pt *pgd, u32 pdei)
 	return true;
 }
 
+static inline u64
+nvkm_vmm_iter_addr(const struct nvkm_vmm_iter *it,
+		   const struct nvkm_vmm_desc *desc)
+{
+	int max = it->max;
+	u64 addr;
+
+	/* Reconstruct address */
+	addr = it->pte[max--];
+	do {
+		addr  = addr << desc[max].bits;
+		addr |= it->pte[max];
+	} while (max--);
+
+	return addr;
+}
+
 static inline u64
 nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page,
 	      u64 addr, u64 size, const char *name, bool ref,
@@ -494,21 +512,23 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page,
 {
 	const struct nvkm_vmm_desc *desc = page->desc;
 	struct nvkm_vmm_iter it;
-	u64 bits = addr >> page->shift;
+	u64 addr_bits = addr >> page->shift;
 
 	it.page = page;
 	it.desc = desc;
 	it.vmm = vmm;
 	it.cnt = size >> page->shift;
 	it.flush = NVKM_VMM_LEVELS_MAX;
+	it.start = it.addr = addr;
 
 	/* Deconstruct address into PTE indices for each mapping level. */
 	for (it.lvl = 0; desc[it.lvl].bits; it.lvl++) {
-		it.pte[it.lvl] = bits & ((1 << desc[it.lvl].bits) - 1);
-		bits >>= desc[it.lvl].bits;
+		it.pte[it.lvl] = addr_bits & ((1 << desc[it.lvl].bits) - 1);
+		addr_bits >>= desc[it.lvl].bits;
 	}
 	it.max = --it.lvl;
 	it.pt[it.max] = vmm->pd;
+	addr_bits = addr >> page->shift;
 
 	it.lvl = 0;
 	TRA(&it, "%s: %016llx %016llx %d %lld PTEs", name,
@@ -521,7 +541,8 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page,
 		const int type = desc->type == SPT;
 		const u32 pten = 1 << desc->bits;
 		const u32 ptei = it.pte[0];
-		const u32 ptes = min_t(u64, it.cnt, pten - ptei);
+		u32 ptes = min_t(u64, it.cnt, pten - ptei);
+		u64 tmp;
 
 		/* Walk down the tree, finding page tables for each level. */
 		for (; it.lvl; it.lvl--) {
@@ -529,9 +550,14 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page,
 			struct nvkm_vmm_pt *pgd = pgt;
 
 			/* Software PT. */
-			if (ref && NVKM_VMM_PDE_INVALID(pgd->pde[pdei])) {
-				if (!nvkm_vmm_ref_swpt(&it, pgd, pdei))
-					goto fail;
+			if (NVKM_VMM_PDE_INVALID(pgd->pde[pdei])) {
+				if (ref) {
+					if (!nvkm_vmm_ref_swpt(&it, pgd, pdei))
+						goto fail;
+				} else {
+					it.pte[it.lvl] += 1;
+					goto next;
+				}
 			}
 			it.pt[it.lvl - 1] = pgt = pgd->pde[pdei];
 
@@ -545,9 +571,16 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page,
 				if (!nvkm_vmm_ref_hwpt(&it, pgd, pdei))
 					goto fail;
 			}
+
+			/* With HMM we might walk down un-populated range */
+			if (!pgt) {
+				it.pte[it.lvl] += 1;
+				goto next;
+			}
 		}
 
 		/* Handle PTE updates. */
+		it.addr = nvkm_vmm_iter_addr(&it, desc) << PAGE_SHIFT;
 		if (!REF_PTES || REF_PTES(&it, ptei, ptes)) {
 			struct nvkm_mmu_pt *pt = pgt->pt[type];
 			if (MAP_PTES || CLR_PTES) {
@@ -558,32 +591,26 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page,
 				nvkm_vmm_flush_mark(&it);
 			}
 		}
+		it.pte[it.lvl] += ptes;
 
+next:
 		/* Walk back up the tree to the next position. */
-		it.pte[it.lvl] += ptes;
-		it.cnt -= ptes;
-		if (it.cnt) {
-			while (it.pte[it.lvl] == (1 << desc[it.lvl].bits)) {
-				it.pte[it.lvl++] = 0;
-				it.pte[it.lvl]++;
-			}
+		while (it.pte[it.lvl] == (1 << desc[it.lvl].bits)) {
+			it.pte[it.lvl++] = 0;
+			if (it.lvl == it.max)
+				break;
+			it.pte[it.lvl]++;
 		}
+		tmp = nvkm_vmm_iter_addr(&it, desc);
+		it.cnt -= min_t(u64, it.cnt, tmp - addr_bits);
+		addr_bits = tmp;
 	};
 
 	nvkm_vmm_flush(&it);
 	return ~0ULL;
 
 fail:
-	/* Reconstruct the failure address so the caller is able to
-	 * reverse any partially completed operations.
-	 */
-	addr = it.pte[it.max--];
-	do {
-		addr  = addr << desc[it.max].bits;
-		addr |= it.pte[it.max];
-	} while (it.max--);
-
-	return addr << page->shift;
+	return addr_bits << page->shift;
 }
 
 static void
-- 
2.14.3

WARNING: multiple messages have this Message-ID (diff)
From: jglisse@redhat.com
To: dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org
Cc: "Ralph Campbell" <rcampbell@nvidia.com>,
	"Evgeny Baskakov" <ebaskakov@nvidia.com>,
	linux-mm@kvack.org, "Jérôme Glisse" <jglisse@redhat.com>,
	"Ben Skeggs" <bskeggs@redhat.com>,
	"John Hubbard" <jhubbard@nvidia.com>
Subject: [RFC PATCH 01/13] drm/nouveau/vmm: enable page table iterator over non populated range
Date: Fri,  9 Mar 2018 22:21:29 -0500	[thread overview]
Message-ID: <20180310032141.6096-2-jglisse@redhat.com> (raw)
In-Reply-To: <20180310032141.6096-1-jglisse@redhat.com>

From: Jérôme Glisse <jglisse@redhat.com>

This patch modify the page table iterator to support empty range when
unmaping a range (ie when it is not trying to populate the range).

Signed-off-by: Jérôme Glisse <jglisse@redhat.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 75 ++++++++++++++++++---------
 1 file changed, 51 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
index 93946dcee319..20d31526ba8f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
@@ -75,6 +75,7 @@ struct nvkm_vmm_iter {
 	struct nvkm_vmm *vmm;
 	u64 cnt;
 	u16 max, lvl;
+	u64 start, addr;
 	u32 pte[NVKM_VMM_LEVELS_MAX];
 	struct nvkm_vmm_pt *pt[NVKM_VMM_LEVELS_MAX];
 	int flush;
@@ -485,6 +486,23 @@ nvkm_vmm_ref_swpt(struct nvkm_vmm_iter *it, struct nvkm_vmm_pt *pgd, u32 pdei)
 	return true;
 }
 
+static inline u64
+nvkm_vmm_iter_addr(const struct nvkm_vmm_iter *it,
+		   const struct nvkm_vmm_desc *desc)
+{
+	int max = it->max;
+	u64 addr;
+
+	/* Reconstruct address */
+	addr = it->pte[max--];
+	do {
+		addr  = addr << desc[max].bits;
+		addr |= it->pte[max];
+	} while (max--);
+
+	return addr;
+}
+
 static inline u64
 nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page,
 	      u64 addr, u64 size, const char *name, bool ref,
@@ -494,21 +512,23 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page,
 {
 	const struct nvkm_vmm_desc *desc = page->desc;
 	struct nvkm_vmm_iter it;
-	u64 bits = addr >> page->shift;
+	u64 addr_bits = addr >> page->shift;
 
 	it.page = page;
 	it.desc = desc;
 	it.vmm = vmm;
 	it.cnt = size >> page->shift;
 	it.flush = NVKM_VMM_LEVELS_MAX;
+	it.start = it.addr = addr;
 
 	/* Deconstruct address into PTE indices for each mapping level. */
 	for (it.lvl = 0; desc[it.lvl].bits; it.lvl++) {
-		it.pte[it.lvl] = bits & ((1 << desc[it.lvl].bits) - 1);
-		bits >>= desc[it.lvl].bits;
+		it.pte[it.lvl] = addr_bits & ((1 << desc[it.lvl].bits) - 1);
+		addr_bits >>= desc[it.lvl].bits;
 	}
 	it.max = --it.lvl;
 	it.pt[it.max] = vmm->pd;
+	addr_bits = addr >> page->shift;
 
 	it.lvl = 0;
 	TRA(&it, "%s: %016llx %016llx %d %lld PTEs", name,
@@ -521,7 +541,8 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page,
 		const int type = desc->type == SPT;
 		const u32 pten = 1 << desc->bits;
 		const u32 ptei = it.pte[0];
-		const u32 ptes = min_t(u64, it.cnt, pten - ptei);
+		u32 ptes = min_t(u64, it.cnt, pten - ptei);
+		u64 tmp;
 
 		/* Walk down the tree, finding page tables for each level. */
 		for (; it.lvl; it.lvl--) {
@@ -529,9 +550,14 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page,
 			struct nvkm_vmm_pt *pgd = pgt;
 
 			/* Software PT. */
-			if (ref && NVKM_VMM_PDE_INVALID(pgd->pde[pdei])) {
-				if (!nvkm_vmm_ref_swpt(&it, pgd, pdei))
-					goto fail;
+			if (NVKM_VMM_PDE_INVALID(pgd->pde[pdei])) {
+				if (ref) {
+					if (!nvkm_vmm_ref_swpt(&it, pgd, pdei))
+						goto fail;
+				} else {
+					it.pte[it.lvl] += 1;
+					goto next;
+				}
 			}
 			it.pt[it.lvl - 1] = pgt = pgd->pde[pdei];
 
@@ -545,9 +571,16 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page,
 				if (!nvkm_vmm_ref_hwpt(&it, pgd, pdei))
 					goto fail;
 			}
+
+			/* With HMM we might walk down un-populated range */
+			if (!pgt) {
+				it.pte[it.lvl] += 1;
+				goto next;
+			}
 		}
 
 		/* Handle PTE updates. */
+		it.addr = nvkm_vmm_iter_addr(&it, desc) << PAGE_SHIFT;
 		if (!REF_PTES || REF_PTES(&it, ptei, ptes)) {
 			struct nvkm_mmu_pt *pt = pgt->pt[type];
 			if (MAP_PTES || CLR_PTES) {
@@ -558,32 +591,26 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page,
 				nvkm_vmm_flush_mark(&it);
 			}
 		}
+		it.pte[it.lvl] += ptes;
 
+next:
 		/* Walk back up the tree to the next position. */
-		it.pte[it.lvl] += ptes;
-		it.cnt -= ptes;
-		if (it.cnt) {
-			while (it.pte[it.lvl] == (1 << desc[it.lvl].bits)) {
-				it.pte[it.lvl++] = 0;
-				it.pte[it.lvl]++;
-			}
+		while (it.pte[it.lvl] == (1 << desc[it.lvl].bits)) {
+			it.pte[it.lvl++] = 0;
+			if (it.lvl == it.max)
+				break;
+			it.pte[it.lvl]++;
 		}
+		tmp = nvkm_vmm_iter_addr(&it, desc);
+		it.cnt -= min_t(u64, it.cnt, tmp - addr_bits);
+		addr_bits = tmp;
 	};
 
 	nvkm_vmm_flush(&it);
 	return ~0ULL;
 
 fail:
-	/* Reconstruct the failure address so the caller is able to
-	 * reverse any partially completed operations.
-	 */
-	addr = it.pte[it.max--];
-	do {
-		addr  = addr << desc[it.max].bits;
-		addr |= it.pte[it.max];
-	} while (it.max--);
-
-	return addr << page->shift;
+	return addr_bits << page->shift;
 }
 
 static void
-- 
2.14.3

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

  reply	other threads:[~2018-03-10  3:21 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-10  3:21 [RFC PATCH 00/13] SVM (share virtual memory) with HMM in nouveau jglisse
2018-03-10  3:21 ` jglisse
2018-03-10  3:21 ` jglisse [this message]
2018-03-10  3:21   ` [RFC PATCH 01/13] drm/nouveau/vmm: enable page table iterator over non populated range jglisse
2018-03-10  3:21 ` [RFC PATCH 02/13] drm/nouveau/core/memory: add some useful accessor macros jglisse
2018-03-10  3:21   ` jglisse
2018-03-10  3:21 ` [RFC PATCH 03/13] drm/nouveau/core: define engine for handling replayable faults jglisse
2018-03-10  3:21   ` jglisse
2018-03-10  3:21 ` [RFC PATCH 04/13] drm/nouveau/mmu/gp100: allow gcc/tex to generate " jglisse
2018-03-10  3:21   ` jglisse
2018-03-10  3:21 ` [RFC PATCH 05/13] drm/nouveau/mc/gp100-: handle replayable fault interrupt jglisse
2018-03-10  3:21   ` jglisse
2018-03-10  3:21 ` [RFC PATCH 06/13] drm/nouveau/fault/gp100: initial implementation of MaxwellFaultBufferA jglisse
2018-03-10  3:21   ` jglisse
2018-03-10  3:21 ` [RFC PATCH 07/13] drm/nouveau: special mapping method for HMM jglisse
2018-03-10  3:21   ` jglisse
2018-03-10  3:21 ` [RFC PATCH 08/13] drm/nouveau: special mapping method for HMM (user interface) jglisse
2018-03-10  3:21   ` jglisse
2018-03-10  3:21 ` [RFC PATCH 09/13] drm/nouveau: add SVM through HMM support to nouveau client jglisse
2018-03-10  3:21   ` jglisse
2018-03-10  3:21 ` [RFC PATCH 10/13] drm/nouveau: add HMM area creation jglisse
2018-03-10  3:21   ` jglisse
2018-03-10  3:21 ` [RFC PATCH 11/13] drm/nouveau: add HMM area creation user interface jglisse
2018-03-10  3:21   ` jglisse
2018-03-10  3:21 ` [RFC PATCH 12/13] drm/nouveau: HMM area creation helpers for nouveau client jglisse
2018-03-10  3:21   ` jglisse
2018-03-10  3:21 ` [RFC PATCH 13/13] drm/nouveau: HACK FOR HMM AREA jglisse
2018-03-10  3:21   ` jglisse
2018-03-10 15:01 ` [RFC PATCH 00/13] SVM (share virtual memory) with HMM in nouveau Christian König
2018-03-10 15:01   ` Christian König
2018-03-10 17:55   ` Jerome Glisse
2018-03-10 17:55     ` Jerome Glisse
2018-03-12 17:30   ` Daniel Vetter
2018-03-12 17:30     ` Daniel Vetter
2018-03-12 17:50     ` Jerome Glisse
2018-03-12 17:50       ` Jerome Glisse
2018-03-13  6:14       ` John Hubbard
2018-03-13  6:14         ` John Hubbard
2018-03-13 13:29         ` Matthew Wilcox
2018-03-13 13:29           ` Matthew Wilcox
2018-03-13 14:31           ` Jerome Glisse
2018-03-13 14:31             ` Jerome Glisse
2018-03-13 15:56         ` Jerome Glisse
2018-03-13 15:56           ` Jerome Glisse
2018-03-13 10:46       ` Daniel Vetter
2018-03-13 10:46         ` Daniel Vetter
2018-03-12 18:28   ` Felix Kuehling
2018-03-12 18:28     ` Felix Kuehling
2018-03-13 14:28     ` Jerome Glisse
2018-03-13 14:28       ` Jerome Glisse
2018-03-13 15:32       ` Felix Kuehling
2018-03-13 15:32         ` Felix Kuehling

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=20180310032141.6096-2-jglisse@redhat.com \
    --to=jglisse@redhat.com \
    --cc=bskeggs@redhat.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=ebaskakov@nvidia.com \
    --cc=jhubbard@nvidia.com \
    --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.