1 1.1 riastrad /* $NetBSD: scheduler.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright(c) 2011-2016 Intel Corporation. All rights reserved. 5 1.1 riastrad * 6 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 7 1.1 riastrad * copy of this software and associated documentation files (the "Software"), 8 1.1 riastrad * to deal in the Software without restriction, including without limitation 9 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the 11 1.1 riastrad * Software is furnished to do so, subject to the following conditions: 12 1.1 riastrad * 13 1.1 riastrad * The above copyright notice and this permission notice (including the next 14 1.1 riastrad * paragraph) shall be included in all copies or substantial portions of the 15 1.1 riastrad * Software. 16 1.1 riastrad * 17 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 1.1 riastrad * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 1.1 riastrad * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 1.1 riastrad * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 1.1 riastrad * SOFTWARE. 24 1.1 riastrad * 25 1.1 riastrad * Authors: 26 1.1 riastrad * Zhi Wang <zhi.a.wang (at) intel.com> 27 1.1 riastrad * 28 1.1 riastrad * Contributors: 29 1.1 riastrad * Ping Gao <ping.a.gao (at) intel.com> 30 1.1 riastrad * Tina Zhang <tina.zhang (at) intel.com> 31 1.1 riastrad * Chanbin Du <changbin.du (at) intel.com> 32 1.1 riastrad * Min He <min.he (at) intel.com> 33 1.1 riastrad * Bing Niu <bing.niu (at) intel.com> 34 1.1 riastrad * Zhenyu Wang <zhenyuw (at) linux.intel.com> 35 1.1 riastrad * 36 1.1 riastrad */ 37 1.1 riastrad 38 1.1 riastrad #include <sys/cdefs.h> 39 1.1 riastrad __KERNEL_RCSID(0, "$NetBSD: scheduler.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $"); 40 1.1 riastrad 41 1.1 riastrad #include <linux/kthread.h> 42 1.1 riastrad 43 1.1 riastrad #include "gem/i915_gem_pm.h" 44 1.1 riastrad #include "gt/intel_context.h" 45 1.1 riastrad #include "gt/intel_ring.h" 46 1.1 riastrad 47 1.1 riastrad #include "i915_drv.h" 48 1.1 riastrad #include "i915_gem_gtt.h" 49 1.1 riastrad #include "gvt.h" 50 1.1 riastrad 51 1.1 riastrad #define RING_CTX_OFF(x) \ 52 1.1 riastrad offsetof(struct execlist_ring_context, x) 53 1.1 riastrad 54 1.1 riastrad static void set_context_pdp_root_pointer( 55 1.1 riastrad struct execlist_ring_context *ring_context, 56 1.1 riastrad u32 pdp[8]) 57 1.1 riastrad { 58 1.1 riastrad int i; 59 1.1 riastrad 60 1.1 riastrad for (i = 0; i < 8; i++) 61 1.1 riastrad ring_context->pdps[i].val = pdp[7 - i]; 62 1.1 riastrad } 63 1.1 riastrad 64 1.1 riastrad static void update_shadow_pdps(struct intel_vgpu_workload *workload) 65 1.1 riastrad { 66 1.1 riastrad struct drm_i915_gem_object *ctx_obj = 67 1.1 riastrad workload->req->context->state->obj; 68 1.1 riastrad struct execlist_ring_context *shadow_ring_context; 69 1.1 riastrad struct page *page; 70 1.1 riastrad 71 1.1 riastrad if (WARN_ON(!workload->shadow_mm)) 72 1.1 riastrad return; 73 1.1 riastrad 74 1.1 riastrad if (WARN_ON(!atomic_read(&workload->shadow_mm->pincount))) 75 1.1 riastrad return; 76 1.1 riastrad 77 1.1 riastrad page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN); 78 1.1 riastrad shadow_ring_context = kmap(page); 79 1.1 riastrad set_context_pdp_root_pointer(shadow_ring_context, 80 1.1 riastrad (void *)workload->shadow_mm->ppgtt_mm.shadow_pdps); 81 1.1 riastrad kunmap(page); 82 1.1 riastrad } 83 1.1 riastrad 84 1.1 riastrad /* 85 1.1 riastrad * when populating shadow ctx from guest, we should not overrride oa related 86 1.1 riastrad * registers, so that they will not be overlapped by guest oa configs. Thus 87 1.1 riastrad * made it possible to capture oa data from host for both host and guests. 88 1.1 riastrad */ 89 1.1 riastrad static void sr_oa_regs(struct intel_vgpu_workload *workload, 90 1.1 riastrad u32 *reg_state, bool save) 91 1.1 riastrad { 92 1.1 riastrad struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv; 93 1.1 riastrad u32 ctx_oactxctrl = dev_priv->perf.ctx_oactxctrl_offset; 94 1.1 riastrad u32 ctx_flexeu0 = dev_priv->perf.ctx_flexeu0_offset; 95 1.1 riastrad int i = 0; 96 1.1 riastrad u32 flex_mmio[] = { 97 1.1 riastrad i915_mmio_reg_offset(EU_PERF_CNTL0), 98 1.1 riastrad i915_mmio_reg_offset(EU_PERF_CNTL1), 99 1.1 riastrad i915_mmio_reg_offset(EU_PERF_CNTL2), 100 1.1 riastrad i915_mmio_reg_offset(EU_PERF_CNTL3), 101 1.1 riastrad i915_mmio_reg_offset(EU_PERF_CNTL4), 102 1.1 riastrad i915_mmio_reg_offset(EU_PERF_CNTL5), 103 1.1 riastrad i915_mmio_reg_offset(EU_PERF_CNTL6), 104 1.1 riastrad }; 105 1.1 riastrad 106 1.1 riastrad if (workload->ring_id != RCS0) 107 1.1 riastrad return; 108 1.1 riastrad 109 1.1 riastrad if (save) { 110 1.1 riastrad workload->oactxctrl = reg_state[ctx_oactxctrl + 1]; 111 1.1 riastrad 112 1.1 riastrad for (i = 0; i < ARRAY_SIZE(workload->flex_mmio); i++) { 113 1.1 riastrad u32 state_offset = ctx_flexeu0 + i * 2; 114 1.1 riastrad 115 1.1 riastrad workload->flex_mmio[i] = reg_state[state_offset + 1]; 116 1.1 riastrad } 117 1.1 riastrad } else { 118 1.1 riastrad reg_state[ctx_oactxctrl] = 119 1.1 riastrad i915_mmio_reg_offset(GEN8_OACTXCONTROL); 120 1.1 riastrad reg_state[ctx_oactxctrl + 1] = workload->oactxctrl; 121 1.1 riastrad 122 1.1 riastrad for (i = 0; i < ARRAY_SIZE(workload->flex_mmio); i++) { 123 1.1 riastrad u32 state_offset = ctx_flexeu0 + i * 2; 124 1.1 riastrad u32 mmio = flex_mmio[i]; 125 1.1 riastrad 126 1.1 riastrad reg_state[state_offset] = mmio; 127 1.1 riastrad reg_state[state_offset + 1] = workload->flex_mmio[i]; 128 1.1 riastrad } 129 1.1 riastrad } 130 1.1 riastrad } 131 1.1 riastrad 132 1.1 riastrad static int populate_shadow_context(struct intel_vgpu_workload *workload) 133 1.1 riastrad { 134 1.1 riastrad struct intel_vgpu *vgpu = workload->vgpu; 135 1.1 riastrad struct intel_gvt *gvt = vgpu->gvt; 136 1.1 riastrad int ring_id = workload->ring_id; 137 1.1 riastrad struct drm_i915_gem_object *ctx_obj = 138 1.1 riastrad workload->req->context->state->obj; 139 1.1 riastrad struct execlist_ring_context *shadow_ring_context; 140 1.1 riastrad struct page *page; 141 1.1 riastrad void *dst; 142 1.1 riastrad unsigned long context_gpa, context_page_num; 143 1.1 riastrad int i; 144 1.1 riastrad 145 1.1 riastrad page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN); 146 1.1 riastrad shadow_ring_context = kmap(page); 147 1.1 riastrad 148 1.1 riastrad sr_oa_regs(workload, (u32 *)shadow_ring_context, true); 149 1.1 riastrad #define COPY_REG(name) \ 150 1.1 riastrad intel_gvt_hypervisor_read_gpa(vgpu, workload->ring_context_gpa \ 151 1.1 riastrad + RING_CTX_OFF(name.val), &shadow_ring_context->name.val, 4) 152 1.1 riastrad #define COPY_REG_MASKED(name) {\ 153 1.1 riastrad intel_gvt_hypervisor_read_gpa(vgpu, workload->ring_context_gpa \ 154 1.1 riastrad + RING_CTX_OFF(name.val),\ 155 1.1 riastrad &shadow_ring_context->name.val, 4);\ 156 1.1 riastrad shadow_ring_context->name.val |= 0xffff << 16;\ 157 1.1 riastrad } 158 1.1 riastrad 159 1.1 riastrad COPY_REG_MASKED(ctx_ctrl); 160 1.1 riastrad COPY_REG(ctx_timestamp); 161 1.1 riastrad 162 1.1 riastrad if (ring_id == RCS0) { 163 1.1 riastrad COPY_REG(bb_per_ctx_ptr); 164 1.1 riastrad COPY_REG(rcs_indirect_ctx); 165 1.1 riastrad COPY_REG(rcs_indirect_ctx_offset); 166 1.1 riastrad } 167 1.1 riastrad #undef COPY_REG 168 1.1 riastrad #undef COPY_REG_MASKED 169 1.1 riastrad 170 1.1 riastrad intel_gvt_hypervisor_read_gpa(vgpu, 171 1.1 riastrad workload->ring_context_gpa + 172 1.1 riastrad sizeof(*shadow_ring_context), 173 1.1 riastrad (void *)shadow_ring_context + 174 1.1 riastrad sizeof(*shadow_ring_context), 175 1.1 riastrad I915_GTT_PAGE_SIZE - sizeof(*shadow_ring_context)); 176 1.1 riastrad 177 1.1 riastrad sr_oa_regs(workload, (u32 *)shadow_ring_context, false); 178 1.1 riastrad kunmap(page); 179 1.1 riastrad 180 1.1 riastrad if (IS_RESTORE_INHIBIT(shadow_ring_context->ctx_ctrl.val)) 181 1.1 riastrad return 0; 182 1.1 riastrad 183 1.1 riastrad gvt_dbg_sched("ring id %d workload lrca %x", ring_id, 184 1.1 riastrad workload->ctx_desc.lrca); 185 1.1 riastrad 186 1.1 riastrad context_page_num = gvt->dev_priv->engine[ring_id]->context_size; 187 1.1 riastrad 188 1.1 riastrad context_page_num = context_page_num >> PAGE_SHIFT; 189 1.1 riastrad 190 1.1 riastrad if (IS_BROADWELL(gvt->dev_priv) && ring_id == RCS0) 191 1.1 riastrad context_page_num = 19; 192 1.1 riastrad 193 1.1 riastrad i = 2; 194 1.1 riastrad while (i < context_page_num) { 195 1.1 riastrad context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, 196 1.1 riastrad (u32)((workload->ctx_desc.lrca + i) << 197 1.1 riastrad I915_GTT_PAGE_SHIFT)); 198 1.1 riastrad if (context_gpa == INTEL_GVT_INVALID_ADDR) { 199 1.1 riastrad gvt_vgpu_err("Invalid guest context descriptor\n"); 200 1.1 riastrad return -EFAULT; 201 1.1 riastrad } 202 1.1 riastrad 203 1.1 riastrad page = i915_gem_object_get_page(ctx_obj, i); 204 1.1 riastrad dst = kmap(page); 205 1.1 riastrad intel_gvt_hypervisor_read_gpa(vgpu, context_gpa, dst, 206 1.1 riastrad I915_GTT_PAGE_SIZE); 207 1.1 riastrad kunmap(page); 208 1.1 riastrad i++; 209 1.1 riastrad } 210 1.1 riastrad return 0; 211 1.1 riastrad } 212 1.1 riastrad 213 1.1 riastrad static inline bool is_gvt_request(struct i915_request *rq) 214 1.1 riastrad { 215 1.1 riastrad return intel_context_force_single_submission(rq->context); 216 1.1 riastrad } 217 1.1 riastrad 218 1.1 riastrad static void save_ring_hw_state(struct intel_vgpu *vgpu, int ring_id) 219 1.1 riastrad { 220 1.1 riastrad struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 221 1.1 riastrad u32 ring_base = dev_priv->engine[ring_id]->mmio_base; 222 1.1 riastrad i915_reg_t reg; 223 1.1 riastrad 224 1.1 riastrad reg = RING_INSTDONE(ring_base); 225 1.1 riastrad vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg); 226 1.1 riastrad reg = RING_ACTHD(ring_base); 227 1.1 riastrad vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg); 228 1.1 riastrad reg = RING_ACTHD_UDW(ring_base); 229 1.1 riastrad vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg); 230 1.1 riastrad } 231 1.1 riastrad 232 1.1 riastrad static int shadow_context_status_change(struct notifier_block *nb, 233 1.1 riastrad unsigned long action, void *data) 234 1.1 riastrad { 235 1.1 riastrad struct i915_request *req = data; 236 1.1 riastrad struct intel_gvt *gvt = container_of(nb, struct intel_gvt, 237 1.1 riastrad shadow_ctx_notifier_block[req->engine->id]); 238 1.1 riastrad struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; 239 1.1 riastrad enum intel_engine_id ring_id = req->engine->id; 240 1.1 riastrad struct intel_vgpu_workload *workload; 241 1.1 riastrad unsigned long flags; 242 1.1 riastrad 243 1.1 riastrad if (!is_gvt_request(req)) { 244 1.1 riastrad spin_lock_irqsave(&scheduler->mmio_context_lock, flags); 245 1.1 riastrad if (action == INTEL_CONTEXT_SCHEDULE_IN && 246 1.1 riastrad scheduler->engine_owner[ring_id]) { 247 1.1 riastrad /* Switch ring from vGPU to host. */ 248 1.1 riastrad intel_gvt_switch_mmio(scheduler->engine_owner[ring_id], 249 1.1 riastrad NULL, ring_id); 250 1.1 riastrad scheduler->engine_owner[ring_id] = NULL; 251 1.1 riastrad } 252 1.1 riastrad spin_unlock_irqrestore(&scheduler->mmio_context_lock, flags); 253 1.1 riastrad 254 1.1 riastrad return NOTIFY_OK; 255 1.1 riastrad } 256 1.1 riastrad 257 1.1 riastrad workload = scheduler->current_workload[ring_id]; 258 1.1 riastrad if (unlikely(!workload)) 259 1.1 riastrad return NOTIFY_OK; 260 1.1 riastrad 261 1.1 riastrad switch (action) { 262 1.1 riastrad case INTEL_CONTEXT_SCHEDULE_IN: 263 1.1 riastrad spin_lock_irqsave(&scheduler->mmio_context_lock, flags); 264 1.1 riastrad if (workload->vgpu != scheduler->engine_owner[ring_id]) { 265 1.1 riastrad /* Switch ring from host to vGPU or vGPU to vGPU. */ 266 1.1 riastrad intel_gvt_switch_mmio(scheduler->engine_owner[ring_id], 267 1.1 riastrad workload->vgpu, ring_id); 268 1.1 riastrad scheduler->engine_owner[ring_id] = workload->vgpu; 269 1.1 riastrad } else 270 1.1 riastrad gvt_dbg_sched("skip ring %d mmio switch for vgpu%d\n", 271 1.1 riastrad ring_id, workload->vgpu->id); 272 1.1 riastrad spin_unlock_irqrestore(&scheduler->mmio_context_lock, flags); 273 1.1 riastrad atomic_set(&workload->shadow_ctx_active, 1); 274 1.1 riastrad break; 275 1.1 riastrad case INTEL_CONTEXT_SCHEDULE_OUT: 276 1.1 riastrad save_ring_hw_state(workload->vgpu, ring_id); 277 1.1 riastrad atomic_set(&workload->shadow_ctx_active, 0); 278 1.1 riastrad break; 279 1.1 riastrad case INTEL_CONTEXT_SCHEDULE_PREEMPTED: 280 1.1 riastrad save_ring_hw_state(workload->vgpu, ring_id); 281 1.1 riastrad break; 282 1.1 riastrad default: 283 1.1 riastrad WARN_ON(1); 284 1.1 riastrad return NOTIFY_OK; 285 1.1 riastrad } 286 1.1 riastrad wake_up(&workload->shadow_ctx_status_wq); 287 1.1 riastrad return NOTIFY_OK; 288 1.1 riastrad } 289 1.1 riastrad 290 1.1 riastrad static void 291 1.1 riastrad shadow_context_descriptor_update(struct intel_context *ce, 292 1.1 riastrad struct intel_vgpu_workload *workload) 293 1.1 riastrad { 294 1.1 riastrad u64 desc = ce->lrc_desc; 295 1.1 riastrad 296 1.1 riastrad /* 297 1.1 riastrad * Update bits 0-11 of the context descriptor which includes flags 298 1.1 riastrad * like GEN8_CTX_* cached in desc_template 299 1.1 riastrad */ 300 1.1 riastrad desc &= ~(0x3 << GEN8_CTX_ADDRESSING_MODE_SHIFT); 301 1.1 riastrad desc |= workload->ctx_desc.addressing_mode << 302 1.1 riastrad GEN8_CTX_ADDRESSING_MODE_SHIFT; 303 1.1 riastrad 304 1.1 riastrad ce->lrc_desc = desc; 305 1.1 riastrad } 306 1.1 riastrad 307 1.1 riastrad static int copy_workload_to_ring_buffer(struct intel_vgpu_workload *workload) 308 1.1 riastrad { 309 1.1 riastrad struct intel_vgpu *vgpu = workload->vgpu; 310 1.1 riastrad struct i915_request *req = workload->req; 311 1.1 riastrad void *shadow_ring_buffer_va; 312 1.1 riastrad u32 *cs; 313 1.1 riastrad int err; 314 1.1 riastrad 315 1.1 riastrad if (IS_GEN(req->i915, 9) && is_inhibit_context(req->context)) 316 1.1 riastrad intel_vgpu_restore_inhibit_context(vgpu, req); 317 1.1 riastrad 318 1.1 riastrad /* 319 1.1 riastrad * To track whether a request has started on HW, we can emit a 320 1.1 riastrad * breadcrumb at the beginning of the request and check its 321 1.1 riastrad * timeline's HWSP to see if the breadcrumb has advanced past the 322 1.1 riastrad * start of this request. Actually, the request must have the 323 1.1 riastrad * init_breadcrumb if its timeline set has_init_bread_crumb, or the 324 1.1 riastrad * scheduler might get a wrong state of it during reset. Since the 325 1.1 riastrad * requests from gvt always set the has_init_breadcrumb flag, here 326 1.1 riastrad * need to do the emit_init_breadcrumb for all the requests. 327 1.1 riastrad */ 328 1.1 riastrad if (req->engine->emit_init_breadcrumb) { 329 1.1 riastrad err = req->engine->emit_init_breadcrumb(req); 330 1.1 riastrad if (err) { 331 1.1 riastrad gvt_vgpu_err("fail to emit init breadcrumb\n"); 332 1.1 riastrad return err; 333 1.1 riastrad } 334 1.1 riastrad } 335 1.1 riastrad 336 1.1 riastrad /* allocate shadow ring buffer */ 337 1.1 riastrad cs = intel_ring_begin(workload->req, workload->rb_len / sizeof(u32)); 338 1.1 riastrad if (IS_ERR(cs)) { 339 1.1 riastrad gvt_vgpu_err("fail to alloc size =%ld shadow ring buffer\n", 340 1.1 riastrad workload->rb_len); 341 1.1 riastrad return PTR_ERR(cs); 342 1.1 riastrad } 343 1.1 riastrad 344 1.1 riastrad shadow_ring_buffer_va = workload->shadow_ring_buffer_va; 345 1.1 riastrad 346 1.1 riastrad /* get shadow ring buffer va */ 347 1.1 riastrad workload->shadow_ring_buffer_va = cs; 348 1.1 riastrad 349 1.1 riastrad memcpy(cs, shadow_ring_buffer_va, 350 1.1 riastrad workload->rb_len); 351 1.1 riastrad 352 1.1 riastrad cs += workload->rb_len / sizeof(u32); 353 1.1 riastrad intel_ring_advance(workload->req, cs); 354 1.1 riastrad 355 1.1 riastrad return 0; 356 1.1 riastrad } 357 1.1 riastrad 358 1.1 riastrad static void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) 359 1.1 riastrad { 360 1.1 riastrad if (!wa_ctx->indirect_ctx.obj) 361 1.1 riastrad return; 362 1.1 riastrad 363 1.1 riastrad i915_gem_object_unpin_map(wa_ctx->indirect_ctx.obj); 364 1.1 riastrad i915_gem_object_put(wa_ctx->indirect_ctx.obj); 365 1.1 riastrad 366 1.1 riastrad wa_ctx->indirect_ctx.obj = NULL; 367 1.1 riastrad wa_ctx->indirect_ctx.shadow_va = NULL; 368 1.1 riastrad } 369 1.1 riastrad 370 1.1 riastrad static void set_context_ppgtt_from_shadow(struct intel_vgpu_workload *workload, 371 1.1 riastrad struct intel_context *ce) 372 1.1 riastrad { 373 1.1 riastrad struct intel_vgpu_mm *mm = workload->shadow_mm; 374 1.1 riastrad struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(ce->vm); 375 1.1 riastrad int i = 0; 376 1.1 riastrad 377 1.1 riastrad if (mm->ppgtt_mm.root_entry_type == GTT_TYPE_PPGTT_ROOT_L4_ENTRY) { 378 1.1 riastrad px_dma(ppgtt->pd) = mm->ppgtt_mm.shadow_pdps[0]; 379 1.1 riastrad } else { 380 1.1 riastrad for (i = 0; i < GVT_RING_CTX_NR_PDPS; i++) { 381 1.1 riastrad struct i915_page_directory * const pd = 382 1.1 riastrad i915_pd_entry(ppgtt->pd, i); 383 1.1 riastrad 384 1.1 riastrad px_dma(pd) = mm->ppgtt_mm.shadow_pdps[i]; 385 1.1 riastrad } 386 1.1 riastrad } 387 1.1 riastrad } 388 1.1 riastrad 389 1.1 riastrad static int 390 1.1 riastrad intel_gvt_workload_req_alloc(struct intel_vgpu_workload *workload) 391 1.1 riastrad { 392 1.1 riastrad struct intel_vgpu *vgpu = workload->vgpu; 393 1.1 riastrad struct intel_vgpu_submission *s = &vgpu->submission; 394 1.1 riastrad struct i915_request *rq; 395 1.1 riastrad 396 1.1 riastrad if (workload->req) 397 1.1 riastrad return 0; 398 1.1 riastrad 399 1.1 riastrad rq = i915_request_create(s->shadow[workload->ring_id]); 400 1.1 riastrad if (IS_ERR(rq)) { 401 1.1 riastrad gvt_vgpu_err("fail to allocate gem request\n"); 402 1.1 riastrad return PTR_ERR(rq); 403 1.1 riastrad } 404 1.1 riastrad 405 1.1 riastrad workload->req = i915_request_get(rq); 406 1.1 riastrad return 0; 407 1.1 riastrad } 408 1.1 riastrad 409 1.1 riastrad /** 410 1.1 riastrad * intel_gvt_scan_and_shadow_workload - audit the workload by scanning and 411 1.1 riastrad * shadow it as well, include ringbuffer,wa_ctx and ctx. 412 1.1 riastrad * @workload: an abstract entity for each execlist submission. 413 1.1 riastrad * 414 1.1 riastrad * This function is called before the workload submitting to i915, to make 415 1.1 riastrad * sure the content of the workload is valid. 416 1.1 riastrad */ 417 1.1 riastrad int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload) 418 1.1 riastrad { 419 1.1 riastrad struct intel_vgpu *vgpu = workload->vgpu; 420 1.1 riastrad struct intel_vgpu_submission *s = &vgpu->submission; 421 1.1 riastrad int ret; 422 1.1 riastrad 423 1.1 riastrad lockdep_assert_held(&vgpu->vgpu_lock); 424 1.1 riastrad 425 1.1 riastrad if (workload->shadow) 426 1.1 riastrad return 0; 427 1.1 riastrad 428 1.1 riastrad if (!test_and_set_bit(workload->ring_id, s->shadow_ctx_desc_updated)) 429 1.1 riastrad shadow_context_descriptor_update(s->shadow[workload->ring_id], 430 1.1 riastrad workload); 431 1.1 riastrad 432 1.1 riastrad ret = intel_gvt_scan_and_shadow_ringbuffer(workload); 433 1.1 riastrad if (ret) 434 1.1 riastrad return ret; 435 1.1 riastrad 436 1.1 riastrad if (workload->ring_id == RCS0 && workload->wa_ctx.indirect_ctx.size) { 437 1.1 riastrad ret = intel_gvt_scan_and_shadow_wa_ctx(&workload->wa_ctx); 438 1.1 riastrad if (ret) 439 1.1 riastrad goto err_shadow; 440 1.1 riastrad } 441 1.1 riastrad 442 1.1 riastrad workload->shadow = true; 443 1.1 riastrad return 0; 444 1.1 riastrad err_shadow: 445 1.1 riastrad release_shadow_wa_ctx(&workload->wa_ctx); 446 1.1 riastrad return ret; 447 1.1 riastrad } 448 1.1 riastrad 449 1.1 riastrad static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload); 450 1.1 riastrad 451 1.1 riastrad static int prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload) 452 1.1 riastrad { 453 1.1 riastrad struct intel_gvt *gvt = workload->vgpu->gvt; 454 1.1 riastrad const int gmadr_bytes = gvt->device_info.gmadr_bytes_in_cmd; 455 1.1 riastrad struct intel_vgpu_shadow_bb *bb; 456 1.1 riastrad int ret; 457 1.1 riastrad 458 1.1 riastrad list_for_each_entry(bb, &workload->shadow_bb, list) { 459 1.1 riastrad /* For privilge batch buffer and not wa_ctx, the bb_start_cmd_va 460 1.1 riastrad * is only updated into ring_scan_buffer, not real ring address 461 1.1 riastrad * allocated in later copy_workload_to_ring_buffer. pls be noted 462 1.1 riastrad * shadow_ring_buffer_va is now pointed to real ring buffer va 463 1.1 riastrad * in copy_workload_to_ring_buffer. 464 1.1 riastrad */ 465 1.1 riastrad 466 1.1 riastrad if (bb->bb_offset) 467 1.1 riastrad bb->bb_start_cmd_va = workload->shadow_ring_buffer_va 468 1.1 riastrad + bb->bb_offset; 469 1.1 riastrad 470 1.1 riastrad if (bb->ppgtt) { 471 1.1 riastrad /* for non-priv bb, scan&shadow is only for 472 1.1 riastrad * debugging purpose, so the content of shadow bb 473 1.1 riastrad * is the same as original bb. Therefore, 474 1.1 riastrad * here, rather than switch to shadow bb's gma 475 1.1 riastrad * address, we directly use original batch buffer's 476 1.1 riastrad * gma address, and send original bb to hardware 477 1.1 riastrad * directly 478 1.1 riastrad */ 479 1.1 riastrad if (bb->clflush & CLFLUSH_AFTER) { 480 1.1 riastrad drm_clflush_virt_range(bb->va, 481 1.1 riastrad bb->obj->base.size); 482 1.1 riastrad bb->clflush &= ~CLFLUSH_AFTER; 483 1.1 riastrad } 484 1.1 riastrad i915_gem_object_finish_access(bb->obj); 485 1.1 riastrad bb->accessing = false; 486 1.1 riastrad 487 1.1 riastrad } else { 488 1.1 riastrad bb->vma = i915_gem_object_ggtt_pin(bb->obj, 489 1.1 riastrad NULL, 0, 0, 0); 490 1.1 riastrad if (IS_ERR(bb->vma)) { 491 1.1 riastrad ret = PTR_ERR(bb->vma); 492 1.1 riastrad goto err; 493 1.1 riastrad } 494 1.1 riastrad 495 1.1 riastrad /* relocate shadow batch buffer */ 496 1.1 riastrad bb->bb_start_cmd_va[1] = i915_ggtt_offset(bb->vma); 497 1.1 riastrad if (gmadr_bytes == 8) 498 1.1 riastrad bb->bb_start_cmd_va[2] = 0; 499 1.1 riastrad 500 1.1 riastrad /* No one is going to touch shadow bb from now on. */ 501 1.1 riastrad if (bb->clflush & CLFLUSH_AFTER) { 502 1.1 riastrad drm_clflush_virt_range(bb->va, 503 1.1 riastrad bb->obj->base.size); 504 1.1 riastrad bb->clflush &= ~CLFLUSH_AFTER; 505 1.1 riastrad } 506 1.1 riastrad 507 1.1 riastrad ret = i915_gem_object_set_to_gtt_domain(bb->obj, 508 1.1 riastrad false); 509 1.1 riastrad if (ret) 510 1.1 riastrad goto err; 511 1.1 riastrad 512 1.1 riastrad ret = i915_vma_move_to_active(bb->vma, 513 1.1 riastrad workload->req, 514 1.1 riastrad 0); 515 1.1 riastrad if (ret) 516 1.1 riastrad goto err; 517 1.1 riastrad 518 1.1 riastrad i915_gem_object_finish_access(bb->obj); 519 1.1 riastrad bb->accessing = false; 520 1.1 riastrad } 521 1.1 riastrad } 522 1.1 riastrad return 0; 523 1.1 riastrad err: 524 1.1 riastrad release_shadow_batch_buffer(workload); 525 1.1 riastrad return ret; 526 1.1 riastrad } 527 1.1 riastrad 528 1.1 riastrad static void update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx) 529 1.1 riastrad { 530 1.1 riastrad struct intel_vgpu_workload *workload = 531 1.1 riastrad container_of(wa_ctx, struct intel_vgpu_workload, wa_ctx); 532 1.1 riastrad struct i915_request *rq = workload->req; 533 1.1 riastrad struct execlist_ring_context *shadow_ring_context = 534 1.1 riastrad (struct execlist_ring_context *)rq->context->lrc_reg_state; 535 1.1 riastrad 536 1.1 riastrad shadow_ring_context->bb_per_ctx_ptr.val = 537 1.1 riastrad (shadow_ring_context->bb_per_ctx_ptr.val & 538 1.1 riastrad (~PER_CTX_ADDR_MASK)) | wa_ctx->per_ctx.shadow_gma; 539 1.1 riastrad shadow_ring_context->rcs_indirect_ctx.val = 540 1.1 riastrad (shadow_ring_context->rcs_indirect_ctx.val & 541 1.1 riastrad (~INDIRECT_CTX_ADDR_MASK)) | wa_ctx->indirect_ctx.shadow_gma; 542 1.1 riastrad } 543 1.1 riastrad 544 1.1 riastrad static int prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) 545 1.1 riastrad { 546 1.1 riastrad struct i915_vma *vma; 547 1.1 riastrad unsigned char *per_ctx_va = 548 1.1 riastrad (unsigned char *)wa_ctx->indirect_ctx.shadow_va + 549 1.1 riastrad wa_ctx->indirect_ctx.size; 550 1.1 riastrad 551 1.1 riastrad if (wa_ctx->indirect_ctx.size == 0) 552 1.1 riastrad return 0; 553 1.1 riastrad 554 1.1 riastrad vma = i915_gem_object_ggtt_pin(wa_ctx->indirect_ctx.obj, NULL, 555 1.1 riastrad 0, CACHELINE_BYTES, 0); 556 1.1 riastrad if (IS_ERR(vma)) 557 1.1 riastrad return PTR_ERR(vma); 558 1.1 riastrad 559 1.1 riastrad /* FIXME: we are not tracking our pinned VMA leaving it 560 1.1 riastrad * up to the core to fix up the stray pin_count upon 561 1.1 riastrad * free. 562 1.1 riastrad */ 563 1.1 riastrad 564 1.1 riastrad wa_ctx->indirect_ctx.shadow_gma = i915_ggtt_offset(vma); 565 1.1 riastrad 566 1.1 riastrad wa_ctx->per_ctx.shadow_gma = *((unsigned int *)per_ctx_va + 1); 567 1.1 riastrad memset(per_ctx_va, 0, CACHELINE_BYTES); 568 1.1 riastrad 569 1.1 riastrad update_wa_ctx_2_shadow_ctx(wa_ctx); 570 1.1 riastrad return 0; 571 1.1 riastrad } 572 1.1 riastrad 573 1.1 riastrad static void update_vreg_in_ctx(struct intel_vgpu_workload *workload) 574 1.1 riastrad { 575 1.1 riastrad struct intel_vgpu *vgpu = workload->vgpu; 576 1.1 riastrad struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 577 1.1 riastrad u32 ring_base; 578 1.1 riastrad 579 1.1 riastrad ring_base = dev_priv->engine[workload->ring_id]->mmio_base; 580 1.1 riastrad vgpu_vreg_t(vgpu, RING_START(ring_base)) = workload->rb_start; 581 1.1 riastrad } 582 1.1 riastrad 583 1.1 riastrad static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload) 584 1.1 riastrad { 585 1.1 riastrad struct intel_vgpu_shadow_bb *bb, *pos; 586 1.1 riastrad 587 1.1 riastrad if (list_empty(&workload->shadow_bb)) 588 1.1 riastrad return; 589 1.1 riastrad 590 1.1 riastrad bb = list_first_entry(&workload->shadow_bb, 591 1.1 riastrad struct intel_vgpu_shadow_bb, list); 592 1.1 riastrad 593 1.1 riastrad list_for_each_entry_safe(bb, pos, &workload->shadow_bb, list) { 594 1.1 riastrad if (bb->obj) { 595 1.1 riastrad if (bb->accessing) 596 1.1 riastrad i915_gem_object_finish_access(bb->obj); 597 1.1 riastrad 598 1.1 riastrad if (bb->va && !IS_ERR(bb->va)) 599 1.1 riastrad i915_gem_object_unpin_map(bb->obj); 600 1.1 riastrad 601 1.1 riastrad if (bb->vma && !IS_ERR(bb->vma)) { 602 1.1 riastrad i915_vma_unpin(bb->vma); 603 1.1 riastrad i915_vma_close(bb->vma); 604 1.1 riastrad } 605 1.1 riastrad i915_gem_object_put(bb->obj); 606 1.1 riastrad } 607 1.1 riastrad list_del(&bb->list); 608 1.1 riastrad kfree(bb); 609 1.1 riastrad } 610 1.1 riastrad } 611 1.1 riastrad 612 1.1 riastrad static int prepare_workload(struct intel_vgpu_workload *workload) 613 1.1 riastrad { 614 1.1 riastrad struct intel_vgpu *vgpu = workload->vgpu; 615 1.1 riastrad struct intel_vgpu_submission *s = &vgpu->submission; 616 1.1 riastrad int ring = workload->ring_id; 617 1.1 riastrad int ret = 0; 618 1.1 riastrad 619 1.1 riastrad ret = intel_vgpu_pin_mm(workload->shadow_mm); 620 1.1 riastrad if (ret) { 621 1.1 riastrad gvt_vgpu_err("fail to vgpu pin mm\n"); 622 1.1 riastrad return ret; 623 1.1 riastrad } 624 1.1 riastrad 625 1.1 riastrad if (workload->shadow_mm->type != INTEL_GVT_MM_PPGTT || 626 1.1 riastrad !workload->shadow_mm->ppgtt_mm.shadowed) { 627 1.1 riastrad gvt_vgpu_err("workload shadow ppgtt isn't ready\n"); 628 1.1 riastrad return -EINVAL; 629 1.1 riastrad } 630 1.1 riastrad 631 1.1 riastrad update_shadow_pdps(workload); 632 1.1 riastrad 633 1.1 riastrad set_context_ppgtt_from_shadow(workload, s->shadow[ring]); 634 1.1 riastrad 635 1.1 riastrad ret = intel_vgpu_sync_oos_pages(workload->vgpu); 636 1.1 riastrad if (ret) { 637 1.1 riastrad gvt_vgpu_err("fail to vgpu sync oos pages\n"); 638 1.1 riastrad goto err_unpin_mm; 639 1.1 riastrad } 640 1.1 riastrad 641 1.1 riastrad ret = intel_vgpu_flush_post_shadow(workload->vgpu); 642 1.1 riastrad if (ret) { 643 1.1 riastrad gvt_vgpu_err("fail to flush post shadow\n"); 644 1.1 riastrad goto err_unpin_mm; 645 1.1 riastrad } 646 1.1 riastrad 647 1.1 riastrad ret = copy_workload_to_ring_buffer(workload); 648 1.1 riastrad if (ret) { 649 1.1 riastrad gvt_vgpu_err("fail to generate request\n"); 650 1.1 riastrad goto err_unpin_mm; 651 1.1 riastrad } 652 1.1 riastrad 653 1.1 riastrad ret = prepare_shadow_batch_buffer(workload); 654 1.1 riastrad if (ret) { 655 1.1 riastrad gvt_vgpu_err("fail to prepare_shadow_batch_buffer\n"); 656 1.1 riastrad goto err_unpin_mm; 657 1.1 riastrad } 658 1.1 riastrad 659 1.1 riastrad ret = prepare_shadow_wa_ctx(&workload->wa_ctx); 660 1.1 riastrad if (ret) { 661 1.1 riastrad gvt_vgpu_err("fail to prepare_shadow_wa_ctx\n"); 662 1.1 riastrad goto err_shadow_batch; 663 1.1 riastrad } 664 1.1 riastrad 665 1.1 riastrad if (workload->prepare) { 666 1.1 riastrad ret = workload->prepare(workload); 667 1.1 riastrad if (ret) 668 1.1 riastrad goto err_shadow_wa_ctx; 669 1.1 riastrad } 670 1.1 riastrad 671 1.1 riastrad return 0; 672 1.1 riastrad err_shadow_wa_ctx: 673 1.1 riastrad release_shadow_wa_ctx(&workload->wa_ctx); 674 1.1 riastrad err_shadow_batch: 675 1.1 riastrad release_shadow_batch_buffer(workload); 676 1.1 riastrad err_unpin_mm: 677 1.1 riastrad intel_vgpu_unpin_mm(workload->shadow_mm); 678 1.1 riastrad return ret; 679 1.1 riastrad } 680 1.1 riastrad 681 1.1 riastrad static int dispatch_workload(struct intel_vgpu_workload *workload) 682 1.1 riastrad { 683 1.1 riastrad struct intel_vgpu *vgpu = workload->vgpu; 684 1.1 riastrad struct i915_request *rq; 685 1.1 riastrad int ring_id = workload->ring_id; 686 1.1 riastrad int ret; 687 1.1 riastrad 688 1.1 riastrad gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n", 689 1.1 riastrad ring_id, workload); 690 1.1 riastrad 691 1.1 riastrad mutex_lock(&vgpu->vgpu_lock); 692 1.1 riastrad 693 1.1 riastrad ret = intel_gvt_workload_req_alloc(workload); 694 1.1 riastrad if (ret) 695 1.1 riastrad goto err_req; 696 1.1 riastrad 697 1.1 riastrad ret = intel_gvt_scan_and_shadow_workload(workload); 698 1.1 riastrad if (ret) 699 1.1 riastrad goto out; 700 1.1 riastrad 701 1.1 riastrad ret = populate_shadow_context(workload); 702 1.1 riastrad if (ret) { 703 1.1 riastrad release_shadow_wa_ctx(&workload->wa_ctx); 704 1.1 riastrad goto out; 705 1.1 riastrad } 706 1.1 riastrad 707 1.1 riastrad ret = prepare_workload(workload); 708 1.1 riastrad out: 709 1.1 riastrad if (ret) { 710 1.1 riastrad /* We might still need to add request with 711 1.1 riastrad * clean ctx to retire it properly.. 712 1.1 riastrad */ 713 1.1 riastrad rq = fetch_and_zero(&workload->req); 714 1.1 riastrad i915_request_put(rq); 715 1.1 riastrad } 716 1.1 riastrad 717 1.1 riastrad if (!IS_ERR_OR_NULL(workload->req)) { 718 1.1 riastrad gvt_dbg_sched("ring id %d submit workload to i915 %p\n", 719 1.1 riastrad ring_id, workload->req); 720 1.1 riastrad i915_request_add(workload->req); 721 1.1 riastrad workload->dispatched = true; 722 1.1 riastrad } 723 1.1 riastrad err_req: 724 1.1 riastrad if (ret) 725 1.1 riastrad workload->status = ret; 726 1.1 riastrad mutex_unlock(&vgpu->vgpu_lock); 727 1.1 riastrad return ret; 728 1.1 riastrad } 729 1.1 riastrad 730 1.1 riastrad static struct intel_vgpu_workload *pick_next_workload( 731 1.1 riastrad struct intel_gvt *gvt, int ring_id) 732 1.1 riastrad { 733 1.1 riastrad struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; 734 1.1 riastrad struct intel_vgpu_workload *workload = NULL; 735 1.1 riastrad 736 1.1 riastrad mutex_lock(&gvt->sched_lock); 737 1.1 riastrad 738 1.1 riastrad /* 739 1.1 riastrad * no current vgpu / will be scheduled out / no workload 740 1.1 riastrad * bail out 741 1.1 riastrad */ 742 1.1 riastrad if (!scheduler->current_vgpu) { 743 1.1 riastrad gvt_dbg_sched("ring id %d stop - no current vgpu\n", ring_id); 744 1.1 riastrad goto out; 745 1.1 riastrad } 746 1.1 riastrad 747 1.1 riastrad if (scheduler->need_reschedule) { 748 1.1 riastrad gvt_dbg_sched("ring id %d stop - will reschedule\n", ring_id); 749 1.1 riastrad goto out; 750 1.1 riastrad } 751 1.1 riastrad 752 1.1 riastrad if (!scheduler->current_vgpu->active || 753 1.1 riastrad list_empty(workload_q_head(scheduler->current_vgpu, ring_id))) 754 1.1 riastrad goto out; 755 1.1 riastrad 756 1.1 riastrad /* 757 1.1 riastrad * still have current workload, maybe the workload disptacher 758 1.1 riastrad * fail to submit it for some reason, resubmit it. 759 1.1 riastrad */ 760 1.1 riastrad if (scheduler->current_workload[ring_id]) { 761 1.1 riastrad workload = scheduler->current_workload[ring_id]; 762 1.1 riastrad gvt_dbg_sched("ring id %d still have current workload %p\n", 763 1.1 riastrad ring_id, workload); 764 1.1 riastrad goto out; 765 1.1 riastrad } 766 1.1 riastrad 767 1.1 riastrad /* 768 1.1 riastrad * pick a workload as current workload 769 1.1 riastrad * once current workload is set, schedule policy routines 770 1.1 riastrad * will wait the current workload is finished when trying to 771 1.1 riastrad * schedule out a vgpu. 772 1.1 riastrad */ 773 1.1 riastrad scheduler->current_workload[ring_id] = container_of( 774 1.1 riastrad workload_q_head(scheduler->current_vgpu, ring_id)->next, 775 1.1 riastrad struct intel_vgpu_workload, list); 776 1.1 riastrad 777 1.1 riastrad workload = scheduler->current_workload[ring_id]; 778 1.1 riastrad 779 1.1 riastrad gvt_dbg_sched("ring id %d pick new workload %p\n", ring_id, workload); 780 1.1 riastrad 781 1.1 riastrad atomic_inc(&workload->vgpu->submission.running_workload_num); 782 1.1 riastrad out: 783 1.1 riastrad mutex_unlock(&gvt->sched_lock); 784 1.1 riastrad return workload; 785 1.1 riastrad } 786 1.1 riastrad 787 1.1 riastrad static void update_guest_context(struct intel_vgpu_workload *workload) 788 1.1 riastrad { 789 1.1 riastrad struct i915_request *rq = workload->req; 790 1.1 riastrad struct intel_vgpu *vgpu = workload->vgpu; 791 1.1 riastrad struct intel_gvt *gvt = vgpu->gvt; 792 1.1 riastrad struct drm_i915_gem_object *ctx_obj = rq->context->state->obj; 793 1.1 riastrad struct execlist_ring_context *shadow_ring_context; 794 1.1 riastrad struct page *page; 795 1.1 riastrad void *src; 796 1.1 riastrad unsigned long context_gpa, context_page_num; 797 1.1 riastrad int i; 798 1.1 riastrad struct drm_i915_private *dev_priv = gvt->dev_priv; 799 1.1 riastrad u32 ring_base; 800 1.1 riastrad u32 head, tail; 801 1.1 riastrad u16 wrap_count; 802 1.1 riastrad 803 1.1 riastrad gvt_dbg_sched("ring id %d workload lrca %x\n", rq->engine->id, 804 1.1 riastrad workload->ctx_desc.lrca); 805 1.1 riastrad 806 1.1 riastrad head = workload->rb_head; 807 1.1 riastrad tail = workload->rb_tail; 808 1.1 riastrad wrap_count = workload->guest_rb_head >> RB_HEAD_WRAP_CNT_OFF; 809 1.1 riastrad 810 1.1 riastrad if (tail < head) { 811 1.1 riastrad if (wrap_count == RB_HEAD_WRAP_CNT_MAX) 812 1.1 riastrad wrap_count = 0; 813 1.1 riastrad else 814 1.1 riastrad wrap_count += 1; 815 1.1 riastrad } 816 1.1 riastrad 817 1.1 riastrad head = (wrap_count << RB_HEAD_WRAP_CNT_OFF) | tail; 818 1.1 riastrad 819 1.1 riastrad ring_base = dev_priv->engine[workload->ring_id]->mmio_base; 820 1.1 riastrad vgpu_vreg_t(vgpu, RING_TAIL(ring_base)) = tail; 821 1.1 riastrad vgpu_vreg_t(vgpu, RING_HEAD(ring_base)) = head; 822 1.1 riastrad 823 1.1 riastrad context_page_num = rq->engine->context_size; 824 1.1 riastrad context_page_num = context_page_num >> PAGE_SHIFT; 825 1.1 riastrad 826 1.1 riastrad if (IS_BROADWELL(gvt->dev_priv) && rq->engine->id == RCS0) 827 1.1 riastrad context_page_num = 19; 828 1.1 riastrad 829 1.1 riastrad i = 2; 830 1.1 riastrad 831 1.1 riastrad while (i < context_page_num) { 832 1.1 riastrad context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, 833 1.1 riastrad (u32)((workload->ctx_desc.lrca + i) << 834 1.1 riastrad I915_GTT_PAGE_SHIFT)); 835 1.1 riastrad if (context_gpa == INTEL_GVT_INVALID_ADDR) { 836 1.1 riastrad gvt_vgpu_err("invalid guest context descriptor\n"); 837 1.1 riastrad return; 838 1.1 riastrad } 839 1.1 riastrad 840 1.1 riastrad page = i915_gem_object_get_page(ctx_obj, i); 841 1.1 riastrad src = kmap(page); 842 1.1 riastrad intel_gvt_hypervisor_write_gpa(vgpu, context_gpa, src, 843 1.1 riastrad I915_GTT_PAGE_SIZE); 844 1.1 riastrad kunmap(page); 845 1.1 riastrad i++; 846 1.1 riastrad } 847 1.1 riastrad 848 1.1 riastrad intel_gvt_hypervisor_write_gpa(vgpu, workload->ring_context_gpa + 849 1.1 riastrad RING_CTX_OFF(ring_header.val), &workload->rb_tail, 4); 850 1.1 riastrad 851 1.1 riastrad page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN); 852 1.1 riastrad shadow_ring_context = kmap(page); 853 1.1 riastrad 854 1.1 riastrad #define COPY_REG(name) \ 855 1.1 riastrad intel_gvt_hypervisor_write_gpa(vgpu, workload->ring_context_gpa + \ 856 1.1 riastrad RING_CTX_OFF(name.val), &shadow_ring_context->name.val, 4) 857 1.1 riastrad 858 1.1 riastrad COPY_REG(ctx_ctrl); 859 1.1 riastrad COPY_REG(ctx_timestamp); 860 1.1 riastrad 861 1.1 riastrad #undef COPY_REG 862 1.1 riastrad 863 1.1 riastrad intel_gvt_hypervisor_write_gpa(vgpu, 864 1.1 riastrad workload->ring_context_gpa + 865 1.1 riastrad sizeof(*shadow_ring_context), 866 1.1 riastrad (void *)shadow_ring_context + 867 1.1 riastrad sizeof(*shadow_ring_context), 868 1.1 riastrad I915_GTT_PAGE_SIZE - sizeof(*shadow_ring_context)); 869 1.1 riastrad 870 1.1 riastrad kunmap(page); 871 1.1 riastrad } 872 1.1 riastrad 873 1.1 riastrad void intel_vgpu_clean_workloads(struct intel_vgpu *vgpu, 874 1.1 riastrad intel_engine_mask_t engine_mask) 875 1.1 riastrad { 876 1.1 riastrad struct intel_vgpu_submission *s = &vgpu->submission; 877 1.1 riastrad struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 878 1.1 riastrad struct intel_engine_cs *engine; 879 1.1 riastrad struct intel_vgpu_workload *pos, *n; 880 1.1 riastrad intel_engine_mask_t tmp; 881 1.1 riastrad 882 1.1 riastrad /* free the unsubmited workloads in the queues. */ 883 1.1 riastrad for_each_engine_masked(engine, &dev_priv->gt, engine_mask, tmp) { 884 1.1 riastrad list_for_each_entry_safe(pos, n, 885 1.1 riastrad &s->workload_q_head[engine->id], list) { 886 1.1 riastrad list_del_init(&pos->list); 887 1.1 riastrad intel_vgpu_destroy_workload(pos); 888 1.1 riastrad } 889 1.1 riastrad clear_bit(engine->id, s->shadow_ctx_desc_updated); 890 1.1 riastrad } 891 1.1 riastrad } 892 1.1 riastrad 893 1.1 riastrad static void complete_current_workload(struct intel_gvt *gvt, int ring_id) 894 1.1 riastrad { 895 1.1 riastrad struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; 896 1.1 riastrad struct intel_vgpu_workload *workload = 897 1.1 riastrad scheduler->current_workload[ring_id]; 898 1.1 riastrad struct intel_vgpu *vgpu = workload->vgpu; 899 1.1 riastrad struct intel_vgpu_submission *s = &vgpu->submission; 900 1.1 riastrad struct i915_request *rq = workload->req; 901 1.1 riastrad int event; 902 1.1 riastrad 903 1.1 riastrad mutex_lock(&vgpu->vgpu_lock); 904 1.1 riastrad mutex_lock(&gvt->sched_lock); 905 1.1 riastrad 906 1.1 riastrad /* For the workload w/ request, needs to wait for the context 907 1.1 riastrad * switch to make sure request is completed. 908 1.1 riastrad * For the workload w/o request, directly complete the workload. 909 1.1 riastrad */ 910 1.1 riastrad if (rq) { 911 1.1 riastrad wait_event(workload->shadow_ctx_status_wq, 912 1.1 riastrad !atomic_read(&workload->shadow_ctx_active)); 913 1.1 riastrad 914 1.1 riastrad /* If this request caused GPU hang, req->fence.error will 915 1.1 riastrad * be set to -EIO. Use -EIO to set workload status so 916 1.1 riastrad * that when this request caused GPU hang, didn't trigger 917 1.1 riastrad * context switch interrupt to guest. 918 1.1 riastrad */ 919 1.1 riastrad if (likely(workload->status == -EINPROGRESS)) { 920 1.1 riastrad if (workload->req->fence.error == -EIO) 921 1.1 riastrad workload->status = -EIO; 922 1.1 riastrad else 923 1.1 riastrad workload->status = 0; 924 1.1 riastrad } 925 1.1 riastrad 926 1.1 riastrad if (!workload->status && 927 1.1 riastrad !(vgpu->resetting_eng & BIT(ring_id))) { 928 1.1 riastrad update_guest_context(workload); 929 1.1 riastrad 930 1.1 riastrad for_each_set_bit(event, workload->pending_events, 931 1.1 riastrad INTEL_GVT_EVENT_MAX) 932 1.1 riastrad intel_vgpu_trigger_virtual_event(vgpu, event); 933 1.1 riastrad } 934 1.1 riastrad 935 1.1 riastrad i915_request_put(fetch_and_zero(&workload->req)); 936 1.1 riastrad } 937 1.1 riastrad 938 1.1 riastrad gvt_dbg_sched("ring id %d complete workload %p status %d\n", 939 1.1 riastrad ring_id, workload, workload->status); 940 1.1 riastrad 941 1.1 riastrad scheduler->current_workload[ring_id] = NULL; 942 1.1 riastrad 943 1.1 riastrad list_del_init(&workload->list); 944 1.1 riastrad 945 1.1 riastrad if (workload->status || vgpu->resetting_eng & BIT(ring_id)) { 946 1.1 riastrad /* if workload->status is not successful means HW GPU 947 1.1 riastrad * has occurred GPU hang or something wrong with i915/GVT, 948 1.1 riastrad * and GVT won't inject context switch interrupt to guest. 949 1.1 riastrad * So this error is a vGPU hang actually to the guest. 950 1.1 riastrad * According to this we should emunlate a vGPU hang. If 951 1.1 riastrad * there are pending workloads which are already submitted 952 1.1 riastrad * from guest, we should clean them up like HW GPU does. 953 1.1 riastrad * 954 1.1 riastrad * if it is in middle of engine resetting, the pending 955 1.1 riastrad * workloads won't be submitted to HW GPU and will be 956 1.1 riastrad * cleaned up during the resetting process later, so doing 957 1.1 riastrad * the workload clean up here doesn't have any impact. 958 1.1 riastrad **/ 959 1.1 riastrad intel_vgpu_clean_workloads(vgpu, BIT(ring_id)); 960 1.1 riastrad } 961 1.1 riastrad 962 1.1 riastrad workload->complete(workload); 963 1.1 riastrad 964 1.1 riastrad atomic_dec(&s->running_workload_num); 965 1.1 riastrad wake_up(&scheduler->workload_complete_wq); 966 1.1 riastrad 967 1.1 riastrad if (gvt->scheduler.need_reschedule) 968 1.1 riastrad intel_gvt_request_service(gvt, INTEL_GVT_REQUEST_EVENT_SCHED); 969 1.1 riastrad 970 1.1 riastrad mutex_unlock(&gvt->sched_lock); 971 1.1 riastrad mutex_unlock(&vgpu->vgpu_lock); 972 1.1 riastrad } 973 1.1 riastrad 974 1.1 riastrad struct workload_thread_param { 975 1.1 riastrad struct intel_gvt *gvt; 976 1.1 riastrad int ring_id; 977 1.1 riastrad }; 978 1.1 riastrad 979 1.1 riastrad static int workload_thread(void *priv) 980 1.1 riastrad { 981 1.1 riastrad struct workload_thread_param *p = (struct workload_thread_param *)priv; 982 1.1 riastrad struct intel_gvt *gvt = p->gvt; 983 1.1 riastrad int ring_id = p->ring_id; 984 1.1 riastrad struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; 985 1.1 riastrad struct intel_vgpu_workload *workload = NULL; 986 1.1 riastrad struct intel_vgpu *vgpu = NULL; 987 1.1 riastrad int ret; 988 1.1 riastrad bool need_force_wake = (INTEL_GEN(gvt->dev_priv) >= 9); 989 1.1 riastrad DEFINE_WAIT_FUNC(wait, woken_wake_function); 990 1.1 riastrad struct intel_runtime_pm *rpm = &gvt->dev_priv->runtime_pm; 991 1.1 riastrad 992 1.1 riastrad kfree(p); 993 1.1 riastrad 994 1.1 riastrad gvt_dbg_core("workload thread for ring %d started\n", ring_id); 995 1.1 riastrad 996 1.1 riastrad while (!kthread_should_stop()) { 997 1.1 riastrad add_wait_queue(&scheduler->waitq[ring_id], &wait); 998 1.1 riastrad do { 999 1.1 riastrad workload = pick_next_workload(gvt, ring_id); 1000 1.1 riastrad if (workload) 1001 1.1 riastrad break; 1002 1.1 riastrad wait_woken(&wait, TASK_INTERRUPTIBLE, 1003 1.1 riastrad MAX_SCHEDULE_TIMEOUT); 1004 1.1 riastrad } while (!kthread_should_stop()); 1005 1.1 riastrad remove_wait_queue(&scheduler->waitq[ring_id], &wait); 1006 1.1 riastrad 1007 1.1 riastrad if (!workload) 1008 1.1 riastrad break; 1009 1.1 riastrad 1010 1.1 riastrad gvt_dbg_sched("ring id %d next workload %p vgpu %d\n", 1011 1.1 riastrad workload->ring_id, workload, 1012 1.1 riastrad workload->vgpu->id); 1013 1.1 riastrad 1014 1.1 riastrad intel_runtime_pm_get(rpm); 1015 1.1 riastrad 1016 1.1 riastrad gvt_dbg_sched("ring id %d will dispatch workload %p\n", 1017 1.1 riastrad workload->ring_id, workload); 1018 1.1 riastrad 1019 1.1 riastrad if (need_force_wake) 1020 1.1 riastrad intel_uncore_forcewake_get(&gvt->dev_priv->uncore, 1021 1.1 riastrad FORCEWAKE_ALL); 1022 1.1 riastrad /* 1023 1.1 riastrad * Update the vReg of the vGPU which submitted this 1024 1.1 riastrad * workload. The vGPU may use these registers for checking 1025 1.1 riastrad * the context state. The value comes from GPU commands 1026 1.1 riastrad * in this workload. 1027 1.1 riastrad */ 1028 1.1 riastrad update_vreg_in_ctx(workload); 1029 1.1 riastrad 1030 1.1 riastrad ret = dispatch_workload(workload); 1031 1.1 riastrad 1032 1.1 riastrad if (ret) { 1033 1.1 riastrad vgpu = workload->vgpu; 1034 1.1 riastrad gvt_vgpu_err("fail to dispatch workload, skip\n"); 1035 1.1 riastrad goto complete; 1036 1.1 riastrad } 1037 1.1 riastrad 1038 1.1 riastrad gvt_dbg_sched("ring id %d wait workload %p\n", 1039 1.1 riastrad workload->ring_id, workload); 1040 1.1 riastrad i915_request_wait(workload->req, 0, MAX_SCHEDULE_TIMEOUT); 1041 1.1 riastrad 1042 1.1 riastrad complete: 1043 1.1 riastrad gvt_dbg_sched("will complete workload %p, status: %d\n", 1044 1.1 riastrad workload, workload->status); 1045 1.1 riastrad 1046 1.1 riastrad complete_current_workload(gvt, ring_id); 1047 1.1 riastrad 1048 1.1 riastrad if (need_force_wake) 1049 1.1 riastrad intel_uncore_forcewake_put(&gvt->dev_priv->uncore, 1050 1.1 riastrad FORCEWAKE_ALL); 1051 1.1 riastrad 1052 1.1 riastrad intel_runtime_pm_put_unchecked(rpm); 1053 1.1 riastrad if (ret && (vgpu_is_vm_unhealthy(ret))) 1054 1.1 riastrad enter_failsafe_mode(vgpu, GVT_FAILSAFE_GUEST_ERR); 1055 1.1 riastrad } 1056 1.1 riastrad return 0; 1057 1.1 riastrad } 1058 1.1 riastrad 1059 1.1 riastrad void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu) 1060 1.1 riastrad { 1061 1.1 riastrad struct intel_vgpu_submission *s = &vgpu->submission; 1062 1.1 riastrad struct intel_gvt *gvt = vgpu->gvt; 1063 1.1 riastrad struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; 1064 1.1 riastrad 1065 1.1 riastrad if (atomic_read(&s->running_workload_num)) { 1066 1.1 riastrad gvt_dbg_sched("wait vgpu idle\n"); 1067 1.1 riastrad 1068 1.1 riastrad wait_event(scheduler->workload_complete_wq, 1069 1.1 riastrad !atomic_read(&s->running_workload_num)); 1070 1.1 riastrad } 1071 1.1 riastrad } 1072 1.1 riastrad 1073 1.1 riastrad void intel_gvt_clean_workload_scheduler(struct intel_gvt *gvt) 1074 1.1 riastrad { 1075 1.1 riastrad struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; 1076 1.1 riastrad struct intel_engine_cs *engine; 1077 1.1 riastrad enum intel_engine_id i; 1078 1.1 riastrad 1079 1.1 riastrad gvt_dbg_core("clean workload scheduler\n"); 1080 1.1 riastrad 1081 1.1 riastrad for_each_engine(engine, gvt->dev_priv, i) { 1082 1.1 riastrad atomic_notifier_chain_unregister( 1083 1.1 riastrad &engine->context_status_notifier, 1084 1.1 riastrad &gvt->shadow_ctx_notifier_block[i]); 1085 1.1 riastrad kthread_stop(scheduler->thread[i]); 1086 1.1 riastrad } 1087 1.1 riastrad } 1088 1.1 riastrad 1089 1.1 riastrad int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt) 1090 1.1 riastrad { 1091 1.1 riastrad struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; 1092 1.1 riastrad struct workload_thread_param *param = NULL; 1093 1.1 riastrad struct intel_engine_cs *engine; 1094 1.1 riastrad enum intel_engine_id i; 1095 1.1 riastrad int ret; 1096 1.1 riastrad 1097 1.1 riastrad gvt_dbg_core("init workload scheduler\n"); 1098 1.1 riastrad 1099 1.1 riastrad init_waitqueue_head(&scheduler->workload_complete_wq); 1100 1.1 riastrad 1101 1.1 riastrad for_each_engine(engine, gvt->dev_priv, i) { 1102 1.1 riastrad init_waitqueue_head(&scheduler->waitq[i]); 1103 1.1 riastrad 1104 1.1 riastrad param = kzalloc(sizeof(*param), GFP_KERNEL); 1105 1.1 riastrad if (!param) { 1106 1.1 riastrad ret = -ENOMEM; 1107 1.1 riastrad goto err; 1108 1.1 riastrad } 1109 1.1 riastrad 1110 1.1 riastrad param->gvt = gvt; 1111 1.1 riastrad param->ring_id = i; 1112 1.1 riastrad 1113 1.1 riastrad scheduler->thread[i] = kthread_run(workload_thread, param, 1114 1.1 riastrad "gvt workload %d", i); 1115 1.1 riastrad if (IS_ERR(scheduler->thread[i])) { 1116 1.1 riastrad gvt_err("fail to create workload thread\n"); 1117 1.1 riastrad ret = PTR_ERR(scheduler->thread[i]); 1118 1.1 riastrad goto err; 1119 1.1 riastrad } 1120 1.1 riastrad 1121 1.1 riastrad gvt->shadow_ctx_notifier_block[i].notifier_call = 1122 1.1 riastrad shadow_context_status_change; 1123 1.1 riastrad atomic_notifier_chain_register(&engine->context_status_notifier, 1124 1.1 riastrad &gvt->shadow_ctx_notifier_block[i]); 1125 1.1 riastrad } 1126 1.1 riastrad return 0; 1127 1.1 riastrad err: 1128 1.1 riastrad intel_gvt_clean_workload_scheduler(gvt); 1129 1.1 riastrad kfree(param); 1130 1.1 riastrad param = NULL; 1131 1.1 riastrad return ret; 1132 1.1 riastrad } 1133 1.1 riastrad 1134 1.1 riastrad static void 1135 1.1 riastrad i915_context_ppgtt_root_restore(struct intel_vgpu_submission *s, 1136 1.1 riastrad struct i915_ppgtt *ppgtt) 1137 1.1 riastrad { 1138 1.1 riastrad int i; 1139 1.1 riastrad 1140 1.1 riastrad if (i915_vm_is_4lvl(&ppgtt->vm)) { 1141 1.1 riastrad px_dma(ppgtt->pd) = s->i915_context_pml4; 1142 1.1 riastrad } else { 1143 1.1 riastrad for (i = 0; i < GEN8_3LVL_PDPES; i++) { 1144 1.1 riastrad struct i915_page_directory * const pd = 1145 1.1 riastrad i915_pd_entry(ppgtt->pd, i); 1146 1.1 riastrad 1147 1.1 riastrad px_dma(pd) = s->i915_context_pdps[i]; 1148 1.1 riastrad } 1149 1.1 riastrad } 1150 1.1 riastrad } 1151 1.1 riastrad 1152 1.1 riastrad /** 1153 1.1 riastrad * intel_vgpu_clean_submission - free submission-related resource for vGPU 1154 1.1 riastrad * @vgpu: a vGPU 1155 1.1 riastrad * 1156 1.1 riastrad * This function is called when a vGPU is being destroyed. 1157 1.1 riastrad * 1158 1.1 riastrad */ 1159 1.1 riastrad void intel_vgpu_clean_submission(struct intel_vgpu *vgpu) 1160 1.1 riastrad { 1161 1.1 riastrad struct intel_vgpu_submission *s = &vgpu->submission; 1162 1.1 riastrad struct intel_engine_cs *engine; 1163 1.1 riastrad enum intel_engine_id id; 1164 1.1 riastrad 1165 1.1 riastrad intel_vgpu_select_submission_ops(vgpu, ALL_ENGINES, 0); 1166 1.1 riastrad 1167 1.1 riastrad i915_context_ppgtt_root_restore(s, i915_vm_to_ppgtt(s->shadow[0]->vm)); 1168 1.1 riastrad for_each_engine(engine, vgpu->gvt->dev_priv, id) 1169 1.1 riastrad intel_context_unpin(s->shadow[id]); 1170 1.1 riastrad 1171 1.1 riastrad kmem_cache_destroy(s->workloads); 1172 1.1 riastrad } 1173 1.1 riastrad 1174 1.1 riastrad 1175 1.1 riastrad /** 1176 1.1 riastrad * intel_vgpu_reset_submission - reset submission-related resource for vGPU 1177 1.1 riastrad * @vgpu: a vGPU 1178 1.1 riastrad * @engine_mask: engines expected to be reset 1179 1.1 riastrad * 1180 1.1 riastrad * This function is called when a vGPU is being destroyed. 1181 1.1 riastrad * 1182 1.1 riastrad */ 1183 1.1 riastrad void intel_vgpu_reset_submission(struct intel_vgpu *vgpu, 1184 1.1 riastrad intel_engine_mask_t engine_mask) 1185 1.1 riastrad { 1186 1.1 riastrad struct intel_vgpu_submission *s = &vgpu->submission; 1187 1.1 riastrad 1188 1.1 riastrad if (!s->active) 1189 1.1 riastrad return; 1190 1.1 riastrad 1191 1.1 riastrad intel_vgpu_clean_workloads(vgpu, engine_mask); 1192 1.1 riastrad s->ops->reset(vgpu, engine_mask); 1193 1.1 riastrad } 1194 1.1 riastrad 1195 1.1 riastrad static void 1196 1.1 riastrad i915_context_ppgtt_root_save(struct intel_vgpu_submission *s, 1197 1.1 riastrad struct i915_ppgtt *ppgtt) 1198 1.1 riastrad { 1199 1.1 riastrad int i; 1200 1.1 riastrad 1201 1.1 riastrad if (i915_vm_is_4lvl(&ppgtt->vm)) { 1202 1.1 riastrad s->i915_context_pml4 = px_dma(ppgtt->pd); 1203 1.1 riastrad } else { 1204 1.1 riastrad for (i = 0; i < GEN8_3LVL_PDPES; i++) { 1205 1.1 riastrad struct i915_page_directory * const pd = 1206 1.1 riastrad i915_pd_entry(ppgtt->pd, i); 1207 1.1 riastrad 1208 1.1 riastrad s->i915_context_pdps[i] = px_dma(pd); 1209 1.1 riastrad } 1210 1.1 riastrad } 1211 1.1 riastrad } 1212 1.1 riastrad 1213 1.1 riastrad /** 1214 1.1 riastrad * intel_vgpu_setup_submission - setup submission-related resource for vGPU 1215 1.1 riastrad * @vgpu: a vGPU 1216 1.1 riastrad * 1217 1.1 riastrad * This function is called when a vGPU is being created. 1218 1.1 riastrad * 1219 1.1 riastrad * Returns: 1220 1.1 riastrad * Zero on success, negative error code if failed. 1221 1.1 riastrad * 1222 1.1 riastrad */ 1223 1.1 riastrad int intel_vgpu_setup_submission(struct intel_vgpu *vgpu) 1224 1.1 riastrad { 1225 1.1 riastrad struct drm_i915_private *i915 = vgpu->gvt->dev_priv; 1226 1.1 riastrad struct intel_vgpu_submission *s = &vgpu->submission; 1227 1.1 riastrad struct intel_engine_cs *engine; 1228 1.1 riastrad struct i915_ppgtt *ppgtt; 1229 1.1 riastrad enum intel_engine_id i; 1230 1.1 riastrad int ret; 1231 1.1 riastrad 1232 1.1 riastrad ppgtt = i915_ppgtt_create(&i915->gt); 1233 1.1 riastrad if (IS_ERR(ppgtt)) 1234 1.1 riastrad return PTR_ERR(ppgtt); 1235 1.1 riastrad 1236 1.1 riastrad i915_context_ppgtt_root_save(s, ppgtt); 1237 1.1 riastrad 1238 1.1 riastrad for_each_engine(engine, i915, i) { 1239 1.1 riastrad struct intel_context *ce; 1240 1.1 riastrad 1241 1.1 riastrad INIT_LIST_HEAD(&s->workload_q_head[i]); 1242 1.1 riastrad s->shadow[i] = ERR_PTR(-EINVAL); 1243 1.1 riastrad 1244 1.1 riastrad ce = intel_context_create(engine); 1245 1.1 riastrad if (IS_ERR(ce)) { 1246 1.1 riastrad ret = PTR_ERR(ce); 1247 1.1 riastrad goto out_shadow_ctx; 1248 1.1 riastrad } 1249 1.1 riastrad 1250 1.1 riastrad i915_vm_put(ce->vm); 1251 1.1 riastrad ce->vm = i915_vm_get(&ppgtt->vm); 1252 1.1 riastrad intel_context_set_single_submission(ce); 1253 1.1 riastrad 1254 1.1 riastrad if (!USES_GUC_SUBMISSION(i915)) { /* Max ring buffer size */ 1255 1.1 riastrad const unsigned int ring_size = 512 * SZ_4K; 1256 1.1 riastrad 1257 1.1 riastrad ce->ring = __intel_context_ring_size(ring_size); 1258 1.1 riastrad } 1259 1.1 riastrad 1260 1.1 riastrad ret = intel_context_pin(ce); 1261 1.1 riastrad intel_context_put(ce); 1262 1.1 riastrad if (ret) 1263 1.1 riastrad goto out_shadow_ctx; 1264 1.1 riastrad 1265 1.1 riastrad s->shadow[i] = ce; 1266 1.1 riastrad } 1267 1.1 riastrad 1268 1.1 riastrad bitmap_zero(s->shadow_ctx_desc_updated, I915_NUM_ENGINES); 1269 1.1 riastrad 1270 1.1 riastrad s->workloads = kmem_cache_create_usercopy("gvt-g_vgpu_workload", 1271 1.1 riastrad sizeof(struct intel_vgpu_workload), 0, 1272 1.1 riastrad SLAB_HWCACHE_ALIGN, 1273 1.1 riastrad offsetof(struct intel_vgpu_workload, rb_tail), 1274 1.1 riastrad sizeof_field(struct intel_vgpu_workload, rb_tail), 1275 1.1 riastrad NULL); 1276 1.1 riastrad 1277 1.1 riastrad if (!s->workloads) { 1278 1.1 riastrad ret = -ENOMEM; 1279 1.1 riastrad goto out_shadow_ctx; 1280 1.1 riastrad } 1281 1.1 riastrad 1282 1.1 riastrad atomic_set(&s->running_workload_num, 0); 1283 1.1 riastrad bitmap_zero(s->tlb_handle_pending, I915_NUM_ENGINES); 1284 1.1 riastrad 1285 1.1 riastrad i915_vm_put(&ppgtt->vm); 1286 1.1 riastrad return 0; 1287 1.1 riastrad 1288 1.1 riastrad out_shadow_ctx: 1289 1.1 riastrad i915_context_ppgtt_root_restore(s, ppgtt); 1290 1.1 riastrad for_each_engine(engine, i915, i) { 1291 1.1 riastrad if (IS_ERR(s->shadow[i])) 1292 1.1 riastrad break; 1293 1.1 riastrad 1294 1.1 riastrad intel_context_unpin(s->shadow[i]); 1295 1.1 riastrad intel_context_put(s->shadow[i]); 1296 1.1 riastrad } 1297 1.1 riastrad i915_vm_put(&ppgtt->vm); 1298 1.1 riastrad return ret; 1299 1.1 riastrad } 1300 1.1 riastrad 1301 1.1 riastrad /** 1302 1.1 riastrad * intel_vgpu_select_submission_ops - select virtual submission interface 1303 1.1 riastrad * @vgpu: a vGPU 1304 1.1 riastrad * @engine_mask: either ALL_ENGINES or target engine mask 1305 1.1 riastrad * @interface: expected vGPU virtual submission interface 1306 1.1 riastrad * 1307 1.1 riastrad * This function is called when guest configures submission interface. 1308 1.1 riastrad * 1309 1.1 riastrad * Returns: 1310 1.1 riastrad * Zero on success, negative error code if failed. 1311 1.1 riastrad * 1312 1.1 riastrad */ 1313 1.1 riastrad int intel_vgpu_select_submission_ops(struct intel_vgpu *vgpu, 1314 1.1 riastrad intel_engine_mask_t engine_mask, 1315 1.1 riastrad unsigned int interface) 1316 1.1 riastrad { 1317 1.1 riastrad struct intel_vgpu_submission *s = &vgpu->submission; 1318 1.1 riastrad const struct intel_vgpu_submission_ops *ops[] = { 1319 1.1 riastrad [INTEL_VGPU_EXECLIST_SUBMISSION] = 1320 1.1 riastrad &intel_vgpu_execlist_submission_ops, 1321 1.1 riastrad }; 1322 1.1 riastrad int ret; 1323 1.1 riastrad 1324 1.1 riastrad if (WARN_ON(interface >= ARRAY_SIZE(ops))) 1325 1.1 riastrad return -EINVAL; 1326 1.1 riastrad 1327 1.1 riastrad if (WARN_ON(interface == 0 && engine_mask != ALL_ENGINES)) 1328 1.1 riastrad return -EINVAL; 1329 1.1 riastrad 1330 1.1 riastrad if (s->active) 1331 1.1 riastrad s->ops->clean(vgpu, engine_mask); 1332 1.1 riastrad 1333 1.1 riastrad if (interface == 0) { 1334 1.1 riastrad s->ops = NULL; 1335 1.1 riastrad s->virtual_submission_interface = 0; 1336 1.1 riastrad s->active = false; 1337 1.1 riastrad gvt_dbg_core("vgpu%d: remove submission ops\n", vgpu->id); 1338 1.1 riastrad return 0; 1339 1.1 riastrad } 1340 1.1 riastrad 1341 1.1 riastrad ret = ops[interface]->init(vgpu, engine_mask); 1342 1.1 riastrad if (ret) 1343 1.1 riastrad return ret; 1344 1.1 riastrad 1345 1.1 riastrad s->ops = ops[interface]; 1346 1.1 riastrad s->virtual_submission_interface = interface; 1347 1.1 riastrad s->active = true; 1348 1.1 riastrad 1349 1.1 riastrad gvt_dbg_core("vgpu%d: activate ops [ %s ]\n", 1350 1.1 riastrad vgpu->id, s->ops->name); 1351 1.1 riastrad 1352 1.1 riastrad return 0; 1353 1.1 riastrad } 1354 1.1 riastrad 1355 1.1 riastrad /** 1356 1.1 riastrad * intel_vgpu_destroy_workload - destroy a vGPU workload 1357 1.1 riastrad * @workload: workload to destroy 1358 1.1 riastrad * 1359 1.1 riastrad * This function is called when destroy a vGPU workload. 1360 1.1 riastrad * 1361 1.1 riastrad */ 1362 1.1 riastrad void intel_vgpu_destroy_workload(struct intel_vgpu_workload *workload) 1363 1.1 riastrad { 1364 1.1 riastrad struct intel_vgpu_submission *s = &workload->vgpu->submission; 1365 1.1 riastrad 1366 1.1 riastrad release_shadow_batch_buffer(workload); 1367 1.1 riastrad release_shadow_wa_ctx(&workload->wa_ctx); 1368 1.1 riastrad 1369 1.1 riastrad if (workload->shadow_mm) 1370 1.1 riastrad intel_vgpu_mm_put(workload->shadow_mm); 1371 1.1 riastrad 1372 1.1 riastrad kmem_cache_free(s->workloads, workload); 1373 1.1 riastrad } 1374 1.1 riastrad 1375 1.1 riastrad static struct intel_vgpu_workload * 1376 1.1 riastrad alloc_workload(struct intel_vgpu *vgpu) 1377 1.1 riastrad { 1378 1.1 riastrad struct intel_vgpu_submission *s = &vgpu->submission; 1379 1.1 riastrad struct intel_vgpu_workload *workload; 1380 1.1 riastrad 1381 1.1 riastrad workload = kmem_cache_zalloc(s->workloads, GFP_KERNEL); 1382 1.1 riastrad if (!workload) 1383 1.1 riastrad return ERR_PTR(-ENOMEM); 1384 1.1 riastrad 1385 1.1 riastrad INIT_LIST_HEAD(&workload->list); 1386 1.1 riastrad INIT_LIST_HEAD(&workload->shadow_bb); 1387 1.1 riastrad 1388 1.1 riastrad init_waitqueue_head(&workload->shadow_ctx_status_wq); 1389 1.1 riastrad atomic_set(&workload->shadow_ctx_active, 0); 1390 1.1 riastrad 1391 1.1 riastrad workload->status = -EINPROGRESS; 1392 1.1 riastrad workload->vgpu = vgpu; 1393 1.1 riastrad 1394 1.1 riastrad return workload; 1395 1.1 riastrad } 1396 1.1 riastrad 1397 1.1 riastrad #define RING_CTX_OFF(x) \ 1398 1.1 riastrad offsetof(struct execlist_ring_context, x) 1399 1.1 riastrad 1400 1.1 riastrad static void read_guest_pdps(struct intel_vgpu *vgpu, 1401 1.1 riastrad u64 ring_context_gpa, u32 pdp[8]) 1402 1.1 riastrad { 1403 1.1 riastrad u64 gpa; 1404 1.1 riastrad int i; 1405 1.1 riastrad 1406 1.1 riastrad gpa = ring_context_gpa + RING_CTX_OFF(pdps[0].val); 1407 1.1 riastrad 1408 1.1 riastrad for (i = 0; i < 8; i++) 1409 1.1 riastrad intel_gvt_hypervisor_read_gpa(vgpu, 1410 1.1 riastrad gpa + i * 8, &pdp[7 - i], 4); 1411 1.1 riastrad } 1412 1.1 riastrad 1413 1.1 riastrad static int prepare_mm(struct intel_vgpu_workload *workload) 1414 1.1 riastrad { 1415 1.1 riastrad struct execlist_ctx_descriptor_format *desc = &workload->ctx_desc; 1416 1.1 riastrad struct intel_vgpu_mm *mm; 1417 1.1 riastrad struct intel_vgpu *vgpu = workload->vgpu; 1418 1.1 riastrad enum intel_gvt_gtt_type root_entry_type; 1419 1.1 riastrad u64 pdps[GVT_RING_CTX_NR_PDPS]; 1420 1.1 riastrad 1421 1.1 riastrad switch (desc->addressing_mode) { 1422 1.1 riastrad case 1: /* legacy 32-bit */ 1423 1.1 riastrad root_entry_type = GTT_TYPE_PPGTT_ROOT_L3_ENTRY; 1424 1.1 riastrad break; 1425 1.1 riastrad case 3: /* legacy 64-bit */ 1426 1.1 riastrad root_entry_type = GTT_TYPE_PPGTT_ROOT_L4_ENTRY; 1427 1.1 riastrad break; 1428 1.1 riastrad default: 1429 1.1 riastrad gvt_vgpu_err("Advanced Context mode(SVM) is not supported!\n"); 1430 1.1 riastrad return -EINVAL; 1431 1.1 riastrad } 1432 1.1 riastrad 1433 1.1 riastrad read_guest_pdps(workload->vgpu, workload->ring_context_gpa, (void *)pdps); 1434 1.1 riastrad 1435 1.1 riastrad mm = intel_vgpu_get_ppgtt_mm(workload->vgpu, root_entry_type, pdps); 1436 1.1 riastrad if (IS_ERR(mm)) 1437 1.1 riastrad return PTR_ERR(mm); 1438 1.1 riastrad 1439 1.1 riastrad workload->shadow_mm = mm; 1440 1.1 riastrad return 0; 1441 1.1 riastrad } 1442 1.1 riastrad 1443 1.1 riastrad #define same_context(a, b) (((a)->context_id == (b)->context_id) && \ 1444 1.1 riastrad ((a)->lrca == (b)->lrca)) 1445 1.1 riastrad 1446 1.1 riastrad /** 1447 1.1 riastrad * intel_vgpu_create_workload - create a vGPU workload 1448 1.1 riastrad * @vgpu: a vGPU 1449 1.1 riastrad * @ring_id: ring index 1450 1.1 riastrad * @desc: a guest context descriptor 1451 1.1 riastrad * 1452 1.1 riastrad * This function is called when creating a vGPU workload. 1453 1.1 riastrad * 1454 1.1 riastrad * Returns: 1455 1.1 riastrad * struct intel_vgpu_workload * on success, negative error code in 1456 1.1 riastrad * pointer if failed. 1457 1.1 riastrad * 1458 1.1 riastrad */ 1459 1.1 riastrad struct intel_vgpu_workload * 1460 1.1 riastrad intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, 1461 1.1 riastrad struct execlist_ctx_descriptor_format *desc) 1462 1.1 riastrad { 1463 1.1 riastrad struct intel_vgpu_submission *s = &vgpu->submission; 1464 1.1 riastrad struct list_head *q = workload_q_head(vgpu, ring_id); 1465 1.1 riastrad struct intel_vgpu_workload *last_workload = NULL; 1466 1.1 riastrad struct intel_vgpu_workload *workload = NULL; 1467 1.1 riastrad struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 1468 1.1 riastrad u64 ring_context_gpa; 1469 1.1 riastrad u32 head, tail, start, ctl, ctx_ctl, per_ctx, indirect_ctx; 1470 1.1 riastrad u32 guest_head; 1471 1.1 riastrad int ret; 1472 1.1 riastrad 1473 1.1 riastrad ring_context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, 1474 1.1 riastrad (u32)((desc->lrca + 1) << I915_GTT_PAGE_SHIFT)); 1475 1.1 riastrad if (ring_context_gpa == INTEL_GVT_INVALID_ADDR) { 1476 1.1 riastrad gvt_vgpu_err("invalid guest context LRCA: %x\n", desc->lrca); 1477 1.1 riastrad return ERR_PTR(-EINVAL); 1478 1.1 riastrad } 1479 1.1 riastrad 1480 1.1 riastrad intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + 1481 1.1 riastrad RING_CTX_OFF(ring_header.val), &head, 4); 1482 1.1 riastrad 1483 1.1 riastrad intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + 1484 1.1 riastrad RING_CTX_OFF(ring_tail.val), &tail, 4); 1485 1.1 riastrad 1486 1.1 riastrad guest_head = head; 1487 1.1 riastrad 1488 1.1 riastrad head &= RB_HEAD_OFF_MASK; 1489 1.1 riastrad tail &= RB_TAIL_OFF_MASK; 1490 1.1 riastrad 1491 1.1 riastrad list_for_each_entry_reverse(last_workload, q, list) { 1492 1.1 riastrad 1493 1.1 riastrad if (same_context(&last_workload->ctx_desc, desc)) { 1494 1.1 riastrad gvt_dbg_el("ring id %d cur workload == last\n", 1495 1.1 riastrad ring_id); 1496 1.1 riastrad gvt_dbg_el("ctx head %x real head %lx\n", head, 1497 1.1 riastrad last_workload->rb_tail); 1498 1.1 riastrad /* 1499 1.1 riastrad * cannot use guest context head pointer here, 1500 1.1 riastrad * as it might not be updated at this time 1501 1.1 riastrad */ 1502 1.1 riastrad head = last_workload->rb_tail; 1503 1.1 riastrad break; 1504 1.1 riastrad } 1505 1.1 riastrad } 1506 1.1 riastrad 1507 1.1 riastrad gvt_dbg_el("ring id %d begin a new workload\n", ring_id); 1508 1.1 riastrad 1509 1.1 riastrad /* record some ring buffer register values for scan and shadow */ 1510 1.1 riastrad intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + 1511 1.1 riastrad RING_CTX_OFF(rb_start.val), &start, 4); 1512 1.1 riastrad intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + 1513 1.1 riastrad RING_CTX_OFF(rb_ctrl.val), &ctl, 4); 1514 1.1 riastrad intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + 1515 1.1 riastrad RING_CTX_OFF(ctx_ctrl.val), &ctx_ctl, 4); 1516 1.1 riastrad 1517 1.1 riastrad if (!intel_gvt_ggtt_validate_range(vgpu, start, 1518 1.1 riastrad _RING_CTL_BUF_SIZE(ctl))) { 1519 1.1 riastrad gvt_vgpu_err("context contain invalid rb at: 0x%x\n", start); 1520 1.1 riastrad return ERR_PTR(-EINVAL); 1521 1.1 riastrad } 1522 1.1 riastrad 1523 1.1 riastrad workload = alloc_workload(vgpu); 1524 1.1 riastrad if (IS_ERR(workload)) 1525 1.1 riastrad return workload; 1526 1.1 riastrad 1527 1.1 riastrad workload->ring_id = ring_id; 1528 1.1 riastrad workload->ctx_desc = *desc; 1529 1.1 riastrad workload->ring_context_gpa = ring_context_gpa; 1530 1.1 riastrad workload->rb_head = head; 1531 1.1 riastrad workload->guest_rb_head = guest_head; 1532 1.1 riastrad workload->rb_tail = tail; 1533 1.1 riastrad workload->rb_start = start; 1534 1.1 riastrad workload->rb_ctl = ctl; 1535 1.1 riastrad 1536 1.1 riastrad if (ring_id == RCS0) { 1537 1.1 riastrad intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + 1538 1.1 riastrad RING_CTX_OFF(bb_per_ctx_ptr.val), &per_ctx, 4); 1539 1.1 riastrad intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + 1540 1.1 riastrad RING_CTX_OFF(rcs_indirect_ctx.val), &indirect_ctx, 4); 1541 1.1 riastrad 1542 1.1 riastrad workload->wa_ctx.indirect_ctx.guest_gma = 1543 1.1 riastrad indirect_ctx & INDIRECT_CTX_ADDR_MASK; 1544 1.1 riastrad workload->wa_ctx.indirect_ctx.size = 1545 1.1 riastrad (indirect_ctx & INDIRECT_CTX_SIZE_MASK) * 1546 1.1 riastrad CACHELINE_BYTES; 1547 1.1 riastrad 1548 1.1 riastrad if (workload->wa_ctx.indirect_ctx.size != 0) { 1549 1.1 riastrad if (!intel_gvt_ggtt_validate_range(vgpu, 1550 1.1 riastrad workload->wa_ctx.indirect_ctx.guest_gma, 1551 1.1 riastrad workload->wa_ctx.indirect_ctx.size)) { 1552 1.1 riastrad gvt_vgpu_err("invalid wa_ctx at: 0x%lx\n", 1553 1.1 riastrad workload->wa_ctx.indirect_ctx.guest_gma); 1554 1.1 riastrad kmem_cache_free(s->workloads, workload); 1555 1.1 riastrad return ERR_PTR(-EINVAL); 1556 1.1 riastrad } 1557 1.1 riastrad } 1558 1.1 riastrad 1559 1.1 riastrad workload->wa_ctx.per_ctx.guest_gma = 1560 1.1 riastrad per_ctx & PER_CTX_ADDR_MASK; 1561 1.1 riastrad workload->wa_ctx.per_ctx.valid = per_ctx & 1; 1562 1.1 riastrad if (workload->wa_ctx.per_ctx.valid) { 1563 1.1 riastrad if (!intel_gvt_ggtt_validate_range(vgpu, 1564 1.1 riastrad workload->wa_ctx.per_ctx.guest_gma, 1565 1.1 riastrad CACHELINE_BYTES)) { 1566 1.1 riastrad gvt_vgpu_err("invalid per_ctx at: 0x%lx\n", 1567 1.1 riastrad workload->wa_ctx.per_ctx.guest_gma); 1568 1.1 riastrad kmem_cache_free(s->workloads, workload); 1569 1.1 riastrad return ERR_PTR(-EINVAL); 1570 1.1 riastrad } 1571 1.1 riastrad } 1572 1.1 riastrad } 1573 1.1 riastrad 1574 1.1 riastrad gvt_dbg_el("workload %p ring id %d head %x tail %x start %x ctl %x\n", 1575 1.1 riastrad workload, ring_id, head, tail, start, ctl); 1576 1.1 riastrad 1577 1.1 riastrad ret = prepare_mm(workload); 1578 1.1 riastrad if (ret) { 1579 1.1 riastrad kmem_cache_free(s->workloads, workload); 1580 1.1 riastrad return ERR_PTR(ret); 1581 1.1 riastrad } 1582 1.1 riastrad 1583 1.1 riastrad /* Only scan and shadow the first workload in the queue 1584 1.1 riastrad * as there is only one pre-allocated buf-obj for shadow. 1585 1.1 riastrad */ 1586 1.1 riastrad if (list_empty(workload_q_head(vgpu, ring_id))) { 1587 1.1 riastrad intel_runtime_pm_get(&dev_priv->runtime_pm); 1588 1.1 riastrad ret = intel_gvt_scan_and_shadow_workload(workload); 1589 1.1 riastrad intel_runtime_pm_put_unchecked(&dev_priv->runtime_pm); 1590 1.1 riastrad } 1591 1.1 riastrad 1592 1.1 riastrad if (ret) { 1593 1.1 riastrad if (vgpu_is_vm_unhealthy(ret)) 1594 1.1 riastrad enter_failsafe_mode(vgpu, GVT_FAILSAFE_GUEST_ERR); 1595 1.1 riastrad intel_vgpu_destroy_workload(workload); 1596 1.1 riastrad return ERR_PTR(ret); 1597 1.1 riastrad } 1598 1.1 riastrad 1599 1.1 riastrad return workload; 1600 1.1 riastrad } 1601 1.1 riastrad 1602 1.1 riastrad /** 1603 1.1 riastrad * intel_vgpu_queue_workload - Qeue a vGPU workload 1604 1.1 riastrad * @workload: the workload to queue in 1605 1.1 riastrad */ 1606 1.1 riastrad void intel_vgpu_queue_workload(struct intel_vgpu_workload *workload) 1607 1.1 riastrad { 1608 1.1 riastrad list_add_tail(&workload->list, 1609 1.1 riastrad workload_q_head(workload->vgpu, workload->ring_id)); 1610 1.1 riastrad intel_gvt_kick_schedule(workload->vgpu->gvt); 1611 1.1 riastrad wake_up(&workload->vgpu->gvt->scheduler.waitq[workload->ring_id]); 1612 1.1 riastrad } 1613