diff options
-rw-r--r-- | drivers/gpu/drm/i915/gvt/sched_policy.c | 59 |
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 | ||
70 | static 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 | |||
84 | static 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 | |||
70 | static void try_to_schedule_next_vgpu(struct intel_gvt *gvt) | 124 | static 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) |