scheduler.c (d8235b5e55845de19983cec38af245cc200b81e2) scheduler.c (6d76303553bab75ffc53993c56aad06251d8de60)
1/*
2 * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the

--- 778 unchanged lines hidden (view full) ---

787
788 complete_current_workload(gvt, ring_id);
789
790 if (need_force_wake)
791 intel_uncore_forcewake_put(gvt->dev_priv,
792 FORCEWAKE_ALL);
793
794 intel_runtime_pm_put(gvt->dev_priv);
1/*
2 * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the

--- 778 unchanged lines hidden (view full) ---

787
788 complete_current_workload(gvt, ring_id);
789
790 if (need_force_wake)
791 intel_uncore_forcewake_put(gvt->dev_priv,
792 FORCEWAKE_ALL);
793
794 intel_runtime_pm_put(gvt->dev_priv);
795 if (ret && (vgpu_is_vm_unhealthy(ret))) {
796 mutex_lock(&gvt->lock);
797 intel_vgpu_clean_execlist(vgpu);
798 mutex_unlock(&gvt->lock);
795 if (ret && (vgpu_is_vm_unhealthy(ret)))
799 enter_failsafe_mode(vgpu, GVT_FAILSAFE_GUEST_ERR);
796 enter_failsafe_mode(vgpu, GVT_FAILSAFE_GUEST_ERR);
800 }
801
802 }
803 return 0;
804}
805
806void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu)
807{
808 struct intel_vgpu_submission *s = &vgpu->submission;
809 struct intel_gvt *gvt = vgpu->gvt;

--- 142 unchanged lines hidden (view full) ---

952 struct intel_vgpu_submission *s = &workload->vgpu->submission;
953
954 if (workload->shadow_mm)
955 intel_gvt_mm_unreference(workload->shadow_mm);
956
957 kmem_cache_free(s->workloads, workload);
958}
959
797 }
798 return 0;
799}
800
801void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu)
802{
803 struct intel_vgpu_submission *s = &vgpu->submission;
804 struct intel_gvt *gvt = vgpu->gvt;

--- 142 unchanged lines hidden (view full) ---

947 struct intel_vgpu_submission *s = &workload->vgpu->submission;
948
949 if (workload->shadow_mm)
950 intel_gvt_mm_unreference(workload->shadow_mm);
951
952 kmem_cache_free(s->workloads, workload);
953}
954
955static struct intel_vgpu_workload *
956alloc_workload(struct intel_vgpu *vgpu)
957{
958 struct intel_vgpu_submission *s = &vgpu->submission;
959 struct intel_vgpu_workload *workload;
960
961 workload = kmem_cache_zalloc(s->workloads, GFP_KERNEL);
962 if (!workload)
963 return ERR_PTR(-ENOMEM);
964
965 INIT_LIST_HEAD(&workload->list);
966 INIT_LIST_HEAD(&workload->shadow_bb);
967
968 init_waitqueue_head(&workload->shadow_ctx_status_wq);
969 atomic_set(&workload->shadow_ctx_active, 0);
970
971 workload->status = -EINPROGRESS;
972 workload->shadowed = false;
973 workload->vgpu = vgpu;
974
975 return workload;
976}
977
978#define RING_CTX_OFF(x) \
979 offsetof(struct execlist_ring_context, x)
980
981static void read_guest_pdps(struct intel_vgpu *vgpu,
982 u64 ring_context_gpa, u32 pdp[8])
983{
984 u64 gpa;
985 int i;
986
987 gpa = ring_context_gpa + RING_CTX_OFF(pdp3_UDW.val);
988
989 for (i = 0; i < 8; i++)
990 intel_gvt_hypervisor_read_gpa(vgpu,
991 gpa + i * 8, &pdp[7 - i], 4);
992}
993
994static int prepare_mm(struct intel_vgpu_workload *workload)
995{
996 struct execlist_ctx_descriptor_format *desc = &workload->ctx_desc;
997 struct intel_vgpu_mm *mm;
998 struct intel_vgpu *vgpu = workload->vgpu;
999 int page_table_level;
1000 u32 pdp[8];
1001
1002 if (desc->addressing_mode == 1) { /* legacy 32-bit */
1003 page_table_level = 3;
1004 } else if (desc->addressing_mode == 3) { /* legacy 64 bit */
1005 page_table_level = 4;
1006 } else {
1007 gvt_vgpu_err("Advanced Context mode(SVM) is not supported!\n");
1008 return -EINVAL;
1009 }
1010
1011 read_guest_pdps(workload->vgpu, workload->ring_context_gpa, pdp);
1012
1013 mm = intel_vgpu_find_ppgtt_mm(workload->vgpu, page_table_level, pdp);
1014 if (mm) {
1015 intel_gvt_mm_reference(mm);
1016 } else {
1017
1018 mm = intel_vgpu_create_mm(workload->vgpu, INTEL_GVT_MM_PPGTT,
1019 pdp, page_table_level, 0);
1020 if (IS_ERR(mm)) {
1021 gvt_vgpu_err("fail to create mm object.\n");
1022 return PTR_ERR(mm);
1023 }
1024 }
1025 workload->shadow_mm = mm;
1026 return 0;
1027}
1028
1029#define same_context(a, b) (((a)->context_id == (b)->context_id) && \
1030 ((a)->lrca == (b)->lrca))
1031
1032#define get_last_workload(q) \
1033 (list_empty(q) ? NULL : container_of(q->prev, \
1034 struct intel_vgpu_workload, list))
960/**
961 * intel_vgpu_create_workload - create a vGPU workload
962 * @vgpu: a vGPU
1035/**
1036 * intel_vgpu_create_workload - create a vGPU workload
1037 * @vgpu: a vGPU
1038 * @desc: a guest context descriptor
963 *
964 * This function is called when creating a vGPU workload.
965 *
966 * Returns:
967 * struct intel_vgpu_workload * on success, negative error code in
968 * pointer if failed.
969 *
970 */
971struct intel_vgpu_workload *
1039 *
1040 * This function is called when creating a vGPU workload.
1041 *
1042 * Returns:
1043 * struct intel_vgpu_workload * on success, negative error code in
1044 * pointer if failed.
1045 *
1046 */
1047struct intel_vgpu_workload *
972intel_vgpu_create_workload(struct intel_vgpu *vgpu)
1048intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
1049 struct execlist_ctx_descriptor_format *desc)
973{
974 struct intel_vgpu_submission *s = &vgpu->submission;
1050{
1051 struct intel_vgpu_submission *s = &vgpu->submission;
975 struct intel_vgpu_workload *workload;
1052 struct list_head *q = workload_q_head(vgpu, ring_id);
1053 struct intel_vgpu_workload *last_workload = get_last_workload(q);
1054 struct intel_vgpu_workload *workload = NULL;
1055 struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
1056 u64 ring_context_gpa;
1057 u32 head, tail, start, ctl, ctx_ctl, per_ctx, indirect_ctx;
1058 int ret;
976
1059
977 workload = kmem_cache_zalloc(s->workloads, GFP_KERNEL);
978 if (!workload)
979 return ERR_PTR(-ENOMEM);
1060 ring_context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm,
1061 (u32)((desc->lrca + 1) << GTT_PAGE_SHIFT));
1062 if (ring_context_gpa == INTEL_GVT_INVALID_ADDR) {
1063 gvt_vgpu_err("invalid guest context LRCA: %x\n", desc->lrca);
1064 return ERR_PTR(-EINVAL);
1065 }
980
1066
981 INIT_LIST_HEAD(&workload->list);
982 INIT_LIST_HEAD(&workload->shadow_bb);
1067 intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
1068 RING_CTX_OFF(ring_header.val), &head, 4);
983
1069
984 init_waitqueue_head(&workload->shadow_ctx_status_wq);
985 atomic_set(&workload->shadow_ctx_active, 0);
1070 intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
1071 RING_CTX_OFF(ring_tail.val), &tail, 4);
986
1072
987 workload->status = -EINPROGRESS;
988 workload->shadowed = false;
989 workload->vgpu = vgpu;
1073 head &= RB_HEAD_OFF_MASK;
1074 tail &= RB_TAIL_OFF_MASK;
990
1075
1076 if (last_workload && same_context(&last_workload->ctx_desc, desc)) {
1077 gvt_dbg_el("ring id %d cur workload == last\n", ring_id);
1078 gvt_dbg_el("ctx head %x real head %lx\n", head,
1079 last_workload->rb_tail);
1080 /*
1081 * cannot use guest context head pointer here,
1082 * as it might not be updated at this time
1083 */
1084 head = last_workload->rb_tail;
1085 }
1086
1087 gvt_dbg_el("ring id %d begin a new workload\n", ring_id);
1088
1089 /* record some ring buffer register values for scan and shadow */
1090 intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
1091 RING_CTX_OFF(rb_start.val), &start, 4);
1092 intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
1093 RING_CTX_OFF(rb_ctrl.val), &ctl, 4);
1094 intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
1095 RING_CTX_OFF(ctx_ctrl.val), &ctx_ctl, 4);
1096
1097 workload = alloc_workload(vgpu);
1098 if (IS_ERR(workload))
1099 return workload;
1100
1101 workload->ring_id = ring_id;
1102 workload->ctx_desc = *desc;
1103 workload->ring_context_gpa = ring_context_gpa;
1104 workload->rb_head = head;
1105 workload->rb_tail = tail;
1106 workload->rb_start = start;
1107 workload->rb_ctl = ctl;
1108
1109 if (ring_id == RCS) {
1110 intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
1111 RING_CTX_OFF(bb_per_ctx_ptr.val), &per_ctx, 4);
1112 intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
1113 RING_CTX_OFF(rcs_indirect_ctx.val), &indirect_ctx, 4);
1114
1115 workload->wa_ctx.indirect_ctx.guest_gma =
1116 indirect_ctx & INDIRECT_CTX_ADDR_MASK;
1117 workload->wa_ctx.indirect_ctx.size =
1118 (indirect_ctx & INDIRECT_CTX_SIZE_MASK) *
1119 CACHELINE_BYTES;
1120 workload->wa_ctx.per_ctx.guest_gma =
1121 per_ctx & PER_CTX_ADDR_MASK;
1122 workload->wa_ctx.per_ctx.valid = per_ctx & 1;
1123 }
1124
1125 gvt_dbg_el("workload %p ring id %d head %x tail %x start %x ctl %x\n",
1126 workload, ring_id, head, tail, start, ctl);
1127
1128 ret = prepare_mm(workload);
1129 if (ret) {
1130 kmem_cache_free(s->workloads, workload);
1131 return ERR_PTR(ret);
1132 }
1133
1134 /* Only scan and shadow the first workload in the queue
1135 * as there is only one pre-allocated buf-obj for shadow.
1136 */
1137 if (list_empty(workload_q_head(vgpu, ring_id))) {
1138 intel_runtime_pm_get(dev_priv);
1139 mutex_lock(&dev_priv->drm.struct_mutex);
1140 ret = intel_gvt_scan_and_shadow_workload(workload);
1141 mutex_unlock(&dev_priv->drm.struct_mutex);
1142 intel_runtime_pm_put(dev_priv);
1143 }
1144
1145 if (ret && (vgpu_is_vm_unhealthy(ret))) {
1146 enter_failsafe_mode(vgpu, GVT_FAILSAFE_GUEST_ERR);
1147 intel_vgpu_destroy_workload(workload);
1148 return ERR_PTR(ret);
1149 }
1150
991 return workload;
992}
1151 return workload;
1152}