History

Merge tag 'drm-intel-fixes-2019-11-21' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes

- Fix kernel oops on dumb_create ioctl on no crtc situation - Fix bad ugly colored flash on VLV/CHV related to gamma LUT update - Fix unity of the frequencies reported on PMU - Fix kernel oops on set_page_dirty using better locks around it - Protect the request pointer with RCU to prevent it being freed while we might need still - Make pool objects read-only - Restore physical addresses for fb_map to avoid corrupted page table Signed-off-by: Dave Airlie <airlied@redhat.com>

Dave Airlie committed 6 years ago

Commit 51658c02 parents f824c1b 71d12269 files · +141 −18Browse files

Unified · Split

9 files
  1. drivers/gpu/drm/i915/display/intel_atomic.c +1 −0
  2. drivers/gpu/drm/i915/display/intel_color.c +61 −0
  3. drivers/gpu/drm/i915/display/intel_display.c +9 −0
  4. drivers/gpu/drm/i915/display/intel_display_types.h +1 −0
  5. drivers/gpu/drm/i915/display/intel_fbdev.c +5 −4
  6. drivers/gpu/drm/i915/gem/i915_gem_userptr.c +21 −1
  7. drivers/gpu/drm/i915/gt/intel_engine_pool.c +2 −0
  8. drivers/gpu/drm/i915/i915_pmu.c +2 −2
  9. drivers/gpu/drm/i915/i915_scheduler.c +39 −11
drivers/gpu/drm/i915/display/intel_atomic.c+1−0
@@ -201,6 +201,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) · 200 unmodified lines
201 crtc_state->update_wm_post = false;201 crtc_state->update_wm_post = false;
202 crtc_state->fb_changed = false;202 crtc_state->fb_changed = false;
203 crtc_state->fifo_changed = false;203 crtc_state->fifo_changed = false;
204 crtc_state->preload_luts = false;
204 crtc_state->wm.need_postvbl_update = false;205 crtc_state->wm.need_postvbl_update = false;
205 crtc_state->fb_bits = 0;206 crtc_state->fb_bits = 0;
206 crtc_state->update_planes = 0;207 crtc_state->update_planes = 0;
drivers/gpu/drm/i915/display/intel_color.c+61−0
@@ -990,6 +990,55 @@ void intel_color_commit(const struct intel_crtc_state *crtc_state) · 989 unmodified lines
990 dev_priv->display.color_commit(crtc_state);990 dev_priv->display.color_commit(crtc_state);
991}991}
992 992
993static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
994{
995 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
996 struct intel_atomic_state *state =
997 to_intel_atomic_state(new_crtc_state->base.state);
998 const struct intel_crtc_state *old_crtc_state =
999 intel_atomic_get_old_crtc_state(state, crtc);
1000
1001 return !old_crtc_state->base.gamma_lut &&
1002 !old_crtc_state->base.degamma_lut;
1003}
1004
1005static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1006{
1007 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
1008 struct intel_atomic_state *state =
1009 to_intel_atomic_state(new_crtc_state->base.state);
1010 const struct intel_crtc_state *old_crtc_state =
1011 intel_atomic_get_old_crtc_state(state, crtc);
1012
1013 /*
1014 * CGM_PIPE_MODE is itself single buffered. We'd have to
1015 * somehow split it out from chv_load_luts() if we wanted
1016 * the ability to preload the CGM LUTs/CSC without tearing.
1017 */
1018 if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
1019 return false;
1020
1021 return !old_crtc_state->base.gamma_lut;
1022}
1023
1024static bool glk_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1025{
1026 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
1027 struct intel_atomic_state *state =
1028 to_intel_atomic_state(new_crtc_state->base.state);
1029 const struct intel_crtc_state *old_crtc_state =
1030 intel_atomic_get_old_crtc_state(state, crtc);
1031
1032 /*
1033 * The hardware degamma is active whenever the pipe
1034 * CSC is active. Thus even if the old state has no
1035 * software degamma we need to avoid clobbering the
1036 * linear hardware degamma mid scanout.
1037 */
1038 return !old_crtc_state->csc_enable &&
1039 !old_crtc_state->base.gamma_lut;
1040}
1041
993int intel_color_check(struct intel_crtc_state *crtc_state)1042int intel_color_check(struct intel_crtc_state *crtc_state)
994{1043{
995 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);1044 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
@@ -1133,6 +1182,8 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state) · 137 unmodified lines
1133 if (ret)1182 if (ret)
1134 return ret;1183 return ret;
1135 1184
1185 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1186
1136 return 0;1187 return 0;
1137}1188}
1138 1189
@@ -1185,6 +1236,8 @@ static int chv_color_check(struct intel_crtc_state *crtc_state) · 46 unmodified lines
1185 if (ret)1236 if (ret)
1186 return ret;1237 return ret;
1187 1238
1239 crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
1240
1188 return 0;1241 return 0;
1189}1242}
1190 1243
@@ -1224,6 +1277,8 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state) · 33 unmodified lines
1224 if (ret)1277 if (ret)
1225 return ret;1278 return ret;
1226 1279
1280 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1281
1227 return 0;1282 return 0;
1228}1283}
1229 1284
@@ -1281,6 +1336,8 @@ static int ivb_color_check(struct intel_crtc_state *crtc_state) · 51 unmodified lines
1281 if (ret)1336 if (ret)
1282 return ret;1337 return ret;
1283 1338
1339 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1340
1284 return 0;1341 return 0;
1285}1342}
1286 1343
@@ -1319,6 +1376,8 @@ static int glk_color_check(struct intel_crtc_state *crtc_state) · 32 unmodified lines
1319 if (ret)1376 if (ret)
1320 return ret;1377 return ret;
1321 1378
1379 crtc_state->preload_luts = glk_can_preload_luts(crtc_state);
1380
1322 return 0;1381 return 0;
1323}1382}
1324 1383
@@ -1368,6 +1427,8 @@ static int icl_color_check(struct intel_crtc_state *crtc_state) · 43 unmodified lines
1368 1427
1369 crtc_state->csc_mode = icl_csc_mode(crtc_state);1428 crtc_state->csc_mode = icl_csc_mode(crtc_state);
1370 1429
1430 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1431
1371 return 0;1432 return 0;
1372}1433}
1373 1434
drivers/gpu/drm/i915/display/intel_display.c+9−0
@@ -2504,6 +2504,9 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv, · 2503 unmodified lines
2504 * the highest stride limits of them all.2504 * the highest stride limits of them all.
2505 */2505 */
2506 crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_A);2506 crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_A);
2507 if (!crtc)
2508 return 0;
2509
2507 plane = to_intel_plane(crtc->base.primary);2510 plane = to_intel_plane(crtc->base.primary);
2508 2511
2509 return plane->max_stride(plane, pixel_format, modifier,2512 return plane->max_stride(plane, pixel_format, modifier,
@@ -13740,6 +13743,11 @@ static void intel_update_crtc(struct intel_crtc *crtc, · 11230 unmodified lines
13740 /* vblanks work again, re-enable pipe CRC. */13743 /* vblanks work again, re-enable pipe CRC. */
13741 intel_crtc_enable_pipe_crc(crtc);13744 intel_crtc_enable_pipe_crc(crtc);
13742 } else {13745 } else {
13746 if (new_crtc_state->preload_luts &&
13747 (new_crtc_state->base.color_mgmt_changed ||
13748 new_crtc_state->update_pipe))
13749 intel_color_load_luts(new_crtc_state);
13750
13743 intel_pre_plane_update(old_crtc_state, new_crtc_state);13751 intel_pre_plane_update(old_crtc_state, new_crtc_state);
13744 13752
13745 if (new_crtc_state->update_pipe)13753 if (new_crtc_state->update_pipe)
@@ -14034,6 +14042,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) · 288 unmodified lines
14034 for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {14042 for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
14035 if (new_crtc_state->base.active &&14043 if (new_crtc_state->base.active &&
14036 !needs_modeset(new_crtc_state) &&14044 !needs_modeset(new_crtc_state) &&
14045 !new_crtc_state->preload_luts &&
14037 (new_crtc_state->base.color_mgmt_changed ||14046 (new_crtc_state->base.color_mgmt_changed ||
14038 new_crtc_state->update_pipe))14047 new_crtc_state->update_pipe))
14039 intel_color_load_luts(new_crtc_state);14048 intel_color_load_luts(new_crtc_state);
drivers/gpu/drm/i915/display/intel_display_types.h+1−0
@@ -761,6 +761,7 @@ struct intel_crtc_state { · 760 unmodified lines
761 bool update_wm_pre, update_wm_post; /* watermarks are updated */761 bool update_wm_pre, update_wm_post; /* watermarks are updated */
762 bool fb_changed; /* fb on any of the planes is changed */762 bool fb_changed; /* fb on any of the planes is changed */
763 bool fifo_changed; /* FIFO split is changed */763 bool fifo_changed; /* FIFO split is changed */
764 bool preload_luts;
764 765
765 /* Pipe source size (ie. panel fitter input size)766 /* Pipe source size (ie. panel fitter input size)
766 * All planes will be positioned inside this space,767 * All planes will be positioned inside this space,
drivers/gpu/drm/i915/display/intel_fbdev.c+5−4
@@ -235,6 +235,11 @@ static int intelfb_create(struct drm_fb_helper *helper, · 234 unmodified lines
235 info->apertures->ranges[0].base = ggtt->gmadr.start;235 info->apertures->ranges[0].base = ggtt->gmadr.start;
236 info->apertures->ranges[0].size = ggtt->mappable_end;236 info->apertures->ranges[0].size = ggtt->mappable_end;
237 237
238 /* Our framebuffer is the entirety of fbdev's system memory */
239 info->fix.smem_start =
240 (unsigned long)(ggtt->gmadr.start + vma->node.start);
241 info->fix.smem_len = vma->node.size;
242
238 vaddr = i915_vma_pin_iomap(vma);243 vaddr = i915_vma_pin_iomap(vma);
239 if (IS_ERR(vaddr)) {244 if (IS_ERR(vaddr)) {
240 DRM_ERROR("Failed to remap framebuffer into virtual memory\n");245 DRM_ERROR("Failed to remap framebuffer into virtual memory\n");
@@ -244,10 +249,6 @@ static int intelfb_create(struct drm_fb_helper *helper, · 3 unmodified lines
244 info->screen_base = vaddr;249 info->screen_base = vaddr;
245 info->screen_size = vma->node.size;250 info->screen_size = vma->node.size;
246 251
247 /* Our framebuffer is the entirety of fbdev's system memory */
248 info->fix.smem_start = (unsigned long)info->screen_base;
249 info->fix.smem_len = info->screen_size;
250
251 drm_fb_helper_fill_info(info, &ifbdev->helper, sizes);252 drm_fb_helper_fill_info(info, &ifbdev->helper, sizes);
252 253
253 /* If the object is shmemfs backed, it will have given us zeroed pages.254 /* If the object is shmemfs backed, it will have given us zeroed pages.
drivers/gpu/drm/i915/gem/i915_gem_userptr.c+21−1
@@ -671,8 +671,28 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj, · 670 unmodified lines
671 obj->mm.dirty = false;671 obj->mm.dirty = false;
672 672
673 for_each_sgt_page(page, sgt_iter, pages) {673 for_each_sgt_page(page, sgt_iter, pages) {
674 if (obj->mm.dirty)674 if (obj->mm.dirty && trylock_page(page)) {
675 /*
676 * As this may not be anonymous memory (e.g. shmem)
677 * but exist on a real mapping, we have to lock
678 * the page in order to dirty it -- holding
679 * the page reference is not sufficient to
680 * prevent the inode from being truncated.
681 * Play safe and take the lock.
682 *
683 * However...!
684 *
685 * The mmu-notifier can be invalidated for a
686 * migrate_page, that is alreadying holding the lock
687 * on the page. Such a try_to_unmap() will result
688 * in us calling put_pages() and so recursively try
689 * to lock the page. We avoid that deadlock with
690 * a trylock_page() and in exchange we risk missing
691 * some page dirtying.
692 */
675 set_page_dirty(page);693 set_page_dirty(page);
694 unlock_page(page);
695 }
676 696
677 mark_page_accessed(page);697 mark_page_accessed(page);
678 put_page(page);698 put_page(page);
drivers/gpu/drm/i915/gt/intel_engine_pool.c+2−0
@@ -103,6 +103,8 @@ node_create(struct intel_engine_pool *pool, size_t sz) · 102 unmodified lines
103 return ERR_CAST(obj);103 return ERR_CAST(obj);
104 }104 }
105 105
106 i915_gem_object_set_readonly(obj);
107
106 node->obj = obj;108 node->obj = obj;
107 return node;109 return node;
108}110}
drivers/gpu/drm/i915/i915_pmu.c+2−2
@@ -843,8 +843,8 @@ create_event_attributes(struct i915_pmu *pmu) · 842 unmodified lines
843 const char *name;843 const char *name;
844 const char *unit;844 const char *unit;
845 } events[] = {845 } events[] = {
846 __event(I915_PMU_ACTUAL_FREQUENCY, "actual-frequency", "MHz"),846 __event(I915_PMU_ACTUAL_FREQUENCY, "actual-frequency", "M"),
847 __event(I915_PMU_REQUESTED_FREQUENCY, "requested-frequency", "MHz"),847 __event(I915_PMU_REQUESTED_FREQUENCY, "requested-frequency", "M"),
848 __event(I915_PMU_INTERRUPTS, "interrupts", NULL),848 __event(I915_PMU_INTERRUPTS, "interrupts", NULL),
849 __event(I915_PMU_RC6_RESIDENCY, "rc6-residency", "ns"),849 __event(I915_PMU_RC6_RESIDENCY, "rc6-residency", "ns"),
850 };850 };
drivers/gpu/drm/i915/i915_scheduler.c+39−11
@@ -177,9 +177,37 @@ static inline int rq_prio(const struct i915_request *rq) · 176 unmodified lines
177 return rq->sched.attr.priority | __NO_PREEMPTION;177 return rq->sched.attr.priority | __NO_PREEMPTION;
178}178}
179 179
180static void kick_submission(struct intel_engine_cs *engine, int prio)180static inline bool need_preempt(int prio, int active)
181{181{
182 const struct i915_request *inflight = *engine->execlists.active;182 /*
183 * Allow preemption of low -> normal -> high, but we do
184 * not allow low priority tasks to preempt other low priority
185 * tasks under the impression that latency for low priority
186 * tasks does not matter (as much as background throughput),
187 * so kiss.
188 */
189 return prio >= max(I915_PRIORITY_NORMAL, active);
190}
191
192static void kick_submission(struct intel_engine_cs *engine,
193 const struct i915_request *rq,
194 int prio)
195{
196 const struct i915_request *inflight;
197
198 /*
199 * We only need to kick the tasklet once for the high priority
200 * new context we add into the queue.
201 */
202 if (prio <= engine->execlists.queue_priority_hint)
203 return;
204
205 rcu_read_lock();
206
207 /* Nothing currently active? We're overdue for a submission! */
208 inflight = execlists_active(&engine->execlists);
209 if (!inflight)
210 goto unlock;
183 211
184 /*212 /*
185 * If we are already the currently executing context, don't213 * If we are already the currently executing context, don't
@@ -188,10 +216,15 @@ static void kick_submission(struct intel_engine_cs *engine, int prio) · 2 unmodified lines
188 * tasklet, i.e. we have not change the priority queue216 * tasklet, i.e. we have not change the priority queue
189 * sufficiently to oust the running context.217 * sufficiently to oust the running context.
190 */218 */
191 if (!inflight || !i915_scheduler_need_preempt(prio, rq_prio(inflight)))219 if (inflight->hw_context == rq->hw_context)
192 return;220 goto unlock;
193 221
194 tasklet_hi_schedule(&engine->execlists.tasklet);222 engine->execlists.queue_priority_hint = prio;
223 if (need_preempt(prio, rq_prio(inflight)))
224 tasklet_hi_schedule(&engine->execlists.tasklet);
225
226unlock:
227 rcu_read_unlock();
195}228}
196 229
197static void __i915_schedule(struct i915_sched_node *node,230static void __i915_schedule(struct i915_sched_node *node,
@@ -317,13 +350,8 @@ static void __i915_schedule(struct i915_sched_node *node, · 119 unmodified lines
317 list_move_tail(&node->link, cache.priolist);350 list_move_tail(&node->link, cache.priolist);
318 }351 }
319 352
320 if (prio <= engine->execlists.queue_priority_hint)
321 continue;
322
323 engine->execlists.queue_priority_hint = prio;
324
325 /* Defer (tasklet) submission until after all of our updates. */353 /* Defer (tasklet) submission until after all of our updates. */
326 kick_submission(engine, prio);354 kick_submission(engine, node_to_request(node), prio);
327 }355 }
328 356
329 spin_unlock(&engine->active.lock);357 spin_unlock(&engine->active.lock);