aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-01-22 09:19:00 -0500
committerDave Airlie <airlied@redhat.com>2010-01-31 20:33:11 -0500
commitff82f052d2a187dd0fa0e431ba70eb457c71a40e (patch)
tree65bf2788445c3087cdb6c05fe2d40e81629ffd3b /drivers/gpu
parent5ffdb658f605cbc420944e7c7eeec9fbb8a73772 (diff)
drm/radeon/kms: Bailout of blit if error happen & protect with mutex V3
If an error happen in r600_blit_prepare_copy report it rather than WARNING and keeping execution. For instance if ib allocation failed we did just warn about but then latter tried to access NULL ib ptr causing oops. This patch also protect r600_copy_blit with a mutex as otherwise one process might overwrite blit temporary data with new one possibly leading to GPU lockup. Should partialy or totaly fix: https://bugzilla.redhat.com/show_bug.cgi?id=553279 V2 failing blit initialization is not fatal, fallback to memcpy when this happen V3 init blit before startup as we pin in startup, remove duplicate code (this one was actualy tested unlike V2) Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/r600.c54
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/rv770.c31
4 files changed, 48 insertions, 45 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index d0bd117a463a..b833b4b97162 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1788,23 +1788,24 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
1788 radeon_ring_write(rdev, RB_INT_STAT); 1788 radeon_ring_write(rdev, RB_INT_STAT);
1789} 1789}
1790 1790
1791int r600_copy_dma(struct radeon_device *rdev,
1792 uint64_t src_offset,
1793 uint64_t dst_offset,
1794 unsigned num_pages,
1795 struct radeon_fence *fence)
1796{
1797 /* FIXME: implement */
1798 return 0;
1799}
1800
1801int r600_copy_blit(struct radeon_device *rdev, 1791int r600_copy_blit(struct radeon_device *rdev,
1802 uint64_t src_offset, uint64_t dst_offset, 1792 uint64_t src_offset, uint64_t dst_offset,
1803 unsigned num_pages, struct radeon_fence *fence) 1793 unsigned num_pages, struct radeon_fence *fence)
1804{ 1794{
1805 r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); 1795 int r;
1796
1797 mutex_lock(&rdev->r600_blit.mutex);
1798 rdev->r600_blit.vb_ib = NULL;
1799 r = r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE);
1800 if (r) {
1801 if (rdev->r600_blit.vb_ib)
1802 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
1803 mutex_unlock(&rdev->r600_blit.mutex);
1804 return r;
1805 }
1806 r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); 1806 r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE);
1807 r600_blit_done_copy(rdev, fence); 1807 r600_blit_done_copy(rdev, fence);
1808 mutex_unlock(&rdev->r600_blit.mutex);
1808 return 0; 1809 return 0;
1809} 1810}
1810 1811
@@ -1860,26 +1861,19 @@ int r600_startup(struct radeon_device *rdev)
1860 return r; 1861 return r;
1861 } 1862 }
1862 r600_gpu_init(rdev); 1863 r600_gpu_init(rdev);
1863 1864 /* pin copy shader into vram */
1864 if (!rdev->r600_blit.shader_obj) { 1865 if (rdev->r600_blit.shader_obj) {
1865 r = r600_blit_init(rdev); 1866 r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
1867 if (unlikely(r != 0))
1868 return r;
1869 r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
1870 &rdev->r600_blit.shader_gpu_addr);
1871 radeon_bo_unreserve(rdev->r600_blit.shader_obj);
1866 if (r) { 1872 if (r) {
1867 DRM_ERROR("radeon: failed blitter (%d).\n", r); 1873 dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
1868 return r; 1874 return r;
1869 } 1875 }
1870 } 1876 }
1871
1872 r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
1873 if (unlikely(r != 0))
1874 return r;
1875 r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
1876 &rdev->r600_blit.shader_gpu_addr);
1877 radeon_bo_unreserve(rdev->r600_blit.shader_obj);
1878 if (r) {
1879 dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
1880 return r;
1881 }
1882
1883 /* Enable IRQ */ 1877 /* Enable IRQ */
1884 r = r600_irq_init(rdev); 1878 r = r600_irq_init(rdev);
1885 if (r) { 1879 if (r) {
@@ -2051,6 +2045,12 @@ int r600_init(struct radeon_device *rdev)
2051 r = r600_pcie_gart_init(rdev); 2045 r = r600_pcie_gart_init(rdev);
2052 if (r) 2046 if (r)
2053 return r; 2047 return r;
2048 r = r600_blit_init(rdev);
2049 if (r) {
2050 r600_blit_fini(rdev);
2051 rdev->asic->copy = NULL;
2052 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
2053 }
2054 2054
2055 rdev->accel_working = true; 2055 rdev->accel_working = true;
2056 r = r600_startup(rdev); 2056 r = r600_startup(rdev);
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index 2bedce477a97..af1c3ca8a4cb 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -449,6 +449,7 @@ int r600_blit_init(struct radeon_device *rdev)
449 u32 packet2s[16]; 449 u32 packet2s[16];
450 int num_packet2s = 0; 450 int num_packet2s = 0;
451 451
452 mutex_init(&rdev->r600_blit.mutex);
452 rdev->r600_blit.state_offset = 0; 453 rdev->r600_blit.state_offset = 0;
453 454
454 if (rdev->family >= CHIP_RV770) 455 if (rdev->family >= CHIP_RV770)
@@ -557,7 +558,8 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
557 int dwords_per_loop = 76, num_loops; 558 int dwords_per_loop = 76, num_loops;
558 559
559 r = r600_vb_ib_get(rdev); 560 r = r600_vb_ib_get(rdev);
560 WARN_ON(r); 561 if (r)
562 return r;
561 563
562 /* set_render_target emits 2 extra dwords on rv6xx */ 564 /* set_render_target emits 2 extra dwords on rv6xx */
563 if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) 565 if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
@@ -583,7 +585,8 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
583 ring_size += 5; /* done copy */ 585 ring_size += 5; /* done copy */
584 ring_size += 7; /* fence emit for done copy */ 586 ring_size += 7; /* fence emit for done copy */
585 r = radeon_ring_lock(rdev, ring_size); 587 r = radeon_ring_lock(rdev, ring_size);
586 WARN_ON(r); 588 if (r)
589 return r;
587 590
588 set_default_state(rdev); /* 14 */ 591 set_default_state(rdev); /* 14 */
589 set_shaders(rdev); /* 26 */ 592 set_shaders(rdev); /* 26 */
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index f7df1a7e4413..2d5f2bfa7201 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -416,6 +416,7 @@ struct r600_ih {
416}; 416};
417 417
418struct r600_blit { 418struct r600_blit {
419 struct mutex mutex;
419 struct radeon_bo *shader_obj; 420 struct radeon_bo *shader_obj;
420 u64 shader_gpu_addr; 421 u64 shader_gpu_addr;
421 u32 vs_offset, ps_offset; 422 u32 vs_offset, ps_offset;
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index cf8f2b17d627..2d465768ac71 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -887,26 +887,19 @@ static int rv770_startup(struct radeon_device *rdev)
887 return r; 887 return r;
888 } 888 }
889 rv770_gpu_init(rdev); 889 rv770_gpu_init(rdev);
890 890 /* pin copy shader into vram */
891 if (!rdev->r600_blit.shader_obj) { 891 if (rdev->r600_blit.shader_obj) {
892 r = r600_blit_init(rdev); 892 r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
893 if (unlikely(r != 0))
894 return r;
895 r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
896 &rdev->r600_blit.shader_gpu_addr);
897 radeon_bo_unreserve(rdev->r600_blit.shader_obj);
893 if (r) { 898 if (r) {
894 DRM_ERROR("radeon: failed blitter (%d).\n", r); 899 DRM_ERROR("failed to pin blit object %d\n", r);
895 return r; 900 return r;
896 } 901 }
897 } 902 }
898
899 r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
900 if (unlikely(r != 0))
901 return r;
902 r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
903 &rdev->r600_blit.shader_gpu_addr);
904 radeon_bo_unreserve(rdev->r600_blit.shader_obj);
905 if (r) {
906 DRM_ERROR("failed to pin blit object %d\n", r);
907 return r;
908 }
909
910 /* Enable IRQ */ 903 /* Enable IRQ */
911 r = r600_irq_init(rdev); 904 r = r600_irq_init(rdev);
912 if (r) { 905 if (r) {
@@ -1062,6 +1055,12 @@ int rv770_init(struct radeon_device *rdev)
1062 r = r600_pcie_gart_init(rdev); 1055 r = r600_pcie_gart_init(rdev);
1063 if (r) 1056 if (r)
1064 return r; 1057 return r;
1058 r = r600_blit_init(rdev);
1059 if (r) {
1060 r600_blit_fini(rdev);
1061 rdev->asic->copy = NULL;
1062 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
1063 }
1065 1064
1066 rdev->accel_working = true; 1065 rdev->accel_working = true;
1067 r = rv770_startup(rdev); 1066 r = rv770_startup(rdev);