diff options
Diffstat (limited to 'SOURCES/cachy-fixes.patch')
-rw-r--r-- | SOURCES/cachy-fixes.patch | 573 |
1 files changed, 573 insertions, 0 deletions
diff --git a/SOURCES/cachy-fixes.patch b/SOURCES/cachy-fixes.patch new file mode 100644 index 0000000..1c632df --- /dev/null +++ b/SOURCES/cachy-fixes.patch @@ -0,0 +1,573 @@ +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 371531b2a3d0..ddc064b4fc32 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -8327,6 +8327,122 @@ static inline uint32_t get_mem_type(struct drm_framebuffer *fb) + return abo->tbo.resource ? abo->tbo.resource->mem_type : 0; + } + ++/* TODO remove duplicate */ ++static int amdgpu_dm_plane_get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc, ++ struct dc_cursor_position *position) ++{ ++ struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); ++ int x, y; ++ int xorigin = 0, yorigin = 0; ++ ++ if (!crtc || !plane->state->fb) ++ return 0; ++ ++ if ((plane->state->crtc_w > amdgpu_crtc->max_cursor_width) || ++ (plane->state->crtc_h > amdgpu_crtc->max_cursor_height)) { ++ DRM_ERROR("%s: bad cursor width or height %d x %d\n", ++ __func__, ++ plane->state->crtc_w, ++ plane->state->crtc_h); ++ return -EINVAL; ++ } ++ ++ x = plane->state->crtc_x; ++ y = plane->state->crtc_y; ++ ++ if (x <= -amdgpu_crtc->max_cursor_width || ++ y <= -amdgpu_crtc->max_cursor_height) ++ return 0; ++ ++ if (x < 0) { ++ xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1); ++ x = 0; ++ } ++ if (y < 0) { ++ yorigin = min(-y, amdgpu_crtc->max_cursor_height - 1); ++ y = 0; ++ } ++ position->enable = true; ++ position->translate_by_source = true; ++ position->x = x; ++ position->y = y; ++ position->x_hotspot = xorigin; ++ position->y_hotspot = yorigin; ++ ++ return 0; ++} ++ ++static void amdgpu_dm_update_cursor(struct drm_plane *plane, ++ struct drm_plane_state *old_plane_state, ++ struct dc_stream_update *update) ++{ ++ struct amdgpu_device *adev = drm_to_adev(plane->dev); ++ struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(plane->state->fb); ++ struct drm_crtc *crtc = afb ? plane->state->crtc : old_plane_state->crtc; ++ struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL; ++ struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); ++ uint64_t address = afb ? afb->address : 0; ++ struct dc_cursor_position position = {0}; ++ struct dc_cursor_attributes attributes; ++ int ret; ++ ++ if (!plane->state->fb && !old_plane_state->fb) ++ return; ++ ++ drm_dbg_atomic(plane->dev, "crtc_id=%d with size %d to %d\n", ++ amdgpu_crtc->crtc_id, plane->state->crtc_w, ++ plane->state->crtc_h); ++ ++ ret = amdgpu_dm_plane_get_cursor_position(plane, crtc, &position); ++ if (ret) ++ return; ++ ++ if (!position.enable) { ++ /* turn off cursor */ ++ if (crtc_state && crtc_state->stream) { ++ dc_stream_set_cursor_position(crtc_state->stream, ++ &position); ++ update->cursor_position = &crtc_state->stream->cursor_position; ++ } ++ return; ++ } ++ ++ amdgpu_crtc->cursor_width = plane->state->crtc_w; ++ amdgpu_crtc->cursor_height = plane->state->crtc_h; ++ ++ memset(&attributes, 0, sizeof(attributes)); ++ attributes.address.high_part = upper_32_bits(address); ++ attributes.address.low_part = lower_32_bits(address); ++ attributes.width = plane->state->crtc_w; ++ attributes.height = plane->state->crtc_h; ++ attributes.color_format = CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA; ++ attributes.rotation_angle = 0; ++ attributes.attribute_flags.value = 0; ++ ++ /* Enable cursor degamma ROM on DCN3+ for implicit sRGB degamma in DRM ++ * legacy gamma setup. ++ */ ++ if (crtc_state->cm_is_degamma_srgb && ++ adev->dm.dc->caps.color.dpp.gamma_corr) ++ attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA = 1; ++ ++ attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0]; ++ ++ if (crtc_state->stream) { ++ if (!dc_stream_set_cursor_attributes(crtc_state->stream, ++ &attributes)) ++ DRM_ERROR("DC failed to set cursor attributes\n"); ++ ++ update->cursor_attributes = &crtc_state->stream->cursor_attributes; ++ ++ if (!dc_stream_set_cursor_position(crtc_state->stream, ++ &position)) ++ DRM_ERROR("DC failed to set cursor position\n"); ++ ++ update->cursor_position = &crtc_state->stream->cursor_position; ++ } ++} ++ + static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + struct drm_device *dev, + struct amdgpu_display_manager *dm, +@@ -8350,6 +8466,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + bool cursor_update = false; + bool pflip_present = false; + bool dirty_rects_changed = false; ++ bool updated_planes_and_streams = false; + struct { + struct dc_surface_update surface_updates[MAX_SURFACES]; + struct dc_plane_info plane_infos[MAX_SURFACES]; +@@ -8386,8 +8503,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + /* Cursor plane is handled after stream updates */ + if (plane->type == DRM_PLANE_TYPE_CURSOR) { + if ((fb && crtc == pcrtc) || +- (old_plane_state->fb && old_plane_state->crtc == pcrtc)) ++ (old_plane_state->fb && old_plane_state->crtc == pcrtc)) { + cursor_update = true; ++ amdgpu_dm_update_cursor(plane, old_plane_state, &bundle->stream_update); ++ } + + continue; + } +@@ -8660,6 +8779,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + acrtc_state->stream, + &bundle->stream_update, + bundle->surface_updates); ++ updated_planes_and_streams = true; + + /** + * Enable or disable the interrupts on the backend. +@@ -8737,7 +8857,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + * This avoids redundant programming in the case where we're going + * to be disabling a single plane - those pipes are being disabled. + */ +- if (acrtc_state->active_planes) ++ if (acrtc_state->active_planes && !updated_planes_and_streams) + amdgpu_dm_commit_cursors(state); + + cleanup: +@@ -8925,7 +9045,7 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state, + + memset(&position, 0, sizeof(position)); + mutex_lock(&dm->dc_lock); +- dc_stream_set_cursor_position(dm_old_crtc_state->stream, &position); ++ dc_stream_program_cursor_position(dm_old_crtc_state->stream, &position); + mutex_unlock(&dm->dc_lock); + } + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +index 779880c64575..8c8d0d209d7a 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +@@ -1254,7 +1254,7 @@ void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane, + /* turn off cursor */ + if (crtc_state && crtc_state->stream) { + mutex_lock(&adev->dm.dc_lock); +- dc_stream_set_cursor_position(crtc_state->stream, ++ dc_stream_program_cursor_position(crtc_state->stream, + &position); + mutex_unlock(&adev->dm.dc_lock); + } +@@ -1284,11 +1284,11 @@ void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane, + + if (crtc_state->stream) { + mutex_lock(&adev->dm.dc_lock); +- if (!dc_stream_set_cursor_attributes(crtc_state->stream, ++ if (!dc_stream_program_cursor_attributes(crtc_state->stream, + &attributes)) + DRM_ERROR("DC failed to set cursor attributes\n"); + +- if (!dc_stream_set_cursor_position(crtc_state->stream, ++ if (!dc_stream_program_cursor_position(crtc_state->stream, + &position)) + DRM_ERROR("DC failed to set cursor position\n"); + mutex_unlock(&adev->dm.dc_lock); +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index d68c83e40d4d..575290784c61 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -3188,6 +3188,83 @@ static bool update_planes_and_stream_state(struct dc *dc, + + } + ++static void program_cursor_attributes( ++ struct dc *dc, ++ struct dc_stream_state *stream) ++{ ++ int i; ++ struct resource_context *res_ctx; ++ struct pipe_ctx *pipe_to_program = NULL; ++ ++ if (!stream) ++ return; ++ ++ res_ctx = &dc->current_state->res_ctx; ++ ++ for (i = 0; i < MAX_PIPES; i++) { ++ struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; ++ ++ if (pipe_ctx->stream != stream) ++ continue; ++ ++ if (!pipe_to_program) { ++ pipe_to_program = pipe_ctx; ++ dc->hwss.cursor_lock(dc, pipe_to_program, true); ++ if (pipe_to_program->next_odm_pipe) ++ dc->hwss.cursor_lock(dc, pipe_to_program->next_odm_pipe, true); ++ } ++ ++ dc->hwss.set_cursor_attribute(pipe_ctx); ++ if (dc->ctx->dmub_srv) ++ dc_send_update_cursor_info_to_dmu(pipe_ctx, i); ++ if (dc->hwss.set_cursor_sdr_white_level) ++ dc->hwss.set_cursor_sdr_white_level(pipe_ctx); ++ } ++ ++ if (pipe_to_program) { ++ dc->hwss.cursor_lock(dc, pipe_to_program, false); ++ if (pipe_to_program->next_odm_pipe) ++ dc->hwss.cursor_lock(dc, pipe_to_program->next_odm_pipe, false); ++ } ++} ++ ++static void program_cursor_position( ++ struct dc *dc, ++ struct dc_stream_state *stream) ++{ ++ int i; ++ struct resource_context *res_ctx; ++ struct pipe_ctx *pipe_to_program = NULL; ++ ++ if (!stream) ++ return; ++ ++ res_ctx = &dc->current_state->res_ctx; ++ ++ for (i = 0; i < MAX_PIPES; i++) { ++ struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; ++ ++ if (pipe_ctx->stream != stream || ++ (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) || ++ !pipe_ctx->plane_state || ++ (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp) || ++ (!pipe_ctx->plane_res.ipp && !pipe_ctx->plane_res.dpp)) ++ continue; ++ ++ if (!pipe_to_program) { ++ pipe_to_program = pipe_ctx; ++ dc->hwss.cursor_lock(dc, pipe_to_program, true); ++ } ++ ++ dc->hwss.set_cursor_position(pipe_ctx); ++ if (dc->ctx->dmub_srv) ++ dc_send_update_cursor_info_to_dmu(pipe_ctx, i); ++ } ++ ++ if (pipe_to_program) ++ dc->hwss.cursor_lock(dc, pipe_to_program, false); ++} ++ + static void commit_planes_do_stream_update(struct dc *dc, + struct dc_stream_state *stream, + struct dc_stream_update *stream_update, +@@ -3248,6 +3325,13 @@ static void commit_planes_do_stream_update(struct dc *dc, + } + } + ++ if (stream_update->cursor_attributes) { ++ program_cursor_attributes(dc, stream); ++ } ++ ++ if (stream_update->cursor_position) { ++ program_cursor_position(dc, stream); ++ } + + /* Full fe update*/ + if (update_type == UPDATE_TYPE_FAST) +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +index 51a970fcb5d0..5601ee8a8d41 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +@@ -278,7 +278,6 @@ bool dc_stream_set_cursor_attributes( + const struct dc_cursor_attributes *attributes) + { + struct dc *dc; +- bool reset_idle_optimizations = false; + + if (NULL == stream) { + dm_error("DC: dc_stream is NULL!\n"); +@@ -309,20 +308,36 @@ bool dc_stream_set_cursor_attributes( + + stream->cursor_attributes = *attributes; + +- dc_z10_restore(dc); +- /* disable idle optimizations while updating cursor */ +- if (dc->idle_optimizations_allowed) { +- dc_allow_idle_optimizations(dc, false); +- reset_idle_optimizations = true; +- } ++ return true; ++} + +- program_cursor_attributes(dc, stream, attributes); ++bool dc_stream_program_cursor_attributes( ++ struct dc_stream_state *stream, ++ const struct dc_cursor_attributes *attributes) ++{ ++ struct dc *dc; ++ bool reset_idle_optimizations = false; + +- /* re-enable idle optimizations if necessary */ +- if (reset_idle_optimizations) +- dc_allow_idle_optimizations(dc, true); ++ dc = stream ? stream->ctx->dc : NULL; + +- return true; ++ if (dc_stream_set_cursor_attributes(stream, attributes)) { ++ dc_z10_restore(dc); ++ /* disable idle optimizations while updating cursor */ ++ if (dc->idle_optimizations_allowed) { ++ dc_allow_idle_optimizations(dc, false); ++ reset_idle_optimizations = true; ++ } ++ ++ program_cursor_attributes(dc, stream, attributes); ++ ++ /* re-enable idle optimizations if necessary */ ++ if (reset_idle_optimizations) ++ dc_allow_idle_optimizations(dc, true); ++ ++ return true; ++ } ++ ++ return false; + } + + static void program_cursor_position( +@@ -367,9 +382,6 @@ bool dc_stream_set_cursor_position( + struct dc_stream_state *stream, + const struct dc_cursor_position *position) + { +- struct dc *dc; +- bool reset_idle_optimizations = false; +- + if (NULL == stream) { + dm_error("DC: dc_stream is NULL!\n"); + return false; +@@ -380,24 +392,43 @@ bool dc_stream_set_cursor_position( + return false; + } + ++ stream->cursor_position = *position; ++ ++ return true; ++} ++ ++bool dc_stream_program_cursor_position( ++ struct dc_stream_state *stream, ++ const struct dc_cursor_position *position) ++{ ++ struct dc *dc; ++ bool reset_idle_optimizations = false; ++ const struct dc_cursor_position *old_position; ++ ++ old_position = stream ? &stream->cursor_position : NULL; + dc = stream->ctx->dc; +- dc_z10_restore(dc); + +- /* disable idle optimizations if enabling cursor */ +- if (dc->idle_optimizations_allowed && (!stream->cursor_position.enable || dc->debug.exit_idle_opt_for_cursor_updates) +- && position->enable) { +- dc_allow_idle_optimizations(dc, false); +- reset_idle_optimizations = true; +- } ++ if (dc_stream_set_cursor_position(stream, position)) { ++ dc_z10_restore(dc); + +- stream->cursor_position = *position; ++ /* disable idle optimizations if enabling cursor */ ++ if (dc->idle_optimizations_allowed && ++ (!old_position->enable || dc->debug.exit_idle_opt_for_cursor_updates) && ++ position->enable) { ++ dc_allow_idle_optimizations(dc, false); ++ reset_idle_optimizations = true; ++ } + +- program_cursor_position(dc, stream, position); +- /* re-enable idle optimizations if necessary */ +- if (reset_idle_optimizations) +- dc_allow_idle_optimizations(dc, true); + +- return true; ++ program_cursor_position(dc, stream, position); ++ /* re-enable idle optimizations if necessary */ ++ if (reset_idle_optimizations) ++ dc_allow_idle_optimizations(dc, true); ++ ++ return true; ++ } ++ ++ return false; + } + + bool dc_stream_add_writeback(struct dc *dc, +diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h +index ee10941caa59..df86668f560f 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h ++++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h +@@ -327,6 +327,9 @@ struct dc_stream_update { + + struct test_pattern *pending_test_pattern; + struct dc_crtc_timing_adjust *crtc_timing_adjust; ++ ++ struct dc_cursor_attributes *cursor_attributes; ++ struct dc_cursor_position *cursor_position; + }; + + bool dc_is_stream_unchanged( +@@ -478,10 +481,17 @@ bool dc_stream_set_cursor_attributes( + struct dc_stream_state *stream, + const struct dc_cursor_attributes *attributes); + ++bool dc_stream_program_cursor_attributes( ++ struct dc_stream_state *stream, ++ const struct dc_cursor_attributes *attributes); ++ + bool dc_stream_set_cursor_position( + struct dc_stream_state *stream, + const struct dc_cursor_position *position); + ++bool dc_stream_program_cursor_position( ++ struct dc_stream_state *stream, ++ const struct dc_cursor_position *position); + + bool dc_stream_adjust_vmin_vmax(struct dc *dc, + struct dc_stream_state *stream, +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c +index 8bc3d01537bb..f91169c80f7f 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c +@@ -1042,7 +1042,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) + + /* Use copied cursor, and it's okay to not switch back */ + cursor_attr.address.quad_part = cmd.mall.cursor_copy_dst.quad_part; +- dc_stream_set_cursor_attributes(stream, &cursor_attr); ++ dc_stream_program_cursor_attributes(stream, &cursor_attr); + } + + /* Enable MALL */ +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index 1e020620748d..082f87834503 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -4269,6 +4269,13 @@ void set_extent_buffer_uptodate(struct extent_buffer *eb) + } + } + ++static void clear_extent_buffer_reading(struct extent_buffer *eb) ++{ ++ clear_bit(EXTENT_BUFFER_READING, &eb->bflags); ++ smp_mb__after_atomic(); ++ wake_up_bit(&eb->bflags, EXTENT_BUFFER_READING); ++} ++ + static void end_bbio_meta_read(struct btrfs_bio *bbio) + { + struct extent_buffer *eb = bbio->private; +@@ -4277,6 +4284,13 @@ static void end_bbio_meta_read(struct btrfs_bio *bbio) + struct folio_iter fi; + u32 bio_offset = 0; + ++ /* ++ * If the extent buffer is marked UPTODATE before the read operation ++ * completes, other calls to read_extent_buffer_pages() will return ++ * early without waiting for the read to finish, causing data races. ++ */ ++ WARN_ON(test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)); ++ + eb->read_mirror = bbio->mirror_num; + + if (uptodate && +@@ -4303,9 +4317,7 @@ static void end_bbio_meta_read(struct btrfs_bio *bbio) + bio_offset += len; + } + +- clear_bit(EXTENT_BUFFER_READING, &eb->bflags); +- smp_mb__after_atomic(); +- wake_up_bit(&eb->bflags, EXTENT_BUFFER_READING); ++ clear_extent_buffer_reading(eb); + free_extent_buffer(eb); + + bio_put(&bbio->bio); +@@ -4339,9 +4351,7 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num, + * will now be set, and we shouldn't read it in again. + */ + if (unlikely(test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))) { +- clear_bit(EXTENT_BUFFER_READING, &eb->bflags); +- smp_mb__after_atomic(); +- wake_up_bit(&eb->bflags, EXTENT_BUFFER_READING); ++ clear_extent_buffer_reading(eb); + return 0; + } + +diff --git a/include/linux/filter.h b/include/linux/filter.h +index cf12bfa2a78c..2acf8634008d 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -644,14 +644,16 @@ static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog, + cant_migrate(); + if (static_branch_unlikely(&bpf_stats_enabled_key)) { + struct bpf_prog_stats *stats; +- u64 start = sched_clock(); ++ u64 duration, start = sched_clock(); + unsigned long flags; + + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); ++ ++ duration = sched_clock() - start; + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->cnt); +- u64_stats_add(&stats->nsecs, sched_clock() - start); ++ u64_stats_add(&stats->nsecs, duration); + u64_stats_update_end_irqrestore(&stats->syncp, flags); + } else { + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); +diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c +index db7599c59c78..146de96e99b8 100644 +--- a/kernel/bpf/trampoline.c ++++ b/kernel/bpf/trampoline.c +@@ -883,12 +883,13 @@ static void notrace update_prog_stats(struct bpf_prog *prog, + * Hence check that 'start' is valid. + */ + start > NO_START_TIME) { ++ u64 duration = sched_clock() - start; + unsigned long flags; + + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->cnt); +- u64_stats_add(&stats->nsecs, sched_clock() - start); ++ u64_stats_add(&stats->nsecs, duration); + u64_stats_update_end_irqrestore(&stats->syncp, flags); + } + } +-- +2.45.2 + |