[Intel-gfx] [PATCH 2/7] drm/i915: Resolving the memory region conflict for Stolen area
Jani Nikula
jani.nikula at intel.com
Fri Feb 28 15:06:54 CET 2014
On Thu, 27 Feb 2014, Chris Wilson <chris at chris-wilson.co.uk> wrote:
> On Mon, Feb 24, 2014 at 09:22:31PM +0200, Jani Nikula wrote:
>> I'm going to need a Reviewed-by and preferrably a Tested-by on this.
>
> I really didn't like this patch because requesting a region other than
> the one we use is morally equivalent to not requesting a region at all.
> The approach I would prefer is to only use the requested resource as our
> available stolen region, like in the attached.
I would need the reviewed- and tested-bys on this one instead then.
I'm keeping Akash's patch in -fixes for now as I've already pushed it
there. Frankly, I'm inclined to queuing that one for 3.14 and fixing
this right for 3.15, as it's a broken BIOS we're talking about, but I
could be convinced otherwise. Particularly with the r-b and t-b.
BR,
Jani.
> -Chris
>
> --
> Chris Wilson, Intel Open Source Technology Centre
> From e5230c7bf7186699f1b83dcbff5a45a3267c9941 Mon Sep 17 00:00:00 2001
> From: Chris Wilson <chris at chris-wilson.co.uk>
> Date: Wed, 26 Feb 2014 18:01:42 +0000
> Subject: [PATCH] drm/i915: Trim stolen region for reserved pages and
> conflicting BIOS setups
>
> On a few systems we have to reserve regions inside the stolen portion
> for use by the BIOS - we have to trim that out of our own allocation. In
> some cases, the BIOS will have reduced the reserved region in the e820
> map and so we have to adjust our own region request to suit. Either way,
> we need to only use the resource that we successfully reserve for
> ourselves - rather than claim one region and use another.
>
> v2: Fix resource request bounds to be inclusive. (Jani)
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 2 +-
> drivers/gpu/drm/i915/i915_gem_stolen.c | 64 ++++++++++++++++++++++------------
> drivers/gpu/drm/i915/intel_pm.c | 9 +++--
> 3 files changed, 49 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 655a45c981fd..eb31c456eb35 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1099,7 +1099,7 @@ struct i915_gem_mm {
> struct list_head unbound_list;
>
> /** Usable portion of the GTT for GEM */
> - unsigned long stolen_base; /* limited to low memory (32-bit) */
> + struct resource *stolen_region; /* limited to low memory (32-bit) */
>
> /** PPGTT used for aliasing the PPGTT with the GTT */
> struct i915_hw_ppgtt *aliasing_ppgtt;
> diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
> index adc5c91f6946..984ada1b0084 100644
> --- a/drivers/gpu/drm/i915/i915_gem_stolen.c
> +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
> @@ -45,10 +45,11 @@
> * for is a boon.
> */
>
> -static unsigned long i915_stolen_to_physical(struct drm_device *dev)
> +static struct resource *i915_stolen_to_physical(struct drm_device *dev)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct resource *r;
> + unsigned long start, end;
> u32 base;
>
> /* Almost universally we can find the Graphics Base of Stolen Memory
> @@ -184,15 +185,38 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev)
> * kernel. So if the region is already marked as busy, something
> * is seriously wrong.
> */
> - r = devm_request_mem_region(dev->dev, base, dev_priv->gtt.stolen_size,
> + start = base + PAGE_SIZE; /* leave the first page alone! */
> +
> + end = base + dev_priv->gtt.stolen_size - 1;
> + if (IS_VALLEYVIEW(dev))
> + end -= 1024*1024; /* top 1M on VLV/BYT is reserved */
> +
> + r = devm_request_mem_region(dev->dev, start, end-start,
> "Graphics Stolen Memory");
> if (r == NULL) {
> - DRM_ERROR("conflict detected with stolen region: [0x%08x - 0x%08x]\n",
> - base, base + (uint32_t)dev_priv->gtt.stolen_size);
> - base = 0;
> + /* Weird. BIOS has not reserved the whole region for us,
> + * try something smaller.
> + */
> + do {
> + start += PAGE_SIZE;
> + end -= PAGE_SIZE;
> + if (start < end)
> + break;
> +
> + r = devm_request_mem_region(dev->dev, start, end-start,
> + "Graphics Stolen Memory");
> + } while (r == NULL);
> +
> + if (r == NULL)
> + DRM_ERROR("conflicting resource reservations detected with stolen region: [0x%08x - 0x%08x]\n",
> + base, base + (uint32_t)dev_priv->gtt.stolen_size - 1);
> + else
> + DRM_INFO("conflict detected with stolen region [0x%08x - 0x%08x], reducing to [0x%08lx - 0x%08lx]\n",
> + base, base + (uint32_t)dev_priv->gtt.stolen_size - 1,
> + start, end);
> }
>
> - return base;
> + return r;
> }
>
> static int i915_setup_compression(struct drm_device *dev, int size)
> @@ -232,9 +256,9 @@ static int i915_setup_compression(struct drm_device *dev, int size)
> dev_priv->fbc.compressed_llb = compressed_llb;
>
> I915_WRITE(FBC_CFB_BASE,
> - dev_priv->mm.stolen_base + compressed_fb->start);
> + dev_priv->mm.stolen_region->start + compressed_fb->start);
> I915_WRITE(FBC_LL_BASE,
> - dev_priv->mm.stolen_base + compressed_llb->start);
> + dev_priv->mm.stolen_region->start + compressed_llb->start);
> }
>
> dev_priv->fbc.compressed_fb = compressed_fb;
> @@ -304,28 +328,22 @@ void i915_gem_cleanup_stolen(struct drm_device *dev)
> int i915_gem_init_stolen(struct drm_device *dev)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> - int bios_reserved = 0;
> + struct resource *r;
>
> if (dev_priv->gtt.stolen_size == 0)
> return 0;
>
> - dev_priv->mm.stolen_base = i915_stolen_to_physical(dev);
> - if (dev_priv->mm.stolen_base == 0)
> + r = i915_stolen_to_physical(dev);
> + if (r == NULL)
> return 0;
>
> - DRM_DEBUG_KMS("found %zd bytes of stolen memory at %08lx\n",
> - dev_priv->gtt.stolen_size, dev_priv->mm.stolen_base);
> -
> - if (IS_VALLEYVIEW(dev))
> - bios_reserved = 1024*1024; /* top 1M on VLV/BYT */
> -
> - if (WARN_ON(bios_reserved > dev_priv->gtt.stolen_size))
> - return 0;
> + DRM_DEBUG_KMS("found %ld bytes of stolen memory at %08lx\n",
> + (long)resource_size(r), (long)r->start);
>
> /* Basic memrange allocator for stolen space */
> - drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_size -
> - bios_reserved);
> + drm_mm_init(&dev_priv->mm.stolen, 0, resource_size(r));
>
> + dev_priv->mm.stolen_region = r;
> return 0;
> }
>
> @@ -338,7 +356,7 @@ i915_pages_create_for_stolen(struct drm_device *dev,
> struct scatterlist *sg;
>
> DRM_DEBUG_DRIVER("offset=0x%x, size=%d\n", offset, size);
> - BUG_ON(offset > dev_priv->gtt.stolen_size - size);
> + BUG_ON(offset > resource_size(dev_priv->mm.stolen_region) - size);
>
> /* We hide that we have no struct page backing our stolen object
> * by wrapping the contiguous physical allocation with a fake
> @@ -358,7 +376,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->mm.stolen_region->start + offset;
> sg_dma_len(sg) = size;
>
> return st;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 3419ddae32c6..ac0cff40d5ec 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3564,12 +3564,17 @@ static void valleyview_setup_pctx(struct drm_device *dev)
> u32 pcbr;
> int pctx_size = 24*1024;
>
> + if (dev_priv->mm.stolen_region == NULL) {
> + DRM_DEBUG("stolen space not reserved, unable to setup power saving context");
> + return;
> + }
> +
> pcbr = I915_READ(VLV_PCBR);
> if (pcbr) {
> /* 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->mm.stolen_region->start;
> pctx = i915_gem_object_create_stolen_for_preallocated(dev_priv->dev,
> pcbr_offset,
> I915_GTT_OFFSET_NONE,
> @@ -3591,7 +3596,7 @@ static void valleyview_setup_pctx(struct drm_device *dev)
> return;
> }
>
> - pctx_paddr = dev_priv->mm.stolen_base + pctx->stolen->start;
> + pctx_paddr = dev_priv->mm.stolen_region->start + pctx->stolen->start;
> I915_WRITE(VLV_PCBR, pctx_paddr);
>
> out:
> --
> 1.9.0
>
--
Jani Nikula, Intel Open Source Technology Center
More information about the Intel-gfx
mailing list