[PATCH 0/6] Properly detect swiotlb.
So this is only build tested as i am away from hardware right now. Idea is to provide reliable way to check if swiotlb is in use for a device or not. It seems swiotlb_nr_tbl() is no longer reliable for that. Please test. Cheers, Jérôme Glisse
[PATCH 1/6] swiotlb: Add helper to know if it is in use for a specific device.
From: Jérôme Glisse Some device like GPU do things differently if swiotlb is in use. We use to rely on swiotlb_nr_tbl() to know if swiotlb was enabled or not but this is unreliable. Patch add a simple helpers to check if any of the dma_ops associated with a device points to the swiotlb functions, making swiotlb check reliable for a device. Signed-off-by: Jérôme Glisse Cc: Konrad Rzeszutek Wilk Cc: Alex Deucher Cc: Ben Skeggs Cc: Dave Airlie Cc: lkml at vger.kernel.org Cc: Daniel Vetter --- include/linux/dma-mapping.h | 18 ++ 1 file changed, 18 insertions(+) diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index ac07ff0..eac911e 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -314,4 +314,22 @@ static inline int dma_mmap_writecombine(struct device *dev, #define dma_unmap_len_set(PTR, LEN_NAME, VAL)do { } while (0) #endif + +#ifdef CONFIG_SWIOTLB +static inline bool swiotlb_in_use(struct device *dev) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + + return (ops->map_sg == swiotlb_map_sg_attrs || + ops->unmap_sg == swiotlb_unmap_sg_attrs || + ops->map_page == swiotlb_map_page); +} +#else +static inline bool swiotlb_in_use(struct device *dev) +{ + return false; +} +#endif + + #endif -- 2.1.0
[PATCH 2/6] drm/radeon: Use swiotlb_in_use() to know if swiotlb is enabled or not.
From: Jérôme Glisse We can not rely on swiotlb_nr_tbl() to know if swiotlb is in use or not for our device. Use the new helper to determine that. Signed-off-by: Jérôme Glisse Cc: Konrad Rzeszutek Wilk Cc: Alex Deucher Cc: Ben Skeggs Cc: Dave Airlie Cc: lkml at vger.kernel.org Cc: Daniel Vetter --- drivers/gpu/drm/radeon/radeon_ttm.c | 13 +++-- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 06ac59fe..5c9814a 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -742,11 +741,9 @@ static int radeon_ttm_tt_populate(struct ttm_tt *ttm) } #endif -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { + if (swiotlb_in_use(rdev->dev)) { return ttm_dma_populate(>t->ttm, rdev->dev); } -#endif r = ttm_pool_populate(ttm); if (r) { @@ -794,12 +791,10 @@ static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm) } #endif -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { + if (swiotlb_in_use(rdev->dev)) { ttm_dma_unpopulate(>t->ttm, rdev->dev); return; } -#endif for (i = 0; i < ttm->num_pages; i++) { if (gtt->ttm.dma_address[i]) { @@ -1169,10 +1164,8 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev) count = ARRAY_SIZE(radeon_ttm_debugfs_list); -#ifdef CONFIG_SWIOTLB - if (!swiotlb_nr_tbl()) + if (!swiotlb_in_use(rdev->dev)) --count; -#endif return radeon_debugfs_add_files(rdev, radeon_ttm_debugfs_list, count); #else -- 2.1.0
[PATCH 3/6] drm/nouveau: Use swiotlb_in_use() to know if swiotlb is enabled or not.
From: Jérôme Glisse We can not rely on swiotlb_nr_tbl() to know if swiotlb is in use or not for our device. Use the new helper to determine that. Signed-off-by: Jérôme Glisse Cc: Konrad Rzeszutek Wilk Cc: Alex Deucher Cc: Ben Skeggs Cc: Dave Airlie Cc: lkml at vger.kernel.org Cc: Daniel Vetter --- drivers/gpu/drm/nouveau/nouveau_bo.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 6edcce1..f601049 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -28,7 +28,6 @@ */ #include -#include #include "nouveau_drm.h" #include "nouveau_dma.h" @@ -1504,11 +1503,9 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm) } #endif -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { + if (swiotlb_in_use(pdev)) { return ttm_dma_populate((void *)ttm, dev->dev); } -#endif r = ttm_pool_populate(ttm); if (r) { @@ -1572,12 +1569,10 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) } #endif -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { + if (swiotlb_in_use(pdev)) { ttm_dma_unpopulate((void *)ttm, dev->dev); return; } -#endif for (i = 0; i < ttm->num_pages; i++) { if (ttm_dma->dma_address[i]) { -- 2.1.0
[PATCH 5/6] drm/i915: Use swiotlb_in_use() to know if swiotlb is enabled.
From: Jérôme Glisse We can not rely on swiotlb_nr_tbl() to know if swiotlb is in use or not for our device. Use the new helper to determine that. Signed-off-by: Jérôme Glisse Cc: Konrad Rzeszutek Wilk Cc: Alex Deucher Cc: Ben Skeggs Cc: Dave Airlie Cc: lkml at vger.kernel.org Cc: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 9 +++-- drivers/gpu/drm/i915/i915_gem_userptr.c | 14 +- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 52b446b..a67b649 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2251,14 +2251,13 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) goto err_pages; } } -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { + if (swiotlb_in_use(obj->base.dev->dev)) { st->nents++; sg_set_page(sg, page, PAGE_SIZE, 0); sg = sg_next(sg); continue; } -#endif + if (!i || page_to_pfn(page) != last_pfn + 1) { if (i) sg = sg_next(sg); @@ -2272,9 +2271,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) /* Check that the i965g/gm workaround works. */ WARN_ON((gfp & __GFP_DMA32) && (last_pfn >= 0x0010UL)); } -#ifdef CONFIG_SWIOTLB - if (!swiotlb_nr_tbl()) -#endif + if (!swiotlb_in_use(obj->base.dev->dev)) sg_mark_end(sg); obj->pages = st; diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 8fd431b..ecf03b7 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -506,14 +506,9 @@ struct get_pages_work { struct task_struct *task; }; -#if IS_ENABLED(CONFIG_SWIOTLB) -#define swiotlb_active() swiotlb_nr_tbl() -#else -#define swiotlb_active() 0 -#endif - static int -st_set_pages(struct sg_table **st, struct page **pvec, int num_pages) +st_set_pages(struct device *dev, struct sg_table **st, +struct page **pvec, int num_pages) { struct scatterlist *sg; int ret, n; @@ -522,7 +517,7 @@ st_set_pages(struct sg_table **st, struct page **pvec, int num_pages) if (*st == NULL) return -ENOMEM; - if (swiotlb_active()) { + if (swiotlb_in_use(dev)) { ret = sg_alloc_table(*st, num_pages, GFP_KERNEL); if (ret) goto err; @@ -549,9 +544,10 @@ static int __i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj, struct page **pvec, int num_pages) { + struct device *dev = obj->base.dev->dev; int ret; - ret = st_set_pages(&obj->pages, pvec, num_pages); + ret = st_set_pages(dev, &obj->pages, pvec, num_pages); if (ret) return ret; -- 2.1.0
[PATCH 6/6] drm/amdgpu: Use swiotlb_in_use() to know if swiotlb is enabled.
From: Jérôme Glisse We can not rely on swiotlb_nr_tbl() to know if swiotlb is in use or not for our device. Use the new helper to determine that. Signed-off-by: Jérôme Glisse Cc: Konrad Rzeszutek Wilk Cc: Alex Deucher Cc: Ben Skeggs Cc: Dave Airlie Cc: lkml at vger.kernel.org Cc: Daniel Vetter --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 13 +++-- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index dd3415d..bb48fc5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -692,11 +691,9 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm) adev = amdgpu_get_adev(ttm->bdev); -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { + if (swiotlb_in_use(adev->dev)) { return ttm_dma_populate(>t->ttm, adev->dev); } -#endif r = ttm_pool_populate(ttm); if (r) { @@ -738,12 +735,10 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) adev = amdgpu_get_adev(ttm->bdev); -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { + if (swiotlb_in_use(adev->dev)) { ttm_dma_unpopulate(>t->ttm, adev->dev); return; } -#endif for (i = 0; i < ttm->num_pages; i++) { if (gtt->ttm.dma_address[i]) { @@ -1190,10 +1185,8 @@ static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev) count = ARRAY_SIZE(amdgpu_ttm_debugfs_list); -#ifdef CONFIG_SWIOTLB - if (!swiotlb_nr_tbl()) + if (!swiotlb_in_use(adev->dev)) --count; -#endif return amdgpu_debugfs_add_files(adev, amdgpu_ttm_debugfs_list, count); #else -- 2.1.0
[PATCH 4/6] drm/vmwgfx: Use swiotlb_in_use() to know if swiotlb is enabled.
From: Jérôme Glisse We can not rely on swiotlb_nr_tbl() to know if swiotlb is in use or not for our device. Use the new helper to determine that. Signed-off-by: Jérôme Glisse Cc: Konrad Rzeszutek Wilk Cc: Alex Deucher Cc: Ben Skeggs Cc: Dave Airlie Cc: lkml at vger.kernel.org Cc: Daniel Vetter --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 620bb5c..a2b0ec0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -517,10 +517,8 @@ static int vmw_dma_select_mode(struct vmw_private *dev_priv) if (dma_ops->sync_single_for_cpu) dev_priv->map_mode = vmw_dma_alloc_coherent; -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl() == 0) + if (!swiotlb_in_use(dev_priv->dev->dev)) dev_priv->map_mode = vmw_dma_map_populate; -#endif #ifdef CONFIG_INTEL_IOMMU out_fixup: -- 2.1.0
[PATCH 1/3] drm/radeon: fix indentation.
From: Jérome Glisse I hate doing this but it hurts my eyes to go over code that does not comply with indentation rules. Only thing that is not only space change is in atom.c all other files are space indentation issues. Signed-off-by: Jérôme Glisse Cc: Alex Deucher --- drivers/gpu/drm/radeon/atom.c | 7 +- drivers/gpu/drm/radeon/atombios_crtc.c | 6 +- drivers/gpu/drm/radeon/atombios_dp.c| 4 +- drivers/gpu/drm/radeon/btc_dpm.c| 41 +++--- drivers/gpu/drm/radeon/ci_dpm.c | 42 +++--- drivers/gpu/drm/radeon/ci_smc.c | 8 +- drivers/gpu/drm/radeon/cik.c| 6 +- drivers/gpu/drm/radeon/cypress_dpm.c| 8 +- drivers/gpu/drm/radeon/evergreen.c | 2 +- drivers/gpu/drm/radeon/evergreen_cs.c | 32 ++--- drivers/gpu/drm/radeon/evergreen_hdmi.c | 2 +- drivers/gpu/drm/radeon/kv_dpm.c | 4 +- drivers/gpu/drm/radeon/ni.c | 4 +- drivers/gpu/drm/radeon/ni_dpm.c | 170 drivers/gpu/drm/radeon/r600.c | 8 +- drivers/gpu/drm/radeon/r600_cs.c| 20 +-- drivers/gpu/drm/radeon/r600_dpm.c | 6 +- drivers/gpu/drm/radeon/r600_hdmi.c | 4 +- drivers/gpu/drm/radeon/radeon_atombios.c| 6 +- drivers/gpu/drm/radeon/radeon_device.c | 8 +- drivers/gpu/drm/radeon/radeon_display.c | 6 +- drivers/gpu/drm/radeon/radeon_fb.c | 6 +- drivers/gpu/drm/radeon/radeon_ib.c | 4 +- drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 92 ++--- drivers/gpu/drm/radeon/radeon_object.c | 6 +- drivers/gpu/drm/radeon/radeon_pm.c | 2 +- drivers/gpu/drm/radeon/radeon_semaphore.c | 4 +- drivers/gpu/drm/radeon/radeon_uvd.c | 8 +- drivers/gpu/drm/radeon/radeon_vce.c | 22 +-- drivers/gpu/drm/radeon/radeon_vm.c | 19 +-- drivers/gpu/drm/radeon/rs780_dpm.c | 2 +- drivers/gpu/drm/radeon/rv6xx_dpm.c | 18 +-- drivers/gpu/drm/radeon/rv740_dpm.c | 16 +-- drivers/gpu/drm/radeon/rv770_dpm.c | 46 +++ drivers/gpu/drm/radeon/si.c | 44 +++--- drivers/gpu/drm/radeon/si_dpm.c | 98 +++--- drivers/gpu/drm/radeon/sumo_dpm.c | 6 +- drivers/gpu/drm/radeon/trinity_dpm.c| 24 ++-- drivers/gpu/drm/radeon/vce_v2_0.c | 2 +- 39 files changed, 407 insertions(+), 406 deletions(-) diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index ec1593a..f66c33d 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -66,9 +66,10 @@ int atom_debug = 0; static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); -static uint32_t atom_arg_mask[8] = -{ 0x, 0x, 0x00, 0x, 0xFF, 0xFF00, 0xFF, -0xFF00 }; +static uint32_t atom_arg_mask[8] = { + 0x, 0x, 0x0000, 0x, + 0x00FF, 0xFF00, 0x00FF, 0xFF00 +}; static int atom_arg_shift[8] = { 0, 0, 8, 16, 0, 8, 16, 24 }; static int atom_dst_to_src[8][4] = { diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index e187bec..cf61e08 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1665,11 +1665,11 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, } int atombios_crtc_set_base_atomic(struct drm_crtc *crtc, - struct drm_framebuffer *fb, + struct drm_framebuffer *fb, int x, int y, enum mode_set_atomic state) { - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; if (ASIC_IS_DCE4(rdev)) return dce4_crtc_do_set_base(crtc, fb, x, y, 1); diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 44ee72e..ae1ab4d 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -37,10 +37,10 @@ #define DP_DPCD_SIZE DP_RECEIVER_CAP_SIZE static char *voltage_names[] = { -"0.4V", "0.6V", "0.8V", "1.2V" + "0.4V", "0.6V", "0.8V", "1.2V" }; static char *pre_emph_names[] = { -"0dB", "3.5dB", "6dB", "9.5dB" + "0dB", "3.5dB", "6dB", "9.5dB" }; /* radeon AUX functions */ diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 69556f5..38e5123 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +
[PATCH 2/3] drm/radeon: add driver option to disable uvd/vce block.
From: Jérome Glisse Quite few suspend/hibernation bugs are related to this block. Add an option to disable those as a work around. Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_asic.c | 3 +++ drivers/gpu/drm/radeon/radeon_drv.c | 4 3 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 007be29..5c6ce3a 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -113,6 +113,7 @@ extern int radeon_bapm; extern int radeon_backlight; extern int radeon_auxch; extern int radeon_mst; +extern int radeon_uvd; /* * Copy from radeon_drv.h so we don't have to include both and have conflicting diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 7d5a36d..49ee180 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2689,6 +2689,9 @@ int radeon_asic_init(struct radeon_device *rdev) rdev->asic->pm.set_memory_clock = NULL; } + if (!radeon_uvd) + rdev->has_uvd = false; + return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index cad2555..03e4781 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -196,6 +196,7 @@ int radeon_bapm = -1; int radeon_backlight = -1; int radeon_auxch = -1; int radeon_mst = 0; +int radeon_uvd = 1; MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); module_param_named(no_wb, radeon_no_wb, int, 0444); @@ -287,6 +288,9 @@ module_param_named(auxch, radeon_auxch, int, 0444); MODULE_PARM_DESC(mst, "DisplayPort MST experimental support (1 = enable, 0 = disable)"); module_param_named(mst, radeon_mst, int, 0444); +MODULE_PARM_DESC(uvd, "uvd/vce enable/disable uvd/vce support (1 = enable, 0 = disable)"); +module_param_named(uvd, radeon_uvd, int, 0444); + static struct pci_device_id pciidlist[] = { radeon_PCI_IDS }; -- 1.8.3.1
[PATCH 3/3] drm/radeon: uvd/vce properly pin/unpin firmware accross suspend/resume.
From: Jérome Glisse We need to unpin on suspend and pin on resume. This shuffle code around to do just that. Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König --- drivers/gpu/drm/radeon/radeon_uvd.c | 61 - drivers/gpu/drm/radeon/radeon_vce.c | 37 +- 2 files changed, 41 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 6fe9e4e..333b885 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -148,30 +148,6 @@ int radeon_uvd_init(struct radeon_device *rdev) return r; } - r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false); - if (r) { - radeon_bo_unref(&rdev->uvd.vcpu_bo); - dev_err(rdev->dev, "(%d) failed to reserve UVD bo\n", r); - return r; - } - - r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, - &rdev->uvd.gpu_addr); - if (r) { - radeon_bo_unreserve(rdev->uvd.vcpu_bo); - radeon_bo_unref(&rdev->uvd.vcpu_bo); - dev_err(rdev->dev, "(%d) UVD bo pin failed\n", r); - return r; - } - - r = radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr); - if (r) { - dev_err(rdev->dev, "(%d) UVD map failed\n", r); - return r; - } - - radeon_bo_unreserve(rdev->uvd.vcpu_bo); - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { atomic_set(&rdev->uvd.handles[i], 0); rdev->uvd.filp[i] = NULL; @@ -183,18 +159,9 @@ int radeon_uvd_init(struct radeon_device *rdev) void radeon_uvd_fini(struct radeon_device *rdev) { - int r; - if (rdev->uvd.vcpu_bo == NULL) return; - r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false); - if (!r) { - radeon_bo_kunmap(rdev->uvd.vcpu_bo); - radeon_bo_unpin(rdev->uvd.vcpu_bo); - radeon_bo_unreserve(rdev->uvd.vcpu_bo); - } - radeon_bo_unref(&rdev->uvd.vcpu_bo); radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX]); @@ -231,6 +198,13 @@ int radeon_uvd_suspend(struct radeon_device *rdev) } } + r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false); + if (!r) { + radeon_bo_kunmap(rdev->uvd.vcpu_bo); + radeon_bo_unpin(rdev->uvd.vcpu_bo); + radeon_bo_unreserve(rdev->uvd.vcpu_bo); + } + return 0; } @@ -238,9 +212,26 @@ int radeon_uvd_resume(struct radeon_device *rdev) { unsigned size; void *ptr; + int r; - if (rdev->uvd.vcpu_bo == NULL) - return -EINVAL; + r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false); + if (r) { + dev_err(rdev->dev, "(%d) failed to reserve UVD bo\n", r); + return r; + } + r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, + &rdev->uvd.gpu_addr); + if (r) { + radeon_bo_unreserve(rdev->uvd.vcpu_bo); + dev_err(rdev->dev, "(%d) UVD bo pin failed\n", r); + return r; + } + r = radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr); + radeon_bo_unreserve(rdev->uvd.vcpu_bo); + if (r) { + dev_err(rdev->dev, "(%d) UVD map failed\n", r); + return r; + } memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c index c1c619f..4f7ae3c 100644 --- a/drivers/gpu/drm/radeon/radeon_vce.c +++ b/drivers/gpu/drm/radeon/radeon_vce.c @@ -147,22 +147,6 @@ int radeon_vce_init(struct radeon_device *rdev) return r; } - r = radeon_bo_reserve(rdev->vce.vcpu_bo, false); - if (r) { - radeon_bo_unref(&rdev->vce.vcpu_bo); - dev_err(rdev->dev, "(%d) failed to reserve VCE bo\n", r); - return r; - } - - r = radeon_bo_pin(rdev->vce.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, - &rdev->vce.gpu_addr); - radeon_bo_unreserve(rdev->vce.vcpu_bo); - if (r) { - radeon_bo_unref(&rdev->vce.vcpu_bo); - dev_err(rdev->dev, "(%d) VCE bo pin failed\n", r); - return r; - } - for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) { atomic_set(&rdev->vce.handles[i], 0); rdev->vce.filp[i] = NULL; @@ -196,7 +180,7 @@ void radeon_vce_fini(struct radeon_device *rdev) */ int radeon_vce_suspend(struct radeon_device *rdev) { - int i; + int i, r; if (rdev->vce.vcpu_bo == NULL) return 0; @@ -209,6 +193,13 @@ int radeon_vce_suspend(struct radeon_device *rdev) return 0; /* TODO: suspending runni
[PATCH] drm/radeon/kms: forbid allocating bo bigger than VRAM or GTT (fdo 31708)
From: Jerome Glisse Forbid allocating buffer bigger than VRAM or GTT, also properly set lpfn field of placement if VRAM is too small. Signed-off-by: Jerome Glisse --- drivers/gpu/drm/radeon/radeon.h|2 +- drivers/gpu/drm/radeon/radeon_object.c | 19 ++- drivers/gpu/drm/radeon/radeon_ttm.c|6 +++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 73f600d..2068cf4 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1361,7 +1361,7 @@ extern void radeon_surface_init(struct radeon_device *rdev); extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); -extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain); +extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain, u32 size); extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo); extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 8eb1834..a09d076 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -64,12 +64,18 @@ bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo) return false; } -void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) +void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain, u32 size) { u32 c = 0; rbo->placement.fpfn = 0; rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; + /* size bigger than vram directly fallback to GTT*/ + if (size >= rbo->rdev->mc.active_vram_size) { + rbo->placement.lpfn = rbo->rdev->mc.gtt_size >> PAGE_SHIFT; + if (!(domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_CPU))) + domain |= RADEON_GEM_DOMAIN_GTT; + } rbo->placement.placement = rbo->placements; rbo->placement.busy_placement = rbo->placements; if (domain & RADEON_GEM_DOMAIN_VRAM) @@ -102,6 +108,9 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, type = ttm_bo_type_device; } *bo_ptr = NULL; + if (size >= rdev->mc.active_vram_size && size >= rdev->mc.gtt_size) { + return -ENOMEM; + } retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); @@ -111,7 +120,7 @@ retry: bo->gobj = gobj; bo->surface_reg = -1; INIT_LIST_HEAD(&bo->list); - radeon_ttm_placement_from_domain(bo, domain); + radeon_ttm_placement_from_domain(bo, domain, size); /* Kernel allocation are uninterruptible */ mutex_lock(&rdev->vram_mutex); r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, @@ -197,7 +206,7 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) *gpu_addr = radeon_bo_gpu_offset(bo); return 0; } - radeon_ttm_placement_from_domain(bo, domain); + radeon_ttm_placement_from_domain(bo, domain, bo->tbo.num_pages << PAGE_SHIFT); if (domain == RADEON_GEM_DOMAIN_VRAM) { /* force to pin into visible video ram */ bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT; @@ -343,7 +352,7 @@ int radeon_bo_list_validate(struct list_head *head) domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain; retry: - radeon_ttm_placement_from_domain(bo, domain); + radeon_ttm_placement_from_domain(bo, domain, bo->tbo.num_pages << PAGE_SHIFT); r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false, false); if (unlikely(r)) { @@ -535,7 +544,7 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) offset = bo->mem.start << PAGE_SHIFT; if ((offset + size) > rdev->mc.visible_vram_size) { /* hurrah the memory is not visible ! */ - radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM); + radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM, bo->num_pages << PAGE_SHIFT); rbo->placement.lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT; r = ttm_bo_validate(bo, &rbo->placement, false, true, false); if (unlikely(r != 0)) diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/dri
[PATCH] drm/radeon/kms: forbid big bo allocation (fdo 31708)
From: Jerome Glisse Forbid allocating buffer bigger than visible VRAM or GTT, also properly set lpfn field. Signed-off-by: Jerome Glisse --- drivers/gpu/drm/radeon/radeon_object.c | 36 ++- 1 files changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1d06774..7ce31be 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -64,23 +64,35 @@ bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo) return false; } +#define MAX(a,b) (((a)>(b))?(a):(b)) + void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) { u32 c = 0; rbo->placement.fpfn = 0; - rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; + rbo->placement.lpfn = 0; rbo->placement.placement = rbo->placements; rbo->placement.busy_placement = rbo->placements; - if (domain & RADEON_GEM_DOMAIN_VRAM) + if (domain & RADEON_GEM_DOMAIN_VRAM) { + rbo->placement.lpfn = MAX(rbo->placement.lpfn, rbo->rdev->mc.active_vram_size >> PAGE_SHIFT); rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM; - if (domain & RADEON_GEM_DOMAIN_GTT) + } + if (domain & RADEON_GEM_DOMAIN_GTT) { + rbo->placement.lpfn = MAX(rbo->placement.lpfn, rbo->rdev->mc.gtt_size >> PAGE_SHIFT); rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; - if (domain & RADEON_GEM_DOMAIN_CPU) + } + if (domain & RADEON_GEM_DOMAIN_CPU) { + /* 4G limit for CPU domain */ + rbo->placement.lpfn = MAX(rbo->placement.lpfn, 0x >> PAGE_SHIFT); rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; - if (!c) + } + if (!c) { + /* 4G limit for CPU domain */ + rbo->placement.lpfn = MAX(rbo->placement.lpfn, 0x >> PAGE_SHIFT); rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; + } rbo->placement.num_placement = c; rbo->placement.num_busy_placement = c; } @@ -91,7 +103,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, { struct radeon_bo *bo; enum ttm_bo_type type; - int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; + unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; + unsigned long max_size = 0; int r; if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { @@ -104,6 +117,17 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, } *bo_ptr = NULL; + /* maximun bo size is the minimun btw visible vram and gtt size */ + max_size = rdev->mc.visible_vram_size; + if (max_size > rdev->mc.gtt_size) { + max_size = rdev->mc.gtt_size; + } + if ((page_align << PAGE_SHIFT) >= max_size) { + printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", + __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); + return -ENOMEM; + } + retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); if (bo == NULL) -- 1.7.3.2
[PATCH] drm/radeon/kms: forbid big bo allocation (fdo 31708) v2
From: Jerome Glisse Forbid allocating buffer bigger than visible VRAM or GTT, also properly set lpfn field. v2 - use max macro - silence warning Signed-off-by: Jerome Glisse --- drivers/gpu/drm/radeon/radeon_object.c | 34 ++- 1 files changed, 28 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1d06774..c2fa64c 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -69,18 +69,28 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) u32 c = 0; rbo->placement.fpfn = 0; - rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; + rbo->placement.lpfn = 0; rbo->placement.placement = rbo->placements; rbo->placement.busy_placement = rbo->placements; - if (domain & RADEON_GEM_DOMAIN_VRAM) + if (domain & RADEON_GEM_DOMAIN_VRAM) { + rbo->placement.lpfn = max((unsigned)rbo->placement.lpfn, (unsigned)rbo->rdev->mc.active_vram_size >> PAGE_SHIFT); rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM; - if (domain & RADEON_GEM_DOMAIN_GTT) + } + if (domain & RADEON_GEM_DOMAIN_GTT) { + rbo->placement.lpfn = max((unsigned)rbo->placement.lpfn, (unsigned)rbo->rdev->mc.gtt_size >> PAGE_SHIFT); rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; - if (domain & RADEON_GEM_DOMAIN_CPU) + } + if (domain & RADEON_GEM_DOMAIN_CPU) { + /* 4G limit for CPU domain */ + rbo->placement.lpfn = max(rbo->placement.lpfn, 0x >> PAGE_SHIFT); rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; - if (!c) + } + if (!c) { + /* 4G limit for CPU domain */ + rbo->placement.lpfn = max(rbo->placement.lpfn, 0x >> PAGE_SHIFT); rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; + } rbo->placement.num_placement = c; rbo->placement.num_busy_placement = c; } @@ -91,7 +101,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, { struct radeon_bo *bo; enum ttm_bo_type type; - int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; + unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; + unsigned long max_size = 0; int r; if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { @@ -104,6 +115,17 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, } *bo_ptr = NULL; + /* maximun bo size is the minimun btw visible vram and gtt size */ + max_size = rdev->mc.visible_vram_size; + if (max_size > rdev->mc.gtt_size) { + max_size = rdev->mc.gtt_size; + } + if ((page_align << PAGE_SHIFT) >= max_size) { + printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", + __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); + return -ENOMEM; + } + retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); if (bo == NULL) -- 1.7.3.2
[PATCH] drm/radeon/kms: fix GTT/VRAM overlapping test
From: Jerome Glisse GTT/VRAM overlapping test had a typo which leaded to not detecting case when vram_end > gtt_end. This patch fix the logic and should fix #16574 cc: stable Signed-off-by: Jerome Glisse --- drivers/gpu/drm/radeon/radeon_device.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 4f7a170..69b3c22 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -199,7 +199,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 mc->mc_vram_size = mc->aper_size; } mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; - if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_end <= mc->gtt_end) { + if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_start <= mc->gtt_end) { dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); mc->real_vram_size = mc->aper_size; mc->mc_vram_size = mc->aper_size; -- 1.7.1
[PATCH] drm/radeon/kms: r6xx/r7xx flush shader cache at fence emision
From: Jerome Glisse GPU is prone to lockup if we deallocate shader bo right after submitting command using the shader. Force shader cache flush after each batch submission seems to fix the issue. It could fix some of the lockup people were experiencing. Signed-off-by: Jerome Glisse --- drivers/gpu/drm/radeon/r600.c |7 +++ drivers/gpu/drm/radeon/r600_blit_kms.c |2 +- 2 files changed, 8 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index d0ebae9..4076443 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2335,6 +2335,13 @@ void r600_fence_ring_emit(struct radeon_device *rdev, { /* Also consider EVENT_WRITE_EOP. it handles the interrupts + timestamps + events */ + /* flush shader */ + radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); + radeon_ring_write(rdev, PACKET3_SH_ACTION_ENA); + radeon_ring_write(rdev, 0x); + radeon_ring_write(rdev, 0x); + radeon_ring_write(rdev, 10); + radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT); /* wait for 3D idle clean */ diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index d13622a..0efba07 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -581,7 +581,7 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) ring_size += 40; /* shaders + def state */ ring_size += 10; /* fence emit for VB IB */ ring_size += 5; /* done copy */ - ring_size += 10; /* fence emit for done copy */ + ring_size += 15; /* fence emit for done copy */ r = radeon_ring_lock(rdev, ring_size); if (r) return r; -- 1.7.2.1
[PATCH] drm/radeon/kms: r6xx/r7xx flush shader cache at fence emision V2
From: Jerome Glisse GPU is prone to lockup if we deallocate shader bo right after submitting command using the shader. Force shader cache flush after each batch submission seems to fix the issue. It could fix some of the lockup people were experiencing. V2 move shader flush after pipeline flush it seems to be more reliable that way (ie if userspace didn't submit a flush pipeline at end of its command buffer we might still lockup while moving shader flush after fence flush pipeline seems to prevent this). Signed-off-by: Jerome Glisse --- drivers/gpu/drm/radeon/r600.c |6 ++ drivers/gpu/drm/radeon/r600_blit_kms.c |2 +- 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index d0ebae9..eab8de0 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2337,6 +2337,12 @@ void r600_fence_ring_emit(struct radeon_device *rdev, radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT); + /* flush shader */ + radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); + radeon_ring_write(rdev, PACKET3_SH_ACTION_ENA); + radeon_ring_write(rdev, 0x); + radeon_ring_write(rdev, 0x); + radeon_ring_write(rdev, 10); /* wait for 3D idle clean */ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index d13622a..0efba07 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -581,7 +581,7 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) ring_size += 40; /* shaders + def state */ ring_size += 10; /* fence emit for VB IB */ ring_size += 5; /* done copy */ - ring_size += 10; /* fence emit for done copy */ + ring_size += 15; /* fence emit for done copy */ r = radeon_ring_lock(rdev, ring_size); if (r) return r; -- 1.7.2.2
[PATCH] drm/radeon/kms: forbid big bo allocation (fdo 31708) v3
From: Jerome Glisse Forbid allocating buffer bigger than visible VRAM or GTT, also properly set lpfn field. v2 - use max macro - silence warning v3 - don't explicitly set range limit - use min macro Cc: stable Signed-off-by: Jerome Glisse --- drivers/gpu/drm/radeon/radeon_object.c | 13 +++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1d06774..a598d00 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -69,7 +69,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) u32 c = 0; rbo->placement.fpfn = 0; - rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; + rbo->placement.lpfn = 0; rbo->placement.placement = rbo->placements; rbo->placement.busy_placement = rbo->placements; if (domain & RADEON_GEM_DOMAIN_VRAM) @@ -91,7 +91,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, { struct radeon_bo *bo; enum ttm_bo_type type; - int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; + unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; + unsigned long max_size = 0; int r; if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { @@ -104,6 +105,14 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, } *bo_ptr = NULL; + /* maximun bo size is the minimun btw visible vram and gtt size */ + max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); + if ((page_align << PAGE_SHIFT) >= max_size) { + printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", + __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); + return -ENOMEM; + } + retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); if (bo == NULL) -- 1.7.3.2
[PATCH] drm/radeon/kms: forbid big bo allocation (fdo 31708) v4
From: Jerome Glisse Forbid allocating buffer bigger than visible VRAM or GTT, also properly set lpfn field. v2 - use max macro - silence warning v3 - don't explicitly set range limit - use min macro v4 - use max btw GTT & VRAM size Cc: stable Signed-off-by: Jerome Glisse --- drivers/gpu/drm/radeon/radeon_object.c | 13 +++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1d06774..2011e00 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -69,7 +69,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) u32 c = 0; rbo->placement.fpfn = 0; - rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; + rbo->placement.lpfn = 0; rbo->placement.placement = rbo->placements; rbo->placement.busy_placement = rbo->placements; if (domain & RADEON_GEM_DOMAIN_VRAM) @@ -91,7 +91,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, { struct radeon_bo *bo; enum ttm_bo_type type; - int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; + unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; + unsigned long max_size; int r; if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { @@ -104,6 +105,14 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, } *bo_ptr = NULL; + /* maximun bo size is the max btw visible vram and gtt size */ + max_size = max(rdev->mc.visible_vram_size, rdev->mc.gtt_size); + if ((page_align << PAGE_SHIFT) >= max_size) { + printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", + __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); + return -ENOMEM; + } + retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); if (bo == NULL) -- 1.7.1
[PATCH] radeon/kms: fix dp displayport mode validation
From: Jerome Glisse Check if there is a big enough dp clock & enough dp lane to drive the video mode provided. Signed-off-by: Jerome Glisse Cc: --- drivers/gpu/drm/radeon/atombios_dp.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 4e7778d..695de9a 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -187,9 +187,9 @@ static int dp_link_clock_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock) int dp_mode_valid(u8 dpcd[DP_DPCD_SIZE], int mode_clock) { int lanes = dp_lanes_for_mode_clock(dpcd, mode_clock); - int bw = dp_lanes_for_mode_clock(dpcd, mode_clock); + int dp_clock = dp_link_clock_for_mode_clock(dpcd, mode_clock); - if ((lanes == 0) || (bw == 0)) + if ((lanes == 0) || (dp_clock == 0)) return MODE_CLOCK_HIGH; return MODE_OK; -- 1.7.3.2