- 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>
Unified · Split
| @@ -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; |
| @@ -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 | ||
| 993 | static 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 | |||
| 1005 | static 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 | |||
| 1024 | static 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 | |||
| 993 | int intel_color_check(struct intel_crtc_state *crtc_state) | 1042 | int 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 | ||
| @@ -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); |
| @@ -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, |
| @@ -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. |
| @@ -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); |
| @@ -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 | } |
| @@ -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 | }; |
| @@ -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 | ||
| 180 | static void kick_submission(struct intel_engine_cs *engine, int prio) | 180 | static 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 | |||
| 192 | static 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't | 213 | * 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 queue | 216 | * 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 | |||
| 226 | unlock: | ||
| 227 | rcu_read_unlock(); | ||
| 195 | } | 228 | } |
| 196 | 229 | ||
| 197 | static void __i915_schedule(struct i915_sched_node *node, | 230 | static 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); |