diff options
author | Chen Li <chenli@uniontech.com> | 2020-12-25 11:54:57 +0800 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2021-01-05 11:32:05 -0500 |
commit | ede6b6bc43c68ef030f88235e91e85939b8bdb49 (patch) | |
tree | 8039d245dd8b3565fc6bc13f5868439fe33ab931 | |
parent | 26eb6b51da86ec7dcc29fd90baf465b38acecfb7 (diff) | |
download | lwn-ede6b6bc43c68ef030f88235e91e85939b8bdb49.tar.gz lwn-ede6b6bc43c68ef030f88235e91e85939b8bdb49.zip |
drm/radeon: use writel to avoid gcc optimization v3
When using e8860(gcn1) on arm64, the kernel crashed on drm/radeon:
[ 11.240414] pc : __memset+0x4c/0x188
[ 11.244101] lr : radeon_uvd_get_create_msg+0x114/0x1d0 [radeon]
[ 11.249995] sp : ffff00000d7eb700
[ 11.253295] x29: ffff00000d7eb700 x28: ffff8001f632a868
[ 11.258585] x27: 0000000000040000 x26: ffff00000de00000
[ 11.263875] x25: 0000000000000125 x24: 0000000000000001
[ 11.269168] x23: 0000000000000000 x22: 0000000000000005
[ 11.274459] x21: ffff00000df24000 x20: ffff8001f74b4000
[ 11.279753] x19: 0000000000124000 x18: 0000000000000020
[ 11.285043] x17: 0000000000000000 x16: 0000000000000000
[ 11.290336] x15: ffff000009309000 x14: ffffffffffffffff
[ 11.290340] x13: ffff0000094b6f88 x12: ffff0000094b6bd2
[ 11.290343] x11: ffff00000d7eb700 x10: ffff00000d7eb700
[ 11.306246] x9 : ffff00000d7eb700 x8 : ffff00000df2402c
[ 11.306254] x7 : 0000000000000000 x6 : ffff0000094b626a
[ 11.306257] x5 : 0000000000000000 x4 : 0000000000000004
[ 11.306262] x3 : ffffffffffffffff x2 : 0000000000000fd4
[ 11.306265] x1 : 0000000000000000 x0 : ffff00000df2402c
[ 11.306272] Call trace:
[ 11.306316] __memset+0x4c/0x188
[ 11.306638] uvd_v1_0_ib_test+0x70/0x1c0 [radeon]
[ 11.306758] radeon_ib_ring_tests+0x54/0xe0 [radeon]
...
Obviously, the __memset call is generated by gcc(8.3.1). It optimizes
this for loop into memset. But this may break on some platforms which
cannot map device memory correctly. So, just invoke `writel` to handle this.
v3 (chk): minor cleanups in code and commit message
Signed-off-by: Chen Li <chenli@uniontech.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_uvd.c | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 39c1c339be7b..dfa9fdbe98da 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -781,7 +781,7 @@ int radeon_uvd_get_create_msg(struct radeon_device *rdev, int ring, uint64_t offs = radeon_bo_size(rdev->uvd.vcpu_bo) - RADEON_GPU_PAGE_SIZE; - uint32_t *msg = rdev->uvd.cpu_addr + offs; + uint32_t __iomem *msg = (void __iomem *)(rdev->uvd.cpu_addr + offs); uint64_t addr = rdev->uvd.gpu_addr + offs; int r, i; @@ -791,19 +791,19 @@ int radeon_uvd_get_create_msg(struct radeon_device *rdev, int ring, return r; /* stitch together an UVD create msg */ - msg[0] = cpu_to_le32(0x00000de4); - msg[1] = cpu_to_le32(0x00000000); - msg[2] = cpu_to_le32(handle); - msg[3] = cpu_to_le32(0x00000000); - msg[4] = cpu_to_le32(0x00000000); - msg[5] = cpu_to_le32(0x00000000); - msg[6] = cpu_to_le32(0x00000000); - msg[7] = cpu_to_le32(0x00000780); - msg[8] = cpu_to_le32(0x00000440); - msg[9] = cpu_to_le32(0x00000000); - msg[10] = cpu_to_le32(0x01b37000); + writel(cpu_to_le32(0x00000de4), &msg[0]); + writel(0x0, (void __iomem *)&msg[1]); + writel(cpu_to_le32(handle), &msg[2]); + writel(0x0, &msg[3]); + writel(0x0, &msg[4]); + writel(0x0, &msg[5]); + writel(0x0, &msg[6]); + writel(cpu_to_le32(0x00000780), &msg[7]); + writel(cpu_to_le32(0x00000440), &msg[8]); + writel(0x0, &msg[9]); + writel(cpu_to_le32(0x01b37000), &msg[10]); for (i = 11; i < 1024; ++i) - msg[i] = cpu_to_le32(0x0); + writel(0x0, &msg[i]); r = radeon_uvd_send_msg(rdev, ring, addr, fence); radeon_bo_unreserve(rdev->uvd.vcpu_bo); @@ -817,7 +817,7 @@ int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring, uint64_t offs = radeon_bo_size(rdev->uvd.vcpu_bo) - RADEON_GPU_PAGE_SIZE; - uint32_t *msg = rdev->uvd.cpu_addr + offs; + uint32_t __iomem *msg = (void __iomem *)(rdev->uvd.cpu_addr + offs); uint64_t addr = rdev->uvd.gpu_addr + offs; int r, i; @@ -827,12 +827,12 @@ int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring, return r; /* stitch together an UVD destroy msg */ - msg[0] = cpu_to_le32(0x00000de4); - msg[1] = cpu_to_le32(0x00000002); - msg[2] = cpu_to_le32(handle); - msg[3] = cpu_to_le32(0x00000000); + writel(cpu_to_le32(0x00000de4), &msg[0]); + writel(cpu_to_le32(0x00000002), &msg[1]); + writel(cpu_to_le32(handle), &msg[2]); + writel(0x0, &msg[3]); for (i = 4; i < 1024; ++i) - msg[i] = cpu_to_le32(0x0); + writel(0x0, &msg[i]); r = radeon_uvd_send_msg(rdev, ring, addr, fence); radeon_bo_unreserve(rdev->uvd.vcpu_bo); |