[PATCH] drm/prime: Only call dma_map_sgtable() for devices with DMA support
Thomas Zimmermann
tzimmermann at suse.de
Fri Feb 19 14:34:57 UTC 2021
Hi
Am 19.02.21 um 14:45 schrieb Christian König:
> Well as far as I can see this is a relative clear NAK.
>
> When a device can't do DMA and has no DMA mask then why it is requesting
> an sg-table in the first place?
>
> The problem is rather in drm_gem_prime_import_dev() which always tries
> to create an sg-table to get a GEM object, even when the device doesn't
> support DMA at all.
Sure, that's the clean solution. But it also needs a bit of work on the
way the importing works. Our generic code assumes that an SG table is
being used. Most driver's memory managers as well, I guess.
The regressing patch has already been in upstream kernels for a while.
The fix at hand is backport-able at least.
Can we add a TODO item for the real thing?
Best regards
Thomas
>
> Regards,
> Christian.
>
> Am 19.02.21 um 14:40 schrieb Thomas Zimmermann:
>> Fixes a regression for udl and probably other USB-based drivers where
>> joining and mirroring displays fails.
>>
>> Joining displays requires importing a dma_buf from another DRM driver.
>> These devices don't support DMA and therefore have no DMA mask. Trying
>> to map imported buffers from a DMA-able memory zone fails with an error.
>> An example is shown below.
>>
>> [ 60.050199] ------------[ cut here ]------------
>> [ 60.055092] WARNING: CPU: 0 PID: 1403 at kernel/dma/mapping.c:190
>> dma_map_sg_attrs+0x8f/0xc0
>> [ 60.064331] Modules linked in: af_packet(E) rfkill(E) dmi_sysfs(E)
>> intel_rapl_msr(E) intel_rapl_common(E) snd_hda_codec_realtek(E)
>> snd_hda_codec_generic(E) ledtrig_audio(E) snd_hda_codec_hdmi(E)
>> x86_pkg_temp_thermal(E) intel_powerclam)
>> [ 60.064801] wmi(E) video(E) btrfs(E) blake2b_generic(E)
>> libcrc32c(E) crc32c_intel(E) xor(E) raid6_pq(E) sg(E) dm_multipath(E)
>> dm_mod(E) scsi_dh_rdac(E) scsi_dh_emc(E) scsi_dh_alua(E) msr(E)
>> efivarfs(E)
>> [ 60.170778] CPU: 0 PID: 1403 Comm: Xorg.bin Tainted: G
>> E 5.11.0-rc5-1-default+ #747
>> [ 60.179841] Hardware name: Dell Inc. OptiPlex 9020/0N4YC8, BIOS A24
>> 10/24/2018
>> [ 60.187145] RIP: 0010:dma_map_sg_attrs+0x8f/0xc0
>> [ 60.191822] Code: 4d 85 ff 75 2b 49 89 d8 44 89 e1 44 89 f2 4c 89
>> ee 48 89 ef e8 62 30 00 00 85 c0 78 36 5b 5d 41 5c 41 5d 41 5e 41 5f
>> c3 0f 0b <0f> 0b 31 c0 eb ed 49 8d 7f 50 e8 72 f5 2a 00 49 8b 47 50 49
>> 89 d8
>> [ 60.210770] RSP: 0018:ffffc90001d6fc18 EFLAGS: 00010246
>> [ 60.216062] RAX: 0000000000000000 RBX: 0000000000000020 RCX:
>> ffffffffb31e677b
>> [ 60.223274] RDX: dffffc0000000000 RSI: ffff888212c10600 RDI:
>> ffff8881b08a9488
>> [ 60.230501] RBP: ffff8881b08a9030 R08: 0000000000000020 R09:
>> ffff888212c10600
>> [ 60.237710] R10: ffffed10425820df R11: 0000000000000001 R12:
>> 0000000000000000
>> [ 60.244939] R13: ffff888212c10600 R14: 0000000000000008 R15:
>> 0000000000000000
>> [ 60.252155] FS: 00007f08ac2b2f00(0000) GS:ffff8887cbe00000(0000)
>> knlGS:0000000000000000
>> [ 60.260333] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> [ 60.266150] CR2: 000055831c899be8 CR3: 000000015372e006 CR4:
>> 00000000001706f0
>> [ 60.273369] Call Trace:
>> [ 60.275845] drm_gem_map_dma_buf+0xb4/0x120
>> [ 60.280089] dma_buf_map_attachment+0x15d/0x1e0
>> [ 60.284688] drm_gem_prime_import_dev.part.0+0x5d/0x140
>> [ 60.289984] drm_gem_prime_fd_to_handle+0x213/0x280
>> [ 60.294931] ? drm_prime_destroy_file_private+0x30/0x30
>> [ 60.300224] drm_ioctl_kernel+0x131/0x180
>> [ 60.304291] ? drm_setversion+0x230/0x230
>> [ 60.308366] ? drm_prime_destroy_file_private+0x30/0x30
>> [ 60.313659] drm_ioctl+0x2f1/0x500
>> [ 60.317118] ? drm_version+0x150/0x150
>> [ 60.320903] ? lock_downgrade+0xa0/0xa0
>> [ 60.324806] ? do_vfs_ioctl+0x5f4/0x680
>> [ 60.328694] ? __fget_files+0x13e/0x210
>> [ 60.332591] ? ioctl_fiemap.isra.0+0x1a0/0x1a0
>> [ 60.337102] ? __fget_files+0x15d/0x210
>> [ 60.340990] __x64_sys_ioctl+0xb9/0xf0
>> [ 60.344795] do_syscall_64+0x33/0x80
>> [ 60.348427] entry_SYSCALL_64_after_hwframe+0x44/0xa9
>> [ 60.353542] RIP: 0033:0x7f08ac7b53cb
>> [ 60.357168] Code: 89 d8 49 8d 3c 1c 48 f7 d8 49 39 c4 72 b5 e8 1c
>> ff ff ff 85 c0 78 ba 4c 89 e0 5b 5d 41 5c c3 f3 0f 1e fa b8 10 00 00
>> 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 75 ba 0c 00 f7 d8 64 89
>> 01 48
>> [ 60.376108] RSP: 002b:00007ffeabc89fc8 EFLAGS: 00000246 ORIG_RAX:
>> 0000000000000010
>> [ 60.383758] RAX: ffffffffffffffda RBX: 00007ffeabc8a00c RCX:
>> 00007f08ac7b53cb
>> [ 60.390970] RDX: 00007ffeabc8a00c RSI: 00000000c00c642e RDI:
>> 000000000000000d
>> [ 60.398221] RBP: 00000000c00c642e R08: 000055831c691d00 R09:
>> 000055831b2ec010
>> [ 60.405446] R10: 00007f08acf6ada0 R11: 0000000000000246 R12:
>> 000055831c691d00
>> [ 60.412667] R13: 000000000000000d R14: 00000000007e9000 R15:
>> 0000000000000000
>> [ 60.419903] irq event stamp: 672893
>> [ 60.423441] hardirqs last enabled at (672913):
>> [<ffffffffb31b796d>] console_unlock+0x44d/0x500
>> [ 60.432230] hardirqs last disabled at (672922):
>> [<ffffffffb31b7963>] console_unlock+0x443/0x500
>> [ 60.441021] softirqs last enabled at (672940):
>> [<ffffffffb46003dd>] __do_softirq+0x3dd/0x554
>> [ 60.449634] softirqs last disabled at (672931):
>> [<ffffffffb44010f2>] asm_call_irq_on_stack+0x12/0x20
>> [ 60.458871] ---[ end trace f2f88696eb17806c ]---
>>
>> For the fix, we don't call dma_map_sgtable() for devices without the
>> DMA mask. Drivers for such devices have to map the imported buffer into
>> kernel address space and perfom the copy operation in software.
>>
>> Tested by joining/mirroring displays of udl and radeon un der Gnome/X11.
>>
>> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
>> Fixes: 6eb0233ec2d0 ("usb: don't inherity DMA properties for USB
>> devices")
>> Cc: Christoph Hellwig <hch at lst.de>
>> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
>> Cc: Alan Stern <stern at rowland.harvard.edu>
>> Cc: Johan Hovold <johan at kernel.org>
>> Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
>> Cc: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
>> Cc: "Ahmed S. Darwish" <a.darwish at linutronix.de>
>> Cc: Mathias Nyman <mathias.nyman at linux.intel.com>
>> Cc: Oliver Neukum <oneukum at suse.com>
>> Cc: Felipe Balbi <balbi at kernel.org>
>> Cc: Thomas Gleixner <tglx at linutronix.de>
>> Cc: <stable at vger.kernel.org> # v5.10+
>> ---
>> drivers/gpu/drm/drm_prime.c | 27 ++++++++++++++++++---------
>> 1 file changed, 18 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>> index 2a54f86856af..d5a39fe76b78 100644
>> --- a/drivers/gpu/drm/drm_prime.c
>> +++ b/drivers/gpu/drm/drm_prime.c
>> @@ -603,10 +603,15 @@ EXPORT_SYMBOL(drm_gem_map_detach);
>> * @attach: attachment whose scatterlist is to be returned
>> * @dir: direction of DMA transfer
>> *
>> - * Calls &drm_gem_object_funcs.get_sg_table and then maps the
>> scatterlist. This
>> - * can be used as the &dma_buf_ops.map_dma_buf callback. Should be
>> used together
>> + * Calls &drm_gem_object_funcs.get_sg_table and, if possible, maps
>> the scatterlist.
>> + * This can be used as the &dma_buf_ops.map_dma_buf callback. Should
>> be used together
>> * with drm_gem_unmap_dma_buf().
>> *
>> + * Devices on some peripheral busses, such as USB, cannot use DMA. In
>> this case,
>> + * pages in the scatterlist remain unmapped. Drivers for such devices
>> should acquire
>> + * a mapping with dma_buf_vmap() and implement copy operation via
>> bus-specific
>> + * interfaces.
>> + *
>> * Returns:sg_table containing the scatterlist to be returned;
>> returns ERR_PTR
>> * on error. May return -EINTR if it is interrupted by a signal.
>> */
>> @@ -627,12 +632,14 @@ struct sg_table *drm_gem_map_dma_buf(struct
>> dma_buf_attachment *attach,
>> if (IS_ERR(sgt))
>> return sgt;
>>
>> - ret = dma_map_sgtable(attach->dev, sgt, dir,
>> - DMA_ATTR_SKIP_CPU_SYNC);
>> - if (ret) {
>> - sg_free_table(sgt);
>> - kfree(sgt);
>> - sgt = ERR_PTR(ret);
>> + if (attach->dev->dma_mask) {
>> + ret = dma_map_sgtable(attach->dev, sgt, dir,
>> + DMA_ATTR_SKIP_CPU_SYNC);
>> + if (ret) {
>> + sg_free_table(sgt);
>> + kfree(sgt);
>> + sgt = ERR_PTR(ret);
>> + }
>> }
>>
>> return sgt;
>> @@ -654,7 +661,9 @@ void drm_gem_unmap_dma_buf(struct
>> dma_buf_attachment *attach,
>> if (!sgt)
>> return;
>>
>> - dma_unmap_sgtable(attach->dev, sgt, dir, DMA_ATTR_SKIP_CPU_SYNC);
>> + if (attach->dev->dma_mask)
>> + dma_unmap_sgtable(attach->dev, sgt, dir,
>> DMA_ATTR_SKIP_CPU_SYNC);
>> +
>> sg_free_table(sgt);
>> kfree(sgt);
>> }
>> --
>> 2.30.0
>>
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20210219/c139500f/attachment.sig>
More information about the dri-devel
mailing list