drm/i915: Call dma_set_max_seg_size() in i915_driver_hw_probe() [Linux 4.19.70]

This Linux kernel change "drm/i915: Call dma_set_max_seg_size() in i915_driver_hw_probe()" is included in the Linux 4.19.70 release. This change is authored by Lyude Paul <lyude [at] redhat.com> on Fri Aug 23 16:52:51 2019 -0400. The commit for this change in Linux stable tree is 68b58d3 (patch) which is from upstream commit 32f0a98. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 32f0a98.

drm/i915: Call dma_set_max_seg_size() in i915_driver_hw_probe()

commit 32f0a982650b123bdab36865617d3e03ebcacf3b upstream.

Currently, we don't call dma_set_max_seg_size() for i915 because we
intentionally do not limit the segment length that the device supports.
However, this results in a warning being emitted if we try to map
anything larger than SZ_64K on a kernel with CONFIG_DMA_API_DEBUG_SG
enabled:

[    7.751926] DMA-API: i915 0000:00:02.0: mapping sg segment longer
than device claims to support [len=98304] [max=65536]
[    7.751934] WARNING: CPU: 5 PID: 474 at kernel/dma/debug.c:1220
debug_dma_map_sg+0x20f/0x340

This was originally brought up on
https://bugs.freedesktop.org/show_bug.cgi?id=108517 , and the consensus
there was it wasn't really useful to set a limit (and that dma-debug
isn't really all that useful for i915 in the first place). Unfortunately
though, CONFIG_DMA_API_DEBUG_SG is enabled in the debug configs for
various distro kernels. Since a WARN_ON() will disable automatic problem
reporting (and cause any CI with said option enabled to start
complaining), we really should just fix the problem.

Note that as me and Chris Wilson discussed, the other solution for this
would be to make DMA-API not make such assumptions when a driver hasn't
explicitly set a maximum segment size. But, taking a look at the commit
which originally introduced this behavior, commit 78c47830a5cb
("dma-debug: check scatterlist segments"), there is an explicit mention
of this assumption and how it applies to devices with no segment size:

    Conversely, devices which are less limited than the rather
    conservative defaults, or indeed have no limitations at all
    (e.g. GPUs with their own internal MMU), should be encouraged to
    set appropriate dma_parms, as they may get more efficient DMA
    mapping performance out of it.

So unless there's any concerns (I'm open to discussion!), let's just
follow suite and call dma_set_max_seg_size() with UINT_MAX as our limit
to silence any warnings.

Changes since v3:
* Drop patch for enabling CONFIG_DMA_API_DEBUG_SG in CI. It looks like
  just turning it on causes the kernel to spit out bogus WARN_ONs()
  during some igt tests which would otherwise require teaching igt to
  disable the various DMA-API debugging options causing this. This is
  too much work to be worth it, since DMA-API debugging is useless for
  us. So, we'll just settle with this single patch to squelch WARN_ONs()
  during driver load for users that have CONFIG_DMA_API_DEBUG_SG turned
  on for some reason.
* Move dma_set_max_seg_size() call into i915_driver_hw_probe() - Chris
  Wilson

Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: <stable@vger.kernel.org> # v4.18+
Link: https://patchwork.freedesktop.org/patch/msgid/20190823205251.14298-1-lyude@redhat.com
(cherry picked from commit acd674af95d3f627062007429b9c195c6b32361d)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

There are 6 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/gpu/drm/i915/i915_drv.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index f8cfd16..a4b4ab7 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1120,6 +1120,12 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)

    pci_set_master(pdev);

+   /*
+    * We don't have a max segment size, so set it to the max so sg's
+    * debugging layer doesn't complain
+    */
+   dma_set_max_seg_size(&pdev->dev, UINT_MAX);
+
    /* overlay on gen2 is broken and can't address above 1G */
    if (IS_GEN2(dev_priv)) {
        ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(30));

Leave a Reply

Your email address will not be published. Required fields are marked *