drm/i915/gvt: Use vgpu_lock to protect per vgpu access
The patch set splits out 2 small locks from the original big gvt lock: - vgpu_lock protects per-vGPU data and logic, especially the vGPU trap emulation path. - sched_lock protects gvt scheudler structure, context schedule logic and vGPU's schedule data. Use vgpu_lock to replace the gvt big lock. By doing this, the mmio read/write trap path, vgpu virtual event emulation and other vgpu related process, would be protected under per vgpu_lock. v9: - Change commit author since the patches are improved a lot compared with original version. Original author: Pei Zhang <pei.zhang@intel.com> - Rebase to latest gvt-staging. v8: - Correct coding and comment style. - Rebase to latest gvt-staging. v7: - Remove gtt_lock since already proteced by gvt_lock and vgpu_lock. - Fix a typo in intel_gvt_deactivate_vgpu, unlock the wrong lock. v6: - Rebase to latest gvt-staging. v5: - Rebase to latest gvt-staging. - intel_vgpu_page_track_handler should use vgpu_lock. v4: - Rebase to latest gvt-staging. - Protect vgpu->active access with vgpu_lock. - Do not wait gpu idle in vgpu_lock. v3: update to latest code base v2: add gvt->lock in function gvt_check_vblank_emulation Performance comparison on Kabylake platform. - Configuration: Host: Ubuntu 16.04. Guest 1 & 2: Ubuntu 16.04. glmark2 score comparison: - Configuration: Host: glxgears. Guests: glmark2. +--------------------------------+-----------------+ | Setup | glmark2 score | +--------------------------------+-----------------+ | unified lock, iommu=on | 58~62 (avg. 60) | +--------------------------------+-----------------+ | unified lock, iommu=igfx_off | 57~61 (avg. 59) | +--------------------------------+-----------------+ | per-logic lock, iommu=on | 60~68 (avg. 64) | +--------------------------------+-----------------+ | per-logic lock, iommu=igfx_off | 61~67 (avg. 64) | +--------------------------------+-----------------+ lock_stat comparison: - Configuration: Stop lock stat immediately after boot up. Boot 2 VM Guests. Run glmark2 in guests. Start perf lock_stat for 20 seconds and stop again. - Legend: c - contentions; w - waittime-avg +------------+-----------------+-----------+---------------+------------+ | | gvt_lock |sched_lock | vgpu_lock | gtt_lock | + lock type; +-----------------+-----------+---------------+------------+ | iommu set | c | w | c | w | c | w | c | w | +------------+-------+---------+----+------+------+--------+-----+------+ | unified; | 20697 | 839 |N/A | N/A | N/A | N/A | N/A | N/A | | on | | | | | | | | | +------------+-------+---------+----+------+------+--------+-----+------+ | unified; | 21838 | 658.15 |N/A | N/A | N/A | N/A | N/A | N/A | | igfx_off | | | | | | | | | +------------+-------+---------+----+------+------+--------+-----+------+ | per-logic; | 1553 | 1599.96 |9458|429.97| 5846 | 274.33 | 0 | 0.00 | | on | | | | | | | | | +------------+-------+---------+----+------+------+--------+-----+------+ | per-logic; | 1911 | 1678.32 |8335|445.16| 5451 | 244.80 | 0 | 0.00 | | igfx_off | | | | | | | | | +------------+-------+---------+----+------+------+--------+-----+------+ Signed-off-by: Pei Zhang <pei.zhang@intel.com> Signed-off-by: Colin Xu <colin.xu@intel.com> Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
This commit is contained in:
@@ -680,6 +680,7 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
|
||||
gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n",
|
||||
ring_id, workload);
|
||||
|
||||
mutex_lock(&vgpu->vgpu_lock);
|
||||
mutex_lock(&dev_priv->drm.struct_mutex);
|
||||
|
||||
ret = intel_gvt_scan_and_shadow_workload(workload);
|
||||
@@ -704,6 +705,7 @@ out:
|
||||
}
|
||||
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
mutex_unlock(&vgpu->vgpu_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -861,14 +863,14 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
|
||||
int event;
|
||||
|
||||
mutex_lock(&gvt->lock);
|
||||
mutex_lock(&vgpu->vgpu_lock);
|
||||
|
||||
/* For the workload w/ request, needs to wait for the context
|
||||
* switch to make sure request is completed.
|
||||
* For the workload w/o request, directly complete the workload.
|
||||
*/
|
||||
if (workload->req) {
|
||||
struct drm_i915_private *dev_priv =
|
||||
workload->vgpu->gvt->dev_priv;
|
||||
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
|
||||
struct intel_engine_cs *engine =
|
||||
dev_priv->engine[workload->ring_id];
|
||||
wait_event(workload->shadow_ctx_status_wq,
|
||||
@@ -939,6 +941,7 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
|
||||
if (gvt->scheduler.need_reschedule)
|
||||
intel_gvt_request_service(gvt, INTEL_GVT_REQUEST_EVENT_SCHED);
|
||||
|
||||
mutex_unlock(&vgpu->vgpu_lock);
|
||||
mutex_unlock(&gvt->lock);
|
||||
}
|
||||
|
||||
@@ -991,9 +994,7 @@ static int workload_thread(void *priv)
|
||||
intel_uncore_forcewake_get(gvt->dev_priv,
|
||||
FORCEWAKE_ALL);
|
||||
|
||||
mutex_lock(&gvt->lock);
|
||||
ret = dispatch_workload(workload);
|
||||
mutex_unlock(&gvt->lock);
|
||||
|
||||
if (ret) {
|
||||
vgpu = workload->vgpu;
|
||||
|
Reference in New Issue
Block a user