Skip to content

Commit

Permalink
drm/i915/gvt: vGPU workload scheduler
Browse files Browse the repository at this point in the history
This patch introduces the vGPU workload scheduler routines.

GVT workload scheduler is responsible for picking and executing GVT workload
from current scheduled vGPU. Before the workload is submitted to host i915,
the guest execlist context will be shadowed in the host GVT shadow context.
the instructions in guest ring buffer will be copied into GVT shadow ring
buffer. Then GVT-g workload scheduler will scan the instructions in guest
ring buffer and submit it to host i915.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
  • Loading branch information
Zhi Wang authored and Zhenyu Wang committed Oct 14, 2016
1 parent 28c4c6c commit e473405
Show file tree
Hide file tree
Showing 10 changed files with 661 additions and 8 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/gvt/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
GVT_DIR := gvt
GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o
execlist.o scheduler.o

ccflags-y += -I$(src) -I$(src)/$(GVT_DIR) -Wall
i915-y += $(addprefix $(GVT_DIR)/, $(GVT_SOURCE))
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/gvt/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,7 @@
#define gvt_dbg_el(fmt, args...) \
DRM_DEBUG_DRIVER("gvt: el: "fmt, ##args)

#define gvt_dbg_sched(fmt, args...) \
DRM_DEBUG_DRIVER("gvt: sched: "fmt, ##args)

#endif
24 changes: 23 additions & 1 deletion drivers/gpu/drm/i915/gvt/execlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ static int complete_execlist_workload(struct intel_vgpu_workload *workload)
gvt_dbg_el("complete workload %p status %d\n", workload,
workload->status);

if (workload->status)
if (workload->status || vgpu->resetting)
goto out;

if (!list_empty(workload_q_head(vgpu, workload->ring_id))) {
Expand Down Expand Up @@ -672,3 +672,25 @@ int intel_vgpu_init_execlist(struct intel_vgpu *vgpu)

return 0;
}

void intel_vgpu_reset_execlist(struct intel_vgpu *vgpu,
unsigned long ring_bitmap)
{
int bit;
struct list_head *pos, *n;
struct intel_vgpu_workload *workload = NULL;

for_each_set_bit(bit, &ring_bitmap, sizeof(ring_bitmap) * 8) {
if (bit >= I915_NUM_ENGINES)
break;
/* free the unsubmited workload in the queue */
list_for_each_safe(pos, n, &vgpu->workload_q_head[bit]) {
workload = container_of(pos,
struct intel_vgpu_workload, list);
list_del_init(&workload->list);
free_workload(workload);
}

init_vgpu_execlist(vgpu, bit);
}
}
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/gvt/execlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,7 @@ int intel_vgpu_init_execlist(struct intel_vgpu *vgpu);

int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id);

void intel_vgpu_reset_execlist(struct intel_vgpu *vgpu,
unsigned long ring_bitmap);

#endif /*_GVT_EXECLIST_H_*/
9 changes: 8 additions & 1 deletion drivers/gpu/drm/i915/gvt/gvt.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
return;

clean_service_thread(gvt);
intel_gvt_clean_workload_scheduler(gvt);
intel_gvt_clean_opregion(gvt);
intel_gvt_clean_gtt(gvt);
intel_gvt_clean_irq(gvt);
Expand Down Expand Up @@ -239,14 +240,20 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
if (ret)
goto out_clean_gtt;

ret = init_service_thread(gvt);
ret = intel_gvt_init_workload_scheduler(gvt);
if (ret)
goto out_clean_opregion;

ret = init_service_thread(gvt);
if (ret)
goto out_clean_workload_scheduler;

gvt_dbg_core("gvt device creation is done\n");
gvt->initialized = true;
return 0;

out_clean_workload_scheduler:
intel_gvt_clean_workload_scheduler(gvt);
out_clean_opregion:
intel_gvt_clean_opregion(gvt);
out_clean_gtt:
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/gvt/gvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ struct intel_vgpu {
struct intel_vgpu_execlist execlist[I915_NUM_ENGINES];
struct list_head workload_q_head[I915_NUM_ENGINES];
struct kmem_cache *workloads;
atomic_t running_workload_num;
struct i915_gem_context *shadow_ctx;
struct notifier_block shadow_ctx_notifier_block;
};

struct intel_gvt_gm {
Expand Down
25 changes: 23 additions & 2 deletions drivers/gpu/drm/i915/gvt/handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,32 @@ static int mul_force_wake_write(struct intel_vgpu *vgpu,
return 0;
}

static int handle_device_reset(struct intel_vgpu *vgpu, unsigned int offset,
void *p_data, unsigned int bytes, unsigned long bitmap)
{
struct intel_gvt_workload_scheduler *scheduler =
&vgpu->gvt->scheduler;

vgpu->resetting = true;

if (scheduler->current_vgpu == vgpu) {
mutex_unlock(&vgpu->gvt->lock);
intel_gvt_wait_vgpu_idle(vgpu);
mutex_lock(&vgpu->gvt->lock);
}

intel_vgpu_reset_execlist(vgpu, bitmap);

vgpu->resetting = false;

return 0;
}

static int gdrst_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
void *p_data, unsigned int bytes)
{
u32 data;
u32 bitmap = 0;
u64 bitmap = 0;

data = vgpu_vreg(vgpu, offset);

Expand Down Expand Up @@ -260,7 +281,7 @@ static int gdrst_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
if (HAS_BSD2(vgpu->gvt->dev_priv))
bitmap |= (1 << VCS2);
}
return 0;
return handle_device_reset(vgpu, offset, p_data, bytes, bitmap);
}

static int gmbus_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
Expand Down
Loading

0 comments on commit e473405

Please sign in to comment.