From: Matthew Auld <matthew.auld@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Subject: [PATCH 5/9] drm/i915: make dsm struct resource centric
Date: Tue, 5 Dec 2017 21:02:45 +0000 [thread overview]
Message-ID: <20171205210249.8875-6-matthew.auld@intel.com> (raw)
In-Reply-To: <20171205210249.8875-1-matthew.auld@intel.com>
Now that we are using struct resource to track the stolen region, it is
more convenient if we track dsm in a resource as well.
v2: check range_overflow when writing to 32b registers (Chris)
pepper in some comments (Chris)
v3: refit i915_stolen_to_dma()
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 13 ++++--
drivers/gpu/drm/i915/i915_gem_stolen.c | 84 +++++++++++++++++-----------------
drivers/gpu/drm/i915/intel_fbc.c | 10 +++-
drivers/gpu/drm/i915/intel_pm.c | 17 +++++--
4 files changed, 72 insertions(+), 52 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 594fd14e66c5..39c8e99f3d3a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1537,9 +1537,6 @@ struct i915_gem_mm {
*/
struct pagevec wc_stash;
- /** Usable portion of the GTT for GEM */
- dma_addr_t stolen_base; /* limited to low memory (32-bit) */
-
/**
* tmpfs instance used for shmem backed objects
*/
@@ -2253,6 +2250,16 @@ struct drm_i915_private {
const struct intel_device_info info;
+ /**
+ * Data Stolen Memory - aka "i915 stolen memory" gives us the start and
+ * end of stolen which we can optionally use to create GEM objects
+ * backed by stolen memory. Note that ggtt->stolen_usable_size tells us
+ * exactly how much of this we are actually allowed to use, given that
+ * some portion of it is in fact reserved for use by hardware functions,
+ * while ggtt->stolen_size gives us the total size of the stolen region.
+ */
+ struct resource dsm;
+
void __iomem *regs;
struct intel_uncore uncore;
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index f8ac1438c35d..eb84db633a23 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -76,27 +76,27 @@ void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv,
mutex_unlock(&dev_priv->mm.stolen_lock);
}
-static dma_addr_t i915_stolen_to_dma(struct drm_i915_private *dev_priv)
+static int i915_adjust_stolen(struct drm_i915_private *dev_priv,
+ struct resource *dsm)
{
struct i915_ggtt *ggtt = &dev_priv->ggtt;
- dma_addr_t base = intel_graphics_stolen_res.start;
+ dma_addr_t base = dsm->start;
struct resource *r;
GEM_BUG_ON(overflows_type(intel_graphics_stolen_res.start, base));
if (base == 0 || add_overflows(base, ggtt->stolen_size))
- return 0;
+ return -EINVAL;
/* make sure we don't clobber the GTT if it's within stolen memory */
if (INTEL_GEN(dev_priv) <= 4 &&
!IS_G33(dev_priv) && !IS_PINEVIEW(dev_priv) && !IS_G4X(dev_priv)) {
- struct {
- dma_addr_t start, end;
- } stolen[2] = {
- { .start = base, .end = base + ggtt->stolen_size, },
- { .start = base, .end = base + ggtt->stolen_size, },
+ struct resource stolen[2] = {
+ DEFINE_RES_MEM(base, ggtt->stolen_size),
+ DEFINE_RES_MEM(base, ggtt->stolen_size),
};
- u64 ggtt_start, ggtt_end;
+ struct resource ggtt_res;
+ u64 ggtt_start;
ggtt_start = I915_READ(PGTBL_CTL);
if (IS_GEN4(dev_priv))
@@ -104,36 +104,31 @@ static dma_addr_t i915_stolen_to_dma(struct drm_i915_private *dev_priv)
(ggtt_start & PGTBL_ADDRESS_HI_MASK) << 28;
else
ggtt_start &= PGTBL_ADDRESS_LO_MASK;
- ggtt_end = ggtt_start + ggtt_total_entries(ggtt) * 4;
- if (ggtt_start >= stolen[0].start && ggtt_start < stolen[0].end)
- stolen[0].end = ggtt_start;
- if (ggtt_end > stolen[1].start && ggtt_end <= stolen[1].end)
- stolen[1].start = ggtt_end;
+ ggtt_res =
+ (struct resource) DEFINE_RES_MEM(ggtt_start,
+ ggtt_total_entries(ggtt) * 4);
+
+ if (ggtt_res.start >= stolen[0].start && ggtt_res.start < stolen[0].end)
+ stolen[0].end = ggtt_res.start;
+ if (ggtt_res.end > stolen[1].start && ggtt_res.end <= stolen[1].end)
+ stolen[1].start = ggtt_res.end;
/* pick the larger of the two chunks */
- if (stolen[0].end - stolen[0].start >
- stolen[1].end - stolen[1].start) {
- base = stolen[0].start;
- ggtt->stolen_size = stolen[0].end - stolen[0].start;
- } else {
- base = stolen[1].start;
- ggtt->stolen_size = stolen[1].end - stolen[1].start;
- }
+ if (resource_size(&stolen[0]) > resource_size(&stolen[1]))
+ *dsm = stolen[0];
+ else
+ *dsm = stolen[1];
+
+ ggtt->stolen_size = resource_size(dsm);
if (stolen[0].start != stolen[1].start ||
stolen[0].end != stolen[1].end) {
- dma_addr_t end = base + ggtt->stolen_size - 1;
-
- DRM_DEBUG_KMS("GTT within stolen memory at 0x%llx-0x%llx\n",
- (unsigned long long)ggtt_start,
- (unsigned long long)ggtt_end - 1);
- DRM_DEBUG_KMS("Stolen memory adjusted to %pad - %pad\n",
- &base, &end);
+ DRM_DEBUG_KMS("GTT within stolen memory at %pR\n", &ggtt_res);
+ DRM_DEBUG_KMS("Stolen memory adjusted to %pR\n", dsm);
}
}
-
/* Verify that nothing else uses this physical address. Stolen
* memory should be reserved by the BIOS and hidden from the
* kernel. So if the region is already marked as busy, something
@@ -159,15 +154,14 @@ static dma_addr_t i915_stolen_to_dma(struct drm_i915_private *dev_priv)
* range. Apparently this works.
*/
if (r == NULL && !IS_GEN3(dev_priv)) {
- dma_addr_t end = base + ggtt->stolen_size;
+ DRM_ERROR("conflict detected with stolen region: %pR\n",
+ dsm);
- DRM_ERROR("conflict detected with stolen region: [%pad - %pad]\n",
- &base, &end);
- base = 0;
+ return -EBUSY;
}
}
- return base;
+ return 0;
}
void i915_gem_cleanup_stolen(struct drm_device *dev)
@@ -187,7 +181,7 @@ static void g4x_get_stolen_reserved(struct drm_i915_private *dev_priv,
uint32_t reg_val = I915_READ(IS_GM45(dev_priv) ?
CTG_STOLEN_RESERVED :
ELK_STOLEN_RESERVED);
- dma_addr_t stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size;
+ dma_addr_t stolen_top = dev_priv->dsm.start + ggtt->stolen_size;
if ((reg_val & G4X_STOLEN_RESERVED_ENABLE) == 0) {
*base = 0;
@@ -318,7 +312,7 @@ static void bdw_get_stolen_reserved(struct drm_i915_private *dev_priv,
return;
}
- stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size;
+ stolen_top = dev_priv->dsm.start + ggtt->stolen_size;
*base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;
@@ -354,11 +348,15 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
if (ggtt->stolen_size == 0)
return 0;
- dev_priv->mm.stolen_base = i915_stolen_to_dma(dev_priv);
- if (dev_priv->mm.stolen_base == 0)
+ dev_priv->dsm = intel_graphics_stolen_res;
+
+ if (i915_adjust_stolen(dev_priv, &dev_priv->dsm))
return 0;
- stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size;
+ GEM_BUG_ON(dev_priv->dsm.start == 0);
+ GEM_BUG_ON(ggtt->stolen_size > resource_size(&dev_priv->dsm));
+
+ stolen_top = dev_priv->dsm.end + 1;
reserved_base = 0;
reserved_size = 0;
@@ -399,12 +397,12 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
reserved_base = stolen_top;
}
- if (reserved_base < dev_priv->mm.stolen_base ||
+ if (reserved_base < dev_priv->dsm.start ||
reserved_base + reserved_size > stolen_top) {
dma_addr_t reserved_top = reserved_base + reserved_size;
DRM_ERROR("Stolen reserved area [%pad - %pad] outside stolen memory [%pad - %pad]\n",
&reserved_base, &reserved_top,
- &dev_priv->mm.stolen_base, &stolen_top);
+ &dev_priv->dsm.start, &stolen_top);
return 0;
}
@@ -462,7 +460,7 @@ i915_pages_create_for_stolen(struct drm_device *dev,
sg->offset = 0;
sg->length = size;
- sg_dma_address(sg) = (dma_addr_t)dev_priv->mm.stolen_base + offset;
+ sg_dma_address(sg) = (dma_addr_t)dev_priv->dsm.start + offset;
sg_dma_len(sg) = size;
return st;
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 4aefc658a5cf..a291bb965e2e 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -615,10 +615,16 @@ static int intel_fbc_alloc_cfb(struct intel_crtc *crtc)
fbc->compressed_llb = compressed_llb;
+ GEM_BUG_ON(range_overflows_t(u64, dev_priv->dsm.start,
+ fbc->compressed_fb.start,
+ U32_MAX));
+ GEM_BUG_ON(range_overflows_t(u64, dev_priv->dsm.start,
+ fbc->compressed_llb->start,
+ U32_MAX));
I915_WRITE(FBC_CFB_BASE,
- dev_priv->mm.stolen_base + fbc->compressed_fb.start);
+ dev_priv->dsm.start + fbc->compressed_fb.start);
I915_WRITE(FBC_LL_BASE,
- dev_priv->mm.stolen_base + compressed_llb->start);
+ dev_priv->dsm.start + compressed_llb->start);
}
DRM_DEBUG_KMS("reserved %llu bytes of contiguous stolen space for FBC, threshold: %d\n",
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 67f326230a7e..2fa2d82f61f2 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7020,7 +7020,7 @@ static void valleyview_check_pctx(struct drm_i915_private *dev_priv)
{
unsigned long pctx_addr = I915_READ(VLV_PCBR) & ~4095;
- WARN_ON(pctx_addr != dev_priv->mm.stolen_base +
+ WARN_ON(pctx_addr != dev_priv->dsm.start +
dev_priv->vlv_pctx->stolen->start);
}
@@ -7043,7 +7043,12 @@ static void cherryview_setup_pctx(struct drm_i915_private *dev_priv)
pcbr = I915_READ(VLV_PCBR);
if ((pcbr >> VLV_PCBR_ADDR_SHIFT) == 0) {
DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n");
- paddr = (dev_priv->mm.stolen_base +
+
+ GEM_BUG_ON(range_overflows_t(resource_size_t,
+ dev_priv->dsm.start,
+ (ggtt->stolen_size - pctx_size),
+ U32_MAX));
+ paddr = (dev_priv->dsm.start +
(ggtt->stolen_size - pctx_size));
pctx_paddr = (paddr & (~4095));
@@ -7065,7 +7070,7 @@ static void valleyview_setup_pctx(struct drm_i915_private *dev_priv)
/* BIOS set it up already, grab the pre-alloc'd space */
int pcbr_offset;
- pcbr_offset = (pcbr & (~4095)) - dev_priv->mm.stolen_base;
+ pcbr_offset = (pcbr & (~4095)) - dev_priv->dsm.start;
pctx = i915_gem_object_create_stolen_for_preallocated(dev_priv,
pcbr_offset,
I915_GTT_OFFSET_NONE,
@@ -7089,7 +7094,11 @@ static void valleyview_setup_pctx(struct drm_i915_private *dev_priv)
goto out;
}
- pctx_paddr = dev_priv->mm.stolen_base + pctx->stolen->start;
+ GEM_BUG_ON(range_overflows_t(u64,
+ dev_priv->dsm.start,
+ pctx->stolen->start,
+ U32_MAX));
+ pctx_paddr = dev_priv->dsm.start + pctx->stolen->start;
I915_WRITE(VLV_PCBR, pctx_paddr);
out:
--
2.14.3
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2017-12-05 21:03 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-05 21:02 [PATCH 0/9] make stolen resource centric Matthew Auld
2017-12-05 21:02 ` [PATCH 1/9] x86/early-quirks: Extend Intel graphics stolen memory placement to 64bit Matthew Auld
2017-12-05 21:02 ` [PATCH 2/9] x86/early-quirks: replace the magical increment start values Matthew Auld
2017-12-05 21:02 ` [PATCH 3/9] x86/early-quirks: reverse the if ladders Matthew Auld
2017-12-05 21:08 ` Ville Syrjälä
2017-12-05 21:02 ` [PATCH 4/9] drm/i915: nuke the duplicated stolen discovery Matthew Auld
2017-12-05 21:02 ` Matthew Auld [this message]
2017-12-05 23:30 ` [PATCH 5/9] drm/i915: make dsm struct resource centric Chris Wilson
2017-12-05 21:02 ` [PATCH 6/9] drm/i915: make reserved " Matthew Auld
2017-12-05 23:27 ` Chris Wilson
2017-12-05 21:02 ` [PATCH 7/9] drm/i915: make mappable " Matthew Auld
2017-12-05 23:26 ` Chris Wilson
2017-12-05 21:02 ` [PATCH 8/9] drm/i915: prefer resource_size_t for everything stolen Matthew Auld
2017-12-05 23:22 ` Chris Wilson
2017-12-05 21:02 ` [PATCH 9/9] drm/i915: use stolen_usable_size for the range sanity check Matthew Auld
2017-12-05 21:25 ` ✓ Fi.CI.BAT: success for make stolen resource centric (rev4) Patchwork
2017-12-05 22:50 ` ✗ Fi.CI.IGT: failure " Patchwork
-- strict thread matches above, loose matches on Subject: below --
2017-12-07 12:28 [PATCH 0/9] make stolen resource centric Matthew Auld
2017-12-07 12:28 ` [PATCH 5/9] drm/i915: make dsm struct " Matthew Auld
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=20171205210249.8875-6-matthew.auld@intel.com \
--to=matthew.auld@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=paulo.r.zanoni@intel.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;
as well as URLs for NNTP newsgroup(s).