[Intel-gfx] [PATCH] drm/i915: Refactor dma mask usage to a common helper
Chris Wilson
chris at chris-wilson.co.uk
Fri Apr 17 16:16:31 UTC 2020
Quoting Ruhl, Michael J (2020-04-17 17:05:07)
> >-----Original Message-----
> >From: Chris Wilson <chris at chris-wilson.co.uk>
> >Sent: Friday, April 17, 2020 11:42 AM
> >To: Ruhl, Michael J <michael.j.ruhl at intel.com>; intel-
> >gfx at lists.freedesktop.org
> >Subject: Re: [Intel-gfx] [PATCH] drm/i915: Refactor dma mask usage to a
> >common helper
> >
> >Quoting Michael J. Ruhl (2020-04-17 16:22:44)
> >> DMA_MASK bit values are different for different generations.
> >>
> >> This will become more difficult to manage over time with the open
> >> coded usage of different versions of the device.
> >>
> >> Fix by:
> >> adding dma_mask_size to the device info configuration,
> >> updating open code call sequence to the latest interface,
> >> refactoring into a common function for setting the dma_mask
> >>
> >> Note: GEN(5) and down is also set in intel_gmch_probe().
> >>
> >> Signed-off-by: Michael J. Ruhl <michael.j.ruhl at intel.com>
> >> cc: Brian Welty <brian.welty at intel.com>
> >> cc: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
> >> ---
> >> drivers/gpu/drm/i915/gt/intel_ggtt.c | 15 --------------
> >> drivers/gpu/drm/i915/i915_drv.c | 25 ++++++++++++++++++++++++
> >> drivers/gpu/drm/i915/i915_pci.c | 14 +++++++++++++
> >> drivers/gpu/drm/i915/intel_device_info.c | 1 +
> >> drivers/gpu/drm/i915/intel_device_info.h | 2 ++
> >> 5 files changed, 42 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c
> >b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> >> index eebd1190506f..66165b10256e 100644
> >> --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
> >> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> >> @@ -840,7 +840,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
> >> struct pci_dev *pdev = i915->drm.pdev;
> >> unsigned int size;
> >> u16 snb_gmch_ctl;
> >> - int err;
> >>
> >> /* TODO: We're not aware of mappable constraints on gen8 yet */
> >> if (!IS_DGFX(i915)) {
> >> @@ -848,13 +847,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
> >> ggtt->mappable_end = resource_size(&ggtt->gmadr);
> >> }
> >>
> >> - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(39));
> >> - if (!err)
> >> - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(39));
> >> - if (err)
> >> - drm_err(&i915->drm,
> >> - "Can't set DMA mask/consistent mask (%d)\n", err);
> >> -
> >> pci_read_config_word(pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
> >> if (IS_CHERRYVIEW(i915))
> >> size = chv_get_total_gtt_size(snb_gmch_ctl);
> >> @@ -990,7 +982,6 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
> >> struct pci_dev *pdev = i915->drm.pdev;
> >> unsigned int size;
> >> u16 snb_gmch_ctl;
> >> - int err;
> >>
> >> ggtt->gmadr = pci_resource(pdev, 2);
> >> ggtt->mappable_end = resource_size(&ggtt->gmadr);
> >> @@ -1005,12 +996,6 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
> >> return -ENXIO;
> >> }
> >>
> >> - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(40));
> >> - if (!err)
> >> - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40));
> >> - if (err)
> >> - drm_err(&i915->drm,
> >> - "Can't set DMA mask/consistent mask (%d)\n", err);
> >> pci_read_config_word(pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
> >>
> >> size = gen6_get_total_gtt_size(snb_gmch_ctl);
> >> diff --git a/drivers/gpu/drm/i915/i915_drv.c
> >b/drivers/gpu/drm/i915/i915_drv.c
> >> index 641f5e03b661..3c5654b5d321 100644
> >> --- a/drivers/gpu/drm/i915/i915_drv.c
> >> +++ b/drivers/gpu/drm/i915/i915_drv.c
> >> @@ -566,6 +566,29 @@ static void intel_sanitize_options(struct
> >drm_i915_private *dev_priv)
> >> intel_gvt_sanitize_options(dev_priv);
> >> }
> >>
> >> +/**
> >> + * i915_set_dma_mask - set the dma mask as configured for the platform
> >> + * @i915: valid i915 instance
> >> + *
> >> + * Set the dma device and coherent masks. This needs to occur before
> >> + * i915_ggtt_probe_hw.
> >> + *
> >> + * NOTE: for devices < GEN(6), the dma_mask will also be set in
> >> + * intel_gmch_probe() (i.e. it will be set a second time).
> >> + */
> >> +static void i915_set_dma_mask(struct drm_i915_private *i915)
> >> +{
> >> + struct pci_dev *pdev = i915->drm.pdev;
> >> + unsigned int mask_size = INTEL_INFO(i915)->dma_mask_size;
> >> + int err;
> >> +
> >> + GEM_BUG_ON(!mask_size);
> >> +
> >> + err = dma_set_mask_and_coherent(&pdev->dev,
> >DMA_BIT_MASK(mask_size));
> >> + if (err)
> >> + DRM_ERROR("Can't set DMA mask/consistent mask (%d)\n", err);
> >
> >Which device again? How serious of an error is it exactly since it is
> >ignored? Since it is being ignored, what's the impact to the user?
> >Should they take any action, or can they ignore it? [If they can ignore
> >it as well, this is barely anything to take note of.]
>
> I am keeping the "original" code path intact. The original locations spit
> out an error, and then ignore it.
You changed from drm_err() though :-p
> A quick sampling of drivers shows that most drivers exit on this failure.
>
> I am not sure why the i915 does not. I am willing to change it. 😊
If we cannot constrain the mask to be a subset of the device
capabilities we probably should bail. I'm happy if you do propagate the
error.
>
> >> /**
> >> * i915_driver_hw_probe - setup state requiring device access
> >> * @dev_priv: device private
> >> @@ -613,6 +636,8 @@ static int i915_driver_hw_probe(struct
> >drm_i915_private *dev_priv)
> >>
> >> i915_perf_init(dev_priv);
> >>
> >> + i915_set_dma_mask(dev_priv);
> >> +
> >> ret = i915_ggtt_probe_hw(dev_priv);
> >> if (ret)
> >> goto err_perf;
> >> diff --git a/drivers/gpu/drm/i915/i915_pci.c
> >b/drivers/gpu/drm/i915/i915_pci.c
> >> index 66738f2c4f28..2fc25ec12c3d 100644
> >> --- a/drivers/gpu/drm/i915/i915_pci.c
> >> +++ b/drivers/gpu/drm/i915/i915_pci.c
> >> @@ -171,6 +171,7 @@
> >> .engine_mask = BIT(RCS0), \
> >> .has_snoop = true, \
> >> .has_coherent_ggtt = false, \
> >> + .dma_mask_size = 32, \
> >> I9XX_PIPE_OFFSETS, \
> >> I9XX_CURSOR_OFFSETS, \
> >> I9XX_COLORS, \
> >> @@ -190,6 +191,7 @@
> >> .engine_mask = BIT(RCS0), \
> >> .has_snoop = true, \
> >> .has_coherent_ggtt = false, \
> >> + .dma_mask_size = 32, \
> >> I845_PIPE_OFFSETS, \
> >> I845_CURSOR_OFFSETS, \
> >> I9XX_COLORS, \
> >> @@ -226,6 +228,7 @@ static const struct intel_device_info i865g_info = {
> >> .engine_mask = BIT(RCS0), \
> >> .has_snoop = true, \
> >> .has_coherent_ggtt = true, \
> >> + .dma_mask_size = 32, \
> >
> >gen2 is set to 30b?
> >
> >> I9XX_PIPE_OFFSETS, \
> >> I9XX_CURSOR_OFFSETS, \
> >> I9XX_COLORS, \
> >> @@ -286,6 +289,7 @@ static const struct intel_device_info g33_info = {
> >> PLATFORM(INTEL_G33),
> >> .display.has_hotplug = 1,
> >> .display.has_overlay = 1,
> >> + .dma_mask_size = 36,
> >> };
> >>
> >> static const struct intel_device_info pnv_g_info = {
> >> @@ -293,6 +297,7 @@ static const struct intel_device_info pnv_g_info = {
> >> PLATFORM(INTEL_PINEVIEW),
> >> .display.has_hotplug = 1,
> >> .display.has_overlay = 1,
> >> + .dma_mask_size = 36,
> >> };
> >>
> >> static const struct intel_device_info pnv_m_info = {
> >> @@ -301,6 +306,7 @@ static const struct intel_device_info pnv_m_info = {
> >> .is_mobile = 1,
> >> .display.has_hotplug = 1,
> >> .display.has_overlay = 1,
> >> + .dma_mask_size = 36,
> >> };
> >>
> >> #define GEN4_FEATURES \
> >> @@ -313,6 +319,7 @@ static const struct intel_device_info pnv_m_info = {
> >> .engine_mask = BIT(RCS0), \
> >> .has_snoop = true, \
> >> .has_coherent_ggtt = true, \
> >> + .dma_mask_size = 36, \
> >> I9XX_PIPE_OFFSETS, \
> >> I9XX_CURSOR_OFFSETS, \
> >> I965_COLORS, \
> >
> >I thought we had restricted i965g/i965gm to 32b.
> >
> >Hmm. dma_set_coherent_mask.
> >
> >Not much point tablifying one without the other?
>
> Since these were the only two, adding this to the table seemed like overkill.
>
> Gen2 (restricted to 30 bits), i965g and i965gm have the coherent mask set after
> the i915_ggtt_enable_hw occurs (in i915_drv.c)
>
> I can move this code into the common location for setting the dma mask, but I
> was not clear on the ramifications of this. Do you know if there is a reason for
> the location of this workaround?
Tbh, I was surprised the pci_set_dma_mask() was being so late in ggtt
probe :)
But the only reason why the dma_set_coherent_mask() is being done much
earlier is because that was historically where we were first handed the
pci device and so where we configure the pci_dev (as opposed to thinking
of operating on the drm_i915_device).
There should not be a problem pulling them into the same location, and
returning an error in case of failure. And if we do that we might as
well do something like:
i915_set_dma_mask {
int dma_mask_size = INTEL_INFO(i915)->dma_mask_size;
err = dma_set_mask(&i915->drm.dev, DMA_BIT_MASK(dma_mask_size));
if (err)
goto err;
/* w/a overlay... */
if (IS_GEN2)
dma_mask_size = 30;
/* w/a lots of fun restrictions */
if (IS_I965G...)
dma_mask_size = 32;
err = dma_set_coherent_mask(&i915->drm.dev, DMA_BIT_MASK(dma_mask_size));
if (err)
goto err;
return 0;
err:
drm_err(&i915->drm, "....");
return err;
}
?
-Chris
More information about the Intel-gfx
mailing list