aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPing Gao <ping.a.gao@intel.com>2017-03-29 22:03:24 -0400
committerZhenyu Wang <zhenyuw@linux.intel.com>2017-03-30 01:34:04 -0400
commit39d467c2b71ccb4a55af830c117fafe0525caa12 (patch)
tree078251548e8d10ac542334055d2686efb8288926
parentbc90d097ae144fab1f789f8523b621de7125c6a8 (diff)
drm/i915/gvt: add basic function for weight control
This method tries to guarantee precision in second level, with the adjustment conducted in every 100ms. At the end of each vGPU switch calculate the sched time and subtract it from the time slice allocated; the allocated time slice for every 100ms together with remaining timeslice, will be used to decide how much timeslice allocated to this vGPU in the next 100ms slice, with the end goal to guarantee weight ratio in second level. Signed-off-by: Ping Gao <ping.a.gao@intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
-rw-r--r--drivers/gpu/drm/i915/gvt/sched_policy.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/gvt/sched_policy.c b/drivers/gpu/drm/i915/gvt/sched_policy.c
index 5aa7a2539e4d..dd5b38c3e4ed 100644
--- a/drivers/gpu/drm/i915/gvt/sched_policy.c
+++ b/drivers/gpu/drm/i915/gvt/sched_policy.c
@@ -67,6 +67,60 @@ struct gvt_sched_data {
67 struct list_head lru_runq_head; 67 struct list_head lru_runq_head;
68}; 68};
69 69
70static void vgpu_update_timeslice(struct intel_vgpu *pre_vgpu)
71{
72 ktime_t delta_ts;
73 struct vgpu_sched_data *vgpu_data = pre_vgpu->sched_data;
74
75 delta_ts = vgpu_data->sched_out_time - vgpu_data->sched_in_time;
76
77 vgpu_data->sched_time += delta_ts;
78 vgpu_data->left_ts -= delta_ts;
79}
80
81#define GVT_TS_BALANCE_PERIOD_MS 100
82#define GVT_TS_BALANCE_STAGE_NUM 10
83
84static void gvt_balance_timeslice(struct gvt_sched_data *sched_data)
85{
86 struct vgpu_sched_data *vgpu_data;
87 struct list_head *pos;
88 static uint64_t stage_check;
89 int stage = stage_check++ % GVT_TS_BALANCE_STAGE_NUM;
90
91 /* The timeslice accumulation reset at stage 0, which is
92 * allocated again without adding previous debt.
93 */
94 if (stage == 0) {
95 int total_weight = 0;
96 ktime_t fair_timeslice;
97
98 list_for_each(pos, &sched_data->lru_runq_head) {
99 vgpu_data = container_of(pos, struct vgpu_sched_data, lru_list);
100 total_weight += vgpu_data->sched_ctl.weight;
101 }
102
103 list_for_each(pos, &sched_data->lru_runq_head) {
104 vgpu_data = container_of(pos, struct vgpu_sched_data, lru_list);
105 fair_timeslice = ms_to_ktime(GVT_TS_BALANCE_PERIOD_MS) *
106 vgpu_data->sched_ctl.weight /
107 total_weight;
108
109 vgpu_data->allocated_ts = fair_timeslice;
110 vgpu_data->left_ts = vgpu_data->allocated_ts;
111 }
112 } else {
113 list_for_each(pos, &sched_data->lru_runq_head) {
114 vgpu_data = container_of(pos, struct vgpu_sched_data, lru_list);
115
116 /* timeslice for next 100ms should add the left/debt
117 * slice of previous stages.
118 */
119 vgpu_data->left_ts += vgpu_data->allocated_ts;
120 }
121 }
122}
123
70static void try_to_schedule_next_vgpu(struct intel_gvt *gvt) 124static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
71{ 125{
72 struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; 126 struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
@@ -103,6 +157,7 @@ static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
103 if (scheduler->current_vgpu) { 157 if (scheduler->current_vgpu) {
104 vgpu_data = scheduler->current_vgpu->sched_data; 158 vgpu_data = scheduler->current_vgpu->sched_data;
105 vgpu_data->sched_out_time = cur_time; 159 vgpu_data->sched_out_time = cur_time;
160 vgpu_update_timeslice(scheduler->current_vgpu);
106 } 161 }
107 vgpu_data = scheduler->next_vgpu->sched_data; 162 vgpu_data = scheduler->next_vgpu->sched_data;
108 vgpu_data->sched_in_time = cur_time; 163 vgpu_data->sched_in_time = cur_time;
@@ -148,6 +203,10 @@ static void tbs_sched_func(struct gvt_sched_data *sched_data)
148 struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; 203 struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
149 struct vgpu_sched_data *vgpu_data; 204 struct vgpu_sched_data *vgpu_data;
150 struct intel_vgpu *vgpu = NULL; 205 struct intel_vgpu *vgpu = NULL;
206 static uint64_t timer_check;
207
208 if (!(timer_check++ % GVT_TS_BALANCE_PERIOD_MS))
209 gvt_balance_timeslice(sched_data);
151 210
152 /* no active vgpu or has already had a target */ 211 /* no active vgpu or has already had a target */
153 if (list_empty(&sched_data->lru_runq_head) || scheduler->next_vgpu) 212 if (list_empty(&sched_data->lru_runq_head) || scheduler->next_vgpu)