diff options
author | Jerome Glisse <jglisse@redhat.com> | 2010-01-22 09:19:00 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-01-31 20:33:11 -0500 |
commit | ff82f052d2a187dd0fa0e431ba70eb457c71a40e (patch) | |
tree | 65bf2788445c3087cdb6c05fe2d40e81629ffd3b /drivers/gpu/drm/radeon/r600.c | |
parent | 5ffdb658f605cbc420944e7c7eeec9fbb8a73772 (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/drm/radeon/r600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 54 |
1 files changed, 27 insertions, 27 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 | ||
1791 | int 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 | |||
1801 | int r600_copy_blit(struct radeon_device *rdev, | 1791 | int 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); |