Commit 41842d6b authored by Daniel Vetter's avatar Daniel Vetter

Merge tag 'gvt-next-fix-2016-10-20' of https://github.com/01org/gvt-linux into...

Merge tag 'gvt-next-fix-2016-10-20' of https://github.com/01org/gvt-linux into drm-intel-next-queued

gvt-next-fix-2016-10-20

This contains fix for first pull request.
- clean up header mess between i915 core and gvt
- new MAINTAINERS item
- new kernel-doc section
- fix compiling warnings
- gvt gem fix series from Chris
- fix for i915 intel_engine_cs change
- some sparse fixes from Changbin
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
parents eafc4894 19e6393f
...@@ -49,6 +49,15 @@ Intel GVT-g Guest Support(vGPU) ...@@ -49,6 +49,15 @@ Intel GVT-g Guest Support(vGPU)
.. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c .. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c
:internal: :internal:
Intel GVT-g Host Support(vGPU device model)
-------------------------------------------
.. kernel-doc:: drivers/gpu/drm/i915/intel_gvt.c
:doc: Intel GVT-g host support
.. kernel-doc:: drivers/gpu/drm/i915/intel_gvt.c
:internal:
Display Hardware Handling Display Hardware Handling
========================= =========================
......
...@@ -4009,6 +4009,16 @@ F: include/drm/i915* ...@@ -4009,6 +4009,16 @@ F: include/drm/i915*
F: include/uapi/drm/i915_drm.h F: include/uapi/drm/i915_drm.h
F: Documentation/gpu/i915.rst F: Documentation/gpu/i915.rst
INTEL GVT-g DRIVERS (Intel GPU Virtualization)
M: Zhenyu Wang <zhenyuw@linux.intel.com>
M: Zhi Wang <zhi.a.wang@intel.com>
L: igvt-g-dev@lists.01.org
L: intel-gfx@lists.freedesktop.org
W: https://01.org/igvt-g
T: git https://github.com/01org/gvt-linux.git
S: Supported
F: drivers/gpu/drm/i915/gvt/
DRM DRIVERS FOR ATMEL HLCDC DRM DRIVERS FOR ATMEL HLCDC
M: Boris Brezillon <boris.brezillon@free-electrons.com> M: Boris Brezillon <boris.brezillon@free-electrons.com>
L: dri-devel@lists.freedesktop.org L: dri-devel@lists.freedesktop.org
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
#define MB_TO_BYTES(mb) ((mb) << 20ULL) #define MB_TO_BYTES(mb) ((mb) << 20ULL)
#define BYTES_TO_MB(b) ((b) >> 20ULL) #define BYTES_TO_MB(b) ((b) >> 20ULL)
...@@ -144,6 +145,8 @@ void intel_vgpu_write_fence(struct intel_vgpu *vgpu, ...@@ -144,6 +145,8 @@ void intel_vgpu_write_fence(struct intel_vgpu *vgpu,
struct drm_i915_fence_reg *reg; struct drm_i915_fence_reg *reg;
i915_reg_t fence_reg_lo, fence_reg_hi; i915_reg_t fence_reg_lo, fence_reg_hi;
assert_rpm_wakelock_held(dev_priv);
if (WARN_ON(fence > vgpu_fence_sz(vgpu))) if (WARN_ON(fence > vgpu_fence_sz(vgpu)))
return; return;
...@@ -172,6 +175,8 @@ static void free_vgpu_fence(struct intel_vgpu *vgpu) ...@@ -172,6 +175,8 @@ static void free_vgpu_fence(struct intel_vgpu *vgpu)
if (WARN_ON(!vgpu_fence_sz(vgpu))) if (WARN_ON(!vgpu_fence_sz(vgpu)))
return; return;
intel_runtime_pm_get(dev_priv);
mutex_lock(&dev_priv->drm.struct_mutex); mutex_lock(&dev_priv->drm.struct_mutex);
for (i = 0; i < vgpu_fence_sz(vgpu); i++) { for (i = 0; i < vgpu_fence_sz(vgpu); i++) {
reg = vgpu->fence.regs[i]; reg = vgpu->fence.regs[i];
...@@ -180,6 +185,8 @@ static void free_vgpu_fence(struct intel_vgpu *vgpu) ...@@ -180,6 +185,8 @@ static void free_vgpu_fence(struct intel_vgpu *vgpu)
&dev_priv->mm.fence_list); &dev_priv->mm.fence_list);
} }
mutex_unlock(&dev_priv->drm.struct_mutex); mutex_unlock(&dev_priv->drm.struct_mutex);
intel_runtime_pm_put(dev_priv);
} }
static int alloc_vgpu_fence(struct intel_vgpu *vgpu) static int alloc_vgpu_fence(struct intel_vgpu *vgpu)
...@@ -190,6 +197,8 @@ static int alloc_vgpu_fence(struct intel_vgpu *vgpu) ...@@ -190,6 +197,8 @@ static int alloc_vgpu_fence(struct intel_vgpu *vgpu)
int i; int i;
struct list_head *pos, *q; struct list_head *pos, *q;
intel_runtime_pm_get(dev_priv);
/* Request fences from host */ /* Request fences from host */
mutex_lock(&dev_priv->drm.struct_mutex); mutex_lock(&dev_priv->drm.struct_mutex);
i = 0; i = 0;
...@@ -207,6 +216,7 @@ static int alloc_vgpu_fence(struct intel_vgpu *vgpu) ...@@ -207,6 +216,7 @@ static int alloc_vgpu_fence(struct intel_vgpu *vgpu)
goto out_free_fence; goto out_free_fence;
mutex_unlock(&dev_priv->drm.struct_mutex); mutex_unlock(&dev_priv->drm.struct_mutex);
intel_runtime_pm_put(dev_priv);
return 0; return 0;
out_free_fence: out_free_fence:
/* Return fences to host, if fail */ /* Return fences to host, if fail */
...@@ -218,6 +228,7 @@ static int alloc_vgpu_fence(struct intel_vgpu *vgpu) ...@@ -218,6 +228,7 @@ static int alloc_vgpu_fence(struct intel_vgpu *vgpu)
&dev_priv->mm.fence_list); &dev_priv->mm.fence_list);
} }
mutex_unlock(&dev_priv->drm.struct_mutex); mutex_unlock(&dev_priv->drm.struct_mutex);
intel_runtime_pm_put(dev_priv);
return -ENOSPC; return -ENOSPC;
} }
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
enum { enum {
INTEL_GVT_PCI_BAR_GTTMMIO = 0, INTEL_GVT_PCI_BAR_GTTMMIO = 0,
......
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#include <linux/slab.h> #include <linux/slab.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
#include "i915_pvinfo.h"
#include "trace.h" #include "trace.h"
#define INVALID_OP (~0U) #define INVALID_OP (~0U)
...@@ -478,8 +480,8 @@ struct parser_exec_state { ...@@ -478,8 +480,8 @@ struct parser_exec_state {
#define gmadr_dw_number(s) \ #define gmadr_dw_number(s) \
(s->vgpu->gvt->device_info.gmadr_bytes_in_cmd >> 2) (s->vgpu->gvt->device_info.gmadr_bytes_in_cmd >> 2)
unsigned long bypass_scan_mask = 0; static unsigned long bypass_scan_mask = 0;
bool bypass_batch_buffer_scan = true; static bool bypass_batch_buffer_scan = true;
/* ring ALL, type = 0 */ /* ring ALL, type = 0 */
static struct sub_op_bits sub_op_mi[] = { static struct sub_op_bits sub_op_mi[] = {
...@@ -958,7 +960,7 @@ struct cmd_interrupt_event { ...@@ -958,7 +960,7 @@ struct cmd_interrupt_event {
int mi_user_interrupt; int mi_user_interrupt;
}; };
struct cmd_interrupt_event cmd_interrupt_events[] = { static struct cmd_interrupt_event cmd_interrupt_events[] = {
[RCS] = { [RCS] = {
.pipe_control_notify = RCS_PIPE_CONTROL, .pipe_control_notify = RCS_PIPE_CONTROL,
.mi_flush_dw = INTEL_GVT_EVENT_RESERVED, .mi_flush_dw = INTEL_GVT_EVENT_RESERVED,
...@@ -1581,44 +1583,6 @@ static uint32_t find_bb_size(struct parser_exec_state *s) ...@@ -1581,44 +1583,6 @@ static uint32_t find_bb_size(struct parser_exec_state *s)
return bb_size; return bb_size;
} }
static u32 *vmap_batch(struct drm_i915_gem_object *obj,
unsigned int start, unsigned int len)
{
int i;
void *addr = NULL;
struct sg_page_iter sg_iter;
int first_page = start >> PAGE_SHIFT;
int last_page = (len + start + 4095) >> PAGE_SHIFT;
int npages = last_page - first_page;
struct page **pages;
pages = drm_malloc_ab(npages, sizeof(*pages));
if (pages == NULL) {
DRM_DEBUG_DRIVER("Failed to get space for pages\n");
goto finish;
}
i = 0;
for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents,
first_page) {
pages[i++] = sg_page_iter_page(&sg_iter);
if (i == npages)
break;
}
addr = vmap(pages, i, 0, PAGE_KERNEL);
if (addr == NULL) {
DRM_DEBUG_DRIVER("Failed to vmap pages\n");
goto finish;
}
finish:
if (pages)
drm_free_large(pages);
return (u32 *)addr;
}
static int perform_bb_shadow(struct parser_exec_state *s) static int perform_bb_shadow(struct parser_exec_state *s)
{ {
struct intel_shadow_bb_entry *entry_obj; struct intel_shadow_bb_entry *entry_obj;
...@@ -1638,25 +1602,20 @@ static int perform_bb_shadow(struct parser_exec_state *s) ...@@ -1638,25 +1602,20 @@ static int perform_bb_shadow(struct parser_exec_state *s)
if (entry_obj == NULL) if (entry_obj == NULL)
return -ENOMEM; return -ENOMEM;
entry_obj->obj = i915_gem_object_create(&(s->vgpu->gvt->dev_priv->drm), entry_obj->obj =
round_up(bb_size, PAGE_SIZE)); i915_gem_object_create(&(s->vgpu->gvt->dev_priv->drm),
if (entry_obj->obj == NULL) roundup(bb_size, PAGE_SIZE));
return -ENOMEM; if (IS_ERR(entry_obj->obj)) {
ret = PTR_ERR(entry_obj->obj);
goto free_entry;
}
entry_obj->len = bb_size; entry_obj->len = bb_size;
INIT_LIST_HEAD(&entry_obj->list); INIT_LIST_HEAD(&entry_obj->list);
ret = i915_gem_object_get_pages(entry_obj->obj); dst = i915_gem_object_pin_map(entry_obj->obj, I915_MAP_WB);
if (ret) if (IS_ERR(dst)) {
return ret; ret = PTR_ERR(dst);
goto put_obj;
i915_gem_object_pin_pages(entry_obj->obj);
/* get the va of the shadow batch buffer */
dst = (void *)vmap_batch(entry_obj->obj, 0, bb_size);
if (!dst) {
gvt_err("failed to vmap shadow batch\n");
ret = -ENOMEM;
goto unpin_src;
} }
ret = i915_gem_object_set_to_cpu_domain(entry_obj->obj, false); ret = i915_gem_object_set_to_cpu_domain(entry_obj->obj, false);
...@@ -1670,10 +1629,11 @@ static int perform_bb_shadow(struct parser_exec_state *s) ...@@ -1670,10 +1629,11 @@ static int perform_bb_shadow(struct parser_exec_state *s)
/* copy batch buffer to shadow batch buffer*/ /* copy batch buffer to shadow batch buffer*/
ret = copy_gma_to_hva(s->vgpu, s->vgpu->gtt.ggtt_mm, ret = copy_gma_to_hva(s->vgpu, s->vgpu->gtt.ggtt_mm,
gma, gma + bb_size, dst); gma, gma + bb_size,
dst);
if (ret) { if (ret) {
gvt_err("fail to copy guest ring buffer\n"); gvt_err("fail to copy guest ring buffer\n");
return ret; goto unmap_src;
} }
list_add(&entry_obj->list, &s->workload->shadow_bb); list_add(&entry_obj->list, &s->workload->shadow_bb);
...@@ -1691,10 +1651,11 @@ static int perform_bb_shadow(struct parser_exec_state *s) ...@@ -1691,10 +1651,11 @@ static int perform_bb_shadow(struct parser_exec_state *s)
return 0; return 0;
unmap_src: unmap_src:
vunmap(dst); i915_gem_object_unpin_map(entry_obj->obj);
unpin_src: put_obj:
i915_gem_object_unpin_pages(entry_obj->obj); i915_gem_object_put(entry_obj->obj);
free_entry:
kfree(entry_obj);
return ret; return ret;
} }
...@@ -2707,55 +2668,47 @@ static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx) ...@@ -2707,55 +2668,47 @@ static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)
struct drm_device *dev = &wa_ctx->workload->vgpu->gvt->dev_priv->drm; struct drm_device *dev = &wa_ctx->workload->vgpu->gvt->dev_priv->drm;
int ctx_size = wa_ctx->indirect_ctx.size; int ctx_size = wa_ctx->indirect_ctx.size;
unsigned long guest_gma = wa_ctx->indirect_ctx.guest_gma; unsigned long guest_gma = wa_ctx->indirect_ctx.guest_gma;
struct drm_i915_gem_object *obj;
int ret = 0; int ret = 0;
void *dest = NULL; void *map;
wa_ctx->indirect_ctx.obj = i915_gem_object_create(dev,
round_up(ctx_size + CACHELINE_BYTES, PAGE_SIZE));
if (wa_ctx->indirect_ctx.obj == NULL)
return -ENOMEM;
ret = i915_gem_object_get_pages(wa_ctx->indirect_ctx.obj); obj = i915_gem_object_create(dev,
if (ret) roundup(ctx_size + CACHELINE_BYTES,
return ret; PAGE_SIZE));
if (IS_ERR(obj))
i915_gem_object_pin_pages(wa_ctx->indirect_ctx.obj); return PTR_ERR(obj);
/* get the va of the shadow batch buffer */ /* get the va of the shadow batch buffer */
dest = (void *)vmap_batch(wa_ctx->indirect_ctx.obj, 0, map = i915_gem_object_pin_map(obj, I915_MAP_WB);
ctx_size + CACHELINE_BYTES); if (IS_ERR(map)) {
if (!dest) {
gvt_err("failed to vmap shadow indirect ctx\n"); gvt_err("failed to vmap shadow indirect ctx\n");
ret = -ENOMEM; ret = PTR_ERR(map);
goto unpin_src; goto put_obj;
} }
ret = i915_gem_object_set_to_cpu_domain(wa_ctx->indirect_ctx.obj, ret = i915_gem_object_set_to_cpu_domain(obj, false);
false);
if (ret) { if (ret) {
gvt_err("failed to set shadow indirect ctx to CPU\n"); gvt_err("failed to set shadow indirect ctx to CPU\n");
goto unmap_src; goto unmap_src;
} }
wa_ctx->indirect_ctx.shadow_va = dest;
memset(dest, 0, round_up(ctx_size + CACHELINE_BYTES, PAGE_SIZE));
ret = copy_gma_to_hva(wa_ctx->workload->vgpu, ret = copy_gma_to_hva(wa_ctx->workload->vgpu,
wa_ctx->workload->vgpu->gtt.ggtt_mm, wa_ctx->workload->vgpu->gtt.ggtt_mm,
guest_gma, guest_gma + ctx_size, dest); guest_gma, guest_gma + ctx_size,
map);
if (ret) { if (ret) {
gvt_err("fail to copy guest indirect ctx\n"); gvt_err("fail to copy guest indirect ctx\n");
return ret; goto unmap_src;
} }
wa_ctx->indirect_ctx.obj = obj;
wa_ctx->indirect_ctx.shadow_va = map;
return 0; return 0;
unmap_src: unmap_src:
vunmap(dest); i915_gem_object_unpin_map(obj);
unpin_src: put_obj:
i915_gem_object_unpin_pages(wa_ctx->indirect_ctx.obj); i915_gem_object_put(wa_ctx->indirect_ctx.obj);
return ret; return ret;
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
static int get_edp_pipe(struct intel_vgpu *vgpu) static int get_edp_pipe(struct intel_vgpu *vgpu)
{ {
...@@ -119,7 +120,7 @@ static unsigned char virtual_dp_monitor_edid[] = { ...@@ -119,7 +120,7 @@ static unsigned char virtual_dp_monitor_edid[] = {
#define DPCD_HEADER_SIZE 0xb #define DPCD_HEADER_SIZE 0xb
u8 dpcd_fix_data[DPCD_HEADER_SIZE] = { static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = {
0x11, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x11, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
#define GMBUS1_TOTAL_BYTES_SHIFT 16 #define GMBUS1_TOTAL_BYTES_SHIFT 16
#define GMBUS1_TOTAL_BYTES_MASK 0x1ff #define GMBUS1_TOTAL_BYTES_MASK 0x1ff
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
#define _EL_OFFSET_STATUS 0x234 #define _EL_OFFSET_STATUS 0x234
#define _EL_OFFSET_STATUS_BUF 0x370 #define _EL_OFFSET_STATUS_BUF 0x370
...@@ -385,8 +386,6 @@ static int set_gma_to_bb_cmd(struct intel_shadow_bb_entry *entry_obj, ...@@ -385,8 +386,6 @@ static int set_gma_to_bb_cmd(struct intel_shadow_bb_entry *entry_obj,
static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload) static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
{ {
int gmadr_bytes = workload->vgpu->gvt->device_info.gmadr_bytes_in_cmd; int gmadr_bytes = workload->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
struct i915_vma *vma;
unsigned long gma;
/* pin the gem object to ggtt */ /* pin the gem object to ggtt */
if (!list_empty(&workload->shadow_bb)) { if (!list_empty(&workload->shadow_bb)) {
...@@ -398,18 +397,24 @@ static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload) ...@@ -398,18 +397,24 @@ static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
list_for_each_entry_safe(entry_obj, temp, &workload->shadow_bb, list_for_each_entry_safe(entry_obj, temp, &workload->shadow_bb,
list) { list) {
struct i915_vma *vma;
vma = i915_gem_object_ggtt_pin(entry_obj->obj, NULL, 0, vma = i915_gem_object_ggtt_pin(entry_obj->obj, NULL, 0,
0, 0); 4, 0);
if (IS_ERR(vma)) { if (IS_ERR(vma)) {
gvt_err("Cannot pin\n"); gvt_err("Cannot pin\n");
return; return;
} }
i915_gem_object_unpin_pages(entry_obj->obj);
/* FIXME: we are not tracking our pinned VMA leaving it
* up to the core to fix up the stray pin_count upon
* free.
*/
/* update the relocate gma with shadow batch buffer*/ /* update the relocate gma with shadow batch buffer*/
gma = i915_gem_object_ggtt_offset(entry_obj->obj, NULL); set_gma_to_bb_cmd(entry_obj,
WARN_ON(!IS_ALIGNED(gma, 4)); i915_ggtt_offset(vma),
set_gma_to_bb_cmd(entry_obj, gma, gmadr_bytes); gmadr_bytes);
} }
} }
} }
...@@ -441,7 +446,6 @@ static int update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx) ...@@ -441,7 +446,6 @@ static int update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx)
static void prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) static void prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
{ {
struct i915_vma *vma; struct i915_vma *vma;
unsigned long gma;
unsigned char *per_ctx_va = unsigned char *per_ctx_va =
(unsigned char *)wa_ctx->indirect_ctx.shadow_va + (unsigned char *)wa_ctx->indirect_ctx.shadow_va +
wa_ctx->indirect_ctx.size; wa_ctx->indirect_ctx.size;
...@@ -449,16 +453,19 @@ static void prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) ...@@ -449,16 +453,19 @@ static void prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
if (wa_ctx->indirect_ctx.size == 0) if (wa_ctx->indirect_ctx.size == 0)
return; return;
vma = i915_gem_object_ggtt_pin(wa_ctx->indirect_ctx.obj, NULL, 0, 0, 0); vma = i915_gem_object_ggtt_pin(wa_ctx->indirect_ctx.obj, NULL,
0, CACHELINE_BYTES, 0);
if (IS_ERR(vma)) { if (IS_ERR(vma)) {
gvt_err("Cannot pin indirect ctx obj\n"); gvt_err("Cannot pin indirect ctx obj\n");
return; return;
} }
i915_gem_object_unpin_pages(wa_ctx->indirect_ctx.obj);
gma = i915_gem_object_ggtt_offset(wa_ctx->indirect_ctx.obj, NULL); /* FIXME: we are not tracking our pinned VMA leaving it
WARN_ON(!IS_ALIGNED(gma, CACHELINE_BYTES)); * up to the core to fix up the stray pin_count upon
wa_ctx->indirect_ctx.shadow_gma = gma; * free.
*/
wa_ctx->indirect_ctx.shadow_gma = i915_ggtt_offset(vma);
wa_ctx->per_ctx.shadow_gma = *((unsigned int *)per_ctx_va + 1); wa_ctx->per_ctx.shadow_gma = *((unsigned int *)per_ctx_va + 1);
memset(per_ctx_va, 0, CACHELINE_BYTES); memset(per_ctx_va, 0, CACHELINE_BYTES);
...@@ -498,8 +505,8 @@ static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload) ...@@ -498,8 +505,8 @@ static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload)
list_for_each_entry_safe(entry_obj, temp, &workload->shadow_bb, list_for_each_entry_safe(entry_obj, temp, &workload->shadow_bb,
list) { list) {
drm_gem_object_unreference(&(entry_obj->obj->base)); i915_gem_object_unpin_map(entry_obj->obj);
kvfree(entry_obj->va); i915_gem_object_put(entry_obj->obj);
list_del(&entry_obj->list); list_del(&entry_obj->list);
kfree(entry_obj); kfree(entry_obj);
} }
...@@ -511,8 +518,8 @@ static void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) ...@@ -511,8 +518,8 @@ static void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
if (wa_ctx->indirect_ctx.size == 0) if (wa_ctx->indirect_ctx.size == 0)
return; return;
drm_gem_object_unreference(&(wa_ctx->indirect_ctx.obj->base)); i915_gem_object_unpin_map(wa_ctx->indirect_ctx.obj);
kvfree(wa_ctx->indirect_ctx.shadow_va); i915_gem_object_put(wa_ctx->indirect_ctx.obj);
} }
static int complete_execlist_workload(struct intel_vgpu_workload *workload) static int complete_execlist_workload(struct intel_vgpu_workload *workload)
...@@ -616,7 +623,7 @@ static int prepare_mm(struct intel_vgpu_workload *workload) ...@@ -616,7 +623,7 @@ static int prepare_mm(struct intel_vgpu_workload *workload)
(list_empty(q) ? NULL : container_of(q->prev, \ (list_empty(q) ? NULL : container_of(q->prev, \
struct intel_vgpu_workload, list)) struct intel_vgpu_workload, list))
bool submit_context(struct intel_vgpu *vgpu, int ring_id, static int submit_context(struct intel_vgpu *vgpu, int ring_id,
struct execlist_ctx_descriptor_format *desc, struct execlist_ctx_descriptor_format *desc,
bool emulate_schedule_in) bool emulate_schedule_in)
{ {
...@@ -810,10 +817,11 @@ void intel_vgpu_clean_execlist(struct intel_vgpu *vgpu) ...@@ -810,10 +817,11 @@ void intel_vgpu_clean_execlist(struct intel_vgpu *vgpu)
int intel_vgpu_init_execlist(struct intel_vgpu *vgpu) int intel_vgpu_init_execlist(struct intel_vgpu *vgpu)
{ {
int i; enum intel_engine_id i;
struct intel_engine_cs *engine;
/* each ring has a virtual execlist engine */ /* each ring has a virtual execlist engine */
for (i = 0; i < I915_NUM_ENGINES; i++) { for_each_engine(engine, vgpu->gvt->dev_priv, i) {
init_vgpu_execlist(vgpu, i); init_vgpu_execlist(vgpu, i);
INIT_LIST_HEAD(&vgpu->workload_q_head[i]); INIT_LIST_HEAD(&vgpu->workload_q_head[i]);
} }
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <linux/crc32.h> #include <linux/crc32.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
#include "i915_pvinfo.h"
#define FIRMWARE_VERSION (0x0) #define FIRMWARE_VERSION (0x0)
...@@ -49,7 +51,7 @@ struct gvt_firmware_header { ...@@ -49,7 +51,7 @@ struct gvt_firmware_header {
#define RD(offset) (readl(mmio + offset.reg)) #define RD(offset) (readl(mmio + offset.reg))
#define WR(v, offset) (writel(v, mmio + offset.reg)) #define WR(v, offset) (writel(v, mmio + offset.reg))
static void bdw_forcewake_get(void *mmio) static void bdw_forcewake_get(void __iomem *mmio)
{ {
WR(_MASKED_BIT_DISABLE(0xffff), FORCEWAKE_MT); WR(_MASKED_BIT_DISABLE(0xffff), FORCEWAKE_MT);
...@@ -89,7 +91,8 @@ static struct bin_attribute firmware_attr = { ...@@ -89,7 +91,8 @@ static struct bin_attribute firmware_attr = {
.mmap = NULL, .mmap = NULL,
}; };
static int expose_firmware_sysfs(struct intel_gvt *gvt, void *mmio) static int expose_firmware_sysfs(struct intel_gvt *gvt,
void __iomem *mmio)
{ {
struct intel_gvt_device_info *info = &gvt->device_info; struct intel_gvt_device_info *info = &gvt->device_info;
struct pci_dev *pdev = gvt->dev_priv->drm.pdev; struct pci_dev *pdev = gvt->dev_priv->drm.pdev;
...@@ -232,7 +235,8 @@ int intel_gvt_load_firmware(struct intel_gvt *gvt) ...@@ -232,7 +235,8 @@ int intel_gvt_load_firmware(struct intel_gvt *gvt)
struct gvt_firmware_header *h; struct gvt_firmware_header *h;
const struct firmware *fw; const struct firmware *fw;
char *path; char *path;
void *mmio, *mem; void __iomem *mmio;
void *mem;
int ret; int ret;
path = kmalloc(PATH_MAX, GFP_KERNEL); path = kmalloc(PATH_MAX, GFP_KERNEL);
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
#include "i915_pvinfo.h"
#include "trace.h" #include "trace.h"
static bool enable_out_of_sync = false; static bool enable_out_of_sync = false;
...@@ -267,7 +269,7 @@ static inline int get_pse_type(int type) ...@@ -267,7 +269,7 @@ static inline int get_pse_type(int type)
static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index) static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index)
{ {
void *addr = (u64 *)dev_priv->ggtt.gsm + index; void __iomem *addr = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + index;
u64 pte; u64 pte;
#ifdef readq #ifdef readq
...@@ -282,7 +284,7 @@ static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index) ...@@ -282,7 +284,7 @@ static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index)
static void write_pte64(struct drm_i915_private *dev_priv, static void write_pte64(struct drm_i915_private *dev_priv,
unsigned long index, u64 pte) unsigned long index, u64 pte)
{ {
void *addr = (u64 *)dev_priv->ggtt.gsm + index; void __iomem *addr = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + index;
#ifdef writeq #ifdef writeq
writeq(pte, addr); writeq(pte, addr);
...@@ -1919,7 +1921,7 @@ int intel_vgpu_emulate_gtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, ...@@ -1919,7 +1921,7 @@ int intel_vgpu_emulate_gtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
return ret; return ret;
} }
bool intel_gvt_create_scratch_page(struct intel_vgpu *vgpu) static int create_scratch_page(struct intel_vgpu *vgpu)
{ {
struct intel_vgpu_gtt *gtt = &vgpu->gtt; struct intel_vgpu_gtt *gtt = &vgpu->gtt;
void *p; void *p;
...@@ -1953,7 +1955,7 @@ bool intel_gvt_create_scratch_page(struct intel_vgpu *vgpu) ...@@ -1953,7 +1955,7 @@ bool intel_gvt_create_scratch_page(struct intel_vgpu *vgpu)
return 0; return 0;
} }
void intel_gvt_release_scratch_page(struct intel_vgpu *vgpu) static void release_scratch_page(struct intel_vgpu *vgpu)
{ {
if (vgpu->gtt.scratch_page != NULL) { if (vgpu->gtt.scratch_page != NULL) {
__free_page(vgpu->gtt.scratch_page); __free_page(vgpu->gtt.scratch_page);
...@@ -1993,8 +1995,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu) ...@@ -1993,8 +1995,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
gtt->ggtt_mm = ggtt_mm; gtt->ggtt_mm = ggtt_mm;
intel_gvt_create_scratch_page(vgpu); return create_scratch_page(vgpu);
return 0;
} }
/** /**
...@@ -2013,7 +2014,7 @@ void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu) ...@@ -2013,7 +2014,7 @@ void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu)
struct intel_vgpu_mm *mm; struct intel_vgpu_mm *mm;
ppgtt_free_all_shadow_page(vgpu); ppgtt_free_all_shadow_page(vgpu);
intel_gvt_release_scratch_page(vgpu); release_scratch_page(vgpu);
list_for_each_safe(pos, n, &vgpu->gtt.mm_list_head) { list_for_each_safe(pos, n, &vgpu->gtt.mm_list_head) {
mm = container_of(pos, struct intel_vgpu_mm, list); mm = container_of(pos, struct intel_vgpu_mm, list);
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/kthread.h> #include <linux/kthread.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
struct intel_gvt_host intel_gvt_host; struct intel_gvt_host intel_gvt_host;
...@@ -173,9 +174,9 @@ static int init_service_thread(struct intel_gvt *gvt) ...@@ -173,9 +174,9 @@ static int init_service_thread(struct intel_gvt *gvt)
*/ */
void intel_gvt_clean_device(struct drm_i915_private *dev_priv) void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
{ {
struct intel_gvt *gvt = &dev_priv->gvt; struct intel_gvt *gvt = to_gvt(dev_priv);
if (WARN_ON(!gvt->initialized)) if (WARN_ON(!gvt))
return; return;
clean_service_thread(gvt); clean_service_thread(gvt);
...@@ -188,7 +189,8 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv) ...@@ -188,7 +189,8 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
intel_gvt_clean_mmio_info(gvt); intel_gvt_clean_mmio_info(gvt);
intel_gvt_free_firmware(gvt); intel_gvt_free_firmware(gvt);
gvt->initialized = false; kfree(dev_priv->gvt);
dev_priv->gvt = NULL;
} }
/** /**
...@@ -204,7 +206,7 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv) ...@@ -204,7 +206,7 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
*/ */
int intel_gvt_init_device(struct drm_i915_private *dev_priv) int intel_gvt_init_device(struct drm_i915_private *dev_priv)
{ {
struct intel_gvt *gvt = &dev_priv->gvt; struct intel_gvt *gvt;
int ret; int ret;
/* /*
...@@ -214,9 +216,13 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv) ...@@ -214,9 +216,13 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
if (WARN_ON(!intel_gvt_host.initialized)) if (WARN_ON(!intel_gvt_host.initialized))
return -EINVAL; return -EINVAL;
if (WARN_ON(gvt->initialized)) if (WARN_ON(dev_priv->gvt))
return -EEXIST; return -EEXIST;
gvt = kzalloc(sizeof(struct intel_gvt), GFP_KERNEL);
if (!gvt)
return -ENOMEM;
gvt_dbg_core("init gvt device\n"); gvt_dbg_core("init gvt device\n");
mutex_init(&gvt->lock); mutex_init(&gvt->lock);
...@@ -261,7 +267,7 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv) ...@@ -261,7 +267,7 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
goto out_clean_cmd_parser; goto out_clean_cmd_parser;
gvt_dbg_core("gvt device creation is done\n"); gvt_dbg_core("gvt device creation is done\n");
gvt->initialized = true; dev_priv->gvt = gvt;
return 0; return 0;
out_clean_cmd_parser: out_clean_cmd_parser:
...@@ -280,5 +286,6 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv) ...@@ -280,5 +286,6 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
intel_gvt_free_firmware(gvt); intel_gvt_free_firmware(gvt);
out_clean_mmio_info: out_clean_mmio_info:
intel_gvt_clean_mmio_info(gvt); intel_gvt_clean_mmio_info(gvt);
kfree(gvt);
return ret; return ret;
} }
...@@ -186,14 +186,12 @@ struct intel_gvt_firmware { ...@@ -186,14 +186,12 @@ struct intel_gvt_firmware {
}; };
struct intel_gvt_opregion { struct intel_gvt_opregion {
void *opregion_va; void __iomem *opregion_va;
u32 opregion_pa; u32 opregion_pa;
}; };
struct intel_gvt { struct intel_gvt {
struct mutex lock; struct mutex lock;
bool initialized;
struct drm_i915_private *dev_priv; struct drm_i915_private *dev_priv;
struct idr vgpu_idr; /* vGPU IDR pool */ struct idr vgpu_idr; /* vGPU IDR pool */
...@@ -213,6 +211,11 @@ struct intel_gvt { ...@@ -213,6 +211,11 @@ struct intel_gvt {
unsigned long service_request; unsigned long service_request;
}; };
static inline struct intel_gvt *to_gvt(struct drm_i915_private *i915)
{
return i915->gvt;
}
enum { enum {
INTEL_GVT_REQUEST_EMULATE_VBLANK = 0, INTEL_GVT_REQUEST_EMULATE_VBLANK = 0,
}; };
......
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
#include "i915_pvinfo.h"
/* XXX FIXME i915 has changed PP_XXX definition */ /* XXX FIXME i915 has changed PP_XXX definition */
#define PCH_PP_STATUS _MMIO(0xc7200) #define PCH_PP_STATUS _MMIO(0xc7200)
...@@ -130,12 +132,13 @@ static int new_mmio_info(struct intel_gvt *gvt, ...@@ -130,12 +132,13 @@ static int new_mmio_info(struct intel_gvt *gvt,
static int render_mmio_to_ring_id(struct intel_gvt *gvt, unsigned int reg) static int render_mmio_to_ring_id(struct intel_gvt *gvt, unsigned int reg)
{ {
int i; enum intel_engine_id id;
struct intel_engine_cs *engine;
reg &= ~GENMASK(11, 0); reg &= ~GENMASK(11, 0);
for (i = 0; i < I915_NUM_ENGINES; i++) { for_each_engine(engine, gvt->dev_priv, id) {
if (gvt->dev_priv->engine[i]->mmio_base == reg) if (engine->mmio_base == reg)
return i; return id;
} }
return -1; return -1;
} }
...@@ -1304,7 +1307,7 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, ...@@ -1304,7 +1307,7 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
u32 data = *(u32 *)p_data; u32 data = *(u32 *)p_data;
int ret; int ret;
if (WARN_ON(ring_id < 0)) if (WARN_ON(ring_id < 0 || ring_id > I915_NUM_ENGINES - 1))
return -EINVAL; return -EINVAL;
execlist = &vgpu->execlist[ring_id]; execlist = &vgpu->execlist[ring_id];
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
/* common offset among interrupt control registers */ /* common offset among interrupt control registers */
#define regbase_to_isr(base) (base) #define regbase_to_isr(base) (base)
...@@ -49,7 +50,7 @@ ...@@ -49,7 +50,7 @@
static void update_upstream_irq(struct intel_vgpu *vgpu, static void update_upstream_irq(struct intel_vgpu *vgpu,
struct intel_gvt_irq_info *info); struct intel_gvt_irq_info *info);
const char * const irq_name[INTEL_GVT_EVENT_MAX] = { static const char * const irq_name[INTEL_GVT_EVENT_MAX] = {
[RCS_MI_USER_INTERRUPT] = "Render CS MI USER INTERRUPT", [RCS_MI_USER_INTERRUPT] = "Render CS MI USER INTERRUPT",
[RCS_DEBUG] = "Render EU debug from SVG", [RCS_DEBUG] = "Render EU debug from SVG",
[RCS_MMIO_SYNC_FLUSH] = "Render MMIO sync flush status", [RCS_MMIO_SYNC_FLUSH] = "Render MMIO sync flush status",
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
/** /**
* intel_vgpu_gpa_to_mmio_offset - translate a GPA to MMIO offset * intel_vgpu_gpa_to_mmio_offset - translate a GPA to MMIO offset
......
...@@ -23,10 +23,11 @@ ...@@ -23,10 +23,11 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
static int init_vgpu_opregion(struct intel_vgpu *vgpu, u32 gpa) static int init_vgpu_opregion(struct intel_vgpu *vgpu, u32 gpa)
{ {
void *host_va = vgpu->gvt->opregion.opregion_va; void __iomem *host_va = vgpu->gvt->opregion.opregion_va;
u8 *buf; u8 *buf;
int i; int i;
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
struct render_mmio { struct render_mmio {
int ring_id; int ring_id;
......
...@@ -32,13 +32,15 @@ ...@@ -32,13 +32,15 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu) static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu)
{ {
struct intel_vgpu_execlist *execlist; struct intel_vgpu_execlist *execlist;
int i; enum intel_engine_id i;
struct intel_engine_cs *engine;
for (i = 0; i < I915_NUM_ENGINES; i++) { for_each_engine(engine, vgpu->gvt->dev_priv, i) {
execlist = &vgpu->execlist[i]; execlist = &vgpu->execlist[i];
if (!list_empty(workload_q_head(vgpu, i))) if (!list_empty(workload_q_head(vgpu, i)))
return true; return true;
...@@ -50,7 +52,8 @@ static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu) ...@@ -50,7 +52,8 @@ static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu)
static void try_to_schedule_next_vgpu(struct intel_gvt *gvt) static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
{ {
struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
int i; enum intel_engine_id i;
struct intel_engine_cs *engine;
/* no target to schedule */ /* no target to schedule */
if (!scheduler->next_vgpu) if (!scheduler->next_vgpu)
...@@ -66,7 +69,7 @@ static void try_to_schedule_next_vgpu(struct intel_gvt *gvt) ...@@ -66,7 +69,7 @@ static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
scheduler->need_reschedule = true; scheduler->need_reschedule = true;
/* still have uncompleted workload? */ /* still have uncompleted workload? */
for (i = 0; i < I915_NUM_ENGINES; i++) { for_each_engine(engine, gvt->dev_priv, i) {
if (scheduler->current_workload[i]) { if (scheduler->current_workload[i]) {
gvt_dbg_sched("still have running workload\n"); gvt_dbg_sched("still have running workload\n");
return; return;
...@@ -83,7 +86,7 @@ static void try_to_schedule_next_vgpu(struct intel_gvt *gvt) ...@@ -83,7 +86,7 @@ static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
scheduler->need_reschedule = false; scheduler->need_reschedule = false;
/* wake up workload dispatch thread */ /* wake up workload dispatch thread */
for (i = 0; i < I915_NUM_ENGINES; i++) for_each_engine(engine, gvt->dev_priv, i)
wake_up(&scheduler->waitq[i]); wake_up(&scheduler->waitq[i]);
} }
...@@ -233,7 +236,7 @@ static void tbs_sched_stop_schedule(struct intel_vgpu *vgpu) ...@@ -233,7 +236,7 @@ static void tbs_sched_stop_schedule(struct intel_vgpu *vgpu)
list_del_init(&vgpu_data->list); list_del_init(&vgpu_data->list);
} }
struct intel_gvt_sched_policy_ops tbs_schedule_ops = { static struct intel_gvt_sched_policy_ops tbs_schedule_ops = {
.init = tbs_sched_init, .init = tbs_sched_init,
.clean = tbs_sched_clean, .clean = tbs_sched_clean,
.init_vgpu = tbs_sched_init_vgpu, .init_vgpu = tbs_sched_init_vgpu,
......
...@@ -33,14 +33,16 @@ ...@@ -33,14 +33,16 @@
* *
*/ */
#include "i915_drv.h"
#include <linux/kthread.h> #include <linux/kthread.h>
#include "i915_drv.h"
#include "gvt.h"
#define RING_CTX_OFF(x) \ #define RING_CTX_OFF(x) \
offsetof(struct execlist_ring_context, x) offsetof(struct execlist_ring_context, x)
void set_context_pdp_root_pointer(struct execlist_ring_context *ring_context, static void set_context_pdp_root_pointer(
struct execlist_ring_context *ring_context,
u32 pdp[8]) u32 pdp[8])
{ {
struct execlist_mmio_pair *pdp_pair = &ring_context->pdp3_UDW; struct execlist_mmio_pair *pdp_pair = &ring_context->pdp3_UDW;
...@@ -163,6 +165,7 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) ...@@ -163,6 +165,7 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
int ring_id = workload->ring_id; int ring_id = workload->ring_id;
struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx; struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx;
struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv; struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
struct drm_i915_gem_request *rq;
int ret; int ret;
gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n", gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n",
...@@ -171,17 +174,16 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) ...@@ -171,17 +174,16 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
shadow_ctx->desc_template = workload->ctx_desc.addressing_mode << shadow_ctx->desc_template = workload->ctx_desc.addressing_mode <<
GEN8_CTX_ADDRESSING_MODE_SHIFT; GEN8_CTX_ADDRESSING_MODE_SHIFT;
workload->req = i915_gem_request_alloc(dev_priv->engine[ring_id], rq = i915_gem_request_alloc(dev_priv->engine[ring_id], shadow_ctx);
shadow_ctx); if (IS_ERR(rq)) {
if (IS_ERR_OR_NULL(workload->req)) {
gvt_err("fail to allocate gem request\n"); gvt_err("fail to allocate gem request\n");
workload->status = PTR_ERR(workload->req); workload->status = PTR_ERR(rq);
workload->req = NULL;
return workload->status; return workload->status;
} }
gvt_dbg_sched("ring id %d get i915 gem request %p\n", gvt_dbg_sched("ring id %d get i915 gem request %p\n", ring_id, rq);
ring_id, workload->req);
workload->req = i915_gem_request_get(rq);
mutex_lock(&gvt->lock); mutex_lock(&gvt->lock);
...@@ -208,16 +210,15 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) ...@@ -208,16 +210,15 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
gvt_dbg_sched("ring id %d submit workload to i915 %p\n", gvt_dbg_sched("ring id %d submit workload to i915 %p\n",
ring_id, workload->req); ring_id, workload->req);
i915_add_request_no_flush(workload->req); i915_add_request_no_flush(rq);
workload->dispatched = true; workload->dispatched = true;
return 0; return 0;
err: err:
workload->status = ret; workload->status = ret;
if (workload->req)
workload->req = NULL;
mutex_unlock(&gvt->lock); mutex_unlock(&gvt->lock);
i915_add_request_no_flush(rq);
return ret; return ret;
} }
...@@ -390,6 +391,8 @@ struct workload_thread_param { ...@@ -390,6 +391,8 @@ struct workload_thread_param {
int ring_id; int ring_id;
}; };
static DEFINE_MUTEX(scheduler_mutex);
static int workload_thread(void *priv) static int workload_thread(void *priv)
{ {
struct workload_thread_param *p = (struct workload_thread_param *)priv; struct workload_thread_param *p = (struct workload_thread_param *)priv;
...@@ -414,22 +417,14 @@ static int workload_thread(void *priv) ...@@ -414,22 +417,14 @@ static int workload_thread(void *priv)
if (kthread_should_stop()) if (kthread_should_stop())
break; break;
mutex_lock(&scheduler_mutex);
gvt_dbg_sched("ring id %d next workload %p vgpu %d\n", gvt_dbg_sched("ring id %d next workload %p vgpu %d\n",
workload->ring_id, workload, workload->ring_id, workload,
workload->vgpu->id); workload->vgpu->id);
intel_runtime_pm_get(gvt->dev_priv); intel_runtime_pm_get(gvt->dev_priv);
/*
* Always take i915 big lock first
*/
ret = i915_mutex_lock_interruptible(&gvt->dev_priv->drm);
if (ret < 0) {
gvt_err("i915 submission is not available, retry\n");
schedule_timeout(1);
continue;
}
gvt_dbg_sched("ring id %d will dispatch workload %p\n", gvt_dbg_sched("ring id %d will dispatch workload %p\n",
workload->ring_id, workload); workload->ring_id, workload);
...@@ -437,7 +432,10 @@ static int workload_thread(void *priv) ...@@ -437,7 +432,10 @@ static int workload_thread(void *priv)
intel_uncore_forcewake_get(gvt->dev_priv, intel_uncore_forcewake_get(gvt->dev_priv,
FORCEWAKE_ALL); FORCEWAKE_ALL);
mutex_lock(&gvt->dev_priv->drm.struct_mutex);
ret = dispatch_workload(workload); ret = dispatch_workload(workload);
mutex_unlock(&gvt->dev_priv->drm.struct_mutex);
if (ret) { if (ret) {
gvt_err("fail to dispatch workload, skip\n"); gvt_err("fail to dispatch workload, skip\n");
goto complete; goto complete;
...@@ -447,8 +445,7 @@ static int workload_thread(void *priv) ...@@ -447,8 +445,7 @@ static int workload_thread(void *priv)
workload->ring_id, workload); workload->ring_id, workload);
workload->status = i915_wait_request(workload->req, workload->status = i915_wait_request(workload->req,
I915_WAIT_INTERRUPTIBLE | I915_WAIT_LOCKED, 0, NULL, NULL);
NULL, NULL);
if (workload->status != 0) if (workload->status != 0)
gvt_err("fail to wait workload, skip\n"); gvt_err("fail to wait workload, skip\n");
...@@ -456,15 +453,20 @@ static int workload_thread(void *priv) ...@@ -456,15 +453,20 @@ static int workload_thread(void *priv)
gvt_dbg_sched("will complete workload %p\n, status: %d\n", gvt_dbg_sched("will complete workload %p\n, status: %d\n",
workload, workload->status); workload, workload->status);
mutex_lock(&gvt->dev_priv->drm.struct_mutex);
complete_current_workload(gvt, ring_id); complete_current_workload(gvt, ring_id);
mutex_unlock(&gvt->dev_priv->drm.struct_mutex);
i915_gem_request_put(fetch_and_zero(&workload->req));
if (need_force_wake) if (need_force_wake)
intel_uncore_forcewake_put(gvt->dev_priv, intel_uncore_forcewake_put(gvt->dev_priv,
FORCEWAKE_ALL); FORCEWAKE_ALL);
mutex_unlock(&gvt->dev_priv->drm.struct_mutex);
intel_runtime_pm_put(gvt->dev_priv); intel_runtime_pm_put(gvt->dev_priv);
mutex_unlock(&scheduler_mutex);
} }
return 0; return 0;
} }
...@@ -509,6 +511,10 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt) ...@@ -509,6 +511,10 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
init_waitqueue_head(&scheduler->workload_complete_wq); init_waitqueue_head(&scheduler->workload_complete_wq);
for (i = 0; i < I915_NUM_ENGINES; i++) { for (i = 0; i < I915_NUM_ENGINES; i++) {
/* check ring mask at init time */
if (!HAS_ENGINE(gvt->dev_priv, i))
continue;
init_waitqueue_head(&scheduler->waitq[i]); init_waitqueue_head(&scheduler->waitq[i]);
param = kzalloc(sizeof(*param), GFP_KERNEL); param = kzalloc(sizeof(*param), GFP_KERNEL);
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "gvt.h"
#include "i915_pvinfo.h"
static void clean_vgpu_mmio(struct intel_vgpu *vgpu) static void clean_vgpu_mmio(struct intel_vgpu *vgpu)
{ {
......
...@@ -1777,7 +1777,7 @@ struct drm_i915_private { ...@@ -1777,7 +1777,7 @@ struct drm_i915_private {
struct i915_virtual_gpu vgpu; struct i915_virtual_gpu vgpu;
struct intel_gvt gvt; struct intel_gvt *gvt;
struct intel_guc guc; struct intel_guc guc;
...@@ -2993,7 +2993,7 @@ int intel_wait_for_register_fw(struct drm_i915_private *dev_priv, ...@@ -2993,7 +2993,7 @@ int intel_wait_for_register_fw(struct drm_i915_private *dev_priv,
static inline bool intel_gvt_active(struct drm_i915_private *dev_priv) static inline bool intel_gvt_active(struct drm_i915_private *dev_priv)
{ {
return dev_priv->gvt.initialized; return dev_priv->gvt;
} }
static inline bool intel_vgpu_active(struct drm_i915_private *dev_priv) static inline bool intel_vgpu_active(struct drm_i915_private *dev_priv)
......
...@@ -31,8 +31,12 @@ ...@@ -31,8 +31,12 @@
* GPU among multiple virtual machines on a time-sharing basis. Each * GPU among multiple virtual machines on a time-sharing basis. Each
* virtual machine is presented a virtual GPU (vGPU), which has equivalent * virtual machine is presented a virtual GPU (vGPU), which has equivalent
* features as the underlying physical GPU (pGPU), so i915 driver can run * features as the underlying physical GPU (pGPU), so i915 driver can run
* seamlessly in a virtual machine. This file provides the englightments * seamlessly in a virtual machine.
* of GVT and the necessary components used by GVT in i915 driver. *
* To virtualize GPU resources GVT-g driver depends on hypervisor technology
* e.g KVM/VFIO/mdev, Xen, etc. to provide resource access trapping capability
* and be virtualized within GVT-g device module. More architectural design
* doc is available on https://01.org/group/2230/documentation-list.
*/ */
static bool is_supported_device(struct drm_i915_private *dev_priv) static bool is_supported_device(struct drm_i915_private *dev_priv)
......
...@@ -24,8 +24,7 @@ ...@@ -24,8 +24,7 @@
#ifndef _INTEL_GVT_H_ #ifndef _INTEL_GVT_H_
#define _INTEL_GVT_H_ #define _INTEL_GVT_H_
#include "i915_pvinfo.h" struct intel_gvt;
#include "gvt/gvt.h"
#ifdef CONFIG_DRM_I915_GVT #ifdef CONFIG_DRM_I915_GVT
int intel_gvt_init(struct drm_i915_private *dev_priv); int intel_gvt_init(struct drm_i915_private *dev_priv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment