aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/gvt/aperture_gm.c
diff options
context:
space:
mode:
authorChangbin Du <changbin.du@intel.com>2017-09-04 16:01:01 +0800
committerChris Wilson <chris@chris-wilson.co.uk>2017-09-04 16:34:59 +0100
commit969b0950a188750bd6ad12693fa3b6e8d63036fb (patch)
tree18116cf70133b8d53756092c05e08b3a0d49d2dd /drivers/gpu/drm/i915/gvt/aperture_gm.c
parentdrm/i915: Use correct path to trace include (diff)
downloadlinux-dev-969b0950a188750bd6ad12693fa3b6e8d63036fb.tar.xz
linux-dev-969b0950a188750bd6ad12693fa3b6e8d63036fb.zip
drm/i915: Add interface to reserve fence registers for vGPU
In the past, vGPU alloc fence registers by walking through mm.fence_list to find fence which pin_count = 0 and vma is empty. vGPU may not find enough fence registers this way. Because a fence can be bind to vma even though it is not in using. We have found such failure many times these days. An option to resolve this issue is that we can force-remove fence from vma in this case. This patch added two new api to the fence management code: - i915_reserve_fence() will try to find a free fence from fence_list and force-remove vma if need. - i915_unreserve_fence() reclaim a reserved fence after vGPU has finished. With this change, the fence management is more clear to work with vGPU. GVTg do not need remove fence from fence_list in private. v3: (Chris) - Add struct_mutex lock assertion. - Only count for unpinned fence. v2: (Chris) - Rename the new api for symmetry. - Add safeguard to ensure at least 1 fence remained for host display. Signed-off-by: Changbin Du <changbin.du@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/1504512061-5892-1-git-send-email-changbin.du@intel.com Acked-by: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/gvt/aperture_gm.c')
-rw-r--r--drivers/gpu/drm/i915/gvt/aperture_gm.c26
1 files changed, 11 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c
index ca3d1925beda..7c9ec4f4f36c 100644
--- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
+++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
@@ -173,8 +173,8 @@ static void free_vgpu_fence(struct intel_vgpu *vgpu)
_clear_vgpu_fence(vgpu);
for (i = 0; i < vgpu_fence_sz(vgpu); i++) {
reg = vgpu->fence.regs[i];
- list_add_tail(&reg->link,
- &dev_priv->mm.fence_list);
+ i915_unreserve_fence(reg);
+ vgpu->fence.regs[i] = NULL;
}
mutex_unlock(&dev_priv->drm.struct_mutex);
@@ -187,24 +187,19 @@ static int alloc_vgpu_fence(struct intel_vgpu *vgpu)
struct drm_i915_private *dev_priv = gvt->dev_priv;
struct drm_i915_fence_reg *reg;
int i;
- struct list_head *pos, *q;
intel_runtime_pm_get(dev_priv);
/* Request fences from host */
mutex_lock(&dev_priv->drm.struct_mutex);
- i = 0;
- list_for_each_safe(pos, q, &dev_priv->mm.fence_list) {
- reg = list_entry(pos, struct drm_i915_fence_reg, link);
- if (reg->pin_count || reg->vma)
- continue;
- list_del(pos);
+
+ for (i = 0; i < vgpu_fence_sz(vgpu); i++) {
+ reg = i915_reserve_fence(dev_priv);
+ if (IS_ERR(reg))
+ goto out_free_fence;
+
vgpu->fence.regs[i] = reg;
- if (++i == vgpu_fence_sz(vgpu))
- break;
}
- if (i != vgpu_fence_sz(vgpu))
- goto out_free_fence;
_clear_vgpu_fence(vgpu);
@@ -212,13 +207,14 @@ static int alloc_vgpu_fence(struct intel_vgpu *vgpu)
intel_runtime_pm_put(dev_priv);
return 0;
out_free_fence:
+ gvt_vgpu_err("Failed to alloc fences\n");
/* Return fences to host, if fail */
for (i = 0; i < vgpu_fence_sz(vgpu); i++) {
reg = vgpu->fence.regs[i];
if (!reg)
continue;
- list_add_tail(&reg->link,
- &dev_priv->mm.fence_list);
+ i915_unreserve_fence(reg);
+ vgpu->fence.regs[i] = NULL;
}
mutex_unlock(&dev_priv->drm.struct_mutex);
intel_runtime_pm_put(dev_priv);