drm/i915/gvt: create an idle vGPU
vGPU resource is allocated by scheduler. To account for non-allocated free cycles, we create an idle vGPU as the placeholder similar to idle task concept, which is useful to handle some corner cases in scheduling policy. Signed-off-by: Ping Gao <ping.a.gao@intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
This commit is contained in:
parent
39d467c2b7
commit
afe04fbe6c
|
@ -202,6 +202,8 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
|
|||
|
||||
idr_destroy(&gvt->vgpu_idr);
|
||||
|
||||
intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
|
||||
|
||||
kfree(dev_priv->gvt);
|
||||
dev_priv->gvt = NULL;
|
||||
}
|
||||
|
@ -220,6 +222,7 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
|
|||
int intel_gvt_init_device(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_gvt *gvt;
|
||||
struct intel_vgpu *vgpu;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
@ -292,6 +295,14 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
|
|||
goto out_clean_types;
|
||||
}
|
||||
|
||||
vgpu = intel_gvt_create_idle_vgpu(gvt);
|
||||
if (IS_ERR(vgpu)) {
|
||||
ret = PTR_ERR(vgpu);
|
||||
gvt_err("failed to create idle vgpu\n");
|
||||
goto out_clean_types;
|
||||
}
|
||||
gvt->idle_vgpu = vgpu;
|
||||
|
||||
gvt_dbg_core("gvt device initialization is done\n");
|
||||
dev_priv->gvt = gvt;
|
||||
return 0;
|
||||
|
|
|
@ -243,6 +243,7 @@ struct intel_gvt {
|
|||
DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS);
|
||||
struct intel_vgpu_type *types;
|
||||
unsigned int num_types;
|
||||
struct intel_vgpu *idle_vgpu;
|
||||
|
||||
struct task_struct *service_thread;
|
||||
wait_queue_head_t service_thread_wq;
|
||||
|
@ -386,6 +387,8 @@ static inline void intel_vgpu_write_pci_bar(struct intel_vgpu *vgpu,
|
|||
int intel_gvt_init_vgpu_types(struct intel_gvt *gvt);
|
||||
void intel_gvt_clean_vgpu_types(struct intel_gvt *gvt);
|
||||
|
||||
struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt);
|
||||
void intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu);
|
||||
struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
|
||||
struct intel_vgpu_type *type);
|
||||
void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu);
|
||||
|
|
|
@ -233,6 +233,59 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
|
|||
mutex_unlock(&gvt->lock);
|
||||
}
|
||||
|
||||
#define IDLE_VGPU_IDR 0
|
||||
|
||||
/**
|
||||
* intel_gvt_create_idle_vgpu - create an idle virtual GPU
|
||||
* @gvt: GVT device
|
||||
*
|
||||
* This function is called when user wants to create an idle virtual GPU.
|
||||
*
|
||||
* Returns:
|
||||
* pointer to intel_vgpu, error pointer if failed.
|
||||
*/
|
||||
struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt)
|
||||
{
|
||||
struct intel_vgpu *vgpu;
|
||||
enum intel_engine_id i;
|
||||
int ret;
|
||||
|
||||
vgpu = vzalloc(sizeof(*vgpu));
|
||||
if (!vgpu)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
vgpu->id = IDLE_VGPU_IDR;
|
||||
vgpu->gvt = gvt;
|
||||
|
||||
for (i = 0; i < I915_NUM_ENGINES; i++)
|
||||
INIT_LIST_HEAD(&vgpu->workload_q_head[i]);
|
||||
|
||||
ret = intel_vgpu_init_sched_policy(vgpu);
|
||||
if (ret)
|
||||
goto out_free_vgpu;
|
||||
|
||||
vgpu->active = false;
|
||||
|
||||
return vgpu;
|
||||
|
||||
out_free_vgpu:
|
||||
vfree(vgpu);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_gvt_destroy_vgpu - destroy an idle virtual GPU
|
||||
* @vgpu: virtual GPU
|
||||
*
|
||||
* This function is called when user wants to destroy an idle virtual GPU.
|
||||
*
|
||||
*/
|
||||
void intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu)
|
||||
{
|
||||
intel_vgpu_clean_sched_policy(vgpu);
|
||||
vfree(vgpu);
|
||||
}
|
||||
|
||||
static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
|
||||
struct intel_vgpu_creation_params *param)
|
||||
{
|
||||
|
@ -249,7 +302,8 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
|
|||
|
||||
mutex_lock(&gvt->lock);
|
||||
|
||||
ret = idr_alloc(&gvt->vgpu_idr, vgpu, 1, GVT_MAX_VGPU, GFP_KERNEL);
|
||||
ret = idr_alloc(&gvt->vgpu_idr, vgpu, IDLE_VGPU_IDR + 1, GVT_MAX_VGPU,
|
||||
GFP_KERNEL);
|
||||
if (ret < 0)
|
||||
goto out_free_vgpu;
|
||||
|
||||
|
|
Loading…
Reference in New Issue