6.16.4-rc1 review
Subsystems (6)
Greg Kroah-Hartman
maintainerPATCH 145/457 media: qcom: camss: Remove extraneous -supply postfix on supply names
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan O'Donoghue <[email protected]>
commit c26e8dcd9d4e86d788c5bf7a5dd0ea70a95ab067 upstream.
The -supply postfix is wrong but wasn't noticed on the CRD devices or indeed the Dell devices, however on Lenovo devices the error comes up.
--- drivers/media/platform/qcom/camss/camss.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/media/platform/qcom/camss/camss.c +8 -8
@@ -2486,8 +2486,8 @@ static const struct resources_icc icc_res_sm8550[] = {static const struct camss_subdev_resources csiphy_res_x1e80100[] = {/* CSIPHY0 */ { - .regulators = {"vdd-csiphy-0p8-supply" , -"vdd-csiphy-1p2-supply" }, + .regulators = {"vdd-csiphy-0p8" , +"vdd-csiphy-1p2" }, .clock = {"csiphy0" ,"csiphy0_timer" }, .clock_rate = { {300000000 ,400000000 ,480000000 }, {266666667 ,400000000 } },
@@ -2501,8 +2501,8 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { },/* CSIPHY1 */ { - .regulators = { "vdd-csiphy-0p8-supply", - "vdd-csiphy-1p2-supply" }, + .regulators = { "vdd-csiphy-0p8", + "vdd-csiphy-1p2" }, .clock = { "csiphy1", "csiphy1_timer" }, .clock_rate = { { 300000000, 400000000, 480000000 }, { 266666667, 400000000 } },
@@ -2516,8 +2516,8 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { },/* CSIPHY2 */ { - .regulators = { "vdd-csiphy-0p8-supply", - "vdd-csiphy-1p2-supply" }, + .regulators = { "vdd-csiphy-0p8", + "vdd-csiphy-1p2" }, .clock = { "csiphy2", "csiphy2_timer" }, .clock_rate = { { 300000000, 400000000, 480000000 }, { 266666667, 400000000 } },
@@ -2531,8 +2531,8 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { },/* CSIPHY4 */ { - .regulators = { "vdd-csiphy-0p8-supply", - "vdd-csiphy-1p2-supply" }, + .regulators = { "vdd-csiphy-0p8", + "vdd-csiphy-1p2" }, .clock = { "csiphy4", "csiphy4_timer" }, .clock_rate = { { 300000000, 400000000, 480000000 }, { 266666667, 400000000 } },
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 146/457 media: venus: Add a check for packet size after reading from shared memory
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vedang Nagar <[email protected]>
commit 49befc830daa743e051a65468c05c2ff9e8580e6 upstream.
Add a check to ensure that the packet size does not exceed the number of available words after reading the packet header from shared memory. This ensures that the size provided by the firmware is safe to process and prevent potential out-of-bounds memory access.
--- drivers/media/platform/qcom/venus/hfi_venus.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/media/platform/qcom/venus/hfi_venus.c +4 -0
@@ -239,6 +239,7 @@ static int venus_write_queue(struct venustatic int venus_read_queue (struct venus_hfi_device *hdev,struct iface_queue *queue,void *pkt,u32 *tx_req) { +struct hfi_pkt_hdr *pkt_hdr =NULL ;struct hfi_queue_header *qhdr;u32 dwords, new_rd_idx;u32 rd_idx, wr_idx, type, qsize;
@@ -304,6 +305,9 @@ static int venus_read_queue(struct venusmemcpy (pkt, rd_ptr, len);memcpy (pkt + len, queue->qmem.kva, new_rd_idx <<2 ); } + pkt_hdr = (struct hfi_pkt_hdr *)(pkt); +if ((pkt_hdr->size >>2 ) != dwords) +return -EINVAL ; }else {/* bad packet received, dropping */ new_rd_idx = qhdr->write_idx;
Greg Kroah-Hartman
maintainerPATCH 147/457 media: venus: Fix MSM8998 frequency table
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <[email protected]>
commit ee3b94f22638e0f7a1893d95d87b08698b680052 upstream.
Fill in the correct data for the production SKU.
--- drivers/media/platform/qcom/venus/core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/media/platform/qcom/venus/core.c +5 -5
@@ -709,11 +709,11 @@ static const struct venus_resources msm8 };static const struct freq_tbl msm8998_freq_table[] = { - {1944000 ,465000000 },/* 4k UHD @ 60 (decode only) */ - {972000 ,465000000 },/* 4k UHD @ 30 */ - {489600 ,360000000 },/* 1080p @ 60 */ - {244800 ,186000000 },/* 1080p @ 30 */ - {108000 ,100000000 },/* 720p @ 30 */ + {1728000 ,533000000 },/* 4k UHD @ 60 (decode only) */ + {1036800 ,444000000 },/* 2k @ 120 */ + {829440 ,355200000 },/* 4k @ 44 */ + {489600 ,269330000 },/* 4k @ 30 */ + {108000 ,200000000 },/* 1080p @ 60 */ };static const struct reg_val msm8998_reg_preset[] = {
Greg Kroah-Hartman
maintainerPATCH 148/457 media: venus: hfi: explicitly release IRQ during teardown
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jorge Ramirez-Ortiz <[email protected]>
commit 640803003cd903cea73dc6a86bf6963e238e2b3f upstream.
Ensure the IRQ is disabled - and all pending handlers completed - before dismantling the interrupt routing and clearing related pointers.
This prevents any possibility of the interrupt triggering after the handler context has been invalidated.
--- drivers/media/platform/qcom/venus/hfi_venus.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/platform/qcom/venus/hfi_venus.c +1 -0
@@ -1682,6 +1682,7 @@ void venus_hfi_destroy(struct venus_corevenus_interface_queues_release (hdev);mutex_destroy (&hdev->lock);kfree (hdev); +disable_irq (core->irq); core->ops =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 149/457 media: venus: protect against spurious interrupts during probe
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jorge Ramirez-Ortiz <[email protected]>
commit 3200144a2fa4209dc084a19941b9b203b43580f0 upstream.
Make sure the interrupt handler is initialized before the interrupt is registered.
If the IRQ is registered before hfi_create(), it's possible that an interrupt fires before the handler setup is complete, leading to a NULL dereference.
This error condition has been observed during system boot on Rb3Gen2.
--- drivers/media/platform/qcom/venus/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/media/platform/qcom/venus/core.c +4 -4
@@ -424,13 +424,13 @@ static int venus_probe(struct platform_dINIT_DELAYED_WORK (&core->work, venus_sys_error_handler);init_waitqueue_head (&core->sys_err_done); - ret =devm_request_threaded_irq (dev, core->irq, hfi_isr, venus_isr_thread, -IRQF_TRIGGER_HIGH |IRQF_ONESHOT , -"venus" , core); + ret =hfi_create (core, &venus_core_ops);if (ret) goto err_core_put; - ret =hfi_create (core, &venus_core_ops); + ret =devm_request_threaded_irq (dev, core->irq, hfi_isr, venus_isr_thread, +IRQF_TRIGGER_HIGH |IRQF_ONESHOT , +"venus" , core);if (ret) goto err_core_put;
Greg Kroah-Hartman
maintainerPATCH 150/457 media: venus: vdec: Clamp param smaller than 1fps and bigger than 240.
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
commit 377dc500d253f0b26732b2cb062e89668aef890a upstream.
The driver uses "whole" fps in all its calculations (e.g. in load_per_instance()). Those calculation expect an fps bigger than 1, and not big enough to overflow.
Clamp the value if the user provides a param that will result in an invalid fps.
--- drivers/media/platform/qcom/venus/core.h | 2 ++ drivers/media/platform/qcom/venus/vdec.c | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-)
drivers/media/platform/qcom/venus/core.h +2 -0
@@ -28,6 +28,8 @@#define VIDC_RESETS_NUM_MAX 2#define VIDC_MAX_HIER_CODING_LAYER 6 +#define VENUS_MAX_FPS 240 +extern int venus_fw_debug;struct freq_tbl {
drivers/media/platform/qcom/venus/vdec.c +2 -3
@@ -481,11 +481,10 @@ static int vdec_s_parm(struct file *file us_per_frame = timeperframe->numerator * (u64 )USEC_PER_SEC ;do_div (us_per_frame, timeperframe->denominator); -if (!us_per_frame) -return -EINVAL ; - + us_per_frame =clamp (us_per_frame,1 ,USEC_PER_SEC ); fps = (u64 )USEC_PER_SEC ;do_div (fps, us_per_frame); + fps =min (VENUS_MAX_FPS , fps); inst->fps = fps; inst->timeperframe = *timeperframe;
Greg Kroah-Hartman
maintainerPATCH 151/457 media: venus: venc: Clamp param smaller than 1fps and bigger than 240
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
commit 417c01b92ec278a1118a05c6ad8a796eaa0c9c52 upstream.
The driver uses "whole" fps in all its calculations (e.g. in load_per_instance()). Those calculation expect an fps bigger than 1, and not big enough to overflow.
Clamp the param if the user provides a value that will result in an invalid fps.
--- drivers/media/platform/qcom/venus/venc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/media/platform/qcom/venus/venc.c +2 -3
@@ -411,11 +411,10 @@ static int venc_s_parm(struct file *file us_per_frame = timeperframe->numerator * (u64 )USEC_PER_SEC ;do_div (us_per_frame, timeperframe->denominator); -if (!us_per_frame) -return -EINVAL ; - + us_per_frame =clamp (us_per_frame,1 ,USEC_PER_SEC ); fps = (u64 )USEC_PER_SEC ;do_div (fps, us_per_frame); + fps =min (VENUS_MAX_FPS , fps); inst->timeperframe = *timeperframe; inst->fps = fps;
Greg Kroah-Hartman
maintainerPATCH 152/457 media: iris: Avoid updating frame size to firmware during reconfig
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit caf2055487694b6cb52f2ecb161c6c5de660dd72 upstream.
During reconfig, the firmware sends the resolution aligned to 8 bytes. If the driver sends the same resolution back to the firmware the resolution will be aligned to 16 bytes not 8.
The alignment mismatch would then subsequently cause the firmware to send another redundant sequence change event.
Fix this by not setting the resolution property during reconfig.
--- drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c | 15 ++++++++------- drivers/media/platform/qcom/iris/iris_state.c | 2 +- drivers/media/platform/qcom/iris/iris_state.h | 1 + 3 files changed, 10 insertions(+), 8 deletions(-)
drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c +8 -7
@@ -546,14 +546,15 @@ static int iris_hfi_gen1_set_resolution(struct hfi_framesize fs;int ret; - fs.buffer_type =HFI_BUFFER_INPUT ; - fs.width = inst->fmt_src->fmt.pix_mp.width; - fs.height = inst->fmt_src->fmt.pix_mp.height; - - ret =hfi_gen1_set_property (inst, ptype, &fs,sizeof (fs)); -if (ret) -return ret; +if (!iris_drc_pending (inst)) { + fs.buffer_type =HFI_BUFFER_INPUT ; + fs.width = inst->fmt_src->fmt.pix_mp.width; + fs.height = inst->fmt_src->fmt.pix_mp.height; + ret =hfi_gen1_set_property (inst, ptype, &fs,sizeof (fs)); +if (ret) +return ret; + } fs.buffer_type =HFI_BUFFER_OUTPUT2 ; fs.width = inst->fmt_dst->fmt.pix_mp.width; fs.height = inst->fmt_dst->fmt.pix_mp.height;
drivers/media/platform/qcom/iris/iris_state.c +1 -1
@@ -245,7 +245,7 @@ int iris_inst_sub_state_change_pause(strreturn iris_inst_change_sub_state (inst,0 , set_sub_state); } -static inline bool iris_drc_pending (struct iris_inst *inst) +bool iris_drc_pending (struct iris_inst *inst) {return inst->sub_state &IRIS_INST_SUB_DRC && inst->sub_state &IRIS_INST_SUB_DRC_LAST ;
drivers/media/platform/qcom/iris/iris_state.h +1 -0
@@ -140,5 +140,6 @@ int iris_inst_sub_state_change_drain_lasint iris_inst_sub_state_change_drc_last (struct iris_inst *inst);int iris_inst_sub_state_change_pause (struct iris_inst *inst,u32 plane);bool iris_allow_cmd (struct iris_inst *inst,u32 cmd); +bool iris_drc_pending (struct iris_inst *inst);#endif
Greg Kroah-Hartman
maintainerPATCH 153/457 media: iris: Drop port check for session property response
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit f3516f856d1f11d9dff7d72491d474a2bae1cf8e upstream.
Currently, port check enforces that session property response must arrive only on the BITSTREAM port. However, firmware can send some responses on other port as well.
Remove the strict port validation to correctly handle session property responses from the firmware.
--- drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c | 3 --- 1 file changed, 3 deletions(-)
drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c +0 -3
@@ -636,9 +636,6 @@ static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, {struct iris_inst_hfi_gen2 *inst_hfi_gen2 =to_iris_inst_hfi_gen2 (inst); -if (pkt->port !=HFI_PORT_BITSTREAM ) -return 0 ; -if (pkt->flags &HFI_FW_FLAGS_INFORMATION )return 0 ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 154/457 media: iris: Fix buffer preparation failure during resolution change
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit 91c6d55b477e1b66578c268214e915dff9f5ea57 upstream.
When the resolution changes, the driver internally updates the width and height, but the client continue to queue buffers with the older resolution until the last flag is received. This results in a mismatch when the buffers are prepared, causing failure due to outdated size.
Introduce a check to prevent size validation during buffer preparation if a resolution reconfiguration is in progress, to handle this.
--- drivers/media/platform/qcom/iris/iris_vb2.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
drivers/media/platform/qcom/iris/iris_vb2.c +8 -7
@@ -259,13 +259,14 @@ int iris_vb2_buf_prepare(struct vb2_buffer *vb)return -EINVAL ; } -if (vb->type ==V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && -vb2_plane_size (vb,0 ) <iris_get_buffer_size (inst,BUF_OUTPUT )) -return -EINVAL ; -if (vb->type ==V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && -vb2_plane_size (vb,0 ) <iris_get_buffer_size (inst,BUF_INPUT )) -return -EINVAL ; - +if (!(inst->sub_state &IRIS_INST_SUB_DRC )) { +if (vb->type ==V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && +vb2_plane_size (vb,0 ) <iris_get_buffer_size (inst,BUF_OUTPUT )) +return -EINVAL ; +if (vb->type ==V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && +vb2_plane_size (vb,0 ) <iris_get_buffer_size (inst,BUF_INPUT )) +return -EINVAL ; + }return 0 ; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 155/457 media: iris: Fix missing function pointer initialization
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit c314a28cdabe45f050fe7bd403ddeaf4b9c960d1 upstream.
The function pointers responsible for setting firmware properties were never initialized in the instance capability structure, causing it to remain NULL. As a result, the firmware properties were not being set correctly.
Fix this by properly assigning the function pointers from the core capability to the instance capability, ensuring that the properties are correctly applied to the firmware.
--- drivers/media/platform/qcom/iris/iris_ctrls.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/platform/qcom/iris/iris_ctrls.c +1 -0
@@ -163,6 +163,7 @@ void iris_session_init_caps(struct iris_ core->inst_fw_caps[cap_id].value = caps[i].value; core->inst_fw_caps[cap_id].flags = caps[i].flags; core->inst_fw_caps[cap_id].hfi_id = caps[i].hfi_id; + core->inst_fw_caps[cap_id].set = caps[i].set; } }
Greg Kroah-Hartman
maintainerPATCH 156/457 media: iris: Fix NULL pointer dereference
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit 0f837559ccdd275c5a059e6ac4d5034b03409f1d upstream.
A warning reported by smatch indicated a possible null pointer dereference where one of the arguments to API "iris_hfi_gen2_handle_system_error" could sometimes be null.
To fix this, add a check to validate that the argument passed is not null before accessing its members.
--- drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c +2 -1
@@ -265,7 +265,8 @@ static int iris_hfi_gen2_handle_system_error(struct iris_core *core, {struct iris_inst *instance; -dev_err (core->dev,"received system error of type %#x\n" , pkt->type); +if (pkt) +dev_err (core->dev,"received system error of type %#x\n" , pkt->type); core->state =IRIS_CORE_ERROR ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 157/457 media: iris: Fix typo in depth variable
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit 58edc8a68de7af45a4c815636595daa530f02c13 upstream.
Correct a typo from "dpeth" to "depth".
--- drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c +2 -2
@@ -178,7 +178,7 @@ static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst) sizeof(u64)); } -static int iris_hfi_gen2_set_bit_dpeth (struct iris_inst *inst) +static int iris_hfi_gen2_set_bit_depth (struct iris_inst *inst) {struct iris_inst_hfi_gen2 *inst_hfi_gen2 =to_iris_inst_hfi_gen2 (inst);u32 port =iris_hfi_gen2_get_port (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE );
@@ -378,7 +378,7 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p {HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution }, {HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets }, {HFI_PROP_CODED_FRAMES, iris_hfi_gen2_set_coded_frames }, - {HFI_PROP_LUMA_CHROMA_BIT_DEPTH, iris_hfi_gen2_set_bit_dpeth }, + {HFI_PROP_LUMA_CHROMA_BIT_DEPTH, iris_hfi_gen2_set_bit_depth }, {HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count }, {HFI_PROP_PIC_ORDER_CNT_TYPE, iris_hfi_gen2_set_picture_order_count }, {HFI_PROP_SIGNAL_COLOR_INFO, iris_hfi_gen2_set_colorspace },
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 158/457 media: iris: Prevent HFI queue writes when core is in deinit state
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit 2781662dee7bbb9675e5440f5dff4e3991dc5624 upstream.
The current check only considers the core error state before allowing writes to the HFI queues. However, the core can also transition to the deinit state due to a system error triggered by the response thread. In such cases, writing to the HFI queues should not be allowed.
Fix this by adding a check for the core deinit state, ensuring that writes are rejected when core is not in a valid state.
--- drivers/media/platform/qcom/iris/iris_hfi_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/qcom/iris/iris_hfi_queue.c +1 -1
@@ -113,7 +113,7 @@ int iris_hfi_queue_cmd_write_locked(stru {struct iris_iface_q_info *q_info = &core->command_queue; -if (core->state ==IRIS_CORE_ERROR ) +if (core->state ==IRIS_CORE_ERROR || core->state ==IRIS_CORE_DEINIT )return -EINVAL ;if (!iris_hfi_queue_write (q_info, pkt, pkt_size)) {
Greg Kroah-Hartman
maintainerPATCH 159/457 media: iris: Remove deprecated property setting to firmware
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit a693b4a3e7a95c010bedef4c8b3122bd8b0961b7 upstream.
HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER is deprecated and no longer supported on current firmware, remove setting the same to firmware.
--- drivers/media/platform/qcom/iris/iris_ctrls.c | 4 ---- drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c | 8 -------- drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h | 1 - drivers/media/platform/qcom/iris/iris_platform_common.h | 2 +- drivers/media/platform/qcom/iris/iris_platform_sm8250.c | 9 --------- 5 files changed, 1 insertion(+), 23 deletions(-)
drivers/media/platform/qcom/iris/iris_ctrls.c +0 -4
@@ -17,8 +17,6 @@ static inline bool iris_valid_cap_id(enustatic enum platform_inst_fw_cap_type iris_get_cap_id (u32 id) {switch (id) { -case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER : -return DEBLOCK ;case V4L2_CID_MPEG_VIDEO_H264_PROFILE :return PROFILE ;case V4L2_CID_MPEG_VIDEO_H264_LEVEL :
@@ -34,8 +32,6 @@ static u32 iris_get_v4l2_id(enum platforreturn 0 ;switch (cap_id) { -case DEBLOCK : -return V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER ;case PROFILE :return V4L2_CID_MPEG_VIDEO_H264_PROFILE ;case LEVEL :
drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c +0 -8
@@ -490,14 +490,6 @@ iris_hfi_gen1_packet_session_set_propert packet->shdr.hdr.size +=sizeof (u32) +sizeof (*wm);break ; } -case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER : { -struct hfi_enable *en = prop_data; -u32 *in = pdata; - - en->enable = *in; - packet->shdr.hdr.size +=sizeof (u32) +sizeof (*en); -break ; - }default :return -EINVAL ; }
drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h +0 -1
@@ -65,7 +65,6 @@#define HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS 0x202001 -#define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER 0x1200001#define HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS 0x120300e#define HFI_PROPERTY_CONFIG_VDEC_ENTROPY 0x1204004
drivers/media/platform/qcom/iris/iris_platform_common.h +1 -1
@@ -89,7 +89,7 @@ enum platform_inst_fw_cap_type {CODED_FRAMES ,BIT_DEPTH ,RAP_FRAME , -DEBLOCK , +TIER , INST_FW_CAP_MAX, };
drivers/media/platform/qcom/iris/iris_platform_sm8250.c +0 -9
@@ -30,15 +30,6 @@ static struct platform_inst_fw_cap inst_ .hfi_id = HFI_PROPERTY_PARAM_WORK_MODE, .set = iris_set_stage, }, - { - .cap_id = DEBLOCK, - .min = 0, - .max = 1, - .step_or_mask = 1, - .value = 0, - .hfi_id = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER, - .set = iris_set_u32, - }, }; static struct platform_inst_caps platform_inst_cap_sm8250 = {
Greg Kroah-Hartman
maintainerPATCH 160/457 media: iris: Remove error check for non-zero v4l2 controls
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit 03e29ab0e94831fcca2f62c96121fd14263b399b upstream.
Remove the check for non-zero number of v4l2 controls as some SOCs might not expose any capability which requires v4l2 control.
--- drivers/media/platform/qcom/iris/iris_ctrls.c | 2 -- 1 file changed, 2 deletions(-)
drivers/media/platform/qcom/iris/iris_ctrls.c +0 -2
@@ -80,8 +80,6 @@ int iris_ctrls_init(struct iris_inst *inif (iris_get_v4l2_id (cap[idx].cap_id)) num_ctrls++; } -if (!num_ctrls) -return -EINVAL ;/* Adding 1 to num_ctrls to include V4L2_CID_MIN_BUFFERS_FOR_CAPTURE */
Greg Kroah-Hartman
maintainerPATCH 161/457 media: iris: Send V4L2_BUF_FLAG_ERROR for capture buffers with 0 filled length
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit 7adc11e6abf619d0bb0c05918d5da5b9d4bcb81e upstream.
Firmware sends capture buffers with 0 filled length which are not to be displayed and should be dropped by client.
To achieve the same, add V4L2_BUF_FLAG_ERROR to such buffers by making sure:
- These 0 length buffers are not returned as result of flush.
- Its not a buffer with LAST flag enabled which will also have 0 filled length.
--- drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c +5 -0
@@ -378,6 +378,11 @@ static int iris_hfi_gen2_handle_output_buffer(struct iris_inst *inst, buf->flags =iris_hfi_gen2_get_driver_buffer_flags (inst, hfi_buffer->flags); +if (!buf->data_size && inst->state ==IRIS_INST_STREAMING && + !(hfi_buffer->flags &HFI_BUF_FW_FLAG_LAST )) { + buf->flags |=V4L2_BUF_FLAG_ERROR ; + } +return 0 ; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 162/457 media: iris: Skip destroying internal buffer if not dequeued
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit 7c452ffda30c0460c568273993a3d3c611486467 upstream.
Firmware might hold the DPB buffers for reference in case of sequence change, so skip destroying buffers for which QUEUED flag is not removed.
--- drivers/media/platform/qcom/iris/iris_buffer.c | 20 +++++++++++++++++++- drivers/media/platform/qcom/iris/iris_buffer.h | 3 ++- drivers/media/platform/qcom/iris/iris_vdec.c | 4 ++-- drivers/media/platform/qcom/iris/iris_vidc.c | 4 ++-- 4 files changed, 25 insertions(+), 6 deletions(-)
drivers/media/platform/qcom/iris/iris_buffer.c +19 -1
@@ -376,7 +376,7 @@ int iris_destroy_internal_buffer(structreturn 0 ; } -int iris_destroy_internal_buffers (struct iris_inst *inst,u32 plane) +static int iris_destroy_internal_buffers (struct iris_inst *inst,u32 plane,bool force) {const struct iris_platform_data *platform_data = inst->core->iris_platform_data;struct iris_buffer *buf, *next;
@@ -396,6 +396,14 @@ int iris_destroy_internal_buffers(structfor (i =0 ; i < len; i++) { buffers = &inst->buffers[internal_buf_type[i]];list_for_each_entry_safe (buf, next, &buffers->list, list) { +/* +* during stream on, skip destroying internal(DPB) buffer +* if firmware did not return it. +* during close, destroy all buffers irrespectively. +*/ +if (!force && buf->attr &BUF_ATTR_QUEUED ) +continue ; + ret =iris_destroy_internal_buffer (inst, buf);if (ret)return ret;
@@ -405,6 +413,16 @@ int iris_destroy_internal_buffers(structreturn 0 ; } +int iris_destroy_all_internal_buffers (struct iris_inst *inst,u32 plane) +{ +return iris_destroy_internal_buffers (inst, plane, true); +} + +int iris_destroy_dequeued_internal_buffers (struct iris_inst *inst,u32 plane) +{ +return iris_destroy_internal_buffers (inst, plane, false); +} +static int iris_release_internal_buffers (struct iris_inst *inst,enum iris_buffer_type buffer_type) {
drivers/media/platform/qcom/iris/iris_buffer.h +2 -1
@@ -106,7 +106,8 @@ void iris_get_internal_buffers(struct irint iris_create_internal_buffers (struct iris_inst *inst,u32 plane);int iris_queue_internal_buffers (struct iris_inst *inst,u32 plane);int iris_destroy_internal_buffer (struct iris_inst *inst,struct iris_buffer *buffer); -int iris_destroy_internal_buffers (struct iris_inst *inst,u32 plane); +int iris_destroy_all_internal_buffers (struct iris_inst *inst,u32 plane); +int iris_destroy_dequeued_internal_buffers (struct iris_inst *inst,u32 plane);int iris_alloc_and_queue_persist_bufs (struct iris_inst *inst);int iris_alloc_and_queue_input_int_bufs (struct iris_inst *inst);int iris_queue_buffer (struct iris_inst *inst,struct iris_buffer *buf);
drivers/media/platform/qcom/iris/iris_vdec.c +2 -2
@@ -408,7 +408,7 @@ int iris_vdec_streamon_input(struct irisiris_get_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ); - ret =iris_destroy_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ); + ret =iris_destroy_dequeued_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE );if (ret)return ret;
@@ -496,7 +496,7 @@ int iris_vdec_streamon_output(struct iriiris_get_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ); - ret =iris_destroy_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ); + ret =iris_destroy_dequeued_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE );if (ret)return ret;
drivers/media/platform/qcom/iris/iris_vidc.c +2 -2
@@ -233,8 +233,8 @@ int iris_close(struct file *filp)iris_session_close (inst);iris_inst_change_state (inst,IRIS_INST_DEINIT );iris_v4l2_fh_deinit (inst); -iris_destroy_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ); -iris_destroy_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ); +iris_destroy_all_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ); +iris_destroy_all_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE );iris_remove_session (inst);mutex_unlock (&inst->lock);mutex_destroy (&inst->ctx_q_lock);
Greg Kroah-Hartman
maintainerPATCH 163/457 media: iris: Skip flush on first sequence change
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit 1e27e9ffce59ac41cde71673d74eb368a533cdb2 upstream.
Add a condition to skip the flush operation during the first sequence change event. At this point, the capture queue is not streaming, making the flush unnecessary.
--- drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c +1 -1
@@ -200,7 +200,7 @@ static void iris_hfi_gen1_event_seq_changed(struct iris_inst *inst,iris_hfi_gen1_read_changed_params (inst, pkt); -if (inst->state !=IRIS_INST_ERROR ) { +if (inst->state !=IRIS_INST_ERROR && !(inst->sub_state &IRIS_INST_SUB_FIRST_IPSC )) {reinit_completion (&inst->flush_completion); flush_pkt.shdr.hdr.size =sizeof (struct hfi_session_flush_pkt );
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 164/457 media: iris: Track flush responses to prevent premature completion
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit 9bf58db157139abcd60e425e5718c8e6a917f9dc upstream.
Currently, two types of flush commands are queued to the firmware, the first flush queued as part of sequence change, does not wait for a response, while the second flush queued as part of stop, expects a completion response before proceeding further.
Due to timing issue, the flush response corresponding to the first command could arrive after the second flush is issued. This casuses the driver to incorrectly assume that the second flush has completed, leading to the premature signaling of flush_completion.
To address this, introduce a counter to track the number of pending flush responses and signal flush completion only when all expected responses are received.
--- drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c | 4 ++- drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c | 17 +++++++++----- drivers/media/platform/qcom/iris/iris_instance.h | 2 + 3 files changed, 16 insertions(+), 7 deletions(-)
drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c +3 -1
@@ -208,8 +208,10 @@ static int iris_hfi_gen1_session_stop(st flush_pkt.flush_type = flush_type; ret =iris_hfi_queue_cmd_write (core, &flush_pkt, flush_pkt.shdr.hdr.size); -if (!ret) +if (!ret) { + inst->flush_responses_pending++; ret =iris_wait_for_session_response (inst, true); + } }return ret;
drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c +11 -6
@@ -207,7 +207,8 @@ static void iris_hfi_gen1_event_seq_chan flush_pkt.shdr.hdr.pkt_type =HFI_CMD_SESSION_FLUSH ; flush_pkt.shdr.session_id = inst->session_id; flush_pkt.flush_type =HFI_FLUSH_OUTPUT ; -iris_hfi_queue_cmd_write (inst->core, &flush_pkt, flush_pkt.shdr.hdr.size); +if (!iris_hfi_queue_cmd_write (inst->core, &flush_pkt, flush_pkt.shdr.hdr.size)) + inst->flush_responses_pending++; }iris_vdec_src_change (inst);
@@ -408,7 +409,9 @@ static void iris_hfi_gen1_session_ftb_do flush_pkt.shdr.hdr.pkt_type =HFI_CMD_SESSION_FLUSH ; flush_pkt.shdr.session_id = inst->session_id; flush_pkt.flush_type =HFI_FLUSH_OUTPUT ; -iris_hfi_queue_cmd_write (core, &flush_pkt, flush_pkt.shdr.hdr.size); +if (!iris_hfi_queue_cmd_write (core, &flush_pkt, flush_pkt.shdr.hdr.size)) + inst->flush_responses_pending++; +iris_inst_sub_state_change_drain_last (inst);return ;
@@ -564,7 +567,6 @@ static void iris_hfi_gen1_handle_responsconst struct iris_hfi_gen1_response_pkt_info *pkt_info;struct device *dev = core->dev;struct hfi_session_pkt *pkt; -struct completion *done;struct iris_inst *inst;bool found = false;u32 i;
@@ -625,9 +627,12 @@ static void iris_hfi_gen1_handle_responsif (shdr->error_type !=HFI_ERR_NONE )iris_inst_change_state (inst,IRIS_INST_ERROR ); - done = pkt_info->pkt ==HFI_MSG_SESSION_FLUSH ? - &inst->flush_completion : &inst->completion; -complete (done); +if (pkt_info->pkt ==HFI_MSG_SESSION_FLUSH ) { +if (!(--inst->flush_responses_pending)) +complete (&inst->flush_completion); + }else { +complete (&inst->completion); + } }mutex_unlock (&inst->lock);
drivers/media/platform/qcom/iris/iris_instance.h +2 -0
@@ -27,6 +27,7 @@* @crop: structure of crop info * @completion: structure of signal completions * @flush_completion: structure of signal completions for flush cmd +* @flush_responses_pending: counter to track number of pending flush responses * @fw_caps: array of supported instance firmware capabilities * @buffers: array of different iris buffers * @fw_min_count: minimnum count of buffers needed by fw
@@ -57,6 +58,7 @@ struct iris_inst {struct iris_hfi_rect_desc crop;struct completion completion;struct completion flush_completion; +u32 flush_responses_pending;struct platform_inst_fw_cap fw_caps[INST_FW_CAP_MAX ];struct iris_buffers buffers[BUF_TYPE_MAX ];u32 fw_min_count;
Greg Kroah-Hartman
maintainerPATCH 165/457 media: iris: Update CAPTURE format info based on OUTPUT format
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit 8aadfd445373b74de4a5cd36736843ae01856636 upstream.
Update the width, height and buffer size of CAPTURE based on the resolution set to OUTPUT via VIDIOC_S_FMT. This is required to set the updated capture resolution to firmware when S_FMT is called only for OUTPUT.
--- drivers/media/platform/qcom/iris/iris_vdec.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/media/platform/qcom/iris/iris_vdec.c +5 -0
@@ -171,6 +171,11 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; +/* Update capture format based on new ip w/h */ + output_fmt->fmt.pix_mp.width =ALIGN (f->fmt.pix_mp.width,128 ); + output_fmt->fmt.pix_mp.height =ALIGN (f->fmt.pix_mp.height,32 ); + inst->buffers[BUF_OUTPUT ].size =iris_get_buffer_size (inst,BUF_OUTPUT ); + inst->crop.left =0 ; inst->crop.top =0 ; inst->crop.width = f->fmt.pix_mp.width;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 166/457 media: iris: Verify internal buffer release on close
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit d2abb1ff5a3c13321d407ee19865d0d8d834c7c6 upstream.
Validate all internal buffers queued to firmware are released back to driver on close. This helps ensure buffer lifecycle correctness and aids in debugging any resporce leaks.
--- drivers/media/platform/qcom/iris/iris_vidc.c | 29 ++++++++++++++++++++ 1 file changed, 29 insertions(+)
drivers/media/platform/qcom/iris/iris_vidc.c +29 -0
@@ -221,6 +221,33 @@ static void iris_session_close(struct iris_inst *inst)iris_wait_for_session_response (inst, false); } +static void iris_check_num_queued_internal_buffers (struct iris_inst *inst,u32 plane) +{ +const struct iris_platform_data *platform_data = inst->core->iris_platform_data; +struct iris_buffer *buf, *next; +struct iris_buffers *buffers; +const u32 *internal_buf_type; +u32 internal_buffer_count, i; +u32 count =0 ; + +if (V4L2_TYPE_IS_OUTPUT (plane)) { + internal_buf_type = platform_data->dec_ip_int_buf_tbl; + internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; + }else { + internal_buf_type = platform_data->dec_op_int_buf_tbl; + internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; + } + +for (i =0 ; i < internal_buffer_count; i++) { + buffers = &inst->buffers[internal_buf_type[i]]; +list_for_each_entry_safe (buf, next, &buffers->list, list) + count++; +if (count) +dev_err (inst->core->dev,"%d buffer of type %d not released" , + count, internal_buf_type[i]); + } +} +int iris_close (struct file *filp) {struct iris_inst *inst =iris_get_inst (filp,NULL );
@@ -235,6 +262,8 @@ int iris_close(struct file *filp)iris_v4l2_fh_deinit (inst);iris_destroy_all_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE );iris_destroy_all_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ); +iris_check_num_queued_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ); +iris_check_num_queued_internal_buffers (inst,V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE );iris_remove_session (inst);mutex_unlock (&inst->lock);mutex_destroy (&inst->ctx_q_lock);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 167/457 media: iris: Remove unnecessary re-initialization of flush completion
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal <[email protected]>
commit b7a898184e74a8261c34f1265139ac1799ee4e1c upstream.
Currently, The flush completion signal is being re-initialized even though no response is expected during a sequence change.
Simplify the code by removing re-initialization of flush completion signal as it is redundant.
--- drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c | 1 - 1 file changed, 1 deletion(-)
drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c +0 -1
@@ -201,7 +201,6 @@ static void iris_hfi_gen1_event_seq_changed(struct iris_inst *inst,iris_hfi_gen1_read_changed_params (inst, pkt);if (inst->state !=IRIS_INST_ERROR && !(inst->sub_state &IRIS_INST_SUB_FIRST_IPSC )) { -reinit_completion (&inst->flush_completion); flush_pkt.shdr.hdr.size =sizeof (struct hfi_session_flush_pkt ); flush_pkt.shdr.hdr.pkt_type =HFI_CMD_SESSION_FLUSH ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 168/457 drm/xe/bmg: Add one additional PCI ID
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vodapalli, Ravi Kumar <[email protected]>
commit ccfb15b8158c11a8304204aeac354c7b1cfb18a3 upstream.
One additional PCI ID is added in Bspec for BMG, Add it so that driver recognizes this device with this new ID.
Bspec: 68090
--- include/drm/intel/pciids.h | 1 + 1 file changed, 1 insertion(+)
include/drm/intel/pciids.h +1 -0
@@ -846,6 +846,7 @@/* BMG */ #define INTEL_BMG_IDS (MACRO__ , ...) \ MACRO__(0xE202, ## __VA_ARGS__), \ + MACRO__(0xE209, ## __VA_ARGS__), \ MACRO__(0xE20B, ## __VA_ARGS__), \ MACRO__(0xE20C, ## __VA_ARGS__), \ MACRO__(0xE20D, ## __VA_ARGS__), \
Greg Kroah-Hartman
maintainerPATCH 169/457 drm/xe: Defer buffer object shrinker write-backs and GPU waits
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Hellström <[email protected]>
commit 2dd7a47669ae6c1da18c55f8e89c4a44418c7006 upstream.
When the xe buffer-object shrinker allows GPU waits and write-back, (typically from kswapd), perform multiple passes, skipping subsequent passes if the shrinker number of scanned objects target is reached.
1) Without GPU waits and write-back
2) Without write-back
3) With both GPU-waits and write-back
This is to avoid stalls and costly write- and readbacks unless they are really necessary.
v2:
- Don't test for scan completion twice. (Stuart Summers)
- Update tags.
--- drivers/gpu/drm/xe/xe_shrinker.c | 51 +++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-)
drivers/gpu/drm/xe/xe_shrinker.c +47 -4
@@ -53,10 +53,10 @@ xe_shrinker_mod_pages(struct xe_shrinkerwrite_unlock (&shrinker->lock); } -static s64 xe_shrinker_walk (struct xe_device *xe, -struct ttm_operation_ctx *ctx, -const struct xe_bo_shrink_flags flags, -unsigned long to_scan,unsigned long *scanned) +static s64 __xe_shrinker_walk (struct xe_device *xe, +struct ttm_operation_ctx *ctx, +const struct xe_bo_shrink_flags flags, +unsigned long to_scan,unsigned long *scanned) {unsigned int mem_type;s64 freed =0 , lret;
@@ -86,6 +86,48 @@ static s64 xe_shrinker_walk(struct xe_dereturn freed; } +/* +* Try shrinking idle objects without writeback first, then if not sufficient, +* try also non-idle objects and finally if that's not sufficient either, +* add writeback. This avoids stalls and explicit writebacks with light or +* moderate memory pressure. +*/ +static s64 xe_shrinker_walk (struct xe_device *xe, +struct ttm_operation_ctx *ctx, +const struct xe_bo_shrink_flags flags, +unsigned long to_scan,unsigned long *scanned) +{ +bool no_wait_gpu = true; +struct xe_bo_shrink_flags save_flags = flags; +s64 lret, freed; + +swap (no_wait_gpu, ctx->no_wait_gpu); + save_flags.writeback = false; + lret =__xe_shrinker_walk (xe, ctx, save_flags, to_scan, scanned); +swap (no_wait_gpu, ctx->no_wait_gpu); +if (lret <0 || *scanned >= to_scan) +return lret; + + freed = lret; +if (!ctx->no_wait_gpu) { + lret =__xe_shrinker_walk (xe, ctx, save_flags, to_scan, scanned); +if (lret <0 ) +return lret; + freed += lret; +if (*scanned >= to_scan) +return freed; + } + +if (flags.writeback) { + lret =__xe_shrinker_walk (xe, ctx, flags, to_scan, scanned); +if (lret <0 ) +return lret; + freed += lret; + } + +return freed; +} +static unsigned long xe_shrinker_count (struct shrinker *shrink,struct shrink_control *sc) {
@@ -192,6 +234,7 @@ static unsigned long xe_shrinker_scan(st runtime_pm =xe_shrinker_runtime_pm_get (shrinker, true,0 , can_backup); shrink_flags.purge = false; + lret =xe_shrinker_walk (shrinker->xe, &ctx, shrink_flags, nr_to_scan, &nr_scanned);if (lret >=0 )
Greg Kroah-Hartman
maintainerPATCH 170/457 drm/amd/amdgpu: fix missing lock for cper.ring->rptr/wptr access
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Wang <[email protected]>
commit 8e0d1edb5c16732b695eaf4bd7096b1569817cf0 upstream.
Add lock protection for 'ring->wptr'/'ring->rptr' to ensure the correct execution.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c +5 -3
@@ -459,7 +459,7 @@ static u32 amdgpu_cper_ring_get_ent_sz(struct amdgpu_ring *ring, u64 pos)void amdgpu_cper_ring_write (struct amdgpu_ring *ring,void *src,int count) { -u64 pos, wptr_old, rptr = *ring->rptr_cpu_addr & ring->ptr_mask; +u64 pos, wptr_old, rptr;int rec_cnt_dw = count >>2 ;u32 chunk, ent_sz;u8 *s = (u8 *)src;
@@ -472,9 +472,11 @@ void amdgpu_cper_ring_write(struct amdgpu_ring *ring, void *src, int count)return ; } - wptr_old = ring->wptr; -mutex_lock (&ring->adev->cper.ring_lock); + + wptr_old = ring->wptr; + rptr = *ring->rptr_cpu_addr & ring->ptr_mask; +while (count) { ent_sz =amdgpu_cper_ring_get_ent_sz (ring, ring->wptr); chunk =umin (ent_sz, count);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 171/457 drm/amdgpu/discovery: fix fw based ip discovery
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 514678da56da089b756b4d433efd964fa22b2079 upstream.
We only need the fw based discovery table for sysfs. No need to parse it. Additionally parsing some of the board specific tables may result in incorrect data on some boards. just load the binary and don't parse it on those boards.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 5 - drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 72 ++++++++++++++------------ 2 files changed, 41 insertions(+), 36 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +2 -3
@@ -2561,9 +2561,6 @@ static int amdgpu_device_parse_gpu_info_ adev->firmware.gpu_info_fw =NULL ; -if (adev->mman.discovery_bin) -return 0 ; -switch (adev->asic_type) {default :return 0 ;
@@ -2585,6 +2582,8 @@ static int amdgpu_device_parse_gpu_info_ chip_name ="arcturus" ;break ;case CHIP_NAVI12 : +if (adev->mman.discovery_bin) +return 0 ; chip_name ="navi12" ;break ; }
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +39 -33
115 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 172/457 drm/amd: Restore cached power limit during resume
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit ed4efe426a49729952b3dc05d20e33b94409bdd1 upstream.
The power limit will be cached in smu->current_power_limit but if the ASIC goes into S3 this value won't be restored.
Restore the value during SMU resume.
--- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +6 -0
@@ -2175,6 +2175,12 @@ static int smu_resume(struct amdgpu_ip_b adev->pm.dpm_enabled = true; +if (smu->current_power_limit) { + ret =smu_set_power_limit (smu, smu->current_power_limit); +if (ret && ret != -EOPNOTSUPP ) +return ret; + } +dev_info (adev->dev,"SMU is resumed successfully!\n" );return 0 ;
Greg Kroah-Hartman
maintainerPATCH 173/457 drm/amdgpu: add kicker fws loading for gfx12/smu14/psp14
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Min <[email protected]>
commit 0395cde08e1f7eee810b5799466e41635a21e599 upstream.
1. Add kicker firmwares loading for gfx12/smu14/psp14
2. Register additional MODULE_FIRMWARE entries for kicker fws
- gc_12_0_1_rlc_kicker.bin
- gc_12_0_1_imu_kicker.bin
- psp_14_0_3_sos_kicker.bin
- psp_14_0_3_ta_kicker.bin
- smu_14_0_3_kicker.bin
--- drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 1 + drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 14 ++++++++++---- drivers/gpu/drm/amd/amdgpu/imu_v12_0.c | 11 ++++++++--- drivers/gpu/drm/amd/amdgpu/psp_v14_0.c | 2 ++ drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c | 11 ++++++++--- 5 files changed, 29 insertions(+), 10 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +1 -0
@@ -32,6 +32,7 @@static const struct kicker_device kicker_device_list[] = { {0x744B ,0x00 }, + {0x7551 ,0xC8 } };static void amdgpu_ucode_print_common_hdr (const struct common_firmware_header *hdr)
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +10 -4
@@ -79,6 +79,7 @@ MODULE_FIRMWARE("amdgpu/gc_12_0_1_pfp.biMODULE_FIRMWARE ("amdgpu/gc_12_0_1_me.bin" );MODULE_FIRMWARE ("amdgpu/gc_12_0_1_mec.bin" );MODULE_FIRMWARE ("amdgpu/gc_12_0_1_rlc.bin" ); +MODULE_FIRMWARE ("amdgpu/gc_12_0_1_rlc_kicker.bin" );MODULE_FIRMWARE ("amdgpu/gc_12_0_1_toc.bin" );static const struct amdgpu_hwip_reg_entry gc_reg_list_12_0[] = {
@@ -586,7 +587,7 @@ out:static int gfx_v12_0_init_microcode (struct amdgpu_device *adev) { -char ucode_prefix[15 ]; +char ucode_prefix[30 ];int err;const struct rlc_firmware_header_v2_0 *rlc_hdr;uint16_t version_major;
@@ -613,9 +614,14 @@ static int gfx_v12_0_init_microcode(struamdgpu_gfx_cp_init_microcode (adev,AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK );if (!amdgpu_sriov_vf (adev)) { - err =amdgpu_ucode_request (adev, &adev->gfx.rlc_fw, -AMDGPU_UCODE_REQUIRED , -"amdgpu/%s_rlc.bin" , ucode_prefix); +if (amdgpu_is_kicker_fw (adev)) + err =amdgpu_ucode_request (adev, &adev->gfx.rlc_fw, +AMDGPU_UCODE_REQUIRED , +"amdgpu/%s_rlc_kicker.bin" , ucode_prefix); +else + err =amdgpu_ucode_request (adev, &adev->gfx.rlc_fw, +AMDGPU_UCODE_REQUIRED , +"amdgpu/%s_rlc.bin" , ucode_prefix);if (err) goto out; rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
drivers/gpu/drm/amd/amdgpu/imu_v12_0.c +8 -3
@@ -34,12 +34,13 @@MODULE_FIRMWARE ("amdgpu/gc_12_0_0_imu.bin" );MODULE_FIRMWARE ("amdgpu/gc_12_0_1_imu.bin" ); +MODULE_FIRMWARE ("amdgpu/gc_12_0_1_imu_kicker.bin" );#define TRANSFER_RAM_MASK 0x001c0000static int imu_v12_0_init_microcode (struct amdgpu_device *adev) { -char ucode_prefix[15 ]; +char ucode_prefix[30 ];int err;const struct imu_firmware_header_v1_0 *imu_hdr;struct amdgpu_firmware_info *info =NULL ;
@@ -47,8 +48,12 @@ static int imu_v12_0_init_microcode(struDRM_DEBUG ("\n" );amdgpu_ucode_ip_version_decode (adev,GC_HWIP , ucode_prefix,sizeof (ucode_prefix)); - err =amdgpu_ucode_request (adev, &adev->gfx.imu_fw,AMDGPU_UCODE_REQUIRED , -"amdgpu/%s_imu.bin" , ucode_prefix); +if (amdgpu_is_kicker_fw (adev)) + err =amdgpu_ucode_request (adev, &adev->gfx.imu_fw,AMDGPU_UCODE_REQUIRED , +"amdgpu/%s_imu_kicker.bin" , ucode_prefix); +else + err =amdgpu_ucode_request (adev, &adev->gfx.imu_fw,AMDGPU_UCODE_REQUIRED , +"amdgpu/%s_imu.bin" , ucode_prefix);if (err) goto out;
drivers/gpu/drm/amd/amdgpu/psp_v14_0.c +2 -0
@@ -34,7 +34,9 @@MODULE_FIRMWARE ("amdgpu/psp_14_0_2_sos.bin" );MODULE_FIRMWARE ("amdgpu/psp_14_0_2_ta.bin" );MODULE_FIRMWARE ("amdgpu/psp_14_0_3_sos.bin" ); +MODULE_FIRMWARE ("amdgpu/psp_14_0_3_sos_kicker.bin" );MODULE_FIRMWARE ("amdgpu/psp_14_0_3_ta.bin" ); +MODULE_FIRMWARE ("amdgpu/psp_14_0_3_ta_kicker.bin" );MODULE_FIRMWARE ("amdgpu/psp_14_0_5_toc.bin" );MODULE_FIRMWARE ("amdgpu/psp_14_0_5_ta.bin" );
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c +8 -3
@@ -62,13 +62,14 @@ const int decoded_link_width[8] = {0, 1,MODULE_FIRMWARE ("amdgpu/smu_14_0_2.bin" );MODULE_FIRMWARE ("amdgpu/smu_14_0_3.bin" ); +MODULE_FIRMWARE ("amdgpu/smu_14_0_3_kicker.bin" );#define ENABLE_IMU_ARG_GFXOFF_ENABLE 1int smu_v14_0_init_microcode (struct smu_context *smu) {struct amdgpu_device *adev = smu->adev; -char ucode_prefix[15 ]; +char ucode_prefix[30 ];int err =0 ;const struct smc_firmware_header_v1_0 *hdr;const struct common_firmware_header *header;
@@ -79,8 +80,12 @@ int smu_v14_0_init_microcode(struct smu_return 0 ;amdgpu_ucode_ip_version_decode (adev,MP1_HWIP , ucode_prefix,sizeof (ucode_prefix)); - err =amdgpu_ucode_request (adev, &adev->pm.fw,AMDGPU_UCODE_REQUIRED , -"amdgpu/%s.bin" , ucode_prefix); +if (amdgpu_is_kicker_fw (adev)) + err =amdgpu_ucode_request (adev, &adev->pm.fw,AMDGPU_UCODE_REQUIRED , +"amdgpu/%s_kicker.bin" , ucode_prefix); +else + err =amdgpu_ucode_request (adev, &adev->pm.fw,AMDGPU_UCODE_REQUIRED , +"amdgpu/%s.bin" , ucode_prefix);if (err) goto out;
Greg Kroah-Hartman
maintainerPATCH 174/457 drm/amdgpu: add missing vram lost check for LEGACY RESET
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 81699fe81b0be287fb28b6210324db48e8458d9f upstream.
Legacy resets reset the memory controllers so VRAM contents may be unreliable after reset.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +1 -0
@@ -3234,6 +3234,7 @@ static bool amdgpu_device_check_vram_los* always assumed to be lost. */ switch (amdgpu_asic_reset_method (adev)) { +case AMD_RESET_METHOD_LEGACY :case AMD_RESET_METHOD_LINK :case AMD_RESET_METHOD_BACO :case AMD_RESET_METHOD_MODE1 :
Greg Kroah-Hartman
maintainerPATCH 175/457 drm/amdgpu: Avoid extra evict-restore process.
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gang Ba <[email protected]>
commit 1f02f2044bda1db1fd995bc35961ab075fa7b5a2 upstream.
If vm belongs to another process, this is fclose after fork,
wait may enable signaling KFD eviction fence and cause parent process queue evicted.
[677852.634569] amdkfd_fence_enable_signaling+0x56/0x70 [amdgpu] [677852.634814] __dma_fence_enable_signaling+0x3e/0xe0 [677852.634820] dma_fence_wait_timeout+0x3a/0x140 [677852.634825] amddma_resv_wait_timeout+0x7f/0xf0 [amdkcl] [677852.634831] amdgpu_vm_wait_idle+0x2d/0x60 [amdgpu] [677852.635026] amdgpu_flush+0x34/0x50 [amdgpu] [677852.635208] filp_flush+0x38/0x90 [677852.635213] filp_close+0x14/0x30 [677852.635216] do_close_on_exec+0xdd/0x130 [677852.635221] begin_new_exec+0x1da/0x490 [677852.635225] load_elf_binary+0x307/0xea0 [677852.635231] ? srso_alias_return_thunk+0x5/0xfbef5 [677852.635235] ? ima_bprm_check+0xa2/0xd0 [677852.635240] search_binary_handler+0xda/0x260 [677852.635245] exec_binprm+0x58/0x1a0 [677852.635249] bprm_execve.part.0+0x16f/0x210 [677852.635254] bprm_execve+0x45/0x80 [677852.635257] do_execveat_common.isra.0+0x190/0x200
--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +2 -4
@@ -2409,13 +2409,11 @@ void amdgpu_vm_adjust_size(struct amdgpu*/ long amdgpu_vm_wait_idle (struct amdgpu_vm *vm,long timeout) { - timeout =dma_resv_wait_timeout (vm->root.bo->tbo.base.resv, -DMA_RESV_USAGE_BOOKKEEP , - true, timeout); + timeout =drm_sched_entity_flush (&vm->immediate, timeout);if (timeout <=0 )return timeout; -return dma_fence_wait_timeout (vm->last_unlocked, true, timeout); +return drm_sched_entity_flush (&vm->delayed, timeout); }static void amdgpu_vm_destroy_task_info (struct kref *kref)
Greg Kroah-Hartman
maintainerPATCH 176/457 drm/amdgpu: check if hubbub is NULL in debugfs/amdgpu_dm_capabilities
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Shkenev <[email protected]>
commit b4a69f7f29c8a459ad6b4d8a8b72450f1d9fd288 upstream.
HUBBUB structure is not initialized on DCE hardware, so check if it is NULL to avoid null dereference while accessing amdgpu_dm_capabilities file in debugfs.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +1 -1
@@ -3988,7 +3988,7 @@ static int capabilities_show(struct seq_struct hubbub *hubbub = dc->res_pool->hubbub; -if (hubbub->funcs->get_mall_en) +if (hubbub && hubbub->funcs->get_mall_en) hubbub->funcs->get_mall_en (hubbub, &mall_in_use);if (dc->cap_funcs.get_subvp_en)
Greg Kroah-Hartman
maintainerPATCH 177/457 drm/amdgpu: Initialize data to NULL in imu_v12_0_program_rlc_ram()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit c90f2e1172c51fa25492471dc9910e2d7c1444b9 upstream.
After a recent change in clang to expose uninitialized warnings from const variables and pointers [1], there is a warning in imu_v12_0_program_rlc_ram() because data is passed uninitialized to program_imu_rlc_ram():
drivers/gpu/drm/amd/amdgpu/imu_v12_0.c:374:30: error: variable 'data' is uninitialized when used here [-Werror,-Wuninitialized]
374 | program_imu_rlc_ram(adev, data, (const u32)size);
| ^~~~As this warning happens early in clang's frontend, it does not realize that due to the assignment of r to -EINVAL, program_imu_rlc_ram() is never actually called, and even if it were, data would not be dereferenced because size is 0.
Just initialize data to NULL to silence the warning, as the commit that added program_imu_rlc_ram() mentioned it would eventually be used over the old method, at which point data can be properly initialized and used.
--- drivers/gpu/drm/amd/amdgpu/imu_v12_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/imu_v12_0.c +1 -1
@@ -367,7 +367,7 @@ static void program_imu_rlc_ram(struct astatic void imu_v12_0_program_rlc_ram (struct amdgpu_device *adev) {u32 reg_data, size =0 ; -const u32 *data; +const u32 *data =NULL ;int r = -EINVAL ;WREG32_SOC15 (GC ,0 , regGFX_IMU_RLC_RAM_INDEX,0x2 );
Greg Kroah-Hartman
maintainerPATCH 178/457 drm/amdgpu: Retain job->vm in amdgpu_job_prepare_job
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: YuanShang <[email protected]>
commit c00d8b79fd2167c6ac65e096619535acdf8678d5 upstream.
The field job->vm is used in function amdgpu_job_run to get the page table re-generation counter and decide whether the job should be skipped.
Specifically, function amdgpu_vm_generation checks if the VM is valid for this job to use. For instance, if a gfx job depends on a cancelled sdma job from entity vm->delayed, then the gfx job should be skipped.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +0 -7
@@ -387,13 +387,6 @@ amdgpu_job_prepare_job(struct drm_sched_dev_err (ring->adev->dev,"Error getting VM ID (%d)\n" , r); goto error; } -/* -* The VM structure might be released after the VMID is -* assigned, we had multiple problems with people trying to use -* the VM pointer so better set it to NULL. -*/ -if (!fence) - job->vm =NULL ;return fence; }
Greg Kroah-Hartman
maintainerPATCH 179/457 drm/amdgpu: track whether a queue is a kernel queue in amdgpu_mqd_prop
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 284d4dfe850e665f0e7d4dfaf4d3d3da76d11fb0 upstream.
Used to to set the MQD appropriately for each queue type. Kernel queues have additional privileges.
--- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 1 + 2 files changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu.h +1 -0
@@ -886,6 +886,7 @@ struct amdgpu_mqd_prop {uint64_t csa_addr;uint64_t fence_address;bool tmz_queue; +bool kernel_queue; };struct amdgpu_mqd {
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +1 -0
@@ -687,6 +687,7 @@ static void amdgpu_ring_to_mqd_prop(stru prop->eop_gpu_addr = ring->eop_gpu_addr; prop->use_doorbell = ring->use_doorbell; prop->doorbell_index = ring->doorbell_index; + prop->kernel_queue = true;/* map_queues packet doesn't need activate the queue, * so only kiq need set this field.
Greg Kroah-Hartman
maintainerPATCH 180/457 drm/amdgpu: Update external revid for GC v9.5.0
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lijo Lazar <[email protected]>
commit 05c8b690511854ba31d8d1bff7139a13ec66b9e7 upstream.
Use different external revid for GC v9.5.0 SOCs.
--- drivers/gpu/drm/amd/amdgpu/soc15.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/soc15.c +2 -0
@@ -1218,6 +1218,8 @@ static int soc15_common_early_init(strucAMD_PG_SUPPORT_JPEG ;/*TODO: need a new external_rev_id for GC 9.4.4? */ adev->external_rev_id = adev->rev_id +0x46 ; +if (amdgpu_ip_version (adev,GC_HWIP ,0 ) ==IP_VERSION (9 ,5 ,0 )) + adev->external_rev_id = adev->rev_id +0x50 ;break ;default :/* FIXME: not supported yet */
Greg Kroah-Hartman
maintainerPATCH 181/457 drm/amdgpu: update mmhub 3.0.1 client id mappings
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 0bae62cc989fa99ac9cb564eb573aad916d1eb61 upstream.
Update the client id mapping so the correct clients get printed when there is a mmhub page fault.
--- drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c | 57 ++++++++++++++++-------------- 1 file changed, 32 insertions(+), 25 deletions(-)
drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c +32 -25
@@ -36,40 +36,47 @@static const char *mmhub_client_ids_v3_0_1[][2 ] = { [0 ][0 ] ="VMC" , + [1 ][0 ] ="ISPXT" , + [2 ][0 ] ="ISPIXT" , [4 ][0 ] ="DCEDMC" , [5 ][0 ] ="DCEVGA" , [6 ][0 ] ="MP0" , [7 ][0 ] ="MP1" , - [8 ][0 ] ="MPIO" , - [16 ][0 ] ="HDP" , - [17 ][0 ] ="LSDMA" , - [18 ][0 ] ="JPEG" , - [19 ][0 ] ="VCNU0" , - [21 ][0 ] ="VSCH" , - [22 ][0 ] ="VCNU1" , - [23 ][0 ] ="VCN1" , - [32 +20 ][0 ] ="VCN0" , - [2 ][1 ] ="DBGUNBIO" , + [8 ][0 ] ="MPM" , + [12 ][0 ] ="ISPTNR" , + [14 ][0 ] ="ISPCRD0" , + [15 ][0 ] ="ISPCRD1" , + [16 ][0 ] ="ISPCRD2" , + [22 ][0 ] ="HDP" , + [23 ][0 ] ="LSDMA" , + [24 ][0 ] ="JPEG" , + [27 ][0 ] ="VSCH" , + [28 ][0 ] ="VCNU" , + [29 ][0 ] ="VCN" , + [1 ][1 ] ="ISPXT" , + [2 ][1 ] ="ISPIXT" , [3 ][1 ] ="DCEDWB" , [4 ][1 ] ="DCEDMC" , [5 ][1 ] ="DCEVGA" , [6 ][1 ] ="MP0" , [7 ][1 ] ="MP1" , - [8 ][1 ] ="MPIO" , - [10 ][1 ] ="DBGU0" , - [11 ][1 ] ="DBGU1" , - [12 ][1 ] ="DBGU2" , - [13 ][1 ] ="DBGU3" , - [14 ][1 ] ="XDP" , - [15 ][1 ] ="OSSSYS" , - [16 ][1 ] ="HDP" , - [17 ][1 ] ="LSDMA" , - [18 ][1 ] ="JPEG" , - [19 ][1 ] ="VCNU0" , - [20 ][1 ] ="VCN0" , - [21 ][1 ] ="VSCH" , - [22 ][1 ] ="VCNU1" , - [23 ][1 ] ="VCN1" , + [8 ][1 ] ="MPM" , + [10 ][1 ] ="ISPMWR0" , + [11 ][1 ] ="ISPMWR1" , + [12 ][1 ] ="ISPTNR" , + [13 ][1 ] ="ISPSWR" , + [14 ][1 ] ="ISPCWR0" , + [15 ][1 ] ="ISPCWR1" , + [16 ][1 ] ="ISPCWR2" , + [17 ][1 ] ="ISPCWR3" , + [18 ][1 ] ="XDP" , + [21 ][1 ] ="OSSSYS" , + [22 ][1 ] ="HDP" , + [23 ][1 ] ="LSDMA" , + [24 ][1 ] ="JPEG" , + [27 ][1 ] ="VSCH" , + [28 ][1 ] ="VCNU" , + [29 ][1 ] ="VCN" , }; static uint32_t mmhub_v3_0_1_get_invalidate_req(unsigned int vmid,
Greg Kroah-Hartman
maintainerPATCH 182/457 drm/amdgpu: update mmhub 3.3 client id mappings
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 9f9bddfa31d87b084700a6e9eca1a8b4f8ddcdf6 upstream.
Update the client id mapping so the correct clients get printed when there is a mmhub page fault.
v2: fix typos spotted by David Wu.
v3: fix additional typo spotted by David.
--- drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c | 105 +++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c +104 -1
@@ -40,30 +40,129 @@static const char *mmhub_client_ids_v3_3[][2 ] = { [0 ][0 ] ="VMC" , + [1 ][0 ] ="ISPXT" , + [2 ][0 ] ="ISPIXT" , [4 ][0 ] ="DCEDMC" , [6 ][0 ] ="MP0" , [7 ][0 ] ="MP1" , [8 ][0 ] ="MPM" , + [9 ][0 ] ="ISPPDPRD" , + [10 ][0 ] ="ISPCSTATRD" , + [11 ][0 ] ="ISPBYRPRD" , + [12 ][0 ] ="ISPRGBPRD" , + [13 ][0 ] ="ISPMCFPRD" , + [14 ][0 ] ="ISPMCFPRD1" , + [15 ][0 ] ="ISPYUVPRD" , + [16 ][0 ] ="ISPMCSCRD" , + [17 ][0 ] ="ISPGDCRD" , + [18 ][0 ] ="ISPLMERD" , + [22 ][0 ] ="ISPXT1" , + [23 ][0 ] ="ISPIXT1" , [24 ][0 ] ="HDP" , [25 ][0 ] ="LSDMA" , [26 ][0 ] ="JPEG" , [27 ][0 ] ="VPE" , + [28 ][0 ] ="VSCH" , [29 ][0 ] ="VCNU" , [30 ][0 ] ="VCN" , + [1 ][1 ] ="ISPXT" , + [2 ][1 ] ="ISPIXT" , [3 ][1 ] ="DCEDWB" , [4 ][1 ] ="DCEDMC" , + [5 ][1 ] ="ISPCSISWR" , [6 ][1 ] ="MP0" , [7 ][1 ] ="MP1" , [8 ][1 ] ="MPM" , + [9 ][1 ] ="ISPPDPWR" , + [10 ][1 ] ="ISPCSTATWR" , + [11 ][1 ] ="ISPBYRPWR" , + [12 ][1 ] ="ISPRGBPWR" , + [13 ][1 ] ="ISPMCFPWR" , + [14 ][1 ] ="ISPMWR0" , + [15 ][1 ] ="ISPYUVPWR" , + [16 ][1 ] ="ISPMCSCWR" , + [17 ][1 ] ="ISPGDCWR" , + [18 ][1 ] ="ISPLMEWR" , + [20 ][1 ] ="ISPMWR2" , [21 ][1 ] ="OSSSYS" , + [22 ][1 ] ="ISPXT1" , + [23 ][1 ] ="ISPIXT1" , [24 ][1 ] ="HDP" , [25 ][1 ] ="LSDMA" , [26 ][1 ] ="JPEG" , [27 ][1 ] ="VPE" , + [28 ][1 ] ="VSCH" , [29 ][1 ] ="VCNU" , [30 ][1 ] ="VCN" , }; +static const char *mmhub_client_ids_v3_3_1[][2 ] = { + [0 ][0 ] ="VMC" , + [4 ][0 ] ="DCEDMC" , + [6 ][0 ] ="MP0" , + [7 ][0 ] ="MP1" , + [8 ][0 ] ="MPM" , + [24 ][0 ] ="HDP" , + [25 ][0 ] ="LSDMA" , + [26 ][0 ] ="JPEG0" , + [27 ][0 ] ="VPE0" , + [28 ][0 ] ="VSCH" , + [29 ][0 ] ="VCNU0" , + [30 ][0 ] ="VCN0" , + [32 +1 ][0 ] ="ISPXT" , + [32 +2 ][0 ] ="ISPIXT" , + [32 +9 ][0 ] ="ISPPDPRD" , + [32 +10 ][0 ] ="ISPCSTATRD" , + [32 +11 ][0 ] ="ISPBYRPRD" , + [32 +12 ][0 ] ="ISPRGBPRD" , + [32 +13 ][0 ] ="ISPMCFPRD" , + [32 +14 ][0 ] ="ISPMCFPRD1" , + [32 +15 ][0 ] ="ISPYUVPRD" , + [32 +16 ][0 ] ="ISPMCSCRD" , + [32 +17 ][0 ] ="ISPGDCRD" , + [32 +18 ][0 ] ="ISPLMERD" , + [32 +22 ][0 ] ="ISPXT1" , + [32 +23 ][0 ] ="ISPIXT1" , + [32 +26 ][0 ] ="JPEG1" , + [32 +27 ][0 ] ="VPE1" , + [32 +29 ][0 ] ="VCNU1" , + [32 +30 ][0 ] ="VCN1" , + [3 ][1 ] ="DCEDWB" , + [4 ][1 ] ="DCEDMC" , + [6 ][1 ] ="MP0" , + [7 ][1 ] ="MP1" , + [8 ][1 ] ="MPM" , + [21 ][1 ] ="OSSSYS" , + [24 ][1 ] ="HDP" , + [25 ][1 ] ="LSDMA" , + [26 ][1 ] ="JPEG0" , + [27 ][1 ] ="VPE0" , + [28 ][1 ] ="VSCH" , + [29 ][1 ] ="VCNU0" , + [30 ][1 ] ="VCN0" , + [32 +1 ][1 ] ="ISPXT" , + [32 +2 ][1 ] ="ISPIXT" , + [32 +5 ][1 ] ="ISPCSISWR" , + [32 +9 ][1 ] ="ISPPDPWR" , + [32 +10 ][1 ] ="ISPCSTATWR" , + [32 +11 ][1 ] ="ISPBYRPWR" , + [32 +12 ][1 ] ="ISPRGBPWR" , + [32 +13 ][1 ] ="ISPMCFPWR" , + [32 +14 ][1 ] ="ISPMWR0" , + [32 +15 ][1 ] ="ISPYUVPWR" , + [32 +16 ][1 ] ="ISPMCSCWR" , + [32 +17 ][1 ] ="ISPGDCWR" , + [32 +18 ][1 ] ="ISPLMEWR" , + [32 +19 ][1 ] ="ISPMWR1" , + [32 +20 ][1 ] ="ISPMWR2" , + [32 +22 ][1 ] ="ISPXT1" , + [32 +23 ][1 ] ="ISPIXT1" , + [32 +26 ][1 ] ="JPEG1" , + [32 +27 ][1 ] ="VPE1" , + [32 +29 ][1 ] ="VCNU1" , + [32 +30 ][1 ] ="VCN1" , +}; +static uint32_t mmhub_v3_3_get_invalidate_req (unsigned int vmid,uint32_t flush_type) {
@@ -102,12 +201,16 @@ mmhub_v3_3_print_l2_protection_fault_staswitch (amdgpu_ip_version (adev,MMHUB_HWIP ,0 )) {case IP_VERSION (3 ,3 ,0 ): -case IP_VERSION (3 ,3 ,1 ):case IP_VERSION (3 ,3 ,2 ): mmhub_cid = cid <ARRAY_SIZE (mmhub_client_ids_v3_3) ? mmhub_client_ids_v3_3[cid][rw] : cid ==0x140 ?"UMSCH" :NULL ;break ; +case IP_VERSION (3 ,3 ,1 ): + mmhub_cid = cid <ARRAY_SIZE (mmhub_client_ids_v3_3_1) ? + mmhub_client_ids_v3_3_1[cid][rw] : + cid ==0x140 ?"UMSCH" :NULL ; +break ;default : mmhub_cid =NULL ;break ;
Greg Kroah-Hartman
maintainerPATCH 183/457 drm/amdgpu: update mmhub 4.1.0 client id mappings
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit a0b34e4c8663b13e45c78267b4de3004b1a72490 upstream.
Update the client id mapping so the correct clients get printed when there is a mmhub page fault.
--- drivers/gpu/drm/amd/amdgpu/mmhub_v4_1_0.c | 34 +++++++++++------------------- 1 file changed, 13 insertions(+), 21 deletions(-)
drivers/gpu/drm/amd/amdgpu/mmhub_v4_1_0.c +13 -21
@@ -37,39 +37,31 @@static const char *mmhub_client_ids_v4_1_0[][2 ] = { [0 ][0 ] ="VMC" , [4 ][0 ] ="DCEDMC" , - [5 ][0 ] ="DCEVGA" , [6 ][0 ] ="MP0" , [7 ][0 ] ="MP1" , [8 ][0 ] ="MPIO" , - [16 ][0 ] ="HDP" , - [17 ][0 ] ="LSDMA" , - [18 ][0 ] ="JPEG" , - [19 ][0 ] ="VCNU0" , - [21 ][0 ] ="VSCH" , - [22 ][0 ] ="VCNU1" , - [23 ][0 ] ="VCN1" , - [32 +20 ][0 ] ="VCN0" , - [2 ][1 ] ="DBGUNBIO" , + [16 ][0 ] ="LSDMA" , + [17 ][0 ] ="JPEG" , + [19 ][0 ] ="VCNU" , + [22 ][0 ] ="VSCH" , + [23 ][0 ] ="HDP" , + [32 +23 ][0 ] ="VCNRD" , [3 ][1 ] ="DCEDWB" , [4 ][1 ] ="DCEDMC" , - [5 ][1 ] ="DCEVGA" , [6 ][1 ] ="MP0" , [7 ][1 ] ="MP1" , [8 ][1 ] ="MPIO" , [10 ][1 ] ="DBGU0" , [11 ][1 ] ="DBGU1" , - [12 ][1 ] ="DBGU2" , - [13 ][1 ] ="DBGU3" , + [12 ][1 ] ="DBGUNBIO" , [14 ][1 ] ="XDP" , [15 ][1 ] ="OSSSYS" , - [16 ][1 ] ="HDP" , - [17 ][1 ] ="LSDMA" , - [18 ][1 ] ="JPEG" , - [19 ][1 ] ="VCNU0" , - [20 ][1 ] ="VCN0" , - [21 ][1 ] ="VSCH" , - [22 ][1 ] ="VCNU1" , - [23 ][1 ] ="VCN1" , + [16 ][1 ] ="LSDMA" , + [17 ][1 ] ="JPEG" , + [18 ][1 ] ="VCNWR" , + [19 ][1 ] ="VCNU" , + [22 ][1 ] ="VSCH" , + [23 ][1 ] ="HDP" , }; static uint32_t mmhub_v4_1_0_get_invalidate_req(unsigned int vmid,
Greg Kroah-Hartman
maintainerPATCH 184/457 drm/amdgpu: Update supported modes for GC v9.5.0
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lijo Lazar <[email protected]>
commit 389d79a195a9f71a103b39097ee8341a7ca60927 upstream.
For GC v9.5.0 SOCs, both CPX and QPX compute modes are also supported in NPS2 mode.
--- drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c +4 -1
@@ -453,6 +453,7 @@ static int __aqua_vanjaram_get_px_mode_i uint16_t *nps_modes) {struct amdgpu_device *adev = xcp_mgr->adev; +uint32_t gc_ver =amdgpu_ip_version (adev,GC_HWIP ,0 );if (!num_xcp || !nps_modes || !(xcp_mgr->supp_xcp_modes &BIT (px_mode)))return -EINVAL ;
@@ -476,12 +477,14 @@ static int __aqua_vanjaram_get_px_mode_i *num_xcp =4 ; *nps_modes =BIT (AMDGPU_NPS1_PARTITION_MODE ) |BIT (AMDGPU_NPS4_PARTITION_MODE ); +if (gc_ver ==IP_VERSION (9 ,5 ,0 )) + *nps_modes |=BIT (AMDGPU_NPS2_PARTITION_MODE );break ;case AMDGPU_CPX_PARTITION_MODE : *num_xcp =NUM_XCC (adev->gfx.xcc_mask); *nps_modes =BIT (AMDGPU_NPS1_PARTITION_MODE ) |BIT (AMDGPU_NPS4_PARTITION_MODE ); -if (amdgpu_sriov_vf (adev)) +if (gc_ver ==IP_VERSION (9 ,5 ,0 )) *nps_modes |=BIT (AMDGPU_NPS2_PARTITION_MODE );break ;default :
Greg Kroah-Hartman
maintainerPATCH 185/457 drm/amdkfd: Destroy KFD debugfs after destroy KFD wq
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amber Lin <[email protected]>
commit 2e58401a24e7b2d4ec619104e1a76590c1284a4c upstream.
Since KFD proc content was moved to kernel debugfs, we can't destroy KFD debugfs before kfd_process_destroy_wq. Move kfd_process_destroy_wq prior to kfd_debugfs_fini to fix a kernel NULL pointer problem. It happens when /sys/kernel/debug/kfd was already destroyed in kfd_debugfs_fini but kfd_process_destroy_wq calls kfd_debugfs_remove_process. This line
debugfs_remove_recursive(entry->proc_dentry);
tries to remove /sys/kernel/debug/kfd/proc/<pid> while /sys/kernel/debug/kfd is already gone. It hangs the kernel by kernel NULL pointer.
--- drivers/gpu/drm/amd/amdkfd/kfd_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdkfd/kfd_module.c +1 -1
@@ -78,8 +78,8 @@ err_ioctl:static void kfd_exit (void ) {kfd_cleanup_processes (); -kfd_debugfs_fini ();kfd_process_destroy_wq (); +kfd_debugfs_fini ();kfd_procfs_shutdown ();kfd_topology_shutdown ();kfd_chardev_exit ();
Greg Kroah-Hartman
maintainerPATCH 186/457 drm/amdkfd: Fix checkpoint-restore on multi-xcc
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Yat Sin <[email protected]>
commit f6c0f3d24478a0792e50a64c2eba9f34d65519f2 upstream.
GPUs with multi-xcc have multiple MQDs per queue. This patch saves and restores all the MQDs within the partition.
--- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 2 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 61 ++++++++++++++--- drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 20 ++++- 3 files changed, 67 insertions(+), 16 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +1 -1
@@ -2716,7 +2716,7 @@ static void get_queue_checkpoint_info(stdqm_lock (dqm); mqd_mgr = dqm->mqd_mgrs[mqd_type]; - *mqd_size = mqd_mgr->mqd_size; + *mqd_size = mqd_mgr->mqd_size *NUM_XCC (mqd_mgr->dev->xcc_mask); *ctl_stack_size =0 ;if (q->properties.type ==KFD_QUEUE_TYPE_COMPUTE && mqd_mgr->get_checkpoint_info)
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +51 -10
100 lines not on this page · raw message
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +15 -5
@@ -914,7 +914,10 @@ static int criu_checkpoint_queues_device q_data = (struct kfd_criu_queue_priv_data *)q_private_data; -/* data stored in this order: priv_data, mqd, ctl_stack */ +/* +* data stored in this order: +* priv_data, mqd[xcc0], mqd[xcc1],..., ctl_stack[xcc0], ctl_stack[xcc1]... +*/ q_data->mqd_size = mqd_size; q_data->ctl_stack_size = ctl_stack_size;
@@ -963,7 +966,7 @@ int kfd_criu_checkpoint_queues(struct kf }static void set_queue_properties_from_criu (struct queue_properties *qp, -struct kfd_criu_queue_priv_data *q_data) +struct kfd_criu_queue_priv_data *q_data,uint32_t num_xcc) { qp->is_interop = false; qp->queue_percent = q_data->q_percent;
@@ -976,7 +979,11 @@ static void set_queue_properties_from_cr qp->eop_ring_buffer_size = q_data->eop_ring_buffer_size; qp->ctx_save_restore_area_address = q_data->ctx_save_restore_area_address; qp->ctx_save_restore_area_size = q_data->ctx_save_restore_area_size; - qp->ctl_stack_size = q_data->ctl_stack_size; +if (q_data->type ==KFD_QUEUE_TYPE_COMPUTE ) + qp->ctl_stack_size = q_data->ctl_stack_size / num_xcc; +else + qp->ctl_stack_size = q_data->ctl_stack_size; + qp->type = q_data->type; qp->format = q_data->format; }
@@ -1036,12 +1043,15 @@ int kfd_criu_restore_queue(struct kfd_pr goto exit; } -/* data stored in this order: mqd, ctl_stack */ +/* +* data stored in this order: +* mqd[xcc0], mqd[xcc1],..., ctl_stack[xcc0], ctl_stack[xcc1]... +*/ mqd = q_extra_data; ctl_stack = mqd + q_data->mqd_size;memset (&qp,0 ,sizeof (qp)); -set_queue_properties_from_criu (&qp, q_data); +set_queue_properties_from_criu (&qp, q_data,NUM_XCC (pdd->dev->adev->gfx.xcc_mask));print_queue_properties (&qp);
Greg Kroah-Hartman
maintainerPATCH 187/457 drm/amd/display: Add primary plane to commits for correct VRR handling
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michel Dänzer <[email protected]>
commit 3477c1b0972dc1c8a46f78e8fb1fa6966095b5ec upstream.
amdgpu_dm_commit_planes calls update_freesync_state_on_stream only for the primary plane. If a commit affects a CRTC but not its primary plane, it would previously not trigger a refresh cycle or affect LFC, violating current UAPI semantics.
Fixes e.g. atomic commits affecting only the cursor plane being limited to the minimum refresh rate.
Don't do this for the legacy cursor ioctls though, it would break the UAPI semantics for those.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +9 -0
@@ -661,6 +661,15 @@ static int amdgpu_dm_crtc_helper_atomic_return -EINVAL ; } +if (!state->legacy_cursor_update &&amdgpu_dm_crtc_vrr_active (dm_crtc_state)) { +struct drm_plane_state *primary_state; + +/* Pull in primary plane for correct VRR handling */ + primary_state =drm_atomic_get_plane_state (state, crtc->primary); +if (IS_ERR (primary_state)) +return PTR_ERR (primary_state); + } +/* In some use cases, like reset, no stream is attached */ if (!dm_crtc_state->stream)return 0 ;
Greg Kroah-Hartman
maintainerPATCH 188/457 drm/amd/display: fix a Null pointer dereference vulnerability
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Siyang Liu <[email protected]>
commit 1bcf63a44381691d6192872801f830ce3250e367 upstream.
[Why]
A null pointer dereference vulnerability exists in the AMD display driver's (DC module) cleanup function dc_destruct().
When display control context (dc->ctx) construction fails
(due to memory allocation failure), this pointer remains NULL. During subsequent error handling when dc_destruct() is called, there's no NULL check before dereferencing the perf_trace member (dc->ctx->perf_trace), causing a kernel null pointer dereference crash.
[How]
Check if dc->ctx is non-NULL before dereferencing.
(Updated commit text and removed unnecessary error message)
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +10 -9
@@ -938,17 +938,18 @@ static void dc_destruct(struct dc *dc)if (dc->link_srv)link_destroy_link_service (&dc->link_srv); -if (dc->ctx->gpio_service) -dal_gpio_service_destroy (&dc->ctx->gpio_service); +if (dc->ctx) { +if (dc->ctx->gpio_service) +dal_gpio_service_destroy (&dc->ctx->gpio_service); -if (dc->ctx->created_bios) -dal_bios_parser_destroy (&dc->ctx->dc_bios); +if (dc->ctx->created_bios) +dal_bios_parser_destroy (&dc->ctx->dc_bios); +kfree (dc->ctx->logger); +dc_perf_trace_destroy (&dc->ctx->perf_trace); -kfree (dc->ctx->logger); -dc_perf_trace_destroy (&dc->ctx->perf_trace); - -kfree (dc->ctx); - dc->ctx =NULL ; +kfree (dc->ctx); + dc->ctx =NULL ; + }kfree (dc->bw_vbios); dc->bw_vbios =NULL ;
Greg Kroah-Hartman
maintainerPATCH 189/457 drm/amd/display: Fix DCE 6.0 and 6.4 PLL programming.
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 1c8dc3e088e09531bcdfc9fe348204abc3decb6c upstream.
Apparently, both DCE 6.0 and 6.4 have 3 PLLs, but PLL0 can only be used for DP. Make sure to initialize the correct amount of PLLs in DC for these DCE versions and use PLL0 only for DP.
Also, on DCE 6.0 and 6.4, the PLL0 needs to be powered on at initialization as opposed to DCE 6.1 and 7.x which use a different clock source for DFS.
The following functions were used as reference from the old
radeon driver implementation of DCE 6.x:
- radeon_atom_pick_pll
- atombios_crtc_set_disp_eng_pll
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c | 5 + drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c | 34 +++++----- 2 files changed, 25 insertions(+), 14 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c +5 -0
@@ -245,6 +245,11 @@ int dce_set_clock( pxl_clk_params.target_pixel_clock_100hz = requested_clk_khz *10 ; pxl_clk_params.pll_id =CLOCK_SOURCE_ID_DFS ; +/* DCE 6.0, DCE 6.4: engine clock is the same as PLL0 */ +if (clk_mgr_base->ctx->dce_version ==DCE_VERSION_6_0 || + clk_mgr_base->ctx->dce_version ==DCE_VERSION_6_4 ) + pxl_clk_params.pll_id =CLOCK_SOURCE_ID_PLL0 ; +if (clk_mgr_dce->dfs_bypass_active) pxl_clk_params.flags.SET_DISPCLK_DFS_BYPASS = true;
drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +20 -14
@@ -373,7 +373,7 @@ static const struct resource_caps res_ca .num_timing_generator = 6, .num_audio = 6, .num_stream_encoder = 6, - .num_pll = 2, + .num_pll = 3, .num_ddc = 6, };
@@ -389,7 +389,7 @@ static const struct resource_caps res_ca .num_timing_generator = 2, .num_audio = 2, .num_stream_encoder = 2, - .num_pll = 2, + .num_pll = 3, .num_ddc = 2, };
@@ -973,21 +973,24 @@ static bool dce60_construct(if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp !=0 ) { pool->base.dp_clock_source = -dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_EXTERNAL ,NULL , true); +dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_EXTERNAL ,NULL , true); +/* DCE 6.0 and 6.4: PLL0 can only be used with DP. Don't initialize it here. */ pool->base.clock_sources[0 ] = -dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL0 , &clk_src_regs[0 ], false); +dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL1 , &clk_src_regs[1 ], false); pool->base.clock_sources[1 ] = -dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL1 , &clk_src_regs[1 ], false); +dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL2 , &clk_src_regs[2 ], false); pool->base.clk_src_count =2 ; }else { pool->base.dp_clock_source = -dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL0 , &clk_src_regs[0 ], true); +dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL0 , &clk_src_regs[0 ], true); pool->base.clock_sources[0 ] = -dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL1 , &clk_src_regs[1 ], false); - pool->base.clk_src_count =1 ; +dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL1 , &clk_src_regs[1 ], false); + pool->base.clock_sources[1 ] = +dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL2 , &clk_src_regs[2 ], false); + pool->base.clk_src_count =2 ; }if (pool->base.dp_clock_source ==NULL ) {
@@ -1365,21 +1368,24 @@ static bool dce64_construct(if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp !=0 ) { pool->base.dp_clock_source = -dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_EXTERNAL ,NULL , true); +dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_EXTERNAL ,NULL , true); +/* DCE 6.0 and 6.4: PLL0 can only be used with DP. Don't initialize it here. */ pool->base.clock_sources[0 ] = -dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL1 , &clk_src_regs[0 ], false); +dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL1 , &clk_src_regs[1 ], false); pool->base.clock_sources[1 ] = -dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL2 , &clk_src_regs[1 ], false); +dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL2 , &clk_src_regs[2 ], false); pool->base.clk_src_count =2 ; }else { pool->base.dp_clock_source = -dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL1 , &clk_src_regs[0 ], true); +dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL0 , &clk_src_regs[0 ], true); pool->base.clock_sources[0 ] = -dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL2 , &clk_src_regs[1 ], false); - pool->base.clk_src_count =1 ; +dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL1 , &clk_src_regs[1 ], false); + pool->base.clock_sources[1 ] = +dce60_clock_source_create (ctx, bp,CLOCK_SOURCE_ID_PLL2 , &clk_src_regs[2 ], false); + pool->base.clk_src_count =2 ; }if (pool->base.dp_clock_source ==NULL ) {
Greg Kroah-Hartman
maintainerPATCH 190/457 drm/amd/display: fix initial backlight brightness calculation
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lauri Tirkkonen <[email protected]>
commit 9c2883057b3c861879b647f34e8bc448954e8729 upstream.
DIV_ROUND_CLOSEST(x, 100) returns either 0 or 1 if 0<x<=100, so the division needs to be performed after the multiplication and not the other way around, to properly scale the value.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +2 -2
@@ -4952,9 +4952,9 @@ amdgpu_dm_register_backlight_device(stru caps = &dm->backlight_caps[aconnector->bl_idx];if (get_brightness_range (caps, &min, &max)) {if (power_supply_is_system_supplied () >0 ) - props.brightness = (max - min) *DIV_ROUND_CLOSEST (caps->ac_level,100 ); + props.brightness =DIV_ROUND_CLOSEST ((max - min) * caps->ac_level,100 );else - props.brightness = (max - min) *DIV_ROUND_CLOSEST (caps->dc_level,100 ); + props.brightness =DIV_ROUND_CLOSEST ((max - min) * caps->dc_level,100 );/* min is zero, so max needs to be adjusted */ props.max_brightness = max - min; drm_dbg(drm, "Backlight caps: min: %d, max: %d, ac %d, dc %d\n", min, max,
Greg Kroah-Hartman
maintainerPATCH 191/457 drm/amd/display: Pass up errors for reset GPU that fails to init HW
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 2b6943df54136f40aff8a6d7ba7c26724d89a0bd upstream.
[Why]
If a GPU is in reset and the hardware fails to initialize the rest of the resume sequence shouldn't be run.
[How]
Pass error code up to caller of dm_resume().
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +3 -1
@@ -3343,8 +3343,10 @@ static int dm_resume(struct amdgpu_ip_bllink_enc_cfg_copy (adev->dm.dc->current_state, dc_state); r =dm_dmub_hw_init (adev); -if (r) +if (r) {drm_err (adev_to_drm (adev),"DMUB interface failed to initialize: status=%d\n" , r); +return r; + }dc_dmub_srv_set_power_state (dm->dc->ctx->dmub_srv,DC_ACPI_CM_POWER_STATE_D0 );dc_set_power_state (dm->dc,DC_ACPI_CM_POWER_STATE_D0 );
Greg Kroah-Hartman
maintainerPATCH 192/457 drm/amd/display: Revert "drm/amd/display: Fix AMDGPU_MAX_BL_LEVEL value"
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 8e6a18cbf3ee2c1e3d0afd8d3debd0ba8738ad0c upstream.
This reverts commit 66abb996999de0d440a02583a6e70c2c24deab45. This broke custom brightness curves but it wasn't obvious because of other related changes. Custom brightness curves are always from a 0-255 input signal. The correct fix was to fix the default value which was done by [1].
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +4 -4
@@ -4733,16 +4733,16 @@ static int get_brightness_range(const streturn 1 ; } -/* Rescale from [min..max] to [0..MAX_BACKLIGHT_LEVEL] */ +/* Rescale from [min..max] to [0..AMDGPU_MAX_BL_LEVEL] */ static inline u32 scale_input_to_fw (int min,int max,u64 input) { -return DIV_ROUND_CLOSEST_ULL (input *MAX_BACKLIGHT_LEVEL , max - min); +return DIV_ROUND_CLOSEST_ULL (input *AMDGPU_MAX_BL_LEVEL , max - min); } -/* Rescale from [0..MAX_BACKLIGHT_LEVEL] to [min..max] */ +/* Rescale from [0..AMDGPU_MAX_BL_LEVEL] to [min..max] */ static inline u32 scale_fw_to_input (int min,int max,u64 input) { -return min +DIV_ROUND_CLOSEST_ULL (input * (max - min),MAX_BACKLIGHT_LEVEL ); +return min +DIV_ROUND_CLOSEST_ULL (input * (max - min),AMDGPU_MAX_BL_LEVEL ); } static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps,
Greg Kroah-Hartman
maintainerPATCH 193/457 drm/amd/display: Dont overwrite dce60_clk_mgr
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 4db9cd554883e051df1840d4d58d636043101034 upstream.
dc_clk_mgr_create accidentally overwrites the dce60_clk_mgr with the dce_clk_mgr, causing incorrect behaviour on DCE6. Fix it by removing the extra dce_clk_mgr_construct.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 1 - 1 file changed, 1 deletion(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +0 -1
@@ -158,7 +158,6 @@ struct clk_mgr *dc_clk_mgr_create(struct return NULL; }dce60_clk_mgr_construct (ctx, clk_mgr); -dce_clk_mgr_construct (ctx, clk_mgr);return &clk_mgr->base; }#endif
Greg Kroah-Hartman
maintainerPATCH 194/457 LoongArch: KVM: Make function kvm_own_lbt() robust
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bibo Mao <[email protected]>
commit 4be8cefc132606b4a6e851f37f8e8c40c406c910 upstream.
Add the flag KVM_LARCH_LBT checking in function kvm_own_lbt(), so that it can be called safely rather than duplicated enabling again.
--- arch/loongarch/kvm/vcpu.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
arch/loongarch/kvm/vcpu.c +5 -3
@@ -1277,9 +1277,11 @@ int kvm_own_lbt(struct kvm_vcpu *vcpu)return -EINVAL ;preempt_disable (); -set_csr_euen (CSR_EUEN_LBTEN ); -_restore_lbt (&vcpu->arch.lbt); - vcpu->arch.aux_inuse |=KVM_LARCH_LBT ; +if (!(vcpu->arch.aux_inuse &KVM_LARCH_LBT )) { +set_csr_euen (CSR_EUEN_LBTEN ); +_restore_lbt (&vcpu->arch.lbt); + vcpu->arch.aux_inuse |=KVM_LARCH_LBT ; + }preempt_enable ();return 0 ;
Greg Kroah-Hartman
maintainerPATCH 195/457 LoongArch: KVM: Fix stack protector issue in send_ipi_data()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bibo Mao <[email protected]>
commit 5c68549c81bcca70fc464e305ffeefd9af968287 upstream.
Function kvm_io_bus_read() is called in function send_ipi_data(), buffer size of parameter *val should be at least 8 bytes. Since some emulation functions like loongarch_ipi_readl() and kvm_eiointc_read() will write the buffer *val with 8 bytes signed extension regardless parameter len.
Otherwise there will be buffer overflow issue when CONFIG_STACKPROTECTOR is enabled. The bug report is shown as follows:
Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: send_ipi_data+0x194/0x1a0 [kvm]
CPU: 11 UID: 107 PID: 2692 Comm: CPU 0/KVM Not tainted 6.17.0-rc1+ #102 PREEMPT(full)
Stack : 9000000005901568 0000000000000000 9000000003af371c 900000013c68c000
900000013c68f850 900000013c68f858 0000000000000000 900000013c68f998
900000013c68f990 900000013c68f990 900000013c68f6c0 fffffffffffdb058
fffffffffffdb0e0 900000013c68f858 911e1d4d39cf0ec2 9000000105657a00
0000000000000001 fffffffffffffffe 0000000000000578 282049464555206e
6f73676e6f6f4c20 0000000000000001 00000000086b4000 0000000000000000
0000000000000000 0000000000000000 9000000005709968 90000000058f9000
900000013c68fa68 900000013c68fab4 90000000029279f0 900000010153f940
900000010001f360 0000000000000000 9000000003af3734 000000004390000c
00000000000000b0 0000000000000004 0000000000000000 0000000000071c1d
...
Call Trace:
[<9000000003af3734>] show_stack+0x5c/0x180
[<9000000003aed168>] dump_stack_lvl+0x6c/0x9c
[<9000000003ad0ab0>] vpanic+0x108/0x2c4
[<9000000003ad0ca8>] panic+0x3c/0x40
[<9000000004eb0a1c>] __stack_chk_fail+0x14/0x18
[<ffff8000023473f8>] send_ipi_data+0x190/0x1a0 [kvm]
[<ffff8000023313e4>] __kvm_io_bus_write+0xa4/0xe8 [kvm]
[<ffff80000233147c>] kvm_io_bus_write+0x54/0x90 [kvm]
[<ffff80000233f9f8>] kvm_emu_iocsr+0x180/0x310 [kvm]
[<ffff80000233fe08>] kvm_handle_gspr+0x280/0x478 [kvm]
[<ffff8000023443e8>] kvm_handle_exit+0xc0/0x130 [kvm]--- arch/loongarch/kvm/intc/ipi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/loongarch/kvm/intc/ipi.c +3 -3
@@ -99,7 +99,7 @@ static void write_mailbox(struct kvm_vcpstatic int send_ipi_data (struct kvm_vcpu *vcpu,gpa_t addr,uint64_t data) {int i, idx, ret; -uint32_t val =0 , mask =0 ; +uint64_t val =0 , mask =0 ;/* * Bit 27-30 is mask for byte writing.
@@ -108,7 +108,7 @@ static int send_ipi_data(struct kvm_vcpuif ((data >>27 ) &0xf ) {/* Read the old val */ idx =srcu_read_lock (&vcpu->kvm->srcu); - ret =kvm_io_bus_read (vcpu,KVM_IOCSR_BUS , addr,sizeof (val), &val); + ret =kvm_io_bus_read (vcpu,KVM_IOCSR_BUS , addr,4 , &val);srcu_read_unlock (&vcpu->kvm->srcu, idx);if (unlikely (ret)) {kvm_err ("%s: : read data from addr %llx failed\n" , __func__, addr);
@@ -124,7 +124,7 @@ static int send_ipi_data(struct kvm_vcpu } val |= ((uint32_t )(data >>32 ) & ~mask); idx =srcu_read_lock (&vcpu->kvm->srcu); - ret =kvm_io_bus_write (vcpu,KVM_IOCSR_BUS , addr,sizeof (val), &val); + ret =kvm_io_bus_write (vcpu,KVM_IOCSR_BUS , addr,4 , &val);srcu_read_unlock (&vcpu->kvm->srcu, idx);if (unlikely (ret))kvm_err ("%s: : write data to addr %llx failed\n" , __func__, addr);
Greg Kroah-Hartman
maintainerPATCH 196/457 LoongArch: KVM: Add address alignment check in pch_pic register access
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bibo Mao <[email protected]>
commit 538c06e3964a8e94b645686cc58ccc4a06fa6330 upstream.
With pch_pic device, its register is based on MMIO address space, different access size 1/2/4/8 is supported. And base address should be naturally aligned with its access size, here add alignment check in its register access emulation function.
--- arch/loongarch/kvm/intc/pch_pic.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/loongarch/kvm/intc/pch_pic.c +10 -0
@@ -195,6 +195,11 @@ static int kvm_pch_pic_read(struct kvm_vreturn -EINVAL ; } +if (addr & (len -1 )) { +kvm_err ("%s: pch pic not aligned addr %llx len %d\n" , __func__, addr, len); +return -EINVAL ; + } +/* statistics of pch pic reading */ vcpu->kvm->stat.pch_pic_read_exits++; ret =loongarch_pch_pic_read (s, addr, len, val);
@@ -302,6 +307,11 @@ static int kvm_pch_pic_write(struct kvm_return -EINVAL ; } +if (addr & (len -1 )) { +kvm_err ("%s: pch pic not aligned addr %llx len %d\n" , __func__, addr, len); +return -EINVAL ; + } +/* statistics of pch pic writing */ vcpu->kvm->stat.pch_pic_write_exits++; ret =loongarch_pch_pic_write (s, addr, len, val);
Greg Kroah-Hartman
maintainerPATCH 197/457 net, hsr: reject HSR frame if skb cant hold tag
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Acs <[email protected]>
commit 7af76e9d18a9fd6f8611b3313c86c190f9b6a5a7 upstream.
Receiving HSR frame with insufficient space to hold HSR tag in the skb can result in a crash (kernel BUG):
[ 45.390915] skbuff: skb_under_panic: text:ffffffff86f32cac len:26 put:14 head:ffff888042418000 data:ffff888042417ff4 tail:0xe end:0x180 dev:bridge_slave_1 [ 45.392559] ------------[ cut here ]------------ [ 45.392912] kernel BUG at net/core/skbuff.c:211! [ 45.393276] Oops: invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN NOPTI [ 45.393809] CPU: 1 UID: 0 PID: 2496 Comm: reproducer Not tainted 6.15.0 #12 PREEMPT(undef) [ 45.394433] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 [ 45.395273] RIP: 0010:skb_panic+0x15b/0x1d0
<snip registers, remove unreliable trace>
[ 45.402911] Call Trace: [ 45.403105] <IRQ> [ 45.404470] skb_push+0xcd/0xf0 [ 45.404726] br_dev_queue_push_xmit+0x7c/0x6c0 [ 45.406513] br_forward_finish+0x128/0x260 [ 45.408483] __br_forward+0x42d/0x590 [ 45.409464] maybe_deliver+0x2eb/0x420 [ 45.409763] br_flood+0x174/0x4a0 [ 45.410030] br_handle_frame_finish+0xc7c/0x1bc0 [ 45.411618] br_handle_frame+0xac3/0x1230 [ 45.413674] __netif_receive_skb_core.constprop.0+0x808/0x3df0 [ 45.422966] __netif_receive_skb_one_core+0xb4/0x1f0 [ 45.424478] __netif_receive_skb+0x22/0x170 [ 45.424806] process_backlog+0x242/0x6d0 [ 45.425116] __napi_poll+0xbb/0x630 [ 45.425394] net_rx_action+0x4d1/0xcc0 [ 45.427613] handle_softirqs+0x1a4/0x580 [ 45.427926] do_softirq+0x74/0x90 [ 45.428196] </IRQ>
This issue was found by syzkaller.
The panic happens in br_dev_queue_push_xmit() once it receives a corrupted skb with ETH header already pushed in linear data. When it attempts the skb_push() call, there's not enough headroom and skb_push() panics.
The corrupted skb is put on the queue by HSR layer, which makes a sequence of unintended transformations when it receives a specific corrupted HSR frame (with incomplete TAG).
Fix it by dropping and consuming frames that are not long enough to contain both ethernet and hsr headers.
Alternative fix would be to check for enough headroom before skb_push() in br_dev_queue_push_xmit().
In the reproducer, this is injected via AF_PACKET, but I don't easily see why it couldn't be sent over the wire from adjacent network.
Further Details:
In the reproducer, the following network interface chain is set up:
┌────────────────┐ ┌────────────────┐
│ veth0_to_hsr ├───┤ hsr_slave0 ┼───┐
└────────────────┘ └────────────────┘ │
│ ┌──────┐
├─┤ hsr0 ├───┐
│ └──────┘ │
┌────────────────┐ ┌────────────────┐ │ │┌────────┐
│ veth1_to_hsr ┼───┤ hsr_slave1 ├───┘ └┤ │
└────────────────┘ └────────────────┘ ┌┼ bridge │
││ │
│└────────┘
│
┌───────┐ │
│ ... ├──────┘
└───────┘To trigger the events leading up to crash, reproducer sends a corrupted HSR frame with incomplete TAG, via AF_PACKET socket on 'veth0_to_hsr'.
The first HSR-layer function to process this frame is hsr_handle_frame(). It and then checks if the
protocol is ETH_P_PRP or ETH_P_HSR. If it is, it calls skb_set_network_header(skb, ETH_HLEN + HSR_HLEN), without checking that the skb is long enough. For the crashing frame it is not, and hence the skb->network_header and skb->mac_len fields are set incorrectly, pointing after the end of the linear buffer.
I will call this a BUG#1 and it is what is addressed by this patch. In the crashing scenario before the fix, the skb continues to go down the hsr path as follows.
hsr_handle_frame() then calls this sequencehsr_forward_skb()
fill_frame_info()
hsr->proto_ops->fill_frame_info()
hsr_fill_frame_info()hsr_fill_frame_info() contains a check that intends to check whether the skb actually contains the HSR header. But the check relies on the skb->mac_len field which was erroneously setup due to BUG#1, so the check passes and the execution continues back in the hsr_forward_skb():
hsr_forward_skb()
hsr_forward_do()
hsr->proto_ops->get_untagged_frame()
hsr_get_untagged_frame()
create_stripped_skb_hsr()In create_stripped_skb_hsr(), a copy of the skb is created and is further corrupted by operation that attempts to strip the HSR tag in a call to __pskb_copy().
The skb enters create_stripped_skb_hsr() with ethernet header pushed in linear buffer. The skb_pull(skb_in, HSR_HLEN) thus pulls 6 bytes of ethernet header into the headroom, creating skb_in with a headroom of size 8. The subsequent __pskb_copy() then creates an skb with headroom of just 2 and skb->len of just 12, this is how it looks after the copy:
gdb) p skb->len
$10 = 12
(gdb) p skb->data
$11 = (unsigned char *) 0xffff888041e45382 "\252\252\252\252\252!\210\373", (gdb) p skb->head
$12 = (unsigned char *) 0xffff888041e45380 ""
It seems create_stripped_skb_hsr() assumes that ETH header is pulled in the headroom when it's entered, because it just pulls HSR header on top. But that is not the case in our code-path and we end up with the corrupted skb instead. I will call this BUG#2
*I got confused here because it seems that under no conditions can create_stripped_skb_hsr() work well, the assumption it makes is not true during the processing of hsr frames - since the skb_push() in hsr_handle_frame to skb_pull in hsr_deliver_master(). I wonder whether I missed something here.*
Next, the execution arrives in hsr_deliver_master(). It calls skb_pull(ETH_HLEN), which just returns NULL - the SKB does not have enough space for the pull (as it only has 12 bytes in total at this point).
*The skb_pull() here further suggests that ethernet header is meant to be pushed through the whole hsr processing and create_stripped_skb_hsr() should pull it before doing the HSR header pull.*
hsr_deliver_master() then puts the corrupted skb on the queue, it is then picked up from there by bridge frame handling layer and finally lands in br_dev_queue_push_xmit where it panics.
--- net/hsr/hsr_slave.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/hsr/hsr_slave.c +7 -1
@@ -63,8 +63,14 @@ static rx_handler_result_t hsr_handle_frskb_push (skb,ETH_HLEN );skb_reset_mac_header (skb);if ((!hsr->prot_version && protocol ==htons (ETH_P_PRP )) || - protocol ==htons (ETH_P_HSR )) + protocol ==htons (ETH_P_HSR )) { +if (!pskb_may_pull (skb,ETH_HLEN +HSR_HLEN )) { +kfree_skb (skb); + goto finish_consume; + } +skb_set_network_header (skb,ETH_HLEN +HSR_HLEN ); + }skb_reset_mac_len (skb);/* Only the frames received over the interlink port will assign a
Greg Kroah-Hartman
maintainerPATCH 198/457 sched/ext: Fix invalid task state transitions on class switch
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrea Righi <[email protected]>
commit ddf7233fcab6c247379d0928d46cc316ee122229 upstream.
When enabling a sched_ext scheduler, we may trigger invalid task state transitions, resulting in warnings like the following (which can be easily reproduced by running the hotplug selftest in a loop):
sched_ext: Invalid task state transition 0 -> 3 for fish[770]
WARNING: CPU: 18 PID: 787 at kernel/sched/ext.c:3862 scx_set_task_state+0x7c/0xc0 ... RIP: 0010:scx_set_task_state+0x7c/0xc0 ... Call Trace: <TASK> scx_enable_task+0x11f/0x2e0 switching_to_scx+0x24/0x110 scx_enable.isra.0+0xd14/0x13d0 bpf_struct_ops_link_create+0x136/0x1a0 __sys_bpf+0x1edd/0x2c30 __x64_sys_bpf+0x21/0x30 do_syscall_64+0xbb/0x370 entry_SYSCALL_64_after_hwframe+0x77/0x7f
This happens because we skip initialization for tasks that are already dead (with their usage counter set to zero), but we don't exclude them during the scheduling class transition phase.
Fix this by also skipping dead tasks during class swiching, preventing invalid task state transitions.
--- kernel/sched/ext.c | 4 ++++ 1 file changed, 4 insertions(+)
kernel/sched/ext.c +4 -0
@@ -5694,6 +5694,9 @@ static int scx_enable(struct sched_ext_o__setscheduler_class (p->policy, p->prio);struct sched_enq_and_set_ctx ctx; +if (!tryget_task_struct (p)) +continue ; +if (old_class != new_class && p->se.sched_delayed)dequeue_task (task_rq (p), p,DEQUEUE_SLEEP |DEQUEUE_DELAYED );
@@ -5706,6 +5709,7 @@ static int scx_enable(struct sched_ext_osched_enq_and_set_task (&ctx);check_class_changed (task_rq (p), p, old_class, p->prio); +put_task_struct (p); }scx_task_iter_stop (&sti);percpu_up_write (&scx_fork_rwsem);
Greg Kroah-Hartman
maintainerPATCH 199/457 ipv6: sr: Fix MAC comparison to be constant-time
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit a458b2902115b26a25d67393b12ddd57d1216aaa upstream.
To prevent timing attacks, MACs need to be compared in constant time. Use the appropriate helper function for this.
--- net/ipv6/seg6_hmac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv6/seg6_hmac.c +2 -1
@@ -35,6 +35,7 @@#include <net/xfrm.h> #include <crypto/hash.h> +#include <crypto/utils.h> #include <net/seg6.h> #include <net/genetlink.h> #include <net/seg6_hmac.h>
@@ -280,7 +281,7 @@ bool seg6_hmac_validate_skb(struct sk_buif (seg6_hmac_compute (hinfo, srh, &ipv6_hdr (skb)->saddr, hmac_output))return false; -if (memcmp (hmac_output, tlv->hmac,SEG6_HMAC_FIELD_LEN ) !=0 ) +if (crypto_memneq (hmac_output, tlv->hmac,SEG6_HMAC_FIELD_LEN ))return false;return true;
Greg Kroah-Hartman
maintainerPATCH 200/457 cgroup: avoid null de-ref in css_rstat_exit()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: JP Kobryn <[email protected]>
commit eea51c6e3f6675b795f6439eaa960eb2948d6905 upstream.
css_rstat_exit() may be called asynchronously in scenarios where preceding calls to css_rstat_init() have not completed. One such example is this sequence below:
css_create(...)
{
...
init_and_link_css(css, ...);
err = percpu_ref_init(...);
if (err)
goto err_free_css;
err = cgroup_idr_alloc(...);
if (err)
goto err_free_css;
err = css_rstat_init(css, ...);
if (err)
goto err_free_css;
...
err_free_css:
INIT_RCU_WORK(&css->destroy_rwork, css_free_rwork_fn);
queue_rcu_work(cgroup_destroy_wq, &css->destroy_rwork);
return ERR_PTR(err);
}If any of the three goto jumps are taken, async cleanup will begin and css_rstat_exit() will be invoked on an uninitialized css->rstat_cpu.
Avoid accessing the unitialized field by returning early in css_rstat_exit() if this is the case.
--- kernel/cgroup/rstat.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/cgroup/rstat.c +3 -0
@@ -488,6 +488,9 @@ void css_rstat_exit(struct cgroup_subsysif (!css_uses_rstat (css))return ; +if (!css->rstat_cpu) +return ; +css_rstat_flush (css);/* sanity check */
Greg Kroah-Hartman
maintainerPATCH 201/457 cpuidle: governors: menu: Avoid selecting states with too much latency
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
commit 779b1a1cb13ae17028aeddb2fbbdba97357a1e15 upstream.
Occasionally, the exit latency of the idle state selected by the menu governor may exceed the PM QoS CPU wakeup latency limit. Namely, if the scheduler tick has been stopped already and predicted_ns is greater than the tick period length, the governor may return an idle state whose exit latency exceeds latency_req because that decision is made before checking the current idle state's exit latency.
For instance, say that there are 3 idle states, 0, 1, and 2. For idle states 0 and 1, the exit latency is equal to the target residency and the values are 0 and 5 us, respectively. State 2 is deeper and has the exit latency and target residency of 200 us and 2 ms (which is greater than the tick period length), respectively.
Say that predicted_ns is equal to TICK_NSEC and the PM QoS latency limit is 20 us. After the first two iterations of the main loop in menu_select(), idx becomes 1 and in the third iteration of it the target residency of the current state (state 2) is greater than predicted_ns. State 2 is not a polling one and predicted_ns is not less than TICK_NSEC, so the check on whether or not the tick has been stopped is done. Say that the tick has been stopped already and there are no imminent timers (that is, delta_tick is greater than the target residency of state 2). In that case, idx becomes 2 and it is returned immediately, but the exit latency of state 2 exceeds the latency limit.
Address this issue by modifying the code to compare the exit latency of the current idle state (idle state i) with the latency limit before comparing its target residency with predicted_ns, which allows one more exit_latency_ns check that becomes redundant to be dropped.
However, after the above change, latency_req cannot take the predicted_ns value any more, which takes place after commit 38f83090f515 ("cpuidle:
menu: Remove iowait influence"), because it may cause a polling state to be returned prematurely.
In the context of the previous example say that predicted_ns is 3000 and the PM QoS latency limit is still 20 us. Additionally, say that idle state 0 is a polling one. Moving the exit_latency_ns check before the target_residency_ns one causes the loop to terminate in the second iteration, before the target_residency_ns check, so idle state 0 will be returned even though previously state 1 would be returned if there were no imminent timers.
For this reason, remove the assignment of the predicted_ns value to latency_req from the code.
--- drivers/cpuidle/governors/menu.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-)
drivers/cpuidle/governors/menu.c +12 -17
@@ -287,20 +287,15 @@ static int menu_select(struct cpuidle_drreturn 0 ; } -if (tick_nohz_tick_stopped ()) { -/* -* If the tick is already stopped, the cost of possible short -* idle duration misprediction is much higher, because the CPU -* may be stuck in a shallow idle state for a long time as a -* result of it. In that case say we might mispredict and use -* the known time till the closest timer event for the idle -* state selection. -*/ -if (predicted_ns <TICK_NSEC ) - predicted_ns = data->next_timer_ns; - }else if (latency_req > predicted_ns) { - latency_req = predicted_ns; - } +/* +* If the tick is already stopped, the cost of possible short idle +* duration misprediction is much higher, because the CPU may be stuck +* in a shallow idle state for a long time as a result of it. In that +* case, say we might mispredict and use the known time till the closest +* timer event for the idle state selection. +*/ +if (tick_nohz_tick_stopped () && predicted_ns <TICK_NSEC ) + predicted_ns = data->next_timer_ns;/* * Find the idle state with the lowest power while satisfying
@@ -316,13 +311,15 @@ static int menu_select(struct cpuidle_drif (idx ==-1 ) idx = i;/* first enabled state */ +if (s->exit_latency_ns > latency_req) +break ; +if (s->target_residency_ns > predicted_ns) {/* * Use a physical idle state, not busy polling, unless * a timer is going to trigger soon enough. */ if ((drv->states[idx].flags &CPUIDLE_FLAG_POLLING ) && - s->exit_latency_ns <= latency_req && s->target_residency_ns <= data->next_timer_ns) { predicted_ns = s->target_residency_ns; idx = i;
@@ -354,8 +351,6 @@ static int menu_select(struct cpuidle_drreturn idx; } -if (s->exit_latency_ns > latency_req) -break ; idx = i; }
Greg Kroah-Hartman
maintainerPATCH 202/457 ACPI: pfr_update: Fix the driver update version check
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Yu <[email protected]>
commit 8151320c747efb22d30b035af989fed0d502176e upstream.
The security-version-number check should be used rather than the runtime version check for driver updates.
Otherwise, the firmware update would fail when the update binary had a lower runtime version number than the current one.
--- drivers/acpi/pfr_update.c | 2 +- include/uapi/linux/pfrut.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/acpi/pfr_update.c +1 -1
@@ -310,7 +310,7 @@ static bool applicable_image(const voidif (type ==PFRU_CODE_INJECT_TYPE )return payload_hdr->rt_ver >= cap->code_rt_version; -return payload_hdr->rt_ver >= cap->drv_rt_version; +return payload_hdr->svn_ver >= cap->drv_svn; } static void print_update_debug_info(struct pfru_updated_result *result,
include/uapi/linux/pfrut.h +1 -0
@@ -89,6 +89,7 @@ struct pfru_payload_hdr {__u32 hw_ver;__u32 rt_ver;__u8 platform_id[16 ]; +__u32 svn_ver; };enum pfru_dsm_status {
Greg Kroah-Hartman
maintainerPATCH 203/457 ACPI: APEI: EINJ: Fix resource leak by remove callback in .exit.text
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
commit b21d1fbb97c814c76ffa392cd603f8cd3ecc0355 upstream.
The .remove() callback is also used during error handling in faux_probe(). As einj_remove() was marked with __exit it's not linked into the kernel if the driver is built-in, potentially resulting in resource leaks.
Also remove the comment justifying the __exit annotation which doesn't apply any more since the driver was converted to the faux device interface.
--- drivers/acpi/apei/einj-core.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-)
drivers/acpi/apei/einj-core.c +3 -9
@@ -842,7 +842,7 @@ err_put_table:return rc; } -static void __exit einj_remove(struct faux_device *fdev) +static void einj_remove (struct faux_device *fdev) {struct apei_exec_context ctx;
@@ -864,15 +864,9 @@ static void __exit einj_remove(struct fa }static struct faux_device *einj_dev; -/* -* einj_remove() lives in .exit.text. For drivers registered via -* platform_driver_probe() this is ok because they cannot get unbound at -* runtime. So mark the driver struct with __refdata to prevent modpost -* triggering a section mismatch warning. -*/ -static struct faux_device_ops einj_device_ops__refdata = { +static struct faux_device_ops einj_device_ops = { .probe = einj_probe, - .remove =__exit_p (einj_remove), + .remove = einj_remove, };static int __init einj_init (void )
Greg Kroah-Hartman
maintainerPATCH 204/457 mptcp: drop skb if MPTCP skb extension allocation fails
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Paasch <[email protected]>
commit ccab044697980c6c01ab51f43f48f13b8a3e5c33 upstream.
When skb_ext_add(skb, SKB_EXT_MPTCP) fails in mptcp_incoming_options(), we used to return true, letting the segment proceed through the TCP receive path without a DSS mapping. Such segments can leave inconsistent mapping state and trigger a mid-stream fallback to TCP, which in testing collapsed (by artificially forcing failures in skb_ext_add) throughput to zero.
Return false instead so the TCP input path drops the skb (see tcp_data_queue() and step-7 processing). This is the safer choice under memory pressure: it preserves MPTCP correctness and provides backpressure to the sender.
Control packets remain unaffected: ACK updates and DATA_FIN handling happen before attempting the extension allocation, and tcp_reset() continues to ignore the return value.
With this change, MPTCP continues to work at high throughput if we artificially inject failures into skb_ext_add.
--- net/mptcp/options.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/mptcp/options.c +4 -2
@@ -1117,7 +1117,9 @@ static bool add_addr_hmac_valid(struct mreturn hmac == mp_opt->ahmac; } -/* Return false if a subflow has been reset, else return true */ +/* Return false in case of error (or subflow has been reset), +* else return true. +*/ bool mptcp_incoming_options (struct sock *sk,struct sk_buff *skb) {struct mptcp_subflow_context *subflow =mptcp_subflow_ctx (sk);
@@ -1221,7 +1223,7 @@ bool mptcp_incoming_options(struct sock mpext =skb_ext_add (skb,SKB_EXT_MPTCP );if (!mpext) -return true; +return false;memset (mpext,0 ,sizeof (*mpext));
Greg Kroah-Hartman
maintainerPATCH 205/457 mptcp: pm: kernel: flush: do not reset ADD_ADDR limit
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit 68fc0f4b0d25692940cdc85c68e366cae63e1757 upstream.
A flush of the MPTCP endpoints should not affect the MPTCP limits. In other words, 'ip mptcp endpoint flush' should not change 'ip mptcp limits'.
But it was the case: the MPTCP_PM_ATTR_RCV_ADD_ADDRS (add_addr_accepted) limit was reset by accident. Removing the reset of this counter during a flush fixes this issue.
--- net/mptcp/pm_kernel.c | 1 - 1 file changed, 1 deletion(-)
net/mptcp/pm_kernel.c +0 -1
@@ -1085,7 +1085,6 @@ static void __flush_addrs(struct list_hestatic void __reset_counters (struct pm_nl_pernet *pernet) {WRITE_ONCE (pernet->add_addr_signal_max,0 ); -WRITE_ONCE (pernet->add_addr_accept_max,0 );WRITE_ONCE (pernet->local_addr_max,0 ); pernet->addrs =0 ; }
Greg Kroah-Hartman
maintainerPATCH 206/457 mptcp: remove duplicate sk_reset_timer call
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geliang Tang <[email protected]>
commit 5d13349472ac8abcbcb94407969aa0fdc2e1f1be upstream.
sk_reset_timer() was called twice in mptcp_pm_alloc_anno_list.
Simplify the code by using a 'goto' statement to eliminate the duplication.
Note that this is not a fix, but it will help backporting the following patch. The same "Fixes" tag has been added for this reason.
--- net/mptcp/pm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
net/mptcp/pm.c +2 -3
@@ -353,9 +353,7 @@ bool mptcp_pm_alloc_anno_list(struct mptif (WARN_ON_ONCE (mptcp_pm_is_kernel (msk)))return false; -sk_reset_timer (sk, &add_entry->add_timer, - jiffies +mptcp_get_add_addr_timeout (net)); -return true; + goto reset_timer; } add_entry =kmalloc (sizeof (*add_entry),GFP_ATOMIC );
@@ -369,6 +367,7 @@ bool mptcp_pm_alloc_anno_list(struct mpt add_entry->retrans_times =0 ;timer_setup (&add_entry->add_timer, mptcp_pm_add_timer,0 ); +reset_timer:sk_reset_timer (sk, &add_entry->add_timer, jiffies +mptcp_get_add_addr_timeout (net));
Greg Kroah-Hartman
maintainerPATCH 207/457 mptcp: disable add_addr retransmission when timeout is 0
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geliang Tang <[email protected]>
commit f5ce0714623cffd00bf2a83e890d09c609b7f50a upstream.
When add_addr_timeout was set to 0, this caused the ADD_ADDR to be retransmitted immediately, which looks like a buggy behaviour. Instead, interpret 0 as "no retransmissions needed".
The documentation is updated to explicitly state that setting the timeout to 0 disables retransmission.
--- Documentation/networking/mptcp-sysctl.rst | 2 ++ net/mptcp/pm.c | 13 ++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-)
Documentation/networking/mptcp-sysctl.rst +2 -0
@@ -12,6 +12,8 @@ add_addr_timeout - INTEGER (seconds) resent to an MPTCP peer that has not acknowledged a previous ADD_ADDR message. + Do not retransmit if set to 0. + The default value matches TCP_RTO_MAX. This is a per-namespace sysctl.
net/mptcp/pm.c +10 -3
@@ -274,6 +274,7 @@ static void mptcp_pm_add_timer(struct ti add_timer);struct mptcp_sock *msk = entry->sock;struct sock *sk = (struct sock *)msk; +unsigned int timeout;pr_debug ("msk=%p\n" , msk);
@@ -291,6 +292,10 @@ static void mptcp_pm_add_timer(struct ti goto out; } + timeout =mptcp_get_add_addr_timeout (sock_net (sk)); +if (!timeout) + goto out; +spin_lock_bh (&msk->pm.lock);if (!mptcp_pm_should_add_signal_addr (msk)) {
@@ -302,7 +307,7 @@ static void mptcp_pm_add_timer(struct tiif (entry->retrans_times <ADD_ADDR_RETRANS_MAX )sk_reset_timer (sk, timer, - jiffies +mptcp_get_add_addr_timeout (sock_net (sk))); + jiffies + timeout);spin_unlock_bh (&msk->pm.lock);
@@ -344,6 +349,7 @@ bool mptcp_pm_alloc_anno_list(struct mptstruct mptcp_pm_add_entry *add_entry =NULL ;struct sock *sk = (struct sock *)msk;struct net *net =sock_net (sk); +unsigned int timeout;lockdep_assert_held (&msk->pm.lock);
@@ -368,8 +374,9 @@ bool mptcp_pm_alloc_anno_list(struct mpttimer_setup (&add_entry->add_timer, mptcp_pm_add_timer,0 ); reset_timer: -sk_reset_timer (sk, &add_entry->add_timer, - jiffies +mptcp_get_add_addr_timeout (net)); + timeout =mptcp_get_add_addr_timeout (net); +if (timeout) +sk_reset_timer (sk, &add_entry->add_timer, jiffies + timeout);return true; }
Greg Kroah-Hartman
maintainerPATCH 208/457 selftests: mptcp: pm: check flush doesnt reset limits
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit 452690be7de2f91cc0de68cb9e95252875b33503 upstream.
This modification is linked to the parent commit where the received ADD_ADDR limit was accidentally reset when the endpoints were flushed.
To validate that, the test is now flushing endpoints after having set new limits, and before checking them.
The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests, but it validates the previous fix for an issue introduced by this commit ID.
--- tools/testing/selftests/net/mptcp/pm_netlink.sh | 1 + 1 file changed, 1 insertion(+)
tools/testing/selftests/net/mptcp/pm_netlink.sh +1 -0
@@ -198,6 +198,7 @@ set_limits 1 9 2>/dev/null check "get_limits" "${default_limits}" "subflows above hard limit" set_limits 8 8 +flush_endpoint ## to make sure it doesn't affect the limits check "get_limits" "$(format_limits 8 8)" "set limits" flush_endpoint
Greg Kroah-Hartman
maintainerPATCH 209/457 selftests: mptcp: connect: fix C23 extension warning
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit 2eefbed30d46d5e68593baf6b52923e00e7678af upstream.
GCC was complaining about the new label:
mptcp_connect.c:187:2: warning: label followed by a declaration is a C23 extension [-Wc23-extensions]
187 | int err = getaddrinfo(node, service, hints, res);
| ^Simply declare 'err' before the label to avoid this warning.
--- tools/testing/selftests/net/mptcp/mptcp_connect.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_connect.c +3 -2
@@ -183,9 +183,10 @@ static void xgetaddrinfo(const char *node, const char *service,struct addrinfo *hints, struct addrinfo **res) { -again: - int err = getaddrinfo(node, service, hints, res); + int err; +again: + err =getaddrinfo (node, service, hints, res);if (err) {const char *errstr;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 210/457 selftests: mptcp: sockopt: fix C23 extension warning
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit 3259889fd3c0cc165b7e9ee375c789875dd32326 upstream.
GCC was complaining about the new label:
mptcp_inq.c:79:2: warning: label followed by a declaration is a C23 extension [-Wc23-extensions]
79 | int err = getaddrinfo(node, service, hints, res);
| ^mptcp_sockopt.c:166:2: warning: label followed by a declaration is a C23 extension [-Wc23-extensions]
166 | int err = getaddrinfo(node, service, hints, res);
| ^Simply declare 'err' before the label to avoid this warning.
--- tools/testing/selftests/net/mptcp/mptcp_inq.c | 5 +++-- tools/testing/selftests/net/mptcp/mptcp_sockopt.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_inq.c +3 -2
@@ -75,9 +75,10 @@ static void xgetaddrinfo(const char *nodstruct addrinfo *hints, struct addrinfo **res) { -again: - int err = getaddrinfo(node, service, hints, res); + int err; +again: + err =getaddrinfo (node, service, hints, res);if (err) {const char *errstr;
tools/testing/selftests/net/mptcp/mptcp_sockopt.c +3 -2
@@ -162,9 +162,10 @@ static void xgetaddrinfo(const char *nodstruct addrinfo *hints, struct addrinfo **res) { -again: - int err = getaddrinfo(node, service, hints, res); + int err; +again: + err =getaddrinfo (node, service, hints, res);if (err) {const char *errstr;
Greg Kroah-Hartman
maintainerPATCH 211/457 mm/damon/ops-common: ignore migration request to invalid nodes
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 7e6c3130690a01076efdf45aa02ba5d5c16849a0 upstream.
damon_migrate_pages() tries migration even if the target node is invalid. If users mistakenly make such invalid requests via DAMOS_MIGRATE_{HOT,COLD} action, the below kernel BUG can happen.
[ 7831.883495] BUG: unable to handle page fault for address: 0000000000001f48
[ 7831.884160] #PF: supervisor read access in kernel mode
[ 7831.884681] #PF: error_code(0x0000) - not-present page
[ 7831.885203] PGD 0 P4D 0
[ 7831.885468] Oops: Oops: 0000 [#1] SMP PTI
[ 7831.885852] CPU: 31 UID: 0 PID: 94202 Comm: kdamond.0 Not tainted 6.16.0-rc5-mm-new-damon+ #93 PREEMPT(voluntary)
[ 7831.886913] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-4.el9 04/01/2014
[ 7831.887777] RIP: 0010:__alloc_frozen_pages_noprof (include/linux/mmzone.h:1724 include/linux/mmzone.h:1750 mm/page_alloc.c:4936 mm/page_alloc.c:5137)
[...]
[ 7831.895953] Call Trace:
[ 7831.896195] <TASK>
[ 7831.896397] __folio_alloc_noprof (mm/page_alloc.c:5183 mm/page_alloc.c:5192)
[ 7831.896787] migrate_pages_batch (mm/migrate.c:1189 mm/migrate.c:1851)
[ 7831.897228] ? __pfx_alloc_migration_target (mm/migrate.c:2137)
[ 7831.897735] migrate_pages (mm/migrate.c:2078)
[ 7831.898141] ? __pfx_alloc_migration_target (mm/migrate.c:2137)
[ 7831.898664] damon_migrate_folio_list (mm/damon/ops-common.c:321 mm/damon/ops-common.c:354)
[ 7831.899140] damon_migrate_pages (mm/damon/ops-common.c:405)
[...]Add a target node validity check in damon_migrate_pages(). The validity check is stolen from that of do_pages_move(), which is being used for the move_pages() system call.
--- mm/damon/paddr.c | 4 ++++ 1 file changed, 4 insertions(+)
mm/damon/paddr.c +4 -0
@@ -476,6 +476,10 @@ static unsigned long damon_pa_migrate_paif (list_empty (folio_list))return nr_migrated; +if (target_nid <0 || target_nid >=MAX_NUMNODES || + !node_state (target_nid,N_MEMORY )) +return nr_migrated; + noreclaim_flag =memalloc_noreclaim_save (); nid =folio_nid (lru_to_folio (folio_list));
Greg Kroah-Hartman
maintainerPATCH 212/457 btrfs: move transaction aborts to the error site in add_block_group_free_space()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Sterba <[email protected]>
[ Upstream commit b63c8c1ede4407835cb8c8bed2014d96619389f3 ]
Transaction aborts should be done next to the place the error happens, which was not done in add_block_group_free_space().
Stable-dep-of: 1f06c942aa70 ("btrfs: always abort transaction on failure to add block group to free space tree")
--- fs/btrfs/free-space-tree.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/btrfs/free-space-tree.c +3 -2
@@ -1456,16 +1456,17 @@ int add_block_group_free_space(struct bt path =btrfs_alloc_path ();if (!path) { ret = -ENOMEM ; +btrfs_abort_transaction (trans, ret); goto out; } ret =__add_block_group_free_space (trans, block_group, path); +if (ret) +btrfs_abort_transaction (trans, ret); out:btrfs_free_path (path);mutex_unlock (&block_group->free_space_lock); -if (ret) -btrfs_abort_transaction (trans, ret);return ret; }
Greg Kroah-Hartman
maintainerPATCH 213/457 btrfs: always abort transaction on failure to add block group to free space tree
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 1f06c942aa709d397cf6bed577a0d10a61509667 ]
Only one of the callers of __add_block_group_free_space() aborts the transaction if the call fails, while the others don't do it and it's either never done up the call chain or much higher in the call chain.
So make sure we abort the transaction at __add_block_group_free_space() if it fails, which brings a couple benefits:
1) If some call chain never aborts the transaction, we avoid having some metadata inconsistency because BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE is cleared when we enter __add_block_group_free_space() and therefore __add_block_group_free_space() is never called again to add the block group items to the free space tree, since the function is only called when that flag is set in a block group;
2) If the call chain already aborts the transaction, then we get a better trace that points to the exact step from __add_block_group_free_space() which failed, which is better for analysis.
So abort the transaction at __add_block_group_free_space() if any of its steps fails.
--- fs/btrfs/free-space-tree.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
fs/btrfs/free-space-tree.c +9 -7
@@ -1431,12 +1431,17 @@ static int __add_block_group_free_space(set_bit (BLOCK_GROUP_FLAG_FREE_SPACE_ADDED , &block_group->runtime_flags); ret =add_new_free_space_info (trans, block_group, path); -if (ret) +if (ret) { +btrfs_abort_transaction (trans, ret);return ret; + } -return __add_to_free_space_tree (trans, block_group, path, - block_group->start, - block_group->length); + ret =__add_to_free_space_tree (trans, block_group, path, + block_group->start, block_group->length); +if (ret) +btrfs_abort_transaction (trans, ret); + +return 0 ; } int add_block_group_free_space(struct btrfs_trans_handle *trans,
@@ -1461,9 +1466,6 @@ int add_block_group_free_space(struct bt } ret =__add_block_group_free_space (trans, block_group, path); -if (ret) -btrfs_abort_transaction (trans, ret); - out:btrfs_free_path (path);mutex_unlock (&block_group->free_space_lock);
Greg Kroah-Hartman
maintainerPATCH 214/457 btrfs: abort transaction on unexpected eb generation at btrfs_copy_root()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 33e8f24b52d2796b8cfb28c19a1a7dd6476323a8 ]
If we find an unexpected generation for the extent buffer we are cloning at btrfs_copy_root(), we just WARN_ON() and don't error out and abort the transaction, meaning we allow to persist metadata with an unexpected generation. Instead of warning only, abort the transaction and return -EUCLEAN.
--- fs/btrfs/ctree.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/btrfs/ctree.c +8 -1
@@ -283,7 +283,14 @@ int btrfs_copy_root(struct btrfs_trans_hwrite_extent_buffer_fsid (cow, fs_info->fs_devices->metadata_uuid); -WARN_ON (btrfs_header_generation (buf) > trans->transid); +if (unlikely (btrfs_header_generation (buf) > trans->transid)) { +btrfs_tree_unlock (cow); +free_extent_buffer (cow); + ret = -EUCLEAN ; +btrfs_abort_transaction (trans, ret); +return ret; + } +if (new_root_objectid ==BTRFS_TREE_RELOC_OBJECTID ) ret =btrfs_inc_ref (trans, root, cow,1 );else
Greg Kroah-Hartman
maintainerPATCH 215/457 btrfs: reorganize logic at free_extent_buffer() for better readability
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 71c086b30d4373a01bd5627f54516a72891a026a ]
It's hard to read the logic to break out of the while loop since it's a very long expression consisting of a logical or of two composite expressions, each one composed by a logical and. Further each one is also testing for the EXTENT_BUFFER_UNMAPPED bit, making it more verbose than necessary.
So change from this:
if ((!test_bit(EXTENT_BUFFER_UNMAPPED, &eb->bflags) && refs <= 3)
|| (test_bit(EXTENT_BUFFER_UNMAPPED, &eb->bflags) &&
refs == 1))
break;To this:
if (test_bit(EXTENT_BUFFER_UNMAPPED, &eb->bflags)) {
if (refs == 1)
break;
} else if (refs <= 3) {
break;
}At least on x86_64 using gcc 9.3.0, this doesn't change the object size.
Stable-dep-of: ad580dfa388f ("btrfs: fix subpage deadlock in try_release_subpage_extent_buffer()")
--- fs/btrfs/extent_io.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
fs/btrfs/extent_io.c +6 -3
@@ -3486,10 +3486,13 @@ void free_extent_buffer(struct extent_bu refs =atomic_read (&eb->refs);while (1 ) { -if ((!test_bit (EXTENT_BUFFER_UNMAPPED , &eb->bflags) && refs <=3 ) - || (test_bit (EXTENT_BUFFER_UNMAPPED , &eb->bflags) && - refs ==1 )) +if (test_bit (EXTENT_BUFFER_UNMAPPED , &eb->bflags)) { +if (refs ==1 ) +break ; + }else if (refs <=3 ) {break ; + } +if (atomic_try_cmpxchg (&eb->refs, &refs, refs -1 ))return ; }
Greg Kroah-Hartman
maintainerPATCH 216/457 btrfs: add comment for optimization in free_extent_buffer()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 2697b6159744e5afae0f7715da9f830ba6f9e45a ]
There's this special atomic compare and exchange logic which serves to avoid locking the extent buffers refs_lock spinlock and therefore reduce lock contention, so add a comment to make it more obvious.
Stable-dep-of: ad580dfa388f ("btrfs: fix subpage deadlock in try_release_subpage_extent_buffer()")
--- fs/btrfs/extent_io.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/extent_io.c +1 -0
@@ -3493,6 +3493,7 @@ void free_extent_buffer(struct extent_bubreak ; } +/* Optimization to avoid locking eb->refs_lock. */ if (atomic_try_cmpxchg (&eb->refs, &refs, refs -1 ))return ; }
Greg Kroah-Hartman
maintainerPATCH 217/457 btrfs: use refcount_t type for the extent buffer reference counter
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit b769777d927af168b1389388392bfd7dc4e38399 ]
Instead of using a bare atomic, use the refcount_t type, which despite being a structure that contains only an atomic, has an API that checks for underflows and other hazards. This doesn't change the size of the extent_buffer structure.
This removes the need to do things like this:
WARN_ON(atomic_read(&eb->refs) == 0);
if (atomic_dec_and_test(&eb->refs)) {
(...)
}And do just:
if (refcount_dec_and_test(&eb->refs)) {
(...)
}Since refcount_dec_and_test() already triggers a warning when we decrement a ref count that has a value of 0 (or below zero).
Stable-dep-of: ad580dfa388f ("btrfs: fix subpage deadlock in try_release_subpage_extent_buffer()")
--- fs/btrfs/ctree.c | 14 ++++++------- fs/btrfs/extent-tree.c | 2 - fs/btrfs/extent_io.c | 45 +++++++++++++++++++++---------------------- fs/btrfs/extent_io.h | 2 - fs/btrfs/fiemap.c | 2 - fs/btrfs/print-tree.c | 2 - fs/btrfs/qgroup.c | 6 ++--- fs/btrfs/relocation.c | 4 +-- fs/btrfs/tree-log.c | 4 +-- fs/btrfs/zoned.c | 2 - include/trace/events/btrfs.h | 2 - 11 files changed, 42 insertions(+), 43 deletions(-)
fs/btrfs/ctree.c +7 -7
@@ -198,7 +198,7 @@ struct extent_buffer *btrfs_root_node(st* the inc_not_zero dance and if it doesn't work then * synchronize_rcu and try again. */ -if (atomic_inc_not_zero (&eb->refs)) { +if (refcount_inc_not_zero (&eb->refs)) {rcu_read_unlock ();break ; }
@@ -556,7 +556,7 @@ int btrfs_force_cow_block(struct btrfs_tbtrfs_abort_transaction (trans, ret); goto error_unlock_cow; } -atomic_inc (&cow->refs); +refcount_inc (&cow->refs);rcu_assign_pointer (root->node, cow); ret = btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
@@ -1088,7 +1088,7 @@ static noinline int balance_level(struct/* update the path */ if (left) {if (btrfs_header_nritems (left) > orig_slot) { -atomic_inc (&left->refs); +refcount_inc (&left->refs);/* left was locked after cow */ path->nodes[level] = left; path->slots[level +1 ] -=1 ;
@@ -1692,7 +1692,7 @@ static struct extent_buffer *btrfs_searcif (p->search_commit_root) { b = root->commit_root; -atomic_inc (&b->refs); +refcount_inc (&b->refs); level =btrfs_header_level (b);/* * Ensure that all callers have set skip_locking when
@@ -2893,7 +2893,7 @@ static noinline int insert_new_root(strufree_extent_buffer (old);add_root_to_dirty_list (root); -atomic_inc (&c->refs); +refcount_inc (&c->refs); path->nodes[level] = c; path->locks[level] =BTRFS_WRITE_LOCK ; path->slots[level] =0 ;
@@ -4450,7 +4450,7 @@ static noinline int btrfs_del_leaf(strucroot_sub_used_bytes (root); -atomic_inc (&leaf->refs); +refcount_inc (&leaf->refs); ret =btrfs_free_tree_block (trans,btrfs_root_id (root), leaf,0 ,1 );free_extent_buffer_stale (leaf);if (ret <0 )
@@ -4535,7 +4535,7 @@ int btrfs_del_items(struct btrfs_trans_h* for possible call to btrfs_del_ptr below */ slot = path->slots[1 ]; -atomic_inc (&leaf->refs); +refcount_inc (&leaf->refs);/* * We want to be able to at least push one item to the * left neighbour leaf, and that's the first item.
fs/btrfs/extent-tree.c +1 -1
@@ -6342,7 +6342,7 @@ int btrfs_drop_subtree(struct btrfs_tranbtrfs_assert_tree_write_locked (parent); parent_level =btrfs_header_level (parent); -atomic_inc (&parent->refs); +refcount_inc (&parent->refs); path->nodes[parent_level] = parent; path->slots[parent_level] =btrfs_header_nritems (parent);
fs/btrfs/extent_io.c +22 -23
166 lines not on this page · raw message
fs/btrfs/extent_io.h +1 -1
@@ -98,7 +98,7 @@ struct extent_buffer {void *addr;spinlock_t refs_lock; -atomic_t refs; +refcount_t refs;int read_mirror;/* >= 0 if eb belongs to a log tree, -1 otherwise */ s8 log_index;
fs/btrfs/fiemap.c +1 -1
@@ -320,7 +320,7 @@ static int fiemap_next_leaf_item(struct* the cost of allocating a new one. */ ASSERT (test_bit (EXTENT_BUFFER_UNMAPPED , &clone->bflags)); -atomic_inc (&clone->refs); +refcount_inc (&clone->refs); ret =btrfs_next_leaf (inode->root, path);if (ret !=0 )
fs/btrfs/print-tree.c +1 -1
@@ -223,7 +223,7 @@ static void print_eb_refs_lock(const str {#ifdef CONFIG_BTRFS_DEBUG btrfs_info (eb->fs_info,"refs %u lock_owner %u current %u" , -atomic_read (&eb->refs), eb->lock_owner, current->pid); +refcount_read (&eb->refs), eb->lock_owner, current->pid);#endif }
fs/btrfs/qgroup.c +3 -3
@@ -2348,7 +2348,7 @@ static int qgroup_trace_extent_swap(strubtrfs_item_key_to_cpu (dst_path->nodes[dst_level], &key,0 );/* For src_path */ -atomic_inc (&src_eb->refs); +refcount_inc (&src_eb->refs); src_path->nodes[root_level] = src_eb; src_path->slots[root_level] = dst_path->slots[root_level]; src_path->locks[root_level] =0 ;
@@ -2581,7 +2581,7 @@ static int qgroup_trace_subtree_swap(str goto out; }/* For dst_path */ -atomic_inc (&dst_eb->refs); +refcount_inc (&dst_eb->refs); dst_path->nodes[level] = dst_eb; dst_path->slots[level] =0 ; dst_path->locks[level] =0 ;
@@ -2673,7 +2673,7 @@ int btrfs_qgroup_trace_subtree(struct bt* walk back up the tree (adjusting slot pointers as we go) * and restart the search process. */ -atomic_inc (&root_eb->refs);/* For path */ +refcount_inc (&root_eb->refs);/* For path */ path->nodes[root_level] = root_eb; path->slots[root_level] =0 ; path->locks[root_level] =0 ;/* so release_path doesn't try to unlock */
fs/btrfs/relocation.c +2 -2
@@ -1535,7 +1535,7 @@ static noinline_for_stack int merge_reloif (btrfs_disk_key_objectid (&root_item->drop_progress) ==0 ) { level =btrfs_root_level (root_item); -atomic_inc (&reloc_root->node->refs); +refcount_inc (&reloc_root->node->refs); path->nodes[level] = reloc_root->node; path->slots[level] =0 ; }else {
@@ -4358,7 +4358,7 @@ int btrfs_reloc_cow_block(struct btrfs_t }btrfs_backref_drop_node_buffer (node); -atomic_inc (&cow->refs); +refcount_inc (&cow->refs); node->eb = cow; node->new_bytenr = cow->start;
fs/btrfs/tree-log.c +2 -2
@@ -2747,7 +2747,7 @@ static int walk_log_tree(struct btrfs_tr level =btrfs_header_level (log->node); orig_level = level; path->nodes[level] = log->node; -atomic_inc (&log->node->refs); +refcount_inc (&log->node->refs); path->slots[level] =0 ;while (1 ) {
@@ -3711,7 +3711,7 @@ static int clone_leaf(struct btrfs_path* Add extra ref to scratch eb so that it is not freed when callers * release the path, so we can reuse it later if needed. */ -atomic_inc (&ctx->scratch_eb->refs); +refcount_inc (&ctx->scratch_eb->refs);return 0 ; }
fs/btrfs/zoned.c +1 -1
@@ -2491,7 +2491,7 @@ void btrfs_schedule_zone_finish_bg(struc/* For the work */ btrfs_get_block_group (bg); -atomic_inc (&eb->refs); +refcount_inc (&eb->refs); bg->last_eb = eb;INIT_WORK (&bg->zone_finish_work, btrfs_zone_finish_endio_workfn);queue_work (system_unbound_wq, &bg->zone_finish_work);
include/trace/events/btrfs.h +1 -1
@@ -1095,7 +1095,7 @@ TRACE_EVENT(btrfs_cow_block,TP_fast_assign_btrfs (root->fs_info, __entry->root_objectid = btrfs_root_id(root); __entry->buf_start = buf->start; - __entry->refs =atomic_read (&buf->refs); + __entry->refs =refcount_read (&buf->refs); __entry->cow_start = cow->start; __entry->buf_level =btrfs_header_level (buf); __entry->cow_level =btrfs_header_level (cow);
Greg Kroah-Hartman
maintainerPATCH 218/457 btrfs: fix subpage deadlock in try_release_subpage_extent_buffer()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leo Martins <[email protected]>
[ Upstream commit ad580dfa388fabb52af033e3f8cc5d04be985e54 ]
There is a potential deadlock that can happen in try_release_subpage_extent_buffer() because the irq-safe xarray spin lock fs_info->buffer_tree is being acquired before the irq-unsafe eb->refs_lock.
This leads to the potential race:
// T1 (random eb->refs user) // T2 (release folio)
spin_lock(&eb->refs_lock);
// interruptend_bbio_meta_write()
btrfs_meta_folio_clear_writeback()
btree_release_folio()
folio_test_writeback() //false
try_release_extent_buffer()
try_release_subpage_extent_buffer()
xa_lock_irq(&fs_info->buffer_tree)
spin_lock(&eb->refs_lock); // blocked; held by T1 buffer_tree_clear_mark()
xas_lock_irqsave() // blocked; held by T2
I believe that the spin lock can safely be replaced by an rcu_read_lock. The xa_for_each loop does not need the spin lock as it's already internally protected by the rcu_read_lock. The extent buffer is also protected by the rcu_read_lock so it won't be freed before we take the eb->refs_lock and check the ref count.
The rcu_read_lock is taken and released every iteration, just like the spin lock, which means we're not protected against concurrent insertions into the xarray. This is fine because we rely on folio->private to detect if there are any ebs remaining in the folio.
There is already some precedent for this with find_extent_buffer_nolock, which loads an extent buffer from the xarray with only rcu_read_lock.
lockdep warning:
=====================================================
WARNING: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected
6.16.0-0_fbk701_debug_rc0_123_g4c06e63b9203 #1 Tainted: G E N
-----------------------------------------------------
kswapd0/66 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
ffff000011ffd600 (&eb->refs_lock){+.+.}-{3:3}, at: try_release_extent_buffer+0x18c/0x560and this task is already holding:
ffff0000c1d91b88 (&buffer_xa_class){-.-.}-{3:3}, at: try_release_extent_buffer+0x13c/0x560
which would create a new lock dependency:
(&buffer_xa_class){-.-.}-{3:3} -> (&eb->refs_lock){+.+.}-{3:3}but this new dependency connects a HARDIRQ-irq-safe lock:
(&buffer_xa_class){-.-.}-{3:3}... which became HARDIRQ-irq-safe at:
lock_acquire+0x178/0x358
_raw_spin_lock_irqsave+0x60/0x88
buffer_tree_clear_mark+0xc4/0x160
end_bbio_meta_write+0x238/0x398
btrfs_bio_end_io+0x1f8/0x330
btrfs_orig_write_end_io+0x1c4/0x2c0
bio_endio+0x63c/0x678
blk_update_request+0x1c4/0xa00
blk_mq_end_request+0x54/0x88
virtblk_request_done+0x124/0x1d0
blk_mq_complete_request+0x84/0xa0
virtblk_done+0x130/0x238
vring_interrupt+0x130/0x288
__handle_irq_event_percpu+0x1e8/0x708
handle_irq_event+0x98/0x1b0
handle_fasteoi_irq+0x264/0x7c0
generic_handle_domain_irq+0xa4/0x108
gic_handle_irq+0x7c/0x1a0
do_interrupt_handler+0xe4/0x148
el1_interrupt+0x30/0x50
el1h_64_irq_handler+0x14/0x20
el1h_64_irq+0x6c/0x70
_raw_spin_unlock_irq+0x38/0x70
__run_timer_base+0xdc/0x5e0
run_timer_softirq+0xa0/0x138
handle_softirqs.llvm.13542289750107964195+0x32c/0xbd0
____do_softirq.llvm.17674514681856217165+0x18/0x28
call_on_irq_stack+0x24/0x30
__irq_exit_rcu+0x164/0x430
irq_exit_rcu+0x18/0x88
el1_interrupt+0x34/0x50
el1h_64_irq_handler+0x14/0x20
el1h_64_irq+0x6c/0x70
arch_local_irq_enable+0x4/0x8
do_idle+0x1a0/0x3b8
cpu_startup_entry+0x60/0x80
rest_init+0x204/0x228
start_kernel+0x394/0x3f0
__primary_switched+0x8c/0x8958to a HARDIRQ-irq-unsafe lock:
(&eb->refs_lock){+.+.}-{3:3}... which became HARDIRQ-irq-unsafe at:
...
lock_acquire+0x178/0x358
_raw_spin_lock+0x4c/0x68
free_extent_buffer_stale+0x2c/0x170
btrfs_read_sys_array+0x1b0/0x338
open_ctree+0xeb0/0x1df8
btrfs_get_tree+0xb60/0x1110
vfs_get_tree+0x8c/0x250
fc_mount+0x20/0x98
btrfs_get_tree+0x4a4/0x1110
vfs_get_tree+0x8c/0x250
do_new_mount+0x1e0/0x6c0
path_mount+0x4ec/0xa58
__arm64_sys_mount+0x370/0x490
invoke_syscall+0x6c/0x208
el0_svc_common+0x14c/0x1b8
do_el0_svc+0x4c/0x60
el0_svc+0x4c/0x160
el0t_64_sync_handler+0x70/0x100
el0t_64_sync+0x168/0x170other info that might help us debug this:
Possible interrupt unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&eb->refs_lock);
local_irq_disable();
lock(&buffer_xa_class);
lock(&eb->refs_lock);
<Interrupt>
lock(&buffer_xa_class);*** DEADLOCK ***
2 locks held by kswapd0/66:
#0: ffff800085506e40 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat+0xe8/0xe50
#1: ffff0000c1d91b88 (&buffer_xa_class){-.-.}-{3:3}, at: try_release_extent_buffer+0x13c/0x560--- fs/btrfs/extent_io.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
fs/btrfs/extent_io.c +6 -5
@@ -4304,15 +4304,18 @@ static int try_release_subpage_extent_buunsigned long end = index + (PAGE_SIZE >> fs_info->sectorsize_bits) -1 ;int ret; -xa_lock_irq (&fs_info->buffer_tree); +rcu_read_lock ();xa_for_each_range (&fs_info->buffer_tree, index, eb, start, end) {/* * The same as try_release_extent_buffer(), to ensure the eb * won't disappear out from under us. */ spin_lock (&eb->refs_lock); +rcu_read_unlock (); +if (refcount_read (&eb->refs) !=1 ||extent_buffer_under_io (eb)) {spin_unlock (&eb->refs_lock); +rcu_read_lock ();continue ; }
@@ -4331,11 +4334,10 @@ static int try_release_subpage_extent_bu* check the folio private at the end. And * release_extent_buffer() will release the refs_lock. */ -xa_unlock_irq (&fs_info->buffer_tree);release_extent_buffer (eb); -xa_lock_irq (&fs_info->buffer_tree); +rcu_read_lock (); } -xa_unlock_irq (&fs_info->buffer_tree); +rcu_read_unlock ();/* * Finally to check if we have cleared folio private, as if we have
@@ -4348,7 +4350,6 @@ static int try_release_subpage_extent_bu ret =0 ;spin_unlock (&folio->mapping->i_private_lock);return ret; - }int try_release_extent_buffer (struct folio *folio)
Greg Kroah-Hartman
maintainerPATCH 219/457 btrfs: add comments on the extra btrfs specific subpage bitmaps
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit 1e17738d6b76cdc76d240d64de87fa66ba2365f7 ]
Unlike the iomap_folio_state structure, the btrfs_subpage structure has a lot of extra sub-bitmaps, namely:
- writeback sub-bitmap
- locked sub-bitmap
iomap_folio_state uses an atomic for writeback tracking, while it has no per-block locked tracking.
This is because iomap always locks a single folio, and submits dirty blocks with that folio locked.
But btrfs has async delalloc ranges (for compression), which are queued with their range locked, until the compression is done, then marks the involved range writeback and unlocked.
This means a range can be unlocked and marked writeback at seemingly random timing, thus it needs the extra tracking.
This needs a huge rework on the lifespan of async delalloc range before we can remove/simplify these two sub-bitmaps.
- ordered sub-bitmap
- checked sub-bitmap
These are for COW-fixup, but as I mentioned in the past, the COW-fixup is not really needed anymore and these two flags are already marked deprecated, and will be removed in the near future after comprehensive tests.
Add related comments to indicate we're actively trying to align the sub-bitmaps to the iomap ones.
Stable-dep-of: b1511360c8ac ("btrfs: subpage: keep TOWRITE tag until folio is cleaned")
--- fs/btrfs/subpage.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
fs/btrfs/subpage.h +14 -0
@@ -33,8 +33,22 @@ enum { btrfs_bitmap_nr_uptodate =0 , btrfs_bitmap_nr_dirty, btrfs_bitmap_nr_writeback, +/* +* The ordered and checked flags are for COW fixup, already marked +* deprecated, and will be removed eventually. +*/ btrfs_bitmap_nr_ordered, btrfs_bitmap_nr_checked, + +/* +* The locked bit is for async delalloc range (compression), currently +* async extent is queued with the range locked, until the compression +* is done. +* So an async extent can unlock the range at any random timing. +* +* This will need a rework on the async extent lifespan (mark writeback +* and do compression) before deprecating this flag. +*/ btrfs_bitmap_nr_locked, btrfs_bitmap_nr_max };
Greg Kroah-Hartman
maintainerPATCH 220/457 btrfs: rename btrfs_subpage structure
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit 582cd4bad4332cca95c578e99442eb148366eb82 ]
With the incoming large data folios support, the structure name btrfs_subpage is no longer correct, as for we can have multiple blocks inside a large folio, and the block size is still page size.
So to follow the schema of iomap, rename btrfs_subpage to btrfs_folio_state, along with involved enums.
There are still exported functions with "btrfs_subpage_" prefix, and I believe for metadata the name "subpage" will stay forever as we will never allocate a folio larger than nodesize anyway.
The full cleanup of the word "subpage" will happen in much smaller steps in the future.
Stable-dep-of: b1511360c8ac ("btrfs: subpage: keep TOWRITE tag until folio is cleaned")
--- fs/btrfs/extent_io.c | 28 ++--- fs/btrfs/inode.c | 8 - fs/btrfs/subpage.c | 239 ++++++++++++++++++++++++--------------------------- fs/btrfs/subpage.h | 31 ++++-- 4 files changed, 156 insertions(+), 150 deletions(-)
fs/btrfs/extent_io.c +14 -14
@@ -782,7 +782,7 @@ static void submit_extent_folio(struct bstatic int attach_extent_buffer_folio (struct extent_buffer *eb,struct folio *folio, -struct btrfs_subpage *prealloc) +struct btrfs_folio_state *prealloc) {struct btrfs_fs_info *fs_info = eb->fs_info;int ret =0 ;
@@ -806,7 +806,7 @@ static int attach_extent_buffer_folio(st/* Already mapped, just free prealloc */ if (folio_test_private (folio)) { -btrfs_free_subpage (prealloc); +btrfs_free_folio_state (prealloc);return 0 ; }
@@ -815,7 +815,7 @@ static int attach_extent_buffer_folio(stfolio_attach_private (folio, prealloc); else/* Do new allocation to attach subpage */ - ret =btrfs_attach_subpage (fs_info, folio,BTRFS_SUBPAGE_METADATA ); + ret =btrfs_attach_folio_state (fs_info, folio,BTRFS_SUBPAGE_METADATA );return ret; }
@@ -831,7 +831,7 @@ int set_folio_extent_mapped(struct folio fs_info =folio_to_fs_info (folio);if (btrfs_is_subpage (fs_info, folio)) -return btrfs_attach_subpage (fs_info, folio,BTRFS_SUBPAGE_DATA ); +return btrfs_attach_folio_state (fs_info, folio,BTRFS_SUBPAGE_DATA );folio_attach_private (folio, (void *)EXTENT_FOLIO_PRIVATE );return 0 ;
@@ -848,7 +848,7 @@ void clear_folio_extent_mapped(struct fo fs_info =folio_to_fs_info (folio);if (btrfs_is_subpage (fs_info, folio)) -return btrfs_detach_subpage (fs_info, folio,BTRFS_SUBPAGE_DATA ); +return btrfs_detach_folio_state (fs_info, folio,BTRFS_SUBPAGE_DATA );folio_detach_private (folio); }
@@ -2731,13 +2731,13 @@ static int extent_buffer_under_io(conststatic bool folio_range_has_eb (struct folio *folio) { -struct btrfs_subpage *subpage; +struct btrfs_folio_state *bfs;lockdep_assert_held (&folio->mapping->i_private_lock);if (folio_test_private (folio)) { - subpage =folio_get_private (folio); -if (atomic_read (&subpage->eb_refs)) + bfs =folio_get_private (folio); +if (atomic_read (&bfs->eb_refs))return true; }return false;
@@ -2787,7 +2787,7 @@ static void detach_extent_buffer_folio(c* attached to one dummy eb, no sharing. */ if (!mapped) { -btrfs_detach_subpage (fs_info, folio,BTRFS_SUBPAGE_METADATA ); +btrfs_detach_folio_state (fs_info, folio,BTRFS_SUBPAGE_METADATA );return ; }
@@ -2798,7 +2798,7 @@ static void detach_extent_buffer_folio(c* page range and no unfinished IO. */ if (!folio_range_has_eb (folio)) -btrfs_detach_subpage (fs_info, folio,BTRFS_SUBPAGE_METADATA ); +btrfs_detach_folio_state (fs_info, folio,BTRFS_SUBPAGE_METADATA );spin_unlock (&mapping->i_private_lock); }
@@ -3141,7 +3141,7 @@ static bool check_eb_alignment(struct bt* The caller needs to free the existing folios and retry using the same order. */ static int attach_eb_folio_to_filemap (struct extent_buffer *eb,int i, -struct btrfs_subpage *prealloc, +struct btrfs_folio_state *prealloc,struct extent_buffer **found_eb_ret) {
@@ -3224,7 +3224,7 @@ struct extent_buffer *alloc_extent_buffeint attached =0 ;struct extent_buffer *eb;struct extent_buffer *existing_eb =NULL ; -struct btrfs_subpage *prealloc =NULL ; +struct btrfs_folio_state *prealloc =NULL ;u64 lockdep_owner = owner_root;bool page_contig = true;int uptodate =1 ;
@@ -3269,7 +3269,7 @@ struct extent_buffer *alloc_extent_buffe* manually if we exit earlier. */ if (btrfs_meta_is_subpage (fs_info)) { - prealloc =btrfs_alloc_subpage (fs_info,PAGE_SIZE ,BTRFS_SUBPAGE_METADATA ); + prealloc =btrfs_alloc_folio_state (fs_info,PAGE_SIZE ,BTRFS_SUBPAGE_METADATA );if (IS_ERR (prealloc)) { ret =PTR_ERR (prealloc); goto out;
@@ -3280,7 +3280,7 @@ reallocate:/* Allocate all pages first. */ ret =alloc_eb_folio_array (eb, true);if (ret <0 ) { -btrfs_free_subpage (prealloc); +btrfs_free_folio_state (prealloc); goto out; }
fs/btrfs/inode.c +4 -4
@@ -7364,13 +7364,13 @@ struct extent_map *btrfs_create_io_em(ststatic void wait_subpage_spinlock (struct folio *folio) {struct btrfs_fs_info *fs_info =folio_to_fs_info (folio); -struct btrfs_subpage *subpage; +struct btrfs_folio_state *bfs;if (!btrfs_is_subpage (fs_info, folio))return ;ASSERT (folio_test_private (folio) &&folio_get_private (folio)); - subpage =folio_get_private (folio); + bfs =folio_get_private (folio);/* * This may look insane as we just acquire the spinlock and release it,
@@ -7383,8 +7383,8 @@ static void wait_subpage_spinlock(struct* Here we just acquire the spinlock so that all existing callers * should exit and we're safe to release/invalidate the page. */ -spin_lock_irq (&subpage->lock); -spin_unlock_irq (&subpage->lock); +spin_lock_irq (&bfs->lock); +spin_unlock_irq (&bfs->lock); }static int btrfs_launder_folio (struct folio *folio)
fs/btrfs/subpage.c +117 -122
566 lines not on this page · raw message
fs/btrfs/subpage.h +21 -10
@@ -32,7 +32,15 @@ struct folio;enum { btrfs_bitmap_nr_uptodate =0 , btrfs_bitmap_nr_dirty, + +/* +* This can be changed to atomic eventually. But this change will rely +* on the async delalloc range rework for locked bitmap. As async +* delalloc can unlock its range and mark blocks writeback at random +* timing. +*/ btrfs_bitmap_nr_writeback, +/* * The ordered and checked flags are for COW fixup, already marked * deprecated, and will be removed eventually.
@@ -57,7 +65,7 @@ enum {* Structure to trace status of each sector inside a page, attached to * page::private for both data and metadata inodes. */ -struct btrfs_subpage { +struct btrfs_folio_state {/* Common members for both data and metadata pages */ spinlock_t lock;union {
@@ -65,7 +73,7 @@ struct btrfs_subpage {* Structures only used by metadata * * @eb_refs should only be operated under private_lock, as it -* manages whether the subpage can be detached. +* manages whether the btrfs_folio_state can be detached. */ atomic_t eb_refs;
@@ -79,7 +87,7 @@ struct btrfs_subpage {unsigned long bitmaps[]; }; -enum btrfs_subpage_type { +enum btrfs_folio_type {BTRFS_SUBPAGE_METADATA ,BTRFS_SUBPAGE_DATA , };
@@ -119,15 +127,18 @@ static inline bool btrfs_is_subpage(cons }#endif -int btrfs_attach_subpage (const struct btrfs_fs_info *fs_info, -struct folio *folio,enum btrfs_subpage_type type); -void btrfs_detach_subpage (const struct btrfs_fs_info *fs_info,struct folio *folio, -enum btrfs_subpage_type type); +int btrfs_attach_folio_state (const struct btrfs_fs_info *fs_info, +struct folio *folio,enum btrfs_folio_type type); +void btrfs_detach_folio_state (const struct btrfs_fs_info *fs_info,struct folio *folio, +enum btrfs_folio_type type);/* Allocate additional data where page represents more than one sector */ -struct btrfs_subpage *btrfs_alloc_subpage (const struct btrfs_fs_info *fs_info, -size_t fsize,enum btrfs_subpage_type type); -void btrfs_free_subpage (struct btrfs_subpage *subpage); +struct btrfs_folio_state *btrfs_alloc_folio_state (const struct btrfs_fs_info *fs_info, +size_t fsize,enum btrfs_folio_type type); +static inline void btrfs_free_folio_state (struct btrfs_folio_state *bfs) +{ +kfree (bfs); +}void btrfs_folio_inc_eb_refs (const struct btrfs_fs_info *fs_info,struct folio *folio);void btrfs_folio_dec_eb_refs (const struct btrfs_fs_info *fs_info,struct folio *folio);
Greg Kroah-Hartman
maintainerPATCH 221/457 btrfs: subpage: keep TOWRITE tag until folio is cleaned
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naohiro Aota <[email protected]>
[ Upstream commit b1511360c8ac882b0c52caa263620538e8d73220 ]
btrfs_subpage_set_writeback() calls folio_start_writeback() the first time a folio is written back, and it also clears the PAGECACHE_TAG_TOWRITE tag even if there are still dirty blocks in the folio. This can break ordering guarantees, such as those required by btrfs_wait_ordered_extents().
That ordering breakage leads to a real failure. For example, running generic/464 on a zoned setup will hit the following ASSERT. This happens because the broken ordering fails to flush existing dirty pages before the file size is truncated.
assertion failed: !list_empty(&ordered->list) :: 0, in fs/btrfs/zoned.c:1899
------------[ cut here ]------------ kernel BUG at fs/btrfs/zoned.c:1899! Oops: invalid opcode: 0000 [#1] SMP NOPTI CPU: 2 UID: 0 PID: 1906169 Comm: kworker/u130:2 Kdump: loaded Not tainted 6.16.0-rc6-BTRFS-ZNS+ #554 PREEMPT(voluntary) Hardware name: Supermicro Super Server/H12SSL-NT, BIOS 2.0 02/22/2021 Workqueue: btrfs-endio-write btrfs_work_helper [btrfs] RIP: 0010:btrfs_finish_ordered_zoned.cold+0x50/0x52 [btrfs] RSP: 0018:ffffc9002efdbd60 EFLAGS: 00010246 RAX: 000000000000004c RBX: ffff88811923c4e0 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffff827e38b1 RDI: 00000000ffffffff RBP: ffff88810005d000 R08: 00000000ffffdfff R09: ffffffff831051c8 R10: ffffffff83055220 R11: 0000000000000000 R12: ffff8881c2458c00 R13: ffff88811923c540 R14: ffff88811923c5e8 R15: ffff8881c1bd9680 FS: 0000000000000000(0000) GS:ffff88a04acd0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f907c7a918c CR3: 0000000004024000 CR4: 0000000000350ef0 Call Trace: <TASK> ? srso_return_thunk+0x5/0x5f btrfs_finish_ordered_io+0x4a/0x60 [btrfs] btrfs_work_helper+0xf9/0x490 [btrfs] process_one_work+0x204/0x590 ? srso_return_thunk+0x5/0x5f worker_thread+0x1d6/0x3d0 ? __pfx_worker_thread+0x10/0x10 kthread+0x118/0x230 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x205/0x260 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK>
Consider process A calling writepages() with WB_SYNC_NONE. In zoned mode or for compressed writes, it locks several folios for delalloc and starts writing them out. Let's call the last locked folio folio X. Suppose the write range only partially covers folio X, leaving some pages dirty. Process A calls btrfs_subpage_set_writeback() when building a bio. This function call clears the TOWRITE tag of folio X, whose size = 8K and the block size = 4K. It is following state.
0 4K 8K |/////|/////| (flag: DIRTY, tag: DIRTY)
<-----> Process A will write this range.
Now suppose process B concurrently calls writepages() with WB_SYNC_ALL. It calls tag_pages_for_writeback() to tag dirty folios with PAGECACHE_TAG_TOWRITE. Since folio X is still dirty, it gets tagged. Then, B collects tagged folios using filemap_get_folios_tag() and must wait for folio X to be written before returning from writepages().
0 4K 8K |/////|/////| (flag: DIRTY, tag: DIRTY|TOWRITE)
However, between tagging and collecting, process A may call btrfs_subpage_set_writeback() and clear folio X's TOWRITE tag.
0 4K 8K | |/////| (flag: DIRTY|WRITEBACK, tag: DIRTY)
As a result, process B won't see folio X in its batch, and returns without waiting for it. This breaks the WB_SYNC_ALL ordering requirement.
Fix this by using btrfs_subpage_set_writeback_keepwrite(), which retains the TOWRITE tag. We now manually clear the tag only after the folio becomes clean, via the xas operation.
--- fs/btrfs/subpage.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
fs/btrfs/subpage.c +18 -1
@@ -448,8 +448,25 @@ void btrfs_subpage_set_writeback(const sspin_lock_irqsave (&bfs->lock, flags);bitmap_set (bfs->bitmaps, start_bit, len >> fs_info->sectorsize_bits); + +/* +* Don't clear the TOWRITE tag when starting writeback on a still-dirty +* folio. Doing so can cause WB_SYNC_ALL writepages() to overlook it, +* assume writeback is complete, and exit too early — violating sync +* ordering guarantees. +*/ if (!folio_test_writeback (folio)) -folio_start_writeback (folio); +__folio_start_writeback (folio, true); +if (!folio_test_dirty (folio)) { +struct address_space *mapping =folio_mapping (folio); +XA_STATE (xas, &mapping->i_pages, folio->index); +unsigned long flags; + +xas_lock_irqsave (&xas, flags); +xas_load (&xas); +xas_clear_mark (&xas,PAGECACHE_TAG_TOWRITE ); +xas_unlock_irqrestore (&xas, flags); + }spin_unlock_irqrestore (&bfs->lock, flags); }
Greg Kroah-Hartman
maintainerPATCH 222/457 xfs: decouple xfs_trans_alloc_empty from xfs_trans_alloc
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit 83a80e95e797a2a6d14bf7983e5e6eecf8f5facb ]
xfs_trans_alloc_empty only shares the very basic transaction structure allocation and initialization with xfs_trans_alloc.
Split out a new __xfs_trans_alloc helper for that and otherwise decouple xfs_trans_alloc_empty from xfs_trans_alloc.
Stable-dep-of: d2845519b072 ("xfs: fully decouple XFS_IBULK* flags from XFS_IWALK* flags")
--- fs/xfs/xfs_trans.c | 52 ++++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 24 deletions(-)
fs/xfs/xfs_trans.c +28 -24
@@ -241,6 +241,28 @@ undo_blocks:return error; } +static struct xfs_trans * +__xfs_trans_alloc ( +struct xfs_mount *mp, +uint flags) +{ +struct xfs_trans *tp; + +ASSERT (!(flags &XFS_TRANS_RES_FDBLKS ) ||xfs_has_lazysbcount (mp)); + + tp =kmem_cache_zalloc (xfs_trans_cache,GFP_KERNEL | __GFP_NOFAIL); +if (!(flags &XFS_TRANS_NO_WRITECOUNT )) +sb_start_intwrite (mp->m_super); +xfs_trans_set_context (tp); + tp->t_flags = flags; + tp->t_mountp = mp; +INIT_LIST_HEAD (&tp->t_items); +INIT_LIST_HEAD (&tp->t_busy); +INIT_LIST_HEAD (&tp->t_dfops); + tp->t_highest_agno =NULLAGNUMBER ; +return tp; +} + int xfs_trans_alloc( struct xfs_mount *mp,
@@ -254,33 +276,16 @@ xfs_trans_alloc(bool want_retry = true;int error; +ASSERT (resp->tr_logres >0 ); +/* * Allocate the handle before we do our freeze accounting and setting up * GFP_NOFS allocation context so that we avoid lockdep false positives * by doing GFP_KERNEL allocations inside sb_start_intwrite(). */ retry: - tp =kmem_cache_zalloc (xfs_trans_cache,GFP_KERNEL | __GFP_NOFAIL); -if (!(flags &XFS_TRANS_NO_WRITECOUNT )) -sb_start_intwrite (mp->m_super); -xfs_trans_set_context (tp); - -/* -* Zero-reservation ("empty") transactions can't modify anything, so -* they're allowed to run while we're frozen. -*/ -WARN_ON (resp->tr_logres >0 && - mp->m_super->s_writers.frozen ==SB_FREEZE_COMPLETE ); -ASSERT (!(flags &XFS_TRANS_RES_FDBLKS ) || -xfs_has_lazysbcount (mp)); - - tp->t_flags = flags; - tp->t_mountp = mp; -INIT_LIST_HEAD (&tp->t_items); -INIT_LIST_HEAD (&tp->t_busy); -INIT_LIST_HEAD (&tp->t_dfops); - tp->t_highest_agno =NULLAGNUMBER ; - +WARN_ON (mp->m_super->s_writers.frozen ==SB_FREEZE_COMPLETE ); + tp =__xfs_trans_alloc (mp, flags); error =xfs_trans_reserve (tp, resp, blocks, rtextents);if (error == -ENOSPC && want_retry) {xfs_trans_cancel (tp);
@@ -329,9 +334,8 @@ xfs_trans_alloc_empty(struct xfs_mount *mp, struct xfs_trans **tpp) { - struct xfs_trans_res resv = {0}; - -return xfs_trans_alloc (mp, &resv,0 ,0 ,XFS_TRANS_NO_WRITECOUNT , tpp); + *tpp =__xfs_trans_alloc (mp,XFS_TRANS_NO_WRITECOUNT ); +return 0 ; }/*
Greg Kroah-Hartman
maintainerPATCH 223/457 xfs: return the allocated transaction from xfs_trans_alloc_empty
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit d8e1ea43e5a314bc01ec059ce93396639dcf9112 ]
xfs_trans_alloc_empty can't return errors, so return the allocated transaction directly instead of an output double pointer argument.
Stable-dep-of: d2845519b072 ("xfs: fully decouple XFS_IBULK* flags from XFS_IWALK* flags")
--- fs/xfs/libxfs/xfs_refcount.c | 4 +--- fs/xfs/scrub/common.c | 3 ++- fs/xfs/scrub/repair.c | 12 ++---------- fs/xfs/scrub/scrub.c | 5 +---- fs/xfs/xfs_attr_item.c | 5 +---- fs/xfs/xfs_discard.c | 12 +++--------- fs/xfs/xfs_fsmap.c | 4 +--- fs/xfs/xfs_icache.c | 5 +---- fs/xfs/xfs_inode.c | 7 ++----- fs/xfs/xfs_itable.c | 18 +++--------------- fs/xfs/xfs_iwalk.c | 11 +++-------- fs/xfs/xfs_notify_failure.c | 5 +---- fs/xfs/xfs_qm.c | 10 ++-------- fs/xfs/xfs_rtalloc.c | 13 +++---------- fs/xfs/xfs_trans.c | 8 +++----- fs/xfs/xfs_trans.h | 3 +-- fs/xfs/xfs_zone_gc.c | 5 +---- 17 files changed, 31 insertions(+), 99 deletions(-)
fs/xfs/libxfs/xfs_refcount.c +1 -3
@@ -2099,9 +2099,7 @@ xfs_refcount_recover_cow_leftovers(* recording the CoW debris we cancel the (empty) transaction * and everything goes away cleanly. */ - error =xfs_trans_alloc_empty (mp, &tp); -if (error) -return error; + tp =xfs_trans_alloc_empty (mp);if (isrt) {xfs_rtgroup_lock (to_rtg (xg),XFS_RTGLOCK_REFCOUNT );
fs/xfs/scrub/common.c +2 -1
@@ -870,7 +870,8 @@ intxchk_trans_alloc_empty ( struct xfs_scrub *sc) { -return xfs_trans_alloc_empty (sc->mp, &sc->tp); + sc->tp =xfs_trans_alloc_empty (sc->mp); +return 0 ; }/*
fs/xfs/scrub/repair.c +2 -10
@@ -1279,18 +1279,10 @@ xrep_trans_alloc_hook_dummy(void **cookiep, struct xfs_trans **tpp) { - int error; - *cookiep = current->journal_info; current->journal_info =NULL ; - - error =xfs_trans_alloc_empty (mp, tpp); -if (!error) -return 0 ; - - current->journal_info = *cookiep; - *cookiep =NULL ; -return error; + *tpp =xfs_trans_alloc_empty (mp); +return 0 ; }/* Cancel a dummy transaction used by a live update hook function. */
fs/xfs/scrub/scrub.c +1 -4
@@ -876,10 +876,7 @@ xchk_scrubv_open_by_handle(struct xfs_inode *ip;int error; - error =xfs_trans_alloc_empty (mp, &tp); -if (error) -return NULL ; - + tp =xfs_trans_alloc_empty (mp); error =xfs_iget (mp, tp, head->svh_ino,XCHK_IGET_FLAGS ,0 , &ip);xfs_trans_cancel (tp);if (error)
fs/xfs/xfs_attr_item.c +1 -4
@@ -616,10 +616,7 @@ xfs_attri_iread_extents(struct xfs_trans *tp;int error; - error =xfs_trans_alloc_empty (ip->i_mount, &tp); -if (error) -return error; - + tp =xfs_trans_alloc_empty (ip->i_mount);xfs_ilock (ip,XFS_ILOCK_EXCL ); error =xfs_iread_extents (tp, ip,XFS_ATTR_FORK );xfs_iunlock (ip,XFS_ILOCK_EXCL );
fs/xfs/xfs_discard.c +3 -9
@@ -189,9 +189,7 @@ xfs_trim_gather_extents(*/ xfs_log_force (mp,XFS_LOG_SYNC ); - error =xfs_trans_alloc_empty (mp, &tp); -if (error) -return error; + tp =xfs_trans_alloc_empty (mp); error =xfs_alloc_read_agf (pag, tp,0 , &agbp);if (error)
@@ -583,9 +581,7 @@ xfs_trim_rtextents(struct xfs_trans *tp;int error; - error =xfs_trans_alloc_empty (mp, &tp); -if (error) -return error; + tp =xfs_trans_alloc_empty (mp);/* * Walk the free ranges between low and high. The query_range function
@@ -701,9 +697,7 @@ xfs_trim_rtgroup_extents(struct xfs_trans *tp;int error; - error =xfs_trans_alloc_empty (mp, &tp); -if (error) -return error; + tp =xfs_trans_alloc_empty (mp);/* * Walk the free ranges between low and high. The query_range function
fs/xfs/xfs_fsmap.c +1 -3
@@ -1270,9 +1270,7 @@ xfs_getfsmap(* buffer locking abilities to detect cycles in the rmapbt * without deadlocking. */ - error =xfs_trans_alloc_empty (mp, &tp); -if (error) -break ; + tp =xfs_trans_alloc_empty (mp); info.dev = handlers[i].dev; info.last = false;
fs/xfs/xfs_icache.c +1 -4
@@ -893,10 +893,7 @@ xfs_metafile_iget(struct xfs_trans *tp;int error; - error =xfs_trans_alloc_empty (mp, &tp); -if (error) -return error; - + tp =xfs_trans_alloc_empty (mp); error =xfs_trans_metafile_iget (tp, ino, metafile_type, ipp);xfs_trans_cancel (tp);return error;
fs/xfs/xfs_inode.c +2 -5
@@ -2932,12 +2932,9 @@ xfs_inode_reload_unlinked( struct xfs_inode *ip) {struct xfs_trans *tp; -int error; - - error =xfs_trans_alloc_empty (ip->i_mount, &tp); -if (error) -return error; +int error =0 ; + tp =xfs_trans_alloc_empty (ip->i_mount);xfs_ilock (ip,XFS_ILOCK_SHARED );if (xfs_inode_unlinked_incomplete (ip)) error =xfs_inode_reload_unlinked_bucket (tp, ip);
fs/xfs/xfs_itable.c +3 -15
@@ -239,14 +239,10 @@ xfs_bulkstat_one(* Grab an empty transaction so that we can use its recursive buffer * locking abilities to detect cycles in the inobt without deadlocking. */ - error =xfs_trans_alloc_empty (breq->mp, &tp); -if (error) - goto out; - + tp =xfs_trans_alloc_empty (breq->mp); error =xfs_bulkstat_one_int (breq->mp, breq->idmap, tp, breq->startino, &bc);xfs_trans_cancel (tp); -out:kfree (bc.buf);/*
@@ -331,17 +327,13 @@ xfs_bulkstat(* Grab an empty transaction so that we can use its recursive buffer * locking abilities to detect cycles in the inobt without deadlocking. */ - error =xfs_trans_alloc_empty (breq->mp, &tp); -if (error) - goto out; - + tp =xfs_trans_alloc_empty (breq->mp);if (breq->flags &XFS_IBULK_SAME_AG ) iwalk_flags |=XFS_IWALK_SAME_AG ; error =xfs_iwalk (breq->mp, tp, breq->startino, iwalk_flags, xfs_bulkstat_iwalk, breq->icount, &bc);xfs_trans_cancel (tp); -out:kfree (bc.buf);/*
@@ -464,14 +456,10 @@ xfs_inumbers(* Grab an empty transaction so that we can use its recursive buffer * locking abilities to detect cycles in the inobt without deadlocking. */ - error =xfs_trans_alloc_empty (breq->mp, &tp); -if (error) - goto out; - + tp =xfs_trans_alloc_empty (breq->mp); error =xfs_inobt_walk (breq->mp, tp, breq->startino, breq->flags, xfs_inumbers_walk, breq->icount, &ic);xfs_trans_cancel (tp); -out:/* * We found some inode groups, so clear the error status and return
fs/xfs/xfs_iwalk.c +3 -8
@@ -377,11 +377,8 @@ xfs_iwalk_run_callbacks(if (!has_more)return 0 ; -if (iwag->drop_trans) { - error =xfs_trans_alloc_empty (mp, &iwag->tp); -if (error) -return error; - } +if (iwag->drop_trans) + iwag->tp =xfs_trans_alloc_empty (mp);/* ...and recreate the cursor just past where we left off. */ error =xfs_ialloc_read_agi (iwag->pag, iwag->tp,0 , agi_bpp);
@@ -617,9 +614,7 @@ xfs_iwalk_ag_work(* Grab an empty transaction so that we can use its recursive buffer * locking abilities to detect cycles in the inobt without deadlocking. */ - error =xfs_trans_alloc_empty (mp, &iwag->tp); -if (error) - goto out; + iwag->tp =xfs_trans_alloc_empty (mp); iwag->drop_trans =1 ; error =xfs_iwalk_ag (iwag);
fs/xfs/xfs_notify_failure.c +1 -4
@@ -279,10 +279,7 @@ xfs_dax_notify_dev_failure( kernel_frozen =xfs_dax_notify_failure_freeze (mp) ==0 ; } - error =xfs_trans_alloc_empty (mp, &tp); -if (error) - goto out; - + tp =xfs_trans_alloc_empty (mp); start_gno =xfs_fsb_to_gno (mp, start_bno, type); end_gno =xfs_fsb_to_gno (mp, end_bno, type);while ((xg =xfs_group_next_range (mp, xg, start_gno, end_gno, type))) {
fs/xfs/xfs_qm.c +2 -8
@@ -660,10 +660,7 @@ xfs_qm_load_metadir_qinos(struct xfs_trans *tp;int error; - error =xfs_trans_alloc_empty (mp, &tp); -if (error) -return error; - + tp =xfs_trans_alloc_empty (mp); error =xfs_dqinode_load_parent (tp, &qi->qi_dirip);if (error == -ENOENT ) {/* no quota dir directory, but we'll create one later */
@@ -1755,10 +1752,7 @@ xfs_qm_qino_load(struct xfs_inode *dp =NULL ;int error; - error =xfs_trans_alloc_empty (mp, &tp); -if (error) -return error; - + tp =xfs_trans_alloc_empty (mp);if (xfs_has_metadir (mp)) { error =xfs_dqinode_load_parent (tp, &dp);if (error)
fs/xfs/xfs_rtalloc.c +3 -10
@@ -729,9 +729,7 @@ xfs_rtginode_ensure(if (rtg->rtg_inodes[type])return 0 ; - error =xfs_trans_alloc_empty (rtg_mount (rtg), &tp); -if (error) -return error; + tp =xfs_trans_alloc_empty (rtg_mount (rtg)); error =xfs_rtginode_load (rtg, type, tp);xfs_trans_cancel (tp);
@@ -1305,9 +1303,7 @@ xfs_growfs_rt_prep_groups(if (!mp->m_rtdirip) {struct xfs_trans *tp; - error =xfs_trans_alloc_empty (mp, &tp); -if (error) -return error; + tp =xfs_trans_alloc_empty (mp); error =xfs_rtginode_load_parent (tp);xfs_trans_cancel (tp);
@@ -1674,10 +1670,7 @@ xfs_rtmount_inodes(struct xfs_rtgroup *rtg =NULL ;int error; - error =xfs_trans_alloc_empty (mp, &tp); -if (error) -return error; - + tp =xfs_trans_alloc_empty (mp);if (xfs_has_rtgroups (mp) && mp->m_sb.sb_rgcount >0 ) { error =xfs_rtginode_load_parent (tp);if (error)
fs/xfs/xfs_trans.c +3 -5
@@ -329,13 +329,11 @@ retry:* where we can be grabbing buffers at the same time that freeze is trying to * drain the buffer LRU list. */ -int +struct xfs_trans *xfs_trans_alloc_empty ( -struct xfs_mount *mp, -struct xfs_trans **tpp) +struct xfs_mount *mp) { - *tpp =__xfs_trans_alloc (mp,XFS_TRANS_NO_WRITECOUNT ); -return 0 ; +return __xfs_trans_alloc (mp,XFS_TRANS_NO_WRITECOUNT ); }/*
fs/xfs/xfs_trans.h +1 -2
@@ -168,8 +168,7 @@ int xfs_trans_alloc(struct xfs_mount *m struct xfs_trans **tpp);int xfs_trans_reserve_more (struct xfs_trans *tp,unsigned int blocks,unsigned int rtextents); -int xfs_trans_alloc_empty (struct xfs_mount *mp, -struct xfs_trans **tpp); +struct xfs_trans *xfs_trans_alloc_empty (struct xfs_mount *mp);void xfs_trans_mod_sb (xfs_trans_t *,uint ,int64_t ); int xfs_trans_get_buf_map(struct xfs_trans *tp, struct xfs_buftarg *target,
fs/xfs/xfs_zone_gc.c +1 -4
@@ -328,10 +328,7 @@ xfs_zone_gc_query( iter->rec_idx =0 ; iter->rec_count =0 ; - error =xfs_trans_alloc_empty (mp, &tp); -if (error) -return error; - + tp =xfs_trans_alloc_empty (mp);xfs_rtgroup_lock (rtg,XFS_RTGLOCK_RMAP ); cur =xfs_rtrmapbt_init_cursor (tp, rtg); error = xfs_rmap_query_range(cur, &ri_low, &ri_high,
Greg Kroah-Hartman
maintainerPATCH 224/457 xfs: improve the comments in xfs_select_zone_nowait
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit 60e02f956d77af31b85ed4e73abf85d5f12d0a98 ]
The top of the function comment is outdated, and the parts still correct duplicate information in comment inside the function. Remove the top of the function comment and instead improve a comment inside the function.
Stable-dep-of: d2845519b072 ("xfs: fully decouple XFS_IBULK* flags from XFS_IWALK* flags")
--- fs/xfs/xfs_zone_alloc.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
fs/xfs/xfs_zone_alloc.c +2 -8
@@ -654,13 +654,6 @@ static inline bool xfs_zoned_pack_tight( !(ip->i_diflags &XFS_DIFLAG_APPEND ); } -/* -* Pick a new zone for writes. -* -* If we aren't using up our budget of open zones just open a new one from the -* freelist. Else try to find one that matches the expected data lifetime. If -* we don't find one that is good pick any zone that is available. -*/ static struct xfs_open_zone * xfs_select_zone_nowait( struct xfs_mount *mp,
@@ -688,7 +681,8 @@ xfs_select_zone_nowait( goto out_unlock;/* -* See if we can open a new zone and use that. +* See if we can open a new zone and use that so that data for different +* files is mixed as little as possible. */ oz =xfs_try_open_zone (mp, write_hint);if (oz)
Greg Kroah-Hartman
maintainerPATCH 225/457 xfs: fully decouple XFS_IBULK* flags from XFS_IWALK* flags
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit d2845519b0723c5d5a0266cbf410495f9b8fd65c ]
Fix up xfs_inumbers to now pass in the XFS_IBULK* flags into the flags argument to xfs_inobt_walk, which expects the XFS_IWALK* flags.
Currently passing the wrong flags works for non-debug builds because the only XFS_IWALK* flag has the same encoding as the corresponding XFS_IBULK* flag, but in debug builds it can trigger an assert that no incorrect flag is passed. Instead just extra the relevant flag.
--- fs/xfs/xfs_itable.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/xfs/xfs_itable.c +5 -1
@@ -447,17 +447,21 @@ xfs_inumbers( .breq = breq, };struct xfs_trans *tp; +unsigned int iwalk_flags =0 ;int error =0 ;if (xfs_bulkstat_already_done (breq->mp, breq->startino))return 0 ; +if (breq->flags &XFS_IBULK_SAME_AG ) + iwalk_flags |=XFS_IWALK_SAME_AG ; +/* * Grab an empty transaction so that we can use its recursive buffer * locking abilities to detect cycles in the inobt without deadlocking. */ tp =xfs_trans_alloc_empty (breq->mp); - error =xfs_inobt_walk (breq->mp, tp, breq->startino, breq->flags, + error =xfs_inobt_walk (breq->mp, tp, breq->startino, iwalk_flags, xfs_inumbers_walk, breq->icount, &ic);xfs_trans_cancel (tp);
Greg Kroah-Hartman
maintainerPATCH 226/457 xfs: Remove unused label in xfs_dax_notify_dev_failure
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alan Huang <[email protected]>
[ Upstream commit 8c10b04f9fc1760cb79068073686d8866e59d40f ]
--- fs/xfs/xfs_notify_failure.c | 1 - 1 file changed, 1 deletion(-)
fs/xfs/xfs_notify_failure.c +0 -1
@@ -350,7 +350,6 @@ xfs_dax_notify_dev_failure( error = -EFSCORRUPTED ; } -out:/* Thaw the fs if it has been frozen before. */ if (mf_flags &MF_MEM_PRE_REMOVE )xfs_dax_notify_failure_thaw (mp, kernel_frozen);
Greg Kroah-Hartman
maintainerPATCH 227/457 erofs: fix build error with CONFIG_EROFS_FS_ZIP_ACCEL=y
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bo Liu (OpenAnolis) <[email protected]>
commit 5e0bf36fd156b8d9b09f8481ee6daa6cdba1b064 upstream.
fix build err:
ld.lld: error: undefined symbol: crypto_req_done
referenced by decompressor_crypto.c
fs/erofs/decompressor_crypto.o:(z_erofs_crypto_decompress) in archive vmlinux.a
referenced by decompressor_crypto.c
fs/erofs/decompressor_crypto.o:(z_erofs_crypto_decompress) in archive vmlinux.a
ld.lld: error: undefined symbol: crypto_acomp_decompress
referenced by decompressor_crypto.c
fs/erofs/decompressor_crypto.o:(z_erofs_crypto_decompress) in archive vmlinux.a
ld.lld: error: undefined symbol: crypto_alloc_acomp
referenced by decompressor_crypto.c
fs/erofs/decompressor_crypto.o:(z_erofs_crypto_enable_engine) in archive vmlinux.a
--- fs/erofs/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
fs/erofs/Kconfig +2 -0
@@ -147,6 +147,8 @@ config EROFS_FS_ZIP_ZSTD config EROFS_FS_ZIP_ACCEL bool "EROFS hardware decompression support" depends on EROFS_FS_ZIP + select CRYPTO + select CRYPTO_DEFLATE help Saying Y here includes hardware accelerator support for reading EROFS file systems containing compressed data. It gives better
Greg Kroah-Hartman
maintainerPATCH 228/457 erofs: Do not select tristate symbols from bool symbols
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <[email protected]>
commit 74da24f0ac9b8aabfb8d7feeba6c32ddff3065e0 upstream.
The EROFS filesystem has many configurable options, controlled through boolean Kconfig symbols. When enabled, these options may need to enable additional library functionality elsewhere. Currently this is done by selecting the symbol for the additional functionality. However, if EROFS_FS itself is modular, and the target symbol is a tristate symbol, the additional functionality is always forced built-in.
Selecting tristate symbols from a tristate symbol does keep modular transitivity. Hence fix this by moving selects of tristate symbols to the main EROFS_FS symbol.
--- fs/erofs/Kconfig | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
fs/erofs/Kconfig +10 -10
@@ -3,8 +3,18 @@ config EROFS_FS tristate "EROFS filesystem support" depends on BLOCK + select CACHEFILES if EROFS_FS_ONDEMAND select CRC32 + select CRYPTO if EROFS_FS_ZIP_ACCEL + select CRYPTO_DEFLATE if EROFS_FS_ZIP_ACCEL select FS_IOMAP + select LZ4_DECOMPRESS if EROFS_FS_ZIP + select NETFS_SUPPORT if EROFS_FS_ONDEMAND + select XXHASH if EROFS_FS_XATTR + select XZ_DEC if EROFS_FS_ZIP_LZMA + select XZ_DEC_MICROLZMA if EROFS_FS_ZIP_LZMA + select ZLIB_INFLATE if EROFS_FS_ZIP_DEFLATE + select ZSTD_DECOMPRESS if EROFS_FS_ZIP_ZSTD help EROFS (Enhanced Read-Only File System) is a lightweight read-only file system with modern designs (e.g. no buffer heads, inline
@@ -38,7 +48,6 @@ config EROFS_FS_DEBUG config EROFS_FS_XATTR bool "EROFS extended attributes" depends on EROFS_FS - select XXHASH default y help Extended attributes are name:value pairs associated with inodes by
@@ -94,7 +103,6 @@ config EROFS_FS_BACKED_BY_FILE config EROFS_FS_ZIP bool "EROFS Data Compression Support" depends on EROFS_FS - select LZ4_DECOMPRESS default y help Enable transparent compression support for EROFS file systems.
@@ -104,8 +112,6 @@ config EROFS_FS_ZIP config EROFS_FS_ZIP_LZMA bool "EROFS LZMA compressed data support" depends on EROFS_FS_ZIP - select XZ_DEC - select XZ_DEC_MICROLZMA help Saying Y here includes support for reading EROFS file systems containing LZMA compressed data, specifically called microLZMA. It
@@ -117,7 +123,6 @@ config EROFS_FS_ZIP_LZMA config EROFS_FS_ZIP_DEFLATE bool "EROFS DEFLATE compressed data support" depends on EROFS_FS_ZIP - select ZLIB_INFLATE help Saying Y here includes support for reading EROFS file systems containing DEFLATE compressed data. It gives better compression
@@ -132,7 +137,6 @@ config EROFS_FS_ZIP_DEFLATE config EROFS_FS_ZIP_ZSTD bool "EROFS Zstandard compressed data support" depends on EROFS_FS_ZIP - select ZSTD_DECOMPRESS help Saying Y here includes support for reading EROFS file systems containing Zstandard compressed data. It gives better compression
@@ -147,8 +151,6 @@ config EROFS_FS_ZIP_ZSTD config EROFS_FS_ZIP_ACCEL bool "EROFS hardware decompression support" depends on EROFS_FS_ZIP - select CRYPTO - select CRYPTO_DEFLATE help Saying Y here includes hardware accelerator support for reading EROFS file systems containing compressed data. It gives better
@@ -163,9 +165,7 @@ config EROFS_FS_ZIP_ACCEL config EROFS_FS_ONDEMAND bool "EROFS fscache-based on-demand read support (deprecated)" depends on EROFS_FS - select NETFS_SUPPORT select FSCACHE - select CACHEFILES select CACHEFILES_ONDEMAND help This permits EROFS to use fscache-backed data blobs with on-demand
Greg Kroah-Hartman
maintainerPATCH 229/457 crypto: acomp - Fix CFI failure due to type punning
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit 962ddc5a7a4b04c007bba0f3e7298cda13c62efd upstream.
To avoid a crash when control flow integrity is enabled, make the workspace ("stream") free function use a consistent type, and call it through a function pointer that has that same type.
[Giovanni: Backport to 6.16.y. Removed logic in crypto/zstd.c as commit f5ad93ffb541 ("crypto: zstd - convert to acomp") is not going to be backported to stable.]
--- crypto/deflate.c | 7 ++++++- include/crypto/internal/acompress.h | 5 +---- 2 files changed, 7 insertions(+), 5 deletions(-)
crypto/deflate.c +6 -1
@@ -48,9 +48,14 @@ static void *deflate_alloc_stream(void)return ctx; } +static void deflate_free_stream (void *ctx) +{ +kvfree (ctx); +} +static struct crypto_acomp_streams deflate_streams = { .alloc_ctx = deflate_alloc_stream, - .cfree_ctx = kvfree, + .free_ctx = deflate_free_stream, }; static int deflate_compress_one(struct acomp_req *req,
include/crypto/internal/acompress.h +1 -4
@@ -63,10 +63,7 @@ struct crypto_acomp_stream {struct crypto_acomp_streams {/* These must come first because of struct scomp_alg. */ void *(*alloc_ctx)(void ); -union { -void (*free_ctx)(void *); -void (*cfree_ctx)(const void *); - }; +void (*free_ctx)(void *);struct crypto_acomp_stream __percpu *streams;struct work_struct stream_work;
Greg Kroah-Hartman
maintainerPATCH 230/457 iommu/riscv: prevent NULL deref in iova_to_phys
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: XianLiang Huang <[email protected]>
commit 99d4d1a070870aa08163af8ce0522992b7f35d8c upstream.
The riscv_iommu_pte_fetch() function returns either NULL for unmapped/never-mapped iova, or a valid leaf pte pointer that requires no further validation.
riscv_iommu_iova_to_phys() failed to handle NULL returns. Prevent null pointer dereference in riscv_iommu_iova_to_phys(), and remove the pte validation.
--- drivers/iommu/riscv/iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/riscv/iommu.c +1 -1
@@ -1283,7 +1283,7 @@ static phys_addr_t riscv_iommu_iova_to_punsigned long *ptr; ptr =riscv_iommu_pte_fetch (domain, iova, &pte_size); -if (_io_pte_none (*ptr) || !_io_pte_present (*ptr)) +if (!ptr)return 0 ;return pfn_to_phys (__page_val_to_pfn (*ptr)) | (iova & (pte_size -1 ));
Greg Kroah-Hartman
maintainerPATCH 231/457 io_uring/futex: ensure io_futex_wait() cleans up properly on failure
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
commit 508c1314b342b78591f51c4b5dadee31a88335df upstream.
The io_futex_data is allocated upfront and assigned to the io_kiocb async_data field, but the request isn't marked with REQ_F_ASYNC_DATA at that point. Those two should always go together, as the flag tells io_uring whether the field is valid or not.
Additionally, on failure cleanup, the futex handler frees the data but does not clear ->async_data. Clear the data and the flag in the error path as well.
Thanks to Trend Micro Zero Day Initiative and particularly ReDress for reporting this.
--- io_uring/futex.c | 3 +++ 1 file changed, 3 insertions(+)
io_uring/futex.c +3 -0
@@ -288,6 +288,7 @@ int io_futex_wait(struct io_kiocb *req, goto done_unlock; } + req->flags |=REQ_F_ASYNC_DATA ; req->async_data = ifd; ifd->q = futex_q_init; ifd->q.bitset = iof->futex_mask;
@@ -309,6 +310,8 @@ done:if (ret <0 )req_set_fail (req);io_req_set_res (req, ret,0 ); + req->async_data =NULL ; + req->flags &= ~REQ_F_ASYNC_DATA ;kfree (ifd);return IOU_COMPLETE ; }
Greg Kroah-Hartman
maintainerPATCH 232/457 iov_iter: iterate_folioq: fix handling of offset >= folio size
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dominique Martinet <[email protected]>
commit 808471ddb0fa785559c3e7aee59be20a13b46ef5 upstream.
It's apparently possible to get an iov advanced all the way up to the end of the current page we're looking at, e.g.
(gdb) p *iter
$24 = {iter_type = 4 '\004', nofault = false, data_source = false, iov_offset = 4096, {__ubuf_iovec = {
iov_base = 0xffff88800f5bc000, iov_len = 655}, {{__iov = 0xffff88800f5bc000, kvec = 0xffff88800f5bc000,
bvec = 0xffff88800f5bc000, folioq = 0xffff88800f5bc000, xarray = 0xffff88800f5bc000,
ubuf = 0xffff88800f5bc000}, count = 655}}, {nr_segs = 2, folioq_slot = 2 '\002', xarray_start = 2}}Where iov_offset is 4k with 4k-sized folios
This should have been fine because we're only in the 2nd slot and there's another one after this, but iterate_folioq should not try to map a folio that skips the whole size, and more importantly part here does not end up zero (because 'PAGE_SIZE - skip % PAGE_SIZE' ends up PAGE_SIZE and not zero..), so skip forward to the "advance to next folio" code
--- include/linux/iov_iter.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
include/linux/iov_iter.h +11 -9
@@ -160,7 +160,7 @@ size_t iterate_folioq(struct iov_iter *i do { struct folio *folio = folioq_folio(folioq, slot); - size_t part, remain, consumed; + size_t part, remain = 0, consumed; size_t fsize; void *base;
@@ -168,14 +168,16 @@ size_t iterate_folioq(struct iov_iter *ibreak ; fsize =folioq_folio_size (folioq, slot); - base =kmap_local_folio (folio, skip); - part =umin (len,PAGE_SIZE - skip %PAGE_SIZE ); - remain =step (base, progress, part, priv, priv2); -kunmap_local (base); - consumed = part - remain; - len -= consumed; - progress += consumed; - skip += consumed; +if (skip < fsize) { + base =kmap_local_folio (folio, skip); + part =umin (len,PAGE_SIZE - skip %PAGE_SIZE ); + remain =step (base, progress, part, priv, priv2); +kunmap_local (base); + consumed = part - remain; + len -= consumed; + progress += consumed; + skip += consumed; + }if (skip >= fsize) { skip =0 ; slot++;
Greg Kroah-Hartman
maintainerPATCH 233/457 iommu/arm-smmu-v3: Fix smmu_domain->nr_ats_masters decrement
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolin Chen <[email protected]>
commit 685ca577b408ffd9c5a4057a2acc0cd3e6978b36 upstream.
The arm_smmu_attach_commit() updates master->ats_enabled before calling arm_smmu_remove_master_domain() that is supposed to clean up everything in the old domain, including the old domain's nr_ats_masters. So, it is supposed to use the old ats_enabled state of the device, not an updated state.
This isn't a problem if switching between two domains where:
- old ats_enabled = false; new ats_enabled = false
- old ats_enabled = true; new ats_enabled = true
but can fail cases where:
- old ats_enabled = false; new ats_enabled = true
(old domain should keep the counter but incorrectly decreased it)
- old ats_enabled = true; new ats_enabled = false
(old domain needed to decrease the counter but incorrectly missed it)
Update master->ats_enabled after arm_smmu_remove_master_domain() to fix this.
--- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +1 -1
@@ -2997,9 +2997,9 @@ void arm_smmu_attach_commit(struct arm_s/* ATS is being switched off, invalidate the entire ATC */ arm_smmu_atc_inv_master (master,IOMMU_NO_PASID ); } - master->ats_enabled = state->ats_enabled;arm_smmu_remove_master_domain (master, state->old_domain, state->ssid); + master->ats_enabled = state->ats_enabled; }static int arm_smmu_attach_dev (struct iommu_domain *domain,struct device *dev)
Greg Kroah-Hartman
maintainerPATCH 234/457 mm/damon/core: fix commit_ops_filters by using correct nth function
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Heon Jeon <[email protected]>
commit 63f5dec16760f2cd7d3f9034d18fc1fa0d83652f upstream.
damos_commit_ops_filters() incorrectly uses damos_nth_filter() which iterates core_filters. As a result, performing a commit unintentionally corrupts ops_filters.
Add damos_nth_ops_filter() which iterates ops_filters. Use this function to fix issues caused by wrong iteration.
--- mm/damon/core.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
mm/damon/core.c +13 -1
@@ -843,6 +843,18 @@ static struct damos_filter *damos_nth_fireturn NULL ; } +static struct damos_filter *damos_nth_ops_filter (int n,struct damos *s) +{ +struct damos_filter *filter; +int i =0 ; + +damos_for_each_ops_filter (filter, s) { +if (i++ == n) +return filter; + } +return NULL ; +} +static void damos_commit_filter_arg (struct damos_filter *dst,struct damos_filter *src) {
@@ -906,7 +918,7 @@ static int damos_commit_ops_filters(struint i =0 , j =0 ;damos_for_each_ops_filter_safe (dst_filter, next, dst) { - src_filter =damos_nth_filter (i++, src); + src_filter =damos_nth_ops_filter (i++, src);if (src_filter)damos_commit_filter (dst_filter, src_filter);else
Greg Kroah-Hartman
maintainerPATCH 235/457 mmc: sdhci-of-arasan: Ensure CD logic stabilization before power-up
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sai Krishna Potthuri <[email protected]>
commit e251709aaddb3ee1e8ac1ed5e361a608a1cc92de upstream.
During SD suspend/resume without a full card rescan (when using non-removable SD cards for rootfs), the SD card initialization may fail after resume. This occurs because, after a host controller reset, the card detect logic may take time to stabilize due to debounce logic. Without waiting for stabilization, the host may attempt powering up the card prematurely, leading to command timeouts during resume flow. Add sdhci_arasan_set_power_and_bus_voltage() to wait for the card detect stable bit before power up the card. Since the stabilization time is not fixed, a maximum timeout of one second is used to ensure sufficient wait time for the card detect signal to stabilize.
--- drivers/mmc/host/sdhci-of-arasan.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)
drivers/mmc/host/sdhci-of-arasan.c +31 -2
@@ -99,6 +99,9 @@#define HIWORD_UPDATE (val, mask, shift) \ ((val) << (shift) | (mask) << ((shift) + 16)) +#define CD_STABLE_TIMEOUT_US 1000000 +#define CD_STABLE_MAX_SLEEP_US 10 +/** * struct sdhci_arasan_soc_ctl_field - Field used in sdhci_arasan_soc_ctl_map *
@@ -206,12 +209,15 @@ struct sdhci_arasan_data {* 19MHz instead */ #define SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN BIT(2) +/* Enable CD stable check before power-up */ +#define SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE BIT(3) };struct sdhci_arasan_of_data {const struct sdhci_arasan_soc_ctl_map *soc_ctl_map;const struct sdhci_pltfm_data *pdata;const struct sdhci_arasan_clk_ops *clk_ops; +u32 quirks; };static const struct sdhci_arasan_soc_ctl_map rk3399_soc_ctl_map = {
@@ -514,6 +520,24 @@ static int sdhci_arasan_voltage_switch(sreturn -EINVAL ; } +static void sdhci_arasan_set_power_and_bus_voltage (struct sdhci_host *host,unsigned char mode, +unsigned short vdd) +{ +struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host); +struct sdhci_arasan_data *sdhci_arasan =sdhci_pltfm_priv (pltfm_host); +u32 reg; + +/* +* Ensure that the card detect logic has stabilized before powering up, this is +* necessary after a host controller reset. +*/ +if (mode ==MMC_POWER_UP && sdhci_arasan->quirks &SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE ) +read_poll_timeout (sdhci_readl, reg, reg &SDHCI_CD_STABLE ,CD_STABLE_MAX_SLEEP_US , +CD_STABLE_TIMEOUT_US , false, host,SDHCI_PRESENT_STATE ); + +sdhci_set_power_and_bus_voltage (host, mode, vdd); +} +static const struct sdhci_ops sdhci_arasan_ops = { .set_clock = sdhci_arasan_set_clock, .get_max_clock = sdhci_pltfm_clk_get_max_clock,
@@ -521,7 +545,7 @@ static const struct sdhci_ops sdhci_aras .set_bus_width = sdhci_set_bus_width, .reset = sdhci_arasan_reset, .set_uhs_signaling = sdhci_set_uhs_signaling, - .set_power = sdhci_set_power_and_bus_voltage, + .set_power = sdhci_arasan_set_power_and_bus_voltage, .hw_reset = sdhci_arasan_hw_reset, };
@@ -570,7 +594,7 @@ static const struct sdhci_ops sdhci_aras .set_bus_width = sdhci_set_bus_width, .reset = sdhci_arasan_reset, .set_uhs_signaling = sdhci_set_uhs_signaling, - .set_power = sdhci_set_power_and_bus_voltage, + .set_power = sdhci_arasan_set_power_and_bus_voltage, .irq = sdhci_arasan_cqhci_irq, };
@@ -1447,6 +1471,7 @@ static const struct sdhci_arasan_clk_opsstatic struct sdhci_arasan_of_data sdhci_arasan_zynqmp_data = { .pdata = &sdhci_arasan_zynqmp_pdata, .clk_ops = &zynqmp_clk_ops, + .quirks =SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE , };static const struct sdhci_arasan_clk_ops versal_clk_ops = {
@@ -1457,6 +1482,7 @@ static const struct sdhci_arasan_clk_opsstatic struct sdhci_arasan_of_data sdhci_arasan_versal_data = { .pdata = &sdhci_arasan_zynqmp_pdata, .clk_ops = &versal_clk_ops, + .quirks =SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE , };static const struct sdhci_arasan_clk_ops versal_net_clk_ops = {
@@ -1467,6 +1493,7 @@ static const struct sdhci_arasan_clk_opsstatic struct sdhci_arasan_of_data sdhci_arasan_versal_net_data = { .pdata = &sdhci_arasan_versal_net_pdata, .clk_ops = &versal_net_clk_ops, + .quirks =SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE , };static struct sdhci_arasan_of_data intel_keembay_emmc_data = {
@@ -1945,6 +1972,8 @@ static int sdhci_arasan_probe(struct plaif (of_device_is_compatible (np,"rockchip,rk3399-sdhci-5.1" ))sdhci_arasan_update_clockmultiplier (host,0x0 ); + sdhci_arasan->quirks |= data->quirks; +if (of_device_is_compatible (np,"intel,keembay-sdhci-5.1-emmc" ) ||of_device_is_compatible (np,"intel,keembay-sdhci-5.1-sd" ) ||of_device_is_compatible (np,"intel,keembay-sdhci-5.1-sdio" )) {
Greg Kroah-Hartman
maintainerPATCH 236/457 mmc: sdhci-pci-gli: Add a new function to simplify the code
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Shih <[email protected]>
commit dec8b38be4b35cae5f7fa086daf2631e2cfa09c1 upstream.
In preparation to fix replay timer timeout, add sdhci_gli_mask_replay_timer_timeout() function to simplify some of the code, allowing it to be re-used.
--- drivers/mmc/host/sdhci-pci-gli.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)
drivers/mmc/host/sdhci-pci-gli.c +16 -14
@@ -287,6 +287,20 @@#define GLI_MAX_TUNING_LOOP 40/* Genesys Logic chipset */ +static void sdhci_gli_mask_replay_timer_timeout (struct pci_dev *pdev) +{ +int aer; +u32 value; + +/* mask the replay timer timeout of AER */ + aer =pci_find_ext_capability (pdev,PCI_EXT_CAP_ID_ERR ); +if (aer) { +pci_read_config_dword (pdev, aer +PCI_ERR_COR_MASK , &value); + value |=PCI_ERR_COR_REP_TIMER ; +pci_write_config_dword (pdev, aer +PCI_ERR_COR_MASK , value); + } +} +static inline void gl9750_wt_on (struct sdhci_host *host) {u32 wt_value;
@@ -607,7 +621,6 @@ static void gl9750_hw_setting(struct sdh {struct sdhci_pci_slot *slot =sdhci_priv (host);struct pci_dev *pdev; -int aer;u32 value; pdev = slot->chip->pdev;
@@ -626,12 +639,7 @@ static void gl9750_hw_setting(struct sdhpci_set_power_state (pdev,PCI_D0 );/* mask the replay timer timeout of AER */ - aer =pci_find_ext_capability (pdev,PCI_EXT_CAP_ID_ERR ); -if (aer) { -pci_read_config_dword (pdev, aer +PCI_ERR_COR_MASK , &value); - value |=PCI_ERR_COR_REP_TIMER ; -pci_write_config_dword (pdev, aer +PCI_ERR_COR_MASK , value); - } +sdhci_gli_mask_replay_timer_timeout (pdev);gl9750_wt_off (host); }
@@ -806,7 +814,6 @@ static void sdhci_gl9755_set_clock(strucstatic void gl9755_hw_setting (struct sdhci_pci_slot *slot) {struct pci_dev *pdev = slot->chip->pdev; -int aer;u32 value;gl9755_wt_on (pdev);
@@ -841,12 +848,7 @@ static void gl9755_hw_setting(struct sdhpci_set_power_state (pdev,PCI_D0 );/* mask the replay timer timeout of AER */ - aer =pci_find_ext_capability (pdev,PCI_EXT_CAP_ID_ERR ); -if (aer) { -pci_read_config_dword (pdev, aer +PCI_ERR_COR_MASK , &value); - value |=PCI_ERR_COR_REP_TIMER ; -pci_write_config_dword (pdev, aer +PCI_ERR_COR_MASK , value); - } +sdhci_gli_mask_replay_timer_timeout (pdev);gl9755_wt_off (pdev); }
Greg Kroah-Hartman
maintainerPATCH 237/457 kho: init new_physxa->phys_bits to fix lockdep
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pasha Tatashin <[email protected]>
commit 63b17b653df30e90f95338083cb44c35d64bcae4 upstream.
Patch series "Several KHO Hotfixes".
Three unrelated fixes for Kexec Handover.
This patch (of 3):
Lockdep shows the following warning:
INFO: trying to register non-static key. The code is fine but needs lockdep annotation, or maybe you didn't initialize this object before use? turning off the locking correctness validator.
[<ffffffff810133a6>] dump_stack_lvl+0x66/0xa0 [<ffffffff8136012c>] assign_lock_key+0x10c/0x120 [<ffffffff81358bb4>] register_lock_class+0xf4/0x2f0 [<ffffffff813597ff>] __lock_acquire+0x7f/0x2c40 [<ffffffff81360cb0>] ? __pfx_hlock_conflict+0x10/0x10 [<ffffffff811707be>] ? native_flush_tlb_global+0x8e/0xa0 [<ffffffff8117096e>] ? __flush_tlb_all+0x4e/0xa0 [<ffffffff81172fc2>] ? __kernel_map_pages+0x112/0x140 [<ffffffff813ec327>] ? xa_load_or_alloc+0x67/0xe0 [<ffffffff81359556>] lock_acquire+0xe6/0x280 [<ffffffff813ec327>] ? xa_load_or_alloc+0x67/0xe0 [<ffffffff8100b9e0>] _raw_spin_lock+0x30/0x40 [<ffffffff813ec327>] ? xa_load_or_alloc+0x67/0xe0 [<ffffffff813ec327>] xa_load_or_alloc+0x67/0xe0 [<ffffffff813eb4c0>] kho_preserve_folio+0x90/0x100 [<ffffffff813ebb7f>] __kho_finalize+0xcf/0x400 [<ffffffff813ebef4>] kho_finalize+0x34/0x70
This is becase xa has its own lock, that is not initialized in xa_load_or_alloc.
Modifiy __kho_preserve_order(), to properly callxa_init(&new_physxa->phys_bits);
--- kernel/kexec_handover.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-)
kernel/kexec_handover.c +24 -4
@@ -144,14 +144,34 @@ static int __kho_preserve_order(struct kho_mem_track *track, unsigned long pfn, unsigned int order) {struct kho_mem_phys_bits *bits; -struct kho_mem_phys *physxa; +struct kho_mem_phys *physxa, *new_physxa;const unsigned long pfn_high = pfn >> order;might_sleep (); - physxa =xa_load_or_alloc (&track->orders, order,sizeof (*physxa)); -if (IS_ERR (physxa)) -return PTR_ERR (physxa); + physxa =xa_load (&track->orders, order); +if (!physxa) { +int err; + + new_physxa =kzalloc (sizeof (*physxa),GFP_KERNEL ); +if (!new_physxa) +return -ENOMEM ; + +xa_init (&new_physxa->phys_bits); + physxa =xa_cmpxchg (&track->orders, order,NULL , new_physxa, +GFP_KERNEL ); + + err =xa_err (physxa); +if (err || physxa) { +xa_destroy (&new_physxa->phys_bits); +kfree (new_physxa); + +if (err) +return err; + }else { + physxa = new_physxa; + } + } bits =xa_load_or_alloc (&physxa->phys_bits, pfn_high /PRESERVE_BITS ,sizeof (*bits));
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 238/457 kho: mm: dont allow deferred struct page with KHO
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pasha Tatashin <[email protected]>
commit 8b66ed2c3f42cc462e05704af6b94e6a7bad2f5e upstream.
KHO uses struct pages for the preserved memory early in boot, however, with deferred struct page initialization, only a small portion of memory has properly initialized struct pages.
This problem was detected where vmemmap is poisoned, and illegal flag combinations are detected.
Don't allow them to be enabled together, and later we will have to teach KHO to work properly with deferred struct page init kernel feature.
--- kernel/Kconfig.kexec | 1 + 1 file changed, 1 insertion(+)
kernel/Kconfig.kexec +1 -0
@@ -97,6 +97,7 @@ config KEXEC_JUMP config KEXEC_HANDOVER bool "kexec handover" depends on ARCH_SUPPORTS_KEXEC_HANDOVER && ARCH_SUPPORTS_KEXEC_FILE + depends on !DEFERRED_STRUCT_PAGE_INIT select MEMBLOCK_KHO_SCRATCH select KEXEC_FILE select DEBUG_FS
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 239/457 kho: warn if KHO is disabled due to an error
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pasha Tatashin <[email protected]>
commit 44958f2025ed3f29fc3e93bb1f6c16121d7847ad upstream.
During boot scratch area is allocated based on command line parameters or auto calculated. However, scratch area may fail to allocate, and in that case KHO is disabled. Currently, no warning is printed that KHO is disabled, which makes it confusing for the end user to figure out why KHO is not available. Add the missing warning message.
--- kernel/kexec_handover.c | 1 + 1 file changed, 1 insertion(+)
kernel/kexec_handover.c +1 -0
@@ -564,6 +564,7 @@ err_free_scratch_areas: err_free_scratch_desc:memblock_free (kho_scratch, kho_scratch_cnt *sizeof (*kho_scratch)); err_disable_kho: +pr_warn ("Failed to reserve scratch area, disabling kexec handover\n" ); kho_enable = false; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 240/457 memstick: Fix deadlock by moving removing flag earlier
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayi Li <[email protected]>
commit 99d7ab8db9d8230b243f5ed20ba0229e54cc0dfa upstream.
The existing memstick core patch: commit 62c59a8786e6 ("memstick: Skip allocating card when removing host") sets host->removing in memstick_remove_host(),but still exists a critical time window where memstick_check can run after host->eject is set but before removing is set.
In the rtsx_usb_ms driver, the problematic sequence is:
rtsx_usb_ms_drv_remove: memstick_check:
host->eject = true
cancel_work_sync(handle_req) if(!host->removing)
... memstick_alloc_card()
memstick_set_rw_addr()
memstick_new_req()
rtsx_usb_ms_request()
if(!host->eject)
skip schedule_work
wait_for_completion()
memstick_remove_host: [blocks indefinitely]
host->removing = true
flush_workqueue()
[block]1. rtsx_usb_ms_drv_remove sets host->eject = true
2. cancel_work_sync(&host->handle_req) runs
3. memstick_check work may be executed here <-- danger window
4. memstick_remove_host sets removing = 1
During this window (step 3), memstick_check calls memstick_alloc_card, which may indefinitely waiting for mrq_complete completion that will never occur because rtsx_usb_ms_request sees eject=true and skips scheduling work, memstick_set_rw_addr waits forever for completion.
This causes a deadlock when memstick_remove_host tries to flush_workqueue, waiting for memstick_check to complete, while memstick_check is blocked waiting for mrq_complete completion.
Fix this by setting removing=true at the start of rtsx_usb_ms_drv_remove, before any work cancellation. This ensures memstick_check will see the removing flag immediately and exit early, avoiding the deadlock.
--- drivers/memstick/core/memstick.c | 1 - drivers/memstick/host/rtsx_usb_ms.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-)
drivers/memstick/core/memstick.c +0 -1
@@ -555,7 +555,6 @@ EXPORT_SYMBOL(memstick_add_host);*/ void memstick_remove_host (struct memstick_host *host) { - host->removing =1 ;flush_workqueue (workqueue);mutex_lock (&host->lock);if (host->card)
drivers/memstick/host/rtsx_usb_ms.c +1 -0
@@ -812,6 +812,7 @@ static void rtsx_usb_ms_drv_remove(strucint err; host->eject = true; + msh->removing = true;cancel_work_sync (&host->handle_req);cancel_delayed_work_sync (&host->poll_card);
Greg Kroah-Hartman
maintainerPATCH 241/457 mmc: sdhci-pci-gli: GL9763e: Mask the replay timer timeout of AER
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Shih <[email protected]>
commit 340be332e420ed37d15d4169a1b4174e912ad6cb upstream.
Due to a flaw in the hardware design, the GL9763e replay timer frequently times out when ASPM is enabled. As a result, the warning messages will often appear in the system log when the system accesses the GL9763e PCI config. Therefore, the replay timer timeout must be masked.
--- drivers/mmc/host/sdhci-pci-gli.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/mmc/host/sdhci-pci-gli.c +3 -0
@@ -1782,6 +1782,9 @@ static void gli_set_gl9763e(struct sdhci value |=FIELD_PREP (GLI_9763E_HS400_RXDLY ,GLI_9763E_HS400_RXDLY_5 );pci_write_config_dword (pdev,PCIE_GLI_9763E_CLKRXDLY , value); +/* mask the replay timer timeout of AER */ +sdhci_gli_mask_replay_timer_timeout (pdev); +pci_read_config_dword (pdev,PCIE_GLI_9763E_VHS , &value); value &= ~GLI_9763E_VHS_REV ; value |=FIELD_PREP (GLI_9763E_VHS_REV ,GLI_9763E_VHS_REV_R );
Greg Kroah-Hartman
maintainerPATCH 242/457 mmc: sdhci-pci-gli: GL9763e: Rename the gli_set_gl9763e() for consistency
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Shih <[email protected]>
commit 293ed0f5f34e1e9df888456af4b0a021f57b5f54 upstream.
In preparation to fix replay timer timeout, rename the gli_set_gl9763e() to gl9763e_hw_setting() for consistency.
--- drivers/mmc/host/sdhci-pci-gli.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mmc/host/sdhci-pci-gli.c +2 -2
@@ -1753,7 +1753,7 @@ cleanup:return ret; } -static void gli_set_gl9763e (struct sdhci_pci_slot *slot) +static void gl9763e_hw_setting (struct sdhci_pci_slot *slot) {struct pci_dev *pdev = slot->chip->pdev;u32 value;
@@ -1928,7 +1928,7 @@ static int gli_probe_slot_gl9763e(structgli_pcie_enable_msi (slot); host->mmc_host_ops.hs400_enhanced_strobe = gl9763e_hs400_enhanced_strobe; -gli_set_gl9763e (slot); +gl9763e_hw_setting (slot);sdhci_enable_v4_mode (host);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 243/457 mmc: sdhci_am654: Disable HS400 for AM62P SR1.0 and SR1.1
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Judith Mendez <[email protected]>
commit d2d7a96b29ea6ab093973a1a37d26126db70c79f upstream.
This adds SDHCI_AM654_QUIRK_DISABLE_HS400 quirk which shall be used to disable HS400 support. AM62P SR1.0 and SR1.1 do not support HS400 due to errata i2458 [0] so disable HS400 for these SoC revisions.
[0] https://www.ti.com/lit/er/sprz574a/sprz574a.pdf
--- drivers/mmc/host/sdhci_am654.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
drivers/mmc/host/sdhci_am654.c +18 -0
@@ -156,6 +156,7 @@ struct sdhci_am654_data {#define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0)#define SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA BIT(1) +#define SDHCI_AM654_QUIRK_DISABLE_HS400 BIT(2) };struct window {
@@ -765,6 +766,7 @@ static int sdhci_am654_init(struct sdhci {struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host);struct sdhci_am654_data *sdhci_am654 =sdhci_pltfm_priv (pltfm_host); +struct device *dev =mmc_dev (host->mmc);u32 ctl_cfg_2 =0 ;u32 mask;u32 val;
@@ -820,6 +822,12 @@ static int sdhci_am654_init(struct sdhciif (ret) goto err_cleanup_host; +if (sdhci_am654->quirks &SDHCI_AM654_QUIRK_DISABLE_HS400 && + host->mmc->caps2 & (MMC_CAP2_HS400 |MMC_CAP2_HS400_ES )) { +dev_info (dev,"HS400 mode not supported on this silicon revision, disabling it\n" ); + host->mmc->caps2 &= ~(MMC_CAP2_HS400 |MMC_CAP2_HS400_ES ); + } + ret =__sdhci_add_host (host);if (ret) goto err_cleanup_host;
@@ -883,6 +891,12 @@ static int sdhci_am654_get_of_property(sreturn 0 ; } +static const struct soc_device_attribute sdhci_am654_descope_hs400[] = { + { .family ="AM62PX" , .revision ="SR1.0" }, + { .family ="AM62PX" , .revision ="SR1.1" }, + {/* sentinel */ } +}; +static const struct of_device_id sdhci_am654_of_match[] = { { .compatible ="ti,am654-sdhci-5.1" ,
@@ -975,6 +989,10 @@ static int sdhci_am654_probe(struct plat goto err_pltfm_free; } + soc =soc_device_match (sdhci_am654_descope_hs400); +if (soc) + sdhci_am654->quirks |=SDHCI_AM654_QUIRK_DISABLE_HS400 ; + host->mmc_host_ops.start_signal_voltage_switch = sdhci_am654_start_signal_voltage_switch; host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning;
Greg Kroah-Hartman
maintainerPATCH 244/457 NFS: Fix a race when updating an existing write
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit 76d2e3890fb169168c73f2e4f8375c7cc24a765e upstream.
After nfs_lock_and_join_requests() tests for whether the request is still attached to the mapping, nothing prevents a call to nfs_inode_remove_request() from succeeding until we actually lock the page group.
The reason is that whoever called nfs_inode_remove_request() doesn't necessarily have a lock on the page group head.
So in order to avoid races, let's take the page group lock earlier in nfs_lock_and_join_requests(), and hold it across the removal of the request in nfs_inode_remove_request().
--- fs/nfs/pagelist.c | 9 +++++---- fs/nfs/write.c | 29 ++++++++++------------------- include/linux/nfs_page.h | 1 + 3 files changed, 16 insertions(+), 23 deletions(-)
fs/nfs/pagelist.c +5 -4
@@ -253,13 +253,14 @@ nfs_page_group_unlock(struct nfs_page *rnfs_page_clear_headlock (req); } -/* -* nfs_page_group_sync_on_bit_locked +/** +* nfs_page_group_sync_on_bit_locked - Test if all requests have @bit set +* @req: request in page group +* @bit: PG_* bit that is used to sync page group * * must be called with page group lock held */ -static bool -nfs_page_group_sync_on_bit_locked (struct nfs_page *req,unsigned int bit) +bool nfs_page_group_sync_on_bit_locked (struct nfs_page *req,unsigned int bit) {struct nfs_page *head = req->wb_head;struct nfs_page *tmp;
fs/nfs/write.c +10 -19
@@ -153,20 +153,10 @@ nfs_page_set_inode_ref(struct nfs_page * } } -static int -nfs_cancel_remove_inode (struct nfs_page *req,struct inode *inode) +static void nfs_cancel_remove_inode (struct nfs_page *req,struct inode *inode) { -int ret; - -if (!test_bit (PG_REMOVE , &req->wb_flags)) -return 0 ; - ret =nfs_page_group_lock (req); -if (ret) -return ret;if (test_and_clear_bit (PG_REMOVE , &req->wb_flags))nfs_page_set_inode_ref (req, inode); -nfs_page_group_unlock (req); -return 0 ; }/**
@@ -585,19 +575,18 @@ retry: } } + ret =nfs_page_group_lock (head); +if (ret <0 ) + goto out_unlock; +/* Ensure that nobody removed the request before we locked it */ if (head != folio->private) { +nfs_page_group_unlock (head);nfs_unlock_and_release_request (head); goto retry; } - ret =nfs_cancel_remove_inode (head, inode); -if (ret <0 ) - goto out_unlock; - - ret =nfs_page_group_lock (head); -if (ret <0 ) - goto out_unlock; +nfs_cancel_remove_inode (head, inode);/* lock each request in the page group */ for (subreq = head->wb_this_page;
@@ -786,7 +775,8 @@ static void nfs_inode_remove_request(str {struct nfs_inode *nfsi =NFS_I (nfs_page_to_inode (req)); -if (nfs_page_group_sync_on_bit (req,PG_REMOVE )) { +nfs_page_group_lock (req); +if (nfs_page_group_sync_on_bit_locked (req,PG_REMOVE )) {struct folio *folio =nfs_page_to_folio (req->wb_head);struct address_space *mapping = folio->mapping;
@@ -798,6 +788,7 @@ static void nfs_inode_remove_request(str }spin_unlock (&mapping->i_private_lock); } +nfs_page_group_unlock (req);if (test_and_clear_bit (PG_INODE_REF , &req->wb_flags)) {atomic_long_dec (&nfsi->nrequests);
include/linux/nfs_page.h +1 -0
@@ -160,6 +160,7 @@ extern void nfs_join_page_group(struct nextern int nfs_page_group_lock (struct nfs_page *);extern void nfs_page_group_unlock (struct nfs_page *);extern bool nfs_page_group_sync_on_bit (struct nfs_page *,unsigned int ); +extern bool nfs_page_group_sync_on_bit_locked (struct nfs_page *,unsigned int );extern int nfs_page_set_headlock (struct nfs_page *req);extern void nfs_page_clear_headlock (struct nfs_page *req);extern bool nfs_async_iocounter_wait (struct rpc_task *,struct nfs_lock_context *);
Greg Kroah-Hartman
maintainerPATCH 245/457 squashfs: fix memory leak in squashfs_fill_super
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phillip Lougher <[email protected]>
commit b64700d41bdc4e9f82f1346c15a3678ebb91a89c upstream.
If sb_min_blocksize returns 0, squashfs_fill_super exits without freeing allocated memory (sb->s_fs_info).
Fix this by moving the call to sb_min_blocksize to before memory is allocated.
--- fs/squashfs/super.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
fs/squashfs/super.c +7 -7
@@ -187,10 +187,15 @@ static int squashfs_fill_super(struct suunsigned short flags;unsigned int fragments;u64 lookup_table_start, xattr_id_table_start, next_table; -int err; +int err, devblksize =sb_min_blocksize (sb,SQUASHFS_DEVBLK_SIZE );TRACE ("Entered squashfs_fill_superblock\n" ); +if (!devblksize) { +errorf (fc,"squashfs: unable to set blocksize\n" ); +return -EINVAL ; + } + sb->s_fs_info =kzalloc (sizeof (*msblk),GFP_KERNEL );if (sb->s_fs_info ==NULL ) {ERROR ("Failed to allocate squashfs_sb_info\n" );
@@ -201,12 +206,7 @@ static int squashfs_fill_super(struct su msblk->panic_on_errors = (opts->errors == Opt_errors_panic); - msblk->devblksize =sb_min_blocksize (sb,SQUASHFS_DEVBLK_SIZE ); -if (!msblk->devblksize) { -errorf (fc,"squashfs: unable to set blocksize\n" ); -return -EINVAL ; - } - + msblk->devblksize = devblksize; msblk->devblksize_log2 =ffz (~msblk->devblksize);mutex_init (&msblk->meta_index_mutex);
Greg Kroah-Hartman
maintainerPATCH 246/457 mm/damon/core: fix damos_commit_filter not changing allow
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Heon Jeon <[email protected]>
commit b3dee902b6c26b7d8031a4df19753e27dcfcba01 upstream.
Current damos_commit_filter() does not persist the allow' value of the filter. As a result, changing the allow' value of a filter and committing doesn't change the `allow' value.
Add the missing allow' value update, so committing the filter persistently changes the allow' value well.
--- mm/damon/core.c | 1 + 1 file changed, 1 insertion(+)
mm/damon/core.c +1 -0
@@ -881,6 +881,7 @@ static void damos_commit_filter( { dst->type = src->type; dst->matching = src->matching; + dst->allow = src->allow;damos_commit_filter_arg (dst, src); }
Greg Kroah-Hartman
maintainerPATCH 247/457 mm/debug_vm_pgtable: clear page table entries at destroy_args()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herton R. Krzesinski <[email protected]>
commit dde30854bddfb5d69f30022b53c5955a41088b33 upstream.
The mm/debug_vm_pagetable test allocates manually page table entries for the tests it runs, using also its manually allocated mm_struct. That in itself is ok, but when it exits, at destroy_args() it fails to clear those entries with the *_clear functions.
The problem is that leaves stale entries. If another process allocates an mm_struct with a pgd at the same address, it may end up running into the stale entry. This is happening in practice on a debug kernel with CONFIG_DEBUG_VM_PGTABLE=y, for example this is the output with some extra debugging I added (it prints a warning trace if pgtables_bytes goes negative, in addition to the warning at check_mm() function):
[ 2.539353] debug_vm_pgtable: [get_random_vaddr ]: random_vaddr is 0x7ea247140000 [ 2.539366] kmem_cache info [ 2.539374] kmem_cachep 0x000000002ce82385 - freelist 0x0000000000000000 - offset 0x508 [ 2.539447] debug_vm_pgtable: [init_args ]: args->mm is 0x000000002267cc9e (...) [ 2.552800] WARNING: CPU: 5 PID: 116 at include/linux/mm.h:2841 free_pud_range+0x8bc/0x8d0 [ 2.552816] Modules linked in: [ 2.552843] CPU: 5 UID: 0 PID: 116 Comm: modprobe Not tainted 6.12.0-105.debug_vm2.el10.ppc64le+debug #1 VOLUNTARY [ 2.552859] Hardware name: IBM,9009-41A POWER9 (architected) 0x4e0202 0xf000005 of:IBM,FW910.00 (VL910_062) hv:phyp pSeries [ 2.552872] NIP: c0000000007eef3c LR: c0000000007eef30 CTR: c0000000003d8c90 [ 2.552885] REGS: c0000000622e73b0 TRAP: 0700 Not tainted (6.12.0-105.debug_vm2.el10.ppc64le+debug) [ 2.552899] MSR: 800000000282b033 <SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE> CR: 24002822 XER: 0000000a [ 2.552954] CFAR: c0000000008f03f0 IRQMASK: 0 [ 2.552954] GPR00: c0000000007eef30 c0000000622e7650 c000000002b1ac00 0000000000000001 [ 2.552954] GPR04: 0000000000000008 0000000000000000 c0000000007eef30 ffffffffffffffff [ 2.552954] GPR08: 00000000ffff00f5 0000000000000001 0000000000000048 0000000000004000 [ 2.552954] GPR12: 00000003fa440000 c000000017ffa300 c0000000051d9f80 ffffffffffffffdb [ 2.552954] GPR16: 0000000000000000 0000000000000008 000000000000000a 60000000000000e0 [ 2.552954] GPR20: 4080000000000000 c0000000113af038 00007fffcf130000 0000700000000000 [ 2.552954] GPR24: c000000062a6a000 0000000000000001 8000000062a68000 0000000000000001 [ 2.552954] GPR28: 000000000000000a c000000062ebc600 0000000000002000 c000000062ebc760 [ 2.553170] NIP [c0000000007eef3c] free_pud_range+0x8bc/0x8d0 [ 2.553185] LR [c0000000007eef30] free_pud_range+0x8b0/0x8d0 [ 2.553199] Call Trace: [ 2.553207] [c0000000622e7650] [c0000000007eef30] free_pud_range+0x8b0/0x8d0 (unreliable) [ 2.553229] [c0000000622e7750] [c0000000007f40b4] free_pgd_range+0x284/0x3b0 [ 2.553248] [c0000000622e7800] [c0000000007f4630] free_pgtables+0x450/0x570 [ 2.553274] [c0000000622e78e0] [c0000000008161c0] exit_mmap+0x250/0x650 [ 2.553292] [c0000000622e7a30] [c0000000001b95b8] __mmput+0x98/0x290 [ 2.558344] [c0000000622e7a80] [c0000000001d1018] exit_mm+0x118/0x1b0 [ 2.558361] [c0000000622e7ac0] [c0000000001d141c] do_exit+0x2ec/0x870 [ 2.558376] [c0000000622e7b60] [c0000000001d1ca8] do_group_exit+0x88/0x150 [ 2.558391] [c0000000622e7bb0] [c0000000001d1db8] sys_exit_group+0x48/0x50 [ 2.558407] [c0000000622e7be0] [c00000000003d810] system_call_exception+0x1e0/0x4c0 [ 2.558423] [c0000000622e7e50] [c00000000000d05c] system_call_vectored_common+0x15c/0x2ec (...) [ 2.558892] ---[ end trace 0000000000000000 ]--- [ 2.559022] BUG: Bad rss-counter state mm:000000002267cc9e type:MM_ANONPAGES val:1 [ 2.559037] BUG: non-zero pgtables_bytes on freeing mm: -6144
Here the modprobe process ended up with an allocated mm_struct from the mm_struct slab that was used before by the debug_vm_pgtable test. That is not a problem, since the mm_struct is initialized again etc., however, if it ends up using the same pgd table, it bumps into the old stale entry when clearing/freeing the page table entries, so it tries to free an entry already gone (that one which was allocated by the debug_vm_pgtable test), which also explains the negative pgtables_bytes since it's accounting for not allocated entries in the current process.
As far as I looked pgd_{alloc,free} etc. does not clear entries, and clearing of the entries is explicitly done in the free_pgtables-> free_pgd_range->free_p4d_range->free_pud_range->free_pmd_range-> free_pte_range path. However, the debug_vm_pgtable test does not call free_pgtables, since it allocates mm_struct and entries manually for its test and eg. not goes through page faults. So it also should clear manually the entries before exit at destroy_args().
This problem was noticed on a reboot X number of times test being done on a powerpc host, with a debug kernel with CONFIG_DEBUG_VM_PGTABLE enabled. Depends on the system, but on a 100 times reboot loop the problem could manifest once or twice, if a process ends up getting the right mm->pgd entry with the stale entries used by mm/debug_vm_pagetable. After using this patch, I couldn't reproduce/experience the problems anymore. I was able to reproduce the problem as well on latest upstream kernel (6.16).
I also modified destroy_args() to use mmput() instead of mmdrop(), there is no reason to hold mm_users reference and not release the mm_struct entirely, and in the output above with my debugging prints I already had patched it to use mmput, it did not fix the problem, but helped in the debugging as well.
--- mm/debug_vm_pgtable.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
mm/debug_vm_pgtable.c +7 -2
@@ -1041,29 +1041,34 @@ static void __init destroy_args(struct p/* Free page table entries */ if (args->start_ptep) { +pmd_clear (args->pmdp);pte_free (args->mm, args->start_ptep);mm_dec_nr_ptes (args->mm); }if (args->start_pmdp) { +pud_clear (args->pudp);pmd_free (args->mm, args->start_pmdp);mm_dec_nr_pmds (args->mm); }if (args->start_pudp) { +p4d_clear (args->p4dp);pud_free (args->mm, args->start_pudp);mm_dec_nr_puds (args->mm); } -if (args->start_p4dp) +if (args->start_p4dp) { +pgd_clear (args->pgdp);p4d_free (args->mm, args->start_p4dp); + }/* Free vma and mm struct */ if (args->vma)vm_area_free (args->vma);if (args->mm) -mmdrop (args->mm); +mmput (args->mm); } static struct page * __init
Greg Kroah-Hartman
maintainerPATCH 248/457 mm/memory-failure: fix infinite UCE for VM_PFNMAP pfn
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjiang Tu <[email protected]>
commit 2e6053fea379806269c4f7f5e36b523c9c0fb35c upstream.
When memory_failure() is called for a already hwpoisoned pfn, kill_accessing_process() will be called to kill current task. However, if the vma of the accessing vaddr is VM_PFNMAP, walk_page_range() will skip the vma in walk_page_test() and return 0.
Before commit aaf99ac2ceb7 ("mm/hwpoison: do not send SIGBUS to processes with recovered clean pages"), kill_accessing_process() will return EFAULT. For x86, the current task will be killed in kill_me_maybe().
However, after this commit, kill_accessing_process() simplies return 0, that means UCE is handled properly, but it doesn't actually. In such case, the user task will trigger UCE infinitely.
To fix it, add .test_walk callback for hwpoison_walk_ops to scan all vmas.
--- mm/memory-failure.c | 8 ++++++++ 1 file changed, 8 insertions(+)
mm/memory-failure.c +8 -0
@@ -847,9 +847,17 @@ static int hwpoison_hugetlb_range(pte_t#define hwpoison_hugetlb_range NULL#endif +static int hwpoison_test_walk (unsigned long start,unsigned long end, +struct mm_walk *walk) +{ +/* We also want to consider pages mapped into VM_PFNMAP. */ +return 0 ; +} +static const struct mm_walk_ops hwpoison_walk_ops = { .pmd_entry = hwpoison_pte_range, .hugetlb_entry = hwpoison_hugetlb_range, + .test_walk = hwpoison_test_walk, .walk_lock =PGWALK_RDLOCK , };
Greg Kroah-Hartman
maintainerPATCH 249/457 mm/mremap: fix WARN with uffd that has remap events disabled
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand <[email protected]>
commit 772e5b4a5e8360743645b9a466842d16092c4f94 upstream.
Registering userfaultd on a VMA that spans at least one PMD and then mremap()'ing that VMA can trigger a WARN when recovering from a failed page table move due to a page table allocation error.
The code ends up doing the right thing (recurse, avoiding moving actual page tables), but triggering that WARN is unpleasant:
WARNING: CPU: 2 PID: 6133 at mm/mremap.c:357 move_normal_pmd mm/mremap.c:357 [inline] WARNING: CPU: 2 PID: 6133 at mm/mremap.c:357 move_pgt_entry mm/mremap.c:595 [inline] WARNING: CPU: 2 PID: 6133 at mm/mremap.c:357 move_page_tables+0x3832/0x44a0 mm/mremap.c:852 Modules linked in: CPU: 2 UID: 0 PID: 6133 Comm: syz.0.19 Not tainted 6.17.0-rc1-syzkaller-00004-g53e760d89498 #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 RIP: 0010:move_normal_pmd mm/mremap.c:357 [inline] RIP: 0010:move_pgt_entry mm/mremap.c:595 [inline] RIP: 0010:move_page_tables+0x3832/0x44a0 mm/mremap.c:852 Code: ... RSP: 0018:ffffc900037a76d8 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 0000000032930007 RCX: ffffffff820c6645 RDX: ffff88802e56a440 RSI: ffffffff820c7201 RDI: 0000000000000007 RBP: ffff888037728fc0 R08: 0000000000000007 R09: 0000000000000000 R10: 0000000032930007 R11: 0000000000000000 R12: 0000000000000000 R13: ffffc900037a79a8 R14: 0000000000000001 R15: dffffc0000000000 FS: 000055556316a500(0000) GS:ffff8880d68bc000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b30863fff CR3: 0000000050171000 CR4: 0000000000352ef0 Call Trace: <TASK> copy_vma_and_data+0x468/0x790 mm/mremap.c:1215 move_vma+0x548/0x1780 mm/mremap.c:1282 mremap_to+0x1b7/0x450 mm/mremap.c:1406 do_mremap+0xfad/0x1f80 mm/mremap.c:1921 __do_sys_mremap+0x119/0x170 mm/mremap.c:1977 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x4c0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f00d0b8ebe9 Code: ... RSP: 002b:00007ffe5ea5ee98 EFLAGS: 00000246 ORIG_RAX: 0000000000000019 RAX: ffffffffffffffda RBX: 00007f00d0db5fa0 RCX: 00007f00d0b8ebe9 RDX: 0000000000400000 RSI: 0000000000c00000 RDI: 0000200000000000 RBP: 00007ffe5ea5eef0 R08: 0000200000c00000 R09: 0000000000000000 R10: 0000000000000003 R11: 0000000000000246 R12: 0000000000000002 R13: 00007f00d0db5fa0 R14: 00007f00d0db5fa0 R15: 0000000000000005 </TASK>
The underlying issue is that we recurse during the original page table move, but not during the recovery move.
Fix it by checking for both VMAs and performing the check before the pmd_none() sanity check.
Add a new helper where we perform+document that check for the PMD and PUD level.
Thanks to Harry for bisecting.
--- mm/mremap.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-)
mm/mremap.c +23 -18
@@ -294,6 +294,25 @@ static inline bool arch_supports_page_ta }#endif +static inline bool uffd_supports_page_table_move (struct pagetable_move_control *pmc) +{ +/* +* If we are moving a VMA that has uffd-wp registered but with +* remap events disabled (new VMA will not be registered with uffd), we +* need to ensure that the uffd-wp state is cleared from all pgtables. +* This means recursing into lower page tables in move_page_tables(). +* +* We might get called with VMAs reversed when recovering from a +* failed page table move. In that case, the +* "old"-but-actually-"originally new" VMA during recovery will not have +* a uffd context. Recursing into lower page tables during the original +* move but not during the recovery move will cause trouble, because we +* run into already-existing page tables. So check both VMAs. +*/ +return !vma_has_uffd_without_event_remap (pmc->old) && + !vma_has_uffd_without_event_remap (pmc->new); +} +#ifdef CONFIG_HAVE_MOVE_PMD static bool move_normal_pmd (struct pagetable_move_control *pmc,pmd_t *old_pmd,pmd_t *new_pmd)
@@ -306,6 +325,8 @@ static bool move_normal_pmd(struct pagetif (!arch_supports_page_table_move ())return false; +if (!uffd_supports_page_table_move (pmc)) +return false;/* * The destination pmd shouldn't be established, free_pgtables() * should have released it.
@@ -332,15 +353,6 @@ static bool move_normal_pmd(struct pagetif (WARN_ON_ONCE (!pmd_none (*new_pmd)))return false; -/* If this pmd belongs to a uffd vma with remap events disabled, we need -* to ensure that the uffd-wp state is cleared from all pgtables. This -* means recursing into lower page tables in move_page_tables(), and we -* can reuse the existing code if we simply treat the entry as "not -* moved". -*/ -if (vma_has_uffd_without_event_remap (vma)) -return false; -/* * We don't have to worry about the ordering of src and dst * ptlocks because exclusive mmap_lock prevents deadlock.
@@ -389,6 +401,8 @@ static bool move_normal_pud(struct pagetif (!arch_supports_page_table_move ())return false; +if (!uffd_supports_page_table_move (pmc)) +return false;/* * The destination pud shouldn't be established, free_pgtables() * should have released it.
@@ -396,15 +410,6 @@ static bool move_normal_pud(struct pagetif (WARN_ON_ONCE (!pud_none (*new_pud)))return false; -/* If this pud belongs to a uffd vma with remap events disabled, we need -* to ensure that the uffd-wp state is cleared from all pgtables. This -* means recursing into lower page tables in move_page_tables(), and we -* can reuse the existing code if we simply treat the entry as "not -* moved". -*/ -if (vma_has_uffd_without_event_remap (vma)) -return false; -/* * We don't have to worry about the ordering of src and dst * ptlocks because exclusive mmap_lock prevents deadlock.
Greg Kroah-Hartman
maintainerPATCH 250/457 ALSA: hda: tas2781: Fix wrong reference of tasdevice_priv
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 3f4422e7c9436abf81a00270be7e4d6d3760ec0e upstream.
During the conversion to unify the calibration data management, the reference to tasdevice_priv was wrongly set to h->hda_priv instead of h->priv. This resulted in memory corruption and crashes eventually. Unfortunately it's a void pointer, hence the compiler couldn't know that it's wrong.
--- sound/pci/hda/tas2781_hda_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/pci/hda/tas2781_hda_i2c.c +1 -1
@@ -287,7 +287,7 @@ static int tas2563_save_calibration(struefi_char16_t efi_name[TAS2563_CAL_VAR_NAME_MAX ];unsigned long max_size =TAS2563_CAL_DATA_SIZE ;unsigned char var8[TAS2563_CAL_VAR_NAME_MAX ]; -struct tasdevice_priv *p = h->hda_priv; +struct tasdevice_priv *p = h->priv;struct calidata *cd = &p->cali_data;struct cali_reg *r = &cd->cali_reg_array;unsigned int offset =0 ;
Greg Kroah-Hartman
maintainerPATCH 251/457 ALSA: hda/realtek: Add support for HP EliteBook x360 830 G6 and EliteBook 830 G6
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Evgeniy Harchenko <[email protected]>
commit eafae0fdd115a71b3a200ef1a31f86da04bac77f upstream.
The HP EliteBook x360 830 G6 and HP EliteBook 830 G6 have Realtek HDA codec ALC215. It needs the ALC285_FIXUP_HP_GPIO_LED quirk to enable the mute LED.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -10662,6 +10662,8 @@ static const struct hda_quirk alc269_fixSND_PCI_QUIRK (0x103c ,0x84e7 ,"HP Pavilion 15" ,ALC269_FIXUP_HP_MUTE_LED_MIC3 ),SND_PCI_QUIRK (0x103c ,0x8519 ,"HP Spectre x360 15-df0xxx" ,ALC285_FIXUP_HP_SPECTRE_X360 ),SND_PCI_QUIRK (0x103c ,0x8537 ,"HP ProBook 440 G6" ,ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF ), +SND_PCI_QUIRK (0x103c ,0x8548 ,"HP EliteBook x360 830 G6" ,ALC285_FIXUP_HP_GPIO_LED ), +SND_PCI_QUIRK (0x103c ,0x854a ,"HP EliteBook 830 G6" ,ALC285_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x85c6 ,"HP Pavilion x360 Convertible 14-dy1xxx" ,ALC295_FIXUP_HP_MUTE_LED_COEFBIT11 ),SND_PCI_QUIRK (0x103c ,0x85de ,"HP Envy x360 13-ar0xxx" ,ALC285_FIXUP_HP_ENVY_X360 ), SND_PCI_QUIRK(0x103c, 0x860f, "HP ZBook 15 G6", ALC285_FIXUP_HP_GPIO_AMP_INIT),
Greg Kroah-Hartman
maintainerPATCH 252/457 RDMA/rxe: Flush delayed SKBs while releasing RXE resources
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Yanjun <[email protected]>
commit 3c3e9a9f2972b364e8c2cfbfdeb23c6d6be4f87f upstream.
When skb packets are sent out, these skb packets still depends on the rxe resources, for example, QP, sk, when these packets are destroyed.
If these rxe resources are released when the skb packets are destroyed, the call traces will appear.
To avoid skb packets hang too long time in some network devices, a timestamp is added when these skb packets are created. If these skb packets hang too long time in network devices, these network devices can free these skb packets to release rxe resources.
--- drivers/infiniband/sw/rxe/rxe_net.c | 29 ++++++++--------------------- drivers/infiniband/sw/rxe/rxe_qp.c | 2 +- 2 files changed, 9 insertions(+), 22 deletions(-)
drivers/infiniband/sw/rxe/rxe_net.c +8 -21
@@ -345,33 +345,15 @@ int rxe_prepare(struct rxe_av *av, strucstatic void rxe_skb_tx_dtor (struct sk_buff *skb) { -struct net_device *ndev = skb->dev; -struct rxe_dev *rxe; -unsigned int qp_index; -struct rxe_qp *qp; +struct rxe_qp *qp = skb->sk->sk_user_data;int skb_out; - rxe =rxe_get_dev_from_net (ndev); -if (!rxe &&is_vlan_dev (ndev)) - rxe =rxe_get_dev_from_net (vlan_dev_real_dev (ndev)); -if (WARN_ON (!rxe)) -return ; - - qp_index = (int )(uintptr_t )skb->sk->sk_user_data; -if (!qp_index) -return ; - - qp =rxe_pool_get_index (&rxe->qp_pool, qp_index); -if (!qp) - goto put_dev; - skb_out =atomic_dec_return (&qp->skb_out); -if (qp->need_req_skb && skb_out <RXE_INFLIGHT_SKBS_PER_QP_LOW ) +if (unlikely (qp->need_req_skb && + skb_out <RXE_INFLIGHT_SKBS_PER_QP_LOW ))rxe_sched_task (&qp->send_task);rxe_put (qp); -put_dev: -ib_device_put (&rxe->ib_dev);sock_put (skb->sk); }
@@ -383,6 +365,7 @@ static int rxe_send(struct sk_buff *skb,sock_hold (sk); skb->sk = sk; skb->destructor = rxe_skb_tx_dtor; +rxe_get (pkt->qp);atomic_inc (&pkt->qp->skb_out);if (skb->protocol ==htons (ETH_P_IP ))
@@ -405,6 +388,7 @@ static int rxe_loopback(struct sk_buff *sock_hold (sk); skb->sk = sk; skb->destructor = rxe_skb_tx_dtor; +rxe_get (pkt->qp);atomic_inc (&pkt->qp->skb_out);if (skb->protocol ==htons (ETH_P_IP ))
@@ -497,6 +481,9 @@ struct sk_buff *rxe_init_packet(struct r goto out; } +/* Add time stamp to skb. */ + skb->tstamp =ktime_get (); +skb_reserve (skb, hdr_len +LL_RESERVED_SPACE (ndev));/* FIXME: hold reference to this netdev until life of this skb. */
drivers/infiniband/sw/rxe/rxe_qp.c +1 -1
@@ -244,7 +244,7 @@ static int rxe_qp_init_req(struct rxe_de err =sock_create_kern (&init_net,AF_INET ,SOCK_DGRAM ,0 , &qp->sk);if (err <0 )return err; - qp->sk->sk->sk_user_data = (void *)(uintptr_t )qp->elem.index; + qp->sk->sk->sk_user_data = qp;/* pick a source UDP port number for this QP based on * the source QPN. this spreads traffic for different QPs
Greg Kroah-Hartman
maintainerPATCH 253/457 s390/sclp: Fix SCCB present check
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Oberparleiter <[email protected]>
commit 430fa71027b6ac9bb0ce5532b8d0676777d4219a upstream.
Tracing code called by the SCLP interrupt handler contains early exits if the SCCB address associated with an interrupt is NULL. This check is performed after physical to virtual address translation.
If the kernel identity mapping does not start at address zero, the resulting virtual address is never zero, so that the NULL checks won't work. Subsequently this may result in incorrect accesses to the first page of the identity mapping.
Fix this by introducing a function that handles the NULL case before address translation.
--- drivers/s390/char/sclp.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/s390/char/sclp.c +9 -2
@@ -76,6 +76,13 @@ unsigned long sclp_console_full;/* The currently active SCLP command word. */ static sclp_cmdw_t active_cmd; +static inline struct sccb_header *sclpint_to_sccb (u32 sccb_int) +{ +if (sccb_int) +return __va (sccb_int); +return NULL ; +} +static inline void sclp_trace (int prio,char *id,u32 a,u64 b,bool err) {struct sclp_trace_entry e;
@@ -619,7 +626,7 @@ __sclp_find_req(u32 sccb)static bool ok_response (u32 sccb_int,sclp_cmdw_t cmd) { -struct sccb_header *sccb = (struct sccb_header *)__va (sccb_int); +struct sccb_header *sccb =sclpint_to_sccb (sccb_int);struct evbuf_header *evbuf;u16 response;
@@ -658,7 +665,7 @@ static void sclp_interrupt_handler(struc/* INT: Interrupt received (a=intparm, b=cmd) */ sclp_trace_sccb (0 ,"INT" , param32, active_cmd, active_cmd, - (struct sccb_header *)__va (finished_sccb), +sclpint_to_sccb (finished_sccb), !ok_response (finished_sccb, active_cmd));if (finished_sccb) {
Greg Kroah-Hartman
maintainerPATCH 254/457 platform/x86/intel-uncore-freq: Check write blocked for ELC
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Pandruvada <[email protected]>
commit dff6f36878799a5ffabd15336ce993dc737374dc upstream.
Add the missing write_blocked check for updating sysfs related to uncore efficiency latency control (ELC). If write operation is blocked return error.
--- drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c +5 -0
@@ -191,9 +191,14 @@ static int uncore_read_control_freq(strustatic int write_eff_lat_ctrl (struct uncore_data *data,unsigned int val,enum uncore_index index) {struct tpmi_uncore_cluster_info *cluster_info; +struct tpmi_uncore_struct *uncore_root;u64 control; cluster_info = container_of(data, struct tpmi_uncore_cluster_info, uncore_data); + uncore_root = cluster_info->uncore_root; + +if (uncore_root->write_blocked) +return -EPERM ;if (cluster_info->root_domain)return -ENODATA ;
Greg Kroah-Hartman
maintainerPATCH 255/457 compiler: remove __ADDRESSABLE_ASM{_STR,}() again
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Beulich <[email protected]>
commit 8ea815399c3fcce1889bd951fec25b5b9a3979c1 upstream.
__ADDRESSABLE_ASM_STR() is where the necessary stringification happens. As long as "sym" doesn't contain any odd characters, no quoting is required for its use with .quad / .long. In fact the quotation gets in the way with gas 2.25; it's only from 2.26 onwards that quoted symbols are half-way properly supported.
However, assembly being different from C anyway, drop __ADDRESSABLE_ASM_STR() and its helper macro altogether. A simple .global directive will suffice to get the symbol "declared", i.e. into the symbol table. While there also stop open-coding STATIC_CALL_TRAMP() and STATIC_CALL_KEY().
Message-ID: <[email protected]>
--- arch/x86/include/asm/xen/hypercall.h | 5 +++-- include/linux/compiler.h | 8 -------- 2 files changed, 3 insertions(+), 10 deletions(-)
arch/x86/include/asm/xen/hypercall.h +3 -2
@@ -94,12 +94,13 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_h#ifdef MODULE #define __ADDRESSABLE_xen_hypercall#else -#define __ADDRESSABLE_xen_hypercall __ADDRESSABLE_ASM_STR(__SCK__xen_hypercall) +#define __ADDRESSABLE_xen_hypercall \ + __stringify(.global STATIC_CALL_KEY(xen_hypercall);)#endif #define __HYPERCALL \ __ADDRESSABLE_xen_hypercall \ - "call __SCT__xen_hypercall" + __stringify(call STATIC_CALL_TRAMP(xen_hypercall))#define __HYPERCALL_ENTRY (x) "a" (x)
include/linux/compiler.h +0 -8
@@ -288,14 +288,6 @@ static inline void *offset_to_ptr(const#define __ADDRESSABLE (sym) \ ___ADDRESSABLE(sym, __section(".discard.addressable")) -#define __ADDRESSABLE_ASM (sym) \ - .pushsection .discard.addressable,"aw"; \ - .align ARCH_SEL(8,4); \ - ARCH_SEL(.quad, .long) __stringify(sym); \ - .popsection; - -#define __ADDRESSABLE_ASM_STR (sym) __stringify(__ADDRESSABLE_ASM(sym)) -/* * This returns a constant expression while determining if an argument is * a constant expression, most importantly without evaluating the argument.
Greg Kroah-Hartman
maintainerPATCH 256/457 accel/habanalabs/gaudi2: Use kvfree() for memory allocated with kvcalloc()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
commit a44458dfd5bc0c79c6739c3f4c658361d3a5126b upstream.
Use kvfree() to fix the following Coccinelle/coccicheck warning reported by kfree_mismatch.cocci:
WARNING kvmalloc is used to allocate this memory at line 10398
--- drivers/accel/habanalabs/gaudi2/gaudi2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/accel/habanalabs/gaudi2/gaudi2.c +1 -1
@@ -10437,7 +10437,7 @@ end: (u64 *)(lin_dma_pkts_arr), DEBUGFS_WRITE64);WREG32 (sob_addr,0 ); -kfree (lin_dma_pkts_arr); +kvfree (lin_dma_pkts_arr);return rc; }
Greg Kroah-Hartman
maintainerPATCH 257/457 drm/amdgpu/swm14: Update power limit logic
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 79e25cd06e85105c75701ef1773c6c64bb304091 upstream.
Take into account the limits from the vbios. Ported from the SMU13 code.
--- drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +25 -5
@@ -1689,9 +1689,11 @@ static int smu_v14_0_2_get_power_limit(s uint32_t *min_power_limit) {struct smu_table_context *table_context = &smu->smu_table; +struct smu_14_0_2_powerplay_table *powerplay_table = + table_context->power_play_table;PPTable_t *pptable = table_context->driver_pptable;CustomSkuTable_t *skutable = &pptable->CustomSkuTable; -uint32_t power_limit; +uint32_t power_limit, od_percent_upper =0 , od_percent_lower =0 ;uint32_t msg_limit = pptable->SkuTable.MsgLimits.Power[PPT_THROTTLER_PPT0 ][POWER_SOURCE_AC ];if (smu_v14_0_get_current_power_limit (smu, &power_limit))
@@ -1704,11 +1706,29 @@ static int smu_v14_0_2_get_power_limit(sif (default_power_limit) *default_power_limit = power_limit; -if (max_power_limit) - *max_power_limit = msg_limit; +if (powerplay_table) { +if (smu->od_enabled && +smu_v14_0_2_is_od_feature_supported (smu,PP_OD_FEATURE_PPT_BIT )) { + od_percent_upper = pptable->SkuTable.OverDriveLimitsBasicMax.Ppt; + od_percent_lower = pptable->SkuTable.OverDriveLimitsBasicMin.Ppt; + }else if (smu_v14_0_2_is_od_feature_supported (smu,PP_OD_FEATURE_PPT_BIT )) { + od_percent_upper =0 ; + od_percent_lower = pptable->SkuTable.OverDriveLimitsBasicMin.Ppt; + } + } -if (min_power_limit) - *min_power_limit =0 ; +dev_dbg (smu->adev->dev,"od percent upper:%d, od percent lower:%d (default power: %d)\n" , + od_percent_upper, od_percent_lower, power_limit); + +if (max_power_limit) { + *max_power_limit = msg_limit * (100 + od_percent_upper); + *max_power_limit /=100 ; + } + +if (min_power_limit) { + *min_power_limit = power_limit * (100 + od_percent_lower); + *min_power_limit /=100 ; + }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 258/457 drm/i915: silence rpm wakeref asserts on GEN11_GU_MISC_IIR access
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jani Nikula <[email protected]>
commit ff646d033783068cc5b38924873cab4a536b17c1 upstream.
Commit 8d9908e8fe9c ("drm/i915/display: remove small micro-optimizations in irq handling") not only removed the optimizations, it also enabled wakeref asserts for the GEN11_GU_MISC_IIR access. Silence the asserts by wrapping the access inside intel_display_rpm_assert_{block,unblock}().
--- drivers/gpu/drm/i915/display/intel_display_irq.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/gpu/drm/i915/display/intel_display_irq.c +4 -0
@@ -1492,10 +1492,14 @@ u32 gen11_gu_misc_irq_ack(struct intel_dif (!(master_ctl &GEN11_GU_MISC_IRQ ))return 0 ; +intel_display_rpm_assert_block (display); + iir =intel_de_read (display,GEN11_GU_MISC_IIR );if (likely (iir))intel_de_write (display,GEN11_GU_MISC_IIR , iir); +intel_display_rpm_assert_unblock (display); +return iir; }
Greg Kroah-Hartman
maintainerPATCH 259/457 drm/nouveau/gsp: fix mismatched alloc/free for kvmalloc()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qianfeng Rong <[email protected]>
commit 989fe6771266bdb82a815d78802c5aa7c918fdfd upstream.
Replace kfree() with kvfree() for memory allocated by kvmalloc().
Compile-tested only.
--- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c +2 -2
@@ -325,7 +325,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries) rpc =r535_gsp_msgq_peek (gsp,sizeof (*rpc), info.retries);if (IS_ERR_OR_NULL (rpc)) { -kfree (buf); +kvfree (buf);return rpc; }
@@ -334,7 +334,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries) rpc =r535_gsp_msgq_recv_one_elem (gsp, &info);if (IS_ERR_OR_NULL (rpc)) { -kfree (buf); +kvfree (buf);return rpc; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 260/457 drm/i915/gt: Relocate compression repacking WA for JSL/EHL
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Brzezinka <[email protected]>
commit 8236820fd767f400d1baefb71bc7e36e37730a1e upstream.
CACHE_MODE_0 registers should be saved and restored as part of the context, not during engine reset. Move the related workaround (Disable Repacking for Compression) from rcs_engine_wa_init() to icl_ctx_workarounds_init() for Jasper Lake and Elkhart Lake platforms. This ensures the WA is applied during context initialisation.
BSPEC: 11322
--- drivers/gpu/drm/i915/gt/intel_workarounds.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
drivers/gpu/drm/i915/gt/intel_workarounds.c +11 -9
@@ -634,6 +634,8 @@ static void cfl_ctx_workarounds_init(strstatic void icl_ctx_workarounds_init (struct intel_engine_cs *engine,struct i915_wa_list *wal) { +struct drm_i915_private *i915 = engine->i915; +/* Wa_1406697149 (WaDisableBankHangMode:icl) */ wa_write (wal,GEN8_L3CNTLREG ,GEN8_ERRDETBCTRL );
@@ -669,6 +671,15 @@ static void icl_ctx_workarounds_init(str/* Wa_1406306137:icl,ehl */ wa_mcr_masked_en (wal,GEN9_ROW_CHICKEN4 ,GEN11_DIS_PICK_2ND_EU ); + +if (IS_JASPERLAKE (i915) ||IS_ELKHARTLAKE (i915)) { +/* +* Disable Repacking for Compression (masked R/W access) +* before rendering compressed surfaces for display. +*/ +wa_masked_en (wal,CACHE_MODE_0_GEN7 , +DISABLE_REPACKING_FOR_COMPRESSION ); + } }/*
@@ -2306,15 +2317,6 @@ rcs_engine_wa_init(struct intel_engine_c GEN8_RC_SEMA_IDLE_MSG_DISABLE); } -if (IS_JASPERLAKE (i915) ||IS_ELKHARTLAKE (i915)) { -/* -* "Disable Repacking for Compression (masked R/W access) -* before rendering compressed surfaces for display." -*/ -wa_masked_en (wal,CACHE_MODE_0_GEN7 , -DISABLE_REPACKING_FOR_COMPRESSION ); - } -if (GRAPHICS_VER (i915) ==11 ) {/* This is not an Wa. Enable for better image quality */ wa_masked_en(wal,
Greg Kroah-Hartman
maintainerPATCH 261/457 drm/i915/lnl+/tc: Fix handling of an enabled/disconnected dp-alt sink
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
commit f52d6aa98379842fc255d93282655566f2114e0c upstream.
The TypeC PHY HW readout during driver loading and system resume determines which TypeC mode the PHY is in (legacy/DP-alt/TBT-alt) and whether the PHY is connected, based on the PHY's Owned and Ready flags. For the PHY to be in DP-alt or legacy mode and for the PHY to be in the connected state in these modes, both the Owned (set by the BIOS/driver) and the Ready (set by the HW) flags should be set.
On ICL-MTL the HW kept the PHY's Ready flag set after the driver connected the PHY by acquiring the PHY ownership (by setting the Owned flag), until the driver disconnected the PHY by releasing the PHY ownership (by clearing the Owned flag). On LNL+ this has changed, in that the HW clears the Ready flag as soon as the sink gets disconnected, even if the PHY ownership was acquired already and hence the PHY is being used by the display.
When inheriting the HW state from BIOS for a PHY connected in DP-alt mode on which the sink got disconnected - i.e. in a case where the sink was connected while BIOS/GOP was running and so the sink got enabled connecting the PHY, but the user disconnected the sink by the time the driver loaded - the PHY Owned but not Ready state must be accounted for on LNL+ according to the above. Do that by assuming on LNL+ that the PHY is connected in DP-alt mode whenever the PHY Owned flag is set, regardless of the PHY Ready flag.
This fixes a problem on LNL+, where the PHY TypeC mode / connected state was detected incorrectly for a DP-alt sink, which got connected and then disconnected by the user in the above way.
v2: Rename tc_phy_in_legacy_or_dp_alt_mode() to tc_phy_owned_by_display().
(Luca, Jani)
--- drivers/gpu/drm/i915/display/intel_tc.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/gpu/drm/i915/display/intel_tc.c +11 -6
@@ -1225,14 +1225,19 @@ static void tc_phy_get_hw_state(struct i tc->phy_ops->get_hw_state (tc); } -static bool tc_phy_is_ready_and_owned (struct intel_tc_port *tc, -bool phy_is_ready,bool phy_is_owned) +/* Is the PHY owned by display i.e. is it in legacy or DP-alt mode? */ +static bool tc_phy_owned_by_display (struct intel_tc_port *tc, +bool phy_is_ready,bool phy_is_owned) {struct intel_display *display =to_intel_display (tc->dig_port); -drm_WARN_ON (display->drm, phy_is_owned && !phy_is_ready); +if (DISPLAY_VER (display) <20 ) { +drm_WARN_ON (display->drm, phy_is_owned && !phy_is_ready); -return phy_is_ready && phy_is_owned; +return phy_is_ready && phy_is_owned; + }else { +return phy_is_owned; + } } static bool tc_phy_is_connected(struct intel_tc_port *tc,
@@ -1243,7 +1248,7 @@ static bool tc_phy_is_connected(struct ibool phy_is_owned =tc_phy_is_owned (tc);bool is_connected; -if (tc_phy_is_ready_and_owned (tc, phy_is_ready, phy_is_owned)) +if (tc_phy_owned_by_display (tc, phy_is_ready, phy_is_owned)) is_connected = port_pll_type ==ICL_PORT_DPLL_MG_PHY ;else is_connected = port_pll_type ==ICL_PORT_DPLL_DEFAULT ;
@@ -1351,7 +1356,7 @@ tc_phy_get_current_mode(struct intel_tc_ phy_is_ready =tc_phy_is_ready (tc); phy_is_owned =tc_phy_is_owned (tc); -if (!tc_phy_is_ready_and_owned (tc, phy_is_ready, phy_is_owned)) { +if (!tc_phy_owned_by_display (tc, phy_is_ready, phy_is_owned)) { mode =get_tc_mode_in_phy_not_owned_state (tc, live_mode); }else {drm_WARN_ON (display->drm, live_mode ==TC_PORT_TBT_ALT );
Greg Kroah-Hartman
maintainerPATCH 262/457 drm/i915/icl+/tc: Cache the max lane count value
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
commit 5fd35236546abe780eaadb7561e09953719d4fc3 upstream.
The PHY's pin assignment value in the TCSS_DDI_STATUS register - as set by the HW/FW based on the connected DP-alt sink's TypeC/PD pin assignment negotiation - gets cleared by the HW/FW on LNL+ as soon as the sink gets disconnected, even if the PHY ownership got acquired already by the driver (and hence the PHY itself is still connected and used by the display). This is similar to how the PHY Ready flag gets cleared on LNL+ in the same register.
To be able to query the max lane count value on LNL+ - which is based on the above pin assignment - at all times even after the sink gets disconnected, the max lane count must be determined and cached during the PHY's HW readout and connect sequences. Do that here, leaving the actual use of the cached value to a follow-up change.
v2: Don't read out the pin configuration if the PHY is disconnected.
--- drivers/gpu/drm/i915/display/intel_tc.c | 57 ++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 9 deletions(-)
drivers/gpu/drm/i915/display/intel_tc.c +48 -9
@@ -65,6 +65,7 @@ struct intel_tc_port {enum tc_port_mode init_mode;enum phy_fia phy_fia;u8 phy_fia_idx; +u8 max_lane_count; }; static enum intel_display_power_domain
@@ -364,12 +365,12 @@ static int intel_tc_port_get_max_lane_co } } -int intel_tc_port_max_lane_count (struct intel_digital_port *dig_port) +static int get_max_lane_count (struct intel_tc_port *tc) { -struct intel_display *display =to_intel_display (dig_port); -struct intel_tc_port *tc =to_tc_port (dig_port); +struct intel_display *display =to_intel_display (tc->dig_port); +struct intel_digital_port *dig_port = tc->dig_port; -if (!intel_encoder_is_tc (&dig_port->base) || tc->mode !=TC_PORT_DP_ALT ) +if (tc->mode !=TC_PORT_DP_ALT )return 4 ;assert_tc_cold_blocked (tc);
@@ -383,6 +384,21 @@ int intel_tc_port_max_lane_count(structreturn intel_tc_port_get_max_lane_count (dig_port); } +static void read_pin_configuration (struct intel_tc_port *tc) +{ + tc->max_lane_count =get_max_lane_count (tc); +} + +int intel_tc_port_max_lane_count (struct intel_digital_port *dig_port) +{ +struct intel_tc_port *tc =to_tc_port (dig_port); + +if (!intel_encoder_is_tc (&dig_port->base)) +return 4 ; + +return get_max_lane_count (tc); +} +void intel_tc_port_set_fia_lane_count (struct intel_digital_port *dig_port,int required_lanes) {
@@ -595,9 +611,12 @@ static void icl_tc_phy_get_hw_state(stru tc_cold_wref =__tc_cold_block (tc, &domain); tc->mode =tc_phy_get_current_mode (tc); -if (tc->mode !=TC_PORT_DISCONNECTED ) +if (tc->mode !=TC_PORT_DISCONNECTED ) { tc->lock_wakeref =tc_cold_block (tc); +read_pin_configuration (tc); + } +__tc_cold_unblock (tc, domain, tc_cold_wref); }
@@ -655,8 +674,11 @@ static bool icl_tc_phy_connect(struct in tc->lock_wakeref =tc_cold_block (tc); -if (tc->mode ==TC_PORT_TBT_ALT ) +if (tc->mode ==TC_PORT_TBT_ALT ) { +read_pin_configuration (tc); +return true; + } if ((!tc_phy_is_ready(tc) || !icl_tc_phy_take_ownership(tc, true)) &&
@@ -667,6 +689,7 @@ static bool icl_tc_phy_connect(struct in goto out_unblock_tc_cold; } +read_pin_configuration (tc);if (!tc_phy_verify_legacy_or_dp_alt_mode (tc, required_lanes)) goto out_release_phy;
@@ -857,9 +880,12 @@ static void adlp_tc_phy_get_hw_state(str port_wakeref =intel_display_power_get (display, port_power_domain); tc->mode =tc_phy_get_current_mode (tc); -if (tc->mode !=TC_PORT_DISCONNECTED ) +if (tc->mode !=TC_PORT_DISCONNECTED ) { tc->lock_wakeref =tc_cold_block (tc); +read_pin_configuration (tc); + } +intel_display_power_put (display, port_power_domain, port_wakeref); }
@@ -872,6 +898,9 @@ static bool adlp_tc_phy_connect(struct iif (tc->mode ==TC_PORT_TBT_ALT ) { tc->lock_wakeref =tc_cold_block (tc); + +read_pin_configuration (tc); +return true; }
@@ -893,6 +922,8 @@ static bool adlp_tc_phy_connect(struct i tc->lock_wakeref =tc_cold_block (tc); +read_pin_configuration (tc); +if (!tc_phy_verify_legacy_or_dp_alt_mode (tc, required_lanes)) goto out_unblock_tc_cold;
@@ -1123,9 +1154,12 @@ static void xelpdp_tc_phy_get_hw_state(s tc_cold_wref =__tc_cold_block (tc, &domain); tc->mode =tc_phy_get_current_mode (tc); -if (tc->mode !=TC_PORT_DISCONNECTED ) +if (tc->mode !=TC_PORT_DISCONNECTED ) { tc->lock_wakeref =tc_cold_block (tc); +read_pin_configuration (tc); + } +drm_WARN_ON (display->drm, (tc->mode ==TC_PORT_DP_ALT || tc->mode ==TC_PORT_LEGACY ) && !xelpdp_tc_phy_tcss_power_is_enabled (tc));
@@ -1137,14 +1171,19 @@ static bool xelpdp_tc_phy_connect(struct { tc->lock_wakeref =tc_cold_block (tc); -if (tc->mode ==TC_PORT_TBT_ALT ) +if (tc->mode ==TC_PORT_TBT_ALT ) { +read_pin_configuration (tc); +return true; + }if (!xelpdp_tc_phy_enable_tcss_power (tc, true)) goto out_unblock_tccold;xelpdp_tc_phy_take_ownership (tc, true); +read_pin_configuration (tc); +if (!tc_phy_verify_legacy_or_dp_alt_mode (tc, required_lanes)) goto out_release_phy;
Greg Kroah-Hartman
maintainerPATCH 263/457 drm/i915/lnl+/tc: Fix max lane count HW readout
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
commit c87514a0bb0a64507412a2d98264060dc0c1562a upstream.
On LNL+ for a disconnected sink the pin assignment value gets cleared by the HW/FW as soon as the sink gets disconnected, even if the PHY ownership got acquired already by the BIOS/driver (and hence the PHY itself is still connected and used by the display). During HW readout this can result in detecting the PHY's max lane count as 0 - matching the above cleared aka NONE pin assignment HW state. For a connected PHY the driver in general (outside of intel_tc.c) expects the max lane count value to be valid for the video mode enabled on the corresponding output (1, 2 or 4). Ensure this by setting the max lane count to 4 in this case. Note, that it doesn't matter if this lane count happened to be more than the max lane count with which the PHY got connected and enabled, since the only thing the driver can do with such an output - where the DP-alt sink is disconnected - is to disable the output.
v2: Rebased on change reading out the pin configuration only if the PHY
is connected.
--- drivers/gpu/drm/i915/display/intel_tc.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/gpu/drm/i915/display/intel_tc.c +9 -0
@@ -22,6 +22,7 @@#include "intel_modeset_lock.h" #include "intel_tc.h" +#define DP_PIN_ASSIGNMENT_NONE 0x0#define DP_PIN_ASSIGNMENT_C 0x3#define DP_PIN_ASSIGNMENT_D 0x4#define DP_PIN_ASSIGNMENT_E 0x5
@@ -307,6 +308,8 @@ static int lnl_tc_port_get_max_lane_counREG_FIELD_GET (TCSS_DDI_STATUS_PIN_ASSIGNMENT_MASK , val);switch (pin_assignment) { +case DP_PIN_ASSIGNMENT_NONE : +return 0 ;default :MISSING_CASE (pin_assignment); fallthrough;
@@ -1158,6 +1161,12 @@ static void xelpdp_tc_phy_get_hw_state(s tc->lock_wakeref =tc_cold_block (tc);read_pin_configuration (tc); +/* +* Set a valid lane count value for a DP-alt sink which got +* disconnected. The driver can only disable the output on this PHY. +*/ +if (tc->max_lane_count ==0 ) + tc->max_lane_count =4 ; } drm_WARN_ON(display->drm,
Greg Kroah-Hartman
maintainerPATCH 264/457 drm/i915/lnl+/tc: Use the cached max lane count value
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
commit c5c2b4b3841666be3a45346d0ffa96b4b143504e upstream.
Use the cached max lane count value on LNL+, to account for scenarios where this value is queried after the HW cleared the corresponding pin assignment value in the TCSS_DDI_STATUS register after the sink got disconnected.
For consistency, follow-up changes will use the cached max lane count value on other platforms as well and will also cache the pin assignment value in a similar way.
--- drivers/gpu/drm/i915/display/intel_tc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/display/intel_tc.c +5 -1
@@ -394,12 +394,16 @@ static void read_pin_configuration(strucint intel_tc_port_max_lane_count (struct intel_digital_port *dig_port) { +struct intel_display *display =to_intel_display (dig_port);struct intel_tc_port *tc =to_tc_port (dig_port);if (!intel_encoder_is_tc (&dig_port->base))return 4 ; -return get_max_lane_count (tc); +if (DISPLAY_VER (display) <20 ) +return get_max_lane_count (tc); + +return tc->max_lane_count; } void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port,
Greg Kroah-Hartman
maintainerPATCH 265/457 drm/i915/icl+/tc: Convert AUX powered WARN to a debug message
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
commit d7fa5754e83cd36c4327eb2d806064e598a72ff6 upstream.
The BIOS can leave the AUX power well enabled on an output, even if this isn't required (on platforms where the AUX power is only needed for an AUX access). This was observed at least on PTL. To avoid the WARN which would be triggered by this during the HW readout, convert the WARN to a debug message.
--- drivers/gpu/drm/i915/display/intel_tc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/i915/display/intel_tc.c +3 -3
@@ -1497,11 +1497,11 @@ static void intel_tc_port_reset_mode(strintel_display_power_flush_work (display);if (!intel_tc_cold_requires_aux_pw (dig_port)) {enum intel_display_power_domain aux_domain; -bool aux_powered; aux_domain =intel_aux_power_domain (dig_port); - aux_powered =intel_display_power_is_enabled (display, aux_domain); -drm_WARN_ON (display->drm, aux_powered); +if (intel_display_power_is_enabled (display, aux_domain)) +drm_dbg_kms (display->drm,"Port %s: AUX unexpectedly powered\n" , + tc->port_name); }tc_phy_disconnect (tc);
Greg Kroah-Hartman
maintainerPATCH 266/457 drm/amd/display: Avoid a NULL pointer dereference
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 07b93a5704b0b72002f0c4bd1076214af67dc661 upstream.
[WHY]
Although unlikely drm_atomic_get_new_connector_state() or drm_atomic_get_old_connector_state() can return NULL.
[HOW]
Check returns before dereference.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +3 -0
@@ -7761,6 +7761,9 @@ amdgpu_dm_connector_atomic_check(structstruct amdgpu_dm_connector *aconn =to_amdgpu_dm_connector (conn);int ret; +if (WARN_ON (unlikely (!old_con_state || !new_con_state))) +return -EINVAL ; +trace_amdgpu_dm_connector_atomic_check (new_con_state);if (conn->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
Greg Kroah-Hartman
maintainerPATCH 267/457 drm/amd/display: Dont overclock DCE 6 by 15%
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit cb7b7ae53b557d168b4af5cd8549f3eff920bfb5 upstream.
The extra 15% clock was added as a workaround for a Polaris issue which uses DCE 11, and should not have been used on DCE 6 which is already hardcoded to the highest possible display clock. Unfortunately, the extra 15% was mistakenly copied and kept even on code paths which don't affect Polaris.
This commit fixes that and also adds a check to make sure not to exceed the maximum DCE 6 display clock.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c +3 -5
@@ -123,11 +123,9 @@ static void dce60_update_clocks(struct c {struct clk_mgr_internal *clk_mgr_dce =TO_CLK_MGR_INTERNAL (clk_mgr_base);struct dm_pp_power_level_change_request level_change_req; -int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; - -/*TODO: W/A for dal3 linux, investigate why this works */ -if (!clk_mgr_dce->dfs_bypass_active) - patched_disp_clk = patched_disp_clk *115 /100 ; +const int max_disp_clk = + clk_mgr_dce->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE ].display_clk_khz; +int patched_disp_clk =MIN (max_disp_clk, context->bw_ctx.bw.dce.dispclk_khz); level_change_req.power_level =dce_get_required_clocks_state (clk_mgr_base, context);/* get max clock state from PPLIB */
Greg Kroah-Hartman
maintainerPATCH 268/457 drm/amd/display: Fix fractional fb divider in set_pixel_clock_v3
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 10507478468f165ea681605d133991ed05cdff62 upstream.
For later VBIOS versions, the fractional feedback divider is calculated as the remainder of dividing the feedback divider by a factor, which is set to 1000000. For reference, see:
- calculate_fb_and_fractional_fb_divider
- calc_pll_max_vco_construct
However, in case of old VBIOS versions that have set_pixel_clock_v3, they only have 1 byte available for the fractional feedback divider, and it's expected to be set to the remainder from dividing the feedback divider by 10. For reference see the legacy display code:
- amdgpu_pll_compute
- amdgpu_atombios_crtc_program_pll
This commit fixes set_pixel_clock_v3 by dividing the fractional feedback divider passed to the function by 100000.
--- drivers/gpu/drm/amd/display/dc/bios/command_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/bios/command_table.c +1 -1
@@ -993,7 +993,7 @@ static enum bp_result set_pixel_clock_v3 allocation.sPCLKInput.usFbDiv =cpu_to_le16 ((uint16_t )bp_params->feedback_divider); allocation.sPCLKInput.ucFracFbDiv = - (uint8_t )bp_params->fractional_feedback_divider; + (uint8_t )(bp_params->fractional_feedback_divider /100000 ); allocation.sPCLKInput.ucPostDiv = (uint8_t )bp_params->pixel_clock_post_divider;
Greg Kroah-Hartman
maintainerPATCH 269/457 drm/amd/display: Fix Xorg desktop unresponsive on Replay panel
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tom Chung <[email protected]>
commit 66af73a1c319336694a8610fe4c2943f7b33066c upstream.
[WHY & HOW]
IPS & self-fresh feature can cause vblank counter resets between vblank disable and enable.
It may cause system stuck due to wait the vblank counter.
Call the drm_crtc_vblank_restore() during vblank enable to estimate missed vblanks by using timestamps and update the vblank counter in DRM.
It can make the vblank counter increase smoothly and resolve this issue.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 19 +++++++++++++++++ 1 file changed, 19 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +19 -0
@@ -299,6 +299,25 @@ static inline int amdgpu_dm_crtc_set_vbl irq_type =amdgpu_display_crtc_idx_to_irq_type (adev, acrtc->crtc_id);if (enable) { +struct dc *dc = adev->dm.dc; +struct drm_vblank_crtc *vblank =drm_crtc_vblank_crtc (crtc); +struct psr_settings *psr = &acrtc_state->stream->link->psr_settings; +struct replay_settings *pr = &acrtc_state->stream->link->replay_settings; +bool sr_supported = (psr->psr_version !=DC_PSR_VERSION_UNSUPPORTED ) || + pr->config.replay_supported; + +/* +* IPS & self-refresh feature can cause vblank counter resets between +* vblank disable and enable. +* It may cause system stuck due to waiting for the vblank counter. +* Call this function to estimate missed vblanks by using timestamps and +* update the vblank counter in DRM. +*/ +if (dc->caps.ips_support && + dc->config.disable_ips !=DMUB_IPS_DISABLE_ALL && + sr_supported && vblank->config.disable_immediate) +drm_crtc_vblank_restore (crtc); +/* vblank irq on -> Only need vupdate irq in vrr mode */ if (amdgpu_dm_crtc_vrr_active (acrtc_state)) rc =amdgpu_dm_crtc_set_vupdate_irq (crtc, true);
Greg Kroah-Hartman
maintainerPATCH 270/457 drm/amd/display: Fix DP audio DTO1 clock source on DCE 6.
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 297a4833a68aac3316eb808b4123eb016ef242d7 upstream.
On DCE 6, DP audio was not working. However, it worked when an HDMI monitor was also plugged in.
Looking at dce_aud_wall_dto_setup it seems that the main difference is that we use DTO1 when only DP is plugged in.
When programming DTO1, it uses audio_dto_source_clock_in_khz which is set from get_dp_ref_freq_khz
The dce60_get_dp_ref_freq_khz implementation looks incorrect, because DENTIST_DISPCLK_CNTL seems to be always zero on DCE 6, so it isn't usable.
I compared dce60_get_dp_ref_freq_khz to the legacy display code, specifically dce_v6_0_audio_set_dto, and it turns out that in case of DCE 6, it needs to use the display clock. With that, DP audio started working on Pitcairn, Oland and Cape Verde.
However, it still didn't work on Tahiti. Despite having the same DCE version, Tahiti seems to have a different audio device. After some trial and error I realized that it works with the default display clock as reported by the VBIOS, not the current display clock.
The patch was tested on all four SI GPUs:
* Pitcairn (DCE 6.0)
* Oland (DCE 6.4)
* Cape Verde (DCE 6.0)
* Tahiti (DCE 6.0 but different)
The testing was done on Samsung Odyssey G7 LS28BG700EPXEN on each of the above GPUs, at the following settings:
* 4K 60 Hz
* 1080p 60 Hz
* 1080p 144 Hz
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c | 21 +++-------- 1 file changed, 6 insertions(+), 15 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c +6 -15
@@ -83,22 +83,13 @@ static const struct state_dependent_clocstatic int dce60_get_dp_ref_freq_khz (struct clk_mgr *clk_mgr_base) {struct clk_mgr_internal *clk_mgr =TO_CLK_MGR_INTERNAL (clk_mgr_base); -int dprefclk_wdivider; -int dp_ref_clk_khz; -int target_div; +struct dc_context *ctx = clk_mgr_base->ctx; +int dp_ref_clk_khz =0 ; -/* DCE6 has no DPREFCLK_CNTL to read DP Reference Clock source */ - -/* Read the mmDENTIST_DISPCLK_CNTL to get the currently -* programmed DID DENTIST_DPREFCLK_WDIVIDER*/ -REG_GET (DENTIST_DISPCLK_CNTL ,DENTIST_DPREFCLK_WDIVIDER , &dprefclk_wdivider); - -/* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ - target_div =dentist_get_divider_from_did (dprefclk_wdivider); - -/* Calculate the current DFS clock, in kHz.*/ - dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR - * clk_mgr->base.dentist_vco_freq_khz) / target_div; +if (ASIC_REV_IS_TAHITI_P (ctx->asic_id.hw_internal_rev)) + dp_ref_clk_khz = ctx->dc_bios->fw_info.default_display_engine_pll_frequency; +else + dp_ref_clk_khz = clk_mgr_base->clks.dispclk_khz;return dce_adjust_dp_ref_freq_for_ss (clk_mgr, dp_ref_clk_khz); }
Greg Kroah-Hartman
maintainerPATCH 271/457 drm/amd/display: Find first CRTC and its line time in dce110_fill_display_configs
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 669f73a26f6112eedbadac53a2f2707ac6d0b9c8 upstream.
dce110_fill_display_configs is shared between DCE 6-11, and finding the first CRTC and its line time is relevant to DCE 6 too. Move the code to find it from DCE 11 specific code.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c | 30 ++++++---- 1 file changed, 20 insertions(+), 10 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c +20 -10
@@ -120,9 +120,12 @@ void dce110_fill_display_configs(const struct dc_state *context, struct dm_pp_display_configuration *pp_display_cfg) { + struct dc *dc = context->clk_mgr->ctx->dc;int j;int num_cfgs =0 ; + pp_display_cfg->crtc_index = dc->res_pool->res_cap->num_timing_generator; +for (j =0 ; j < context->stream_count; j++) {int k;
@@ -164,6 +167,23 @@ void dce110_fill_display_configs( cfg->v_refresh /= stream->timing.h_total; cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total /2 ) / stream->timing.v_total; + +/* Find first CRTC index and calculate its line time. +* This is necessary for DPM on SI GPUs. +*/ +if (cfg->pipe_idx < pp_display_cfg->crtc_index) { +const struct dc_crtc_timing *timing = + &context->streams[0 ]->timing; + + pp_display_cfg->crtc_index = cfg->pipe_idx; + pp_display_cfg->line_time_in_us = + timing->h_total *10000 / timing->pix_clk_100hz; + } + } + +if (!num_cfgs) { + pp_display_cfg->crtc_index =0 ; + pp_display_cfg->line_time_in_us =0 ; } pp_display_cfg->display_count = num_cfgs;
@@ -232,16 +252,6 @@ void dce11_pplib_apply_display_requiremedce110_fill_display_configs (context, pp_display_cfg); -/* TODO: is this still applicable?*/ -if (pp_display_cfg->display_count ==1 ) { -const struct dc_crtc_timing *timing = - &context->streams[0 ]->timing; - - pp_display_cfg->crtc_index = - pp_display_cfg->disp_configs[0 ].pipe_idx; - pp_display_cfg->line_time_in_us = timing->h_total *10000 / timing->pix_clk_100hz; - } -if (memcmp (&dc->current_state->pp_display_cfg, pp_display_cfg,sizeof (*pp_display_cfg)) !=0 )dm_pp_apply_display_requirements (dc->ctx, pp_display_cfg); }
Greg Kroah-Hartman
maintainerPATCH 272/457 drm/amd/display: Fill display clock and vblank time in dce110_fill_display_configs
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 7d07140d37f792f01cfdb8ca9a6a792ab1d29126 upstream.
Also needed by DCE 6.
This way the code that gathers this info can be shared between different DCE versions and doesn't have to be repeated.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c | 2 -- drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c | 10 +++------- drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c | 2 -- 3 files changed, 3 insertions(+), 11 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c +0 -2
@@ -391,8 +391,6 @@ static void dce_pplib_apply_display_requ {struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; - pp_display_cfg->avail_mclk_switch_time_us =dce110_get_min_vblank_time_us (context); -dce110_fill_display_configs (context, pp_display_cfg);if (memcmp (&dc->current_state->pp_display_cfg, pp_display_cfg,sizeof (*pp_display_cfg)) !=0 )
drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c +3 -7
@@ -124,6 +124,9 @@ void dce110_fill_display_configs(int j;int num_cfgs =0 ; + pp_display_cfg->avail_mclk_switch_time_us =dce110_get_min_vblank_time_us (context); + pp_display_cfg->disp_clk_khz = dc->clk_mgr->clks.dispclk_khz; + pp_display_cfg->avail_mclk_switch_time_in_disp_active_us =0 ; pp_display_cfg->crtc_index = dc->res_pool->res_cap->num_timing_generator;for (j =0 ; j < context->stream_count; j++) {
@@ -243,13 +246,6 @@ void dce11_pplib_apply_display_requireme pp_display_cfg->min_engine_clock_deep_sleep_khz = context->bw_ctx.bw.dce.sclk_deep_sleep_khz; - pp_display_cfg->avail_mclk_switch_time_us = -dce110_get_min_vblank_time_us (context); -/* TODO: dce11.2*/ - pp_display_cfg->avail_mclk_switch_time_in_disp_active_us =0 ; - - pp_display_cfg->disp_clk_khz = dc->clk_mgr->clks.dispclk_khz; -dce110_fill_display_configs (context, pp_display_cfg);if (memcmp (&dc->current_state->pp_display_cfg, pp_display_cfg,sizeof (*pp_display_cfg)) !=0 )
drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c +0 -2
@@ -100,8 +100,6 @@ static void dce60_pplib_apply_display_re {struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; - pp_display_cfg->avail_mclk_switch_time_us =dce110_get_min_vblank_time_us (context); -dce110_fill_display_configs (context, pp_display_cfg);if (memcmp (&dc->current_state->pp_display_cfg, pp_display_cfg,sizeof (*pp_display_cfg)) !=0 )
Greg Kroah-Hartman
maintainerPATCH 273/457 scsi: mpi3mr: Drop unnecessary volatile from __iomem pointers
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranjan Kumar <[email protected]>
[ Upstream commit 6853885b21cb1d7157cc14c9d30cc17141565bae ]
The volatile qualifier is redundant for __iomem pointers.
Cleaned up usage in mpi3mr_writeq() and sysif_regs pointer as per Upstream compliance.
Stable-dep-of: c91e140c82eb ("scsi: mpi3mr: Serialize admin queue BAR writes on 32-bit systems")
--- drivers/scsi/mpi3mr/mpi3mr.h | 2 +- drivers/scsi/mpi3mr/mpi3mr_fw.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/scsi/mpi3mr/mpi3mr.h +1 -1
@@ -1185,7 +1185,7 @@ struct mpi3mr_ioc {char name[MPI3MR_NAME_LENGTH ];char driver_name[MPI3MR_NAME_LENGTH ]; -volatile struct mpi3_sysif_registers __iomem *sysif_regs; +struct mpi3_sysif_registers __iomem *sysif_regs;resource_size_t sysif_regs_phys;int bars;u64 dma_mask;
drivers/scsi/mpi3mr/mpi3mr_fw.c +2 -2
@@ -23,12 +23,12 @@ module_param(poll_queues, int, 0444);MODULE_PARM_DESC (poll_queues,"Number of queues for io_uring poll mode. (Range 1 - 126)" );#if defined(writeq) && defined(CONFIG_64BIT ) -static inline void mpi3mr_writeq (__u64 b,volatile void __iomem *addr) +static inline void mpi3mr_writeq (__u64 b,void __iomem *addr) {writeq (b, addr); }#else -static inline void mpi3mr_writeq (__u64 b,volatile void __iomem *addr) +static inline void mpi3mr_writeq (__u64 b,void __iomem *addr) {__u64 data_out = b;
Greg Kroah-Hartman
maintainerPATCH 274/457 scsi: mpi3mr: Serialize admin queue BAR writes on 32-bit systems
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranjan Kumar <[email protected]>
[ Upstream commit c91e140c82eb58724c435f623702e51cc7896646 ]
On 32-bit systems, 64-bit BAR writes to admin queue registers are performed as two 32-bit writes. Without locking, this can cause partial writes when accessed concurrently.
Updated per-queue spinlocks is used to serialize these writes and prevent race conditions.
--- drivers/scsi/mpi3mr/mpi3mr.h | 4 ++++ drivers/scsi/mpi3mr/mpi3mr_fw.c | 15 +++++++++++---- drivers/scsi/mpi3mr/mpi3mr_os.c | 2 ++ 3 files changed, 17 insertions(+), 4 deletions(-)
drivers/scsi/mpi3mr/mpi3mr.h +4 -0
@@ -1137,6 +1137,8 @@ struct scmd_priv {* @logdata_buf: Circular buffer to store log data entries * @logdata_buf_idx: Index of entry in buffer to store * @logdata_entry_sz: log data entry size +* @adm_req_q_bar_writeq_lock: Admin request queue lock +* @adm_reply_q_bar_writeq_lock: Admin reply queue lock * @pend_large_data_sz: Counter to track pending large data * @io_throttle_data_length: I/O size to track in 512b blocks * @io_throttle_high: I/O size to start throttle in 512b blocks
@@ -1339,6 +1341,8 @@ struct mpi3mr_ioc {u8 *logdata_buf;u16 logdata_buf_idx;u16 logdata_entry_sz; +spinlock_t adm_req_q_bar_writeq_lock; +spinlock_t adm_reply_q_bar_writeq_lock;atomic_t pend_large_data_sz;u32 io_throttle_data_length;
drivers/scsi/mpi3mr/mpi3mr_fw.c +11 -4
@@ -23,17 +23,22 @@ module_param(poll_queues, int, 0444);MODULE_PARM_DESC (poll_queues,"Number of queues for io_uring poll mode. (Range 1 - 126)" );#if defined(writeq) && defined(CONFIG_64BIT ) -static inline void mpi3mr_writeq (__u64 b,void __iomem *addr) +static inline void mpi3mr_writeq (__u64 b,void __iomem *addr, +spinlock_t *write_queue_lock) {writeq (b, addr); }#else -static inline void mpi3mr_writeq (__u64 b,void __iomem *addr) +static inline void mpi3mr_writeq (__u64 b,void __iomem *addr, +spinlock_t *write_queue_lock) {__u64 data_out = b; +unsigned long flags; +spin_lock_irqsave (write_queue_lock, flags);writel ((u32)(data_out), addr);writel ((u32)(data_out >>32 ), (addr +4 )); +spin_unlock_irqrestore (write_queue_lock, flags); }#endif
@@ -2954,9 +2959,11 @@ static int mpi3mr_setup_admin_qpair(stru (mrioc->num_admin_req);writel (num_admin_entries, &mrioc->sysif_regs->admin_queue_num_entries);mpi3mr_writeq (mrioc->admin_req_dma, - &mrioc->sysif_regs->admin_request_queue_address); + &mrioc->sysif_regs->admin_request_queue_address, + &mrioc->adm_req_q_bar_writeq_lock);mpi3mr_writeq (mrioc->admin_reply_dma, - &mrioc->sysif_regs->admin_reply_queue_address); + &mrioc->sysif_regs->admin_reply_queue_address, + &mrioc->adm_reply_q_bar_writeq_lock);writel (mrioc->admin_req_pi, &mrioc->sysif_regs->admin_request_queue_pi);writel (mrioc->admin_reply_ci, &mrioc->sysif_regs->admin_reply_queue_ci);return retval;
drivers/scsi/mpi3mr/mpi3mr_os.c +2 -0
@@ -5383,6 +5383,8 @@ mpi3mr_probe(struct pci_dev *pdev, constspin_lock_init (&mrioc->tgtdev_lock);spin_lock_init (&mrioc->watchdog_lock);spin_lock_init (&mrioc->chain_buf_lock); +spin_lock_init (&mrioc->adm_req_q_bar_writeq_lock); +spin_lock_init (&mrioc->adm_reply_q_bar_writeq_lock);spin_lock_init (&mrioc->sas_node_lock);spin_lock_init (&mrioc->trigger_lock);
Greg Kroah-Hartman
maintainerPATCH 275/457 PCI: rockchip: Use standard PCIe definitions
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geraldo Nascimento <[email protected]>
[ Upstream commit cbbfe9f683f0f9b6a1da2eaa53b995a4b5961086 ]
Current code uses custom-defined register offsets and bitfields for the standard PCIe registers. This creates duplication as the PCI header already defines them. So, switch to using the standard PCIe definitions and drop the custom ones.
Stable-dep-of: 114b06ee108c ("PCI: rockchip: Set Target Link Speed to 5.0 GT/s before retraining")
--- drivers/pci/controller/pcie-rockchip-ep.c | 4 +- drivers/pci/controller/pcie-rockchip-host.c | 45 ++++++++++++++-------------- drivers/pci/controller/pcie-rockchip.h | 12 ------- 3 files changed, 26 insertions(+), 35 deletions(-)
drivers/pci/controller/pcie-rockchip-ep.c +2 -2
@@ -518,9 +518,9 @@ static void rockchip_pcie_ep_retrain_lin {u32 status; - status =rockchip_pcie_read (rockchip,PCIE_EP_CONFIG_LCS ); + status =rockchip_pcie_read (rockchip,PCIE_EP_CONFIG_BASE +PCI_EXP_LNKCTL ); status |=PCI_EXP_LNKCTL_RL ; -rockchip_pcie_write (rockchip, status,PCIE_EP_CONFIG_LCS ); +rockchip_pcie_write (rockchip, status,PCIE_EP_CONFIG_BASE +PCI_EXP_LNKCTL ); }static bool rockchip_pcie_ep_link_up (struct rockchip_pcie *rockchip)
drivers/pci/controller/pcie-rockchip-host.c +23 -22
102 lines not on this page · raw message
drivers/pci/controller/pcie-rockchip.h +1 -11
@@ -155,17 +155,7 @@#define PCIE_EP_CONFIG_DID_VID (PCIE_EP_CONFIG_BASE + 0x00)#define PCIE_EP_CONFIG_LCS (PCIE_EP_CONFIG_BASE + 0xd0)#define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) -#define PCIE_RC_CONFIG_DCR (PCIE_RC_CONFIG_BASE + 0xc4) -#define PCIE_RC_CONFIG_DCR_CSPL_SHIFT 18 -#define PCIE_RC_CONFIG_DCR_CSPL_LIMIT 0xff -#define PCIE_RC_CONFIG_DCR_CPLS_SHIFT 26 -#define PCIE_RC_CONFIG_DCSR (PCIE_RC_CONFIG_BASE + 0xc8) -#define PCIE_RC_CONFIG_DCSR_MPS_MASK GENMASK(7, 5) -#define PCIE_RC_CONFIG_DCSR_MPS_256 (0x1 << 5) -#define PCIE_RC_CONFIG_LINK_CAP (PCIE_RC_CONFIG_BASE + 0xcc) -#define PCIE_RC_CONFIG_LINK_CAP_L0S BIT(10) -#define PCIE_RC_CONFIG_LCS (PCIE_RC_CONFIG_BASE + 0xd0) -#define PCIE_EP_CONFIG_LCS (PCIE_EP_CONFIG_BASE + 0xd0) +#define PCIE_RC_CONFIG_CR (PCIE_RC_CONFIG_BASE + 0xc0)#define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)#define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_CONFIG_BASE + 0x274)#define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK GENMASK(31, 20)
Greg Kroah-Hartman
maintainerPATCH 276/457 PCI: rockchip: Set Target Link Speed to 5.0 GT/s before retraining
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geraldo Nascimento <[email protected]>
[ Upstream commit 114b06ee108cabc82b995fbac6672230a9776936 ]
Rockchip controllers can support up to 5.0 GT/s link speed. But the driver doesn't set the Target Link Speed currently. This may cause failure in retraining the link to 5.0 GT/s if supported by the endpoint. So set the Target Link Speed to 5.0 GT/s in the Link Control and Status Register 2.
--- drivers/pci/controller/pcie-rockchip-host.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/pci/controller/pcie-rockchip-host.c +4 -0
@@ -342,6 +342,10 @@ static int rockchip_pcie_host_init_port(* Enable retrain for gen2. This should be configured only after * gen1 finished. */ + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL2 ); + status &= ~PCI_EXP_LNKCTL2_TLS ; + status |=PCI_EXP_LNKCTL2_TLS_5_0GT ; +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL2 ); status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |=PCI_EXP_LNKCTL_RL ;rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL );
Greg Kroah-Hartman
maintainerPATCH 277/457 drm/amdgpu: fix task hang from failed job submission during process kill
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu01 Tong <[email protected]>
commit aa5fc4362fac9351557eb27c745579159a2e4520 upstream.
During process kill, drm_sched_entity_flush() will kill the vm entities. The following job submissions of this process will fail, and the resources of these jobs have not been released, nor have the fences been signalled, causing tasks to hang and timeout.
Fix by check entity status in amdgpu_vm_ready() and avoid submit jobs to stopped entity.
v2: add amdgpu_vm_ready() check before amdgpu_vm_clear_freed() in function amdgpu_cs_vm_handling().
--- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 3 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 15 +++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +3 -0
@@ -1138,6 +1138,9 @@ static int amdgpu_cs_vm_handling(struct } } +if (!amdgpu_vm_ready (vm)) +return -EINVAL ; + r =amdgpu_vm_clear_freed (adev, vm,NULL );if (r)return r;
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +11 -4
@@ -654,11 +654,10 @@ int amdgpu_vm_validate(struct amdgpu_dev* Check if all VM PDs/PTs are ready for updates * * Returns: -* True if VM is not evicting. +* True if VM is not evicting and all VM entities are not stopped */ bool amdgpu_vm_ready (struct amdgpu_vm *vm) { -bool empty;bool ret;amdgpu_vm_eviction_lock (vm);
@@ -666,10 +665,18 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vamdgpu_vm_eviction_unlock (vm);spin_lock (&vm->status_lock); - empty =list_empty (&vm->evicted); + ret &=list_empty (&vm->evicted);spin_unlock (&vm->status_lock); -return ret && empty; +spin_lock (&vm->immediate.lock); + ret &= !vm->immediate.stopped; +spin_unlock (&vm->immediate.lock); + +spin_lock (&vm->delayed.lock); + ret &= !vm->delayed.stopped; +spin_unlock (&vm->delayed.lock); + +return ret; }/**
Greg Kroah-Hartman
maintainerPATCH 278/457 soc: qcom: mdt_loader: Fix error return values in mdt_header_valid()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit 9f35ab0e53ccbea57bb9cbad8065e0406d516195 upstream.
This function is supposed to return true for valid headers and false for invalid. In a couple places it returns -EINVAL instead which means the invalid headers are counted as true. Change it to return false.
--- drivers/soc/qcom/mdt_loader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/soc/qcom/mdt_loader.c +2 -2
@@ -33,14 +33,14 @@ static bool mdt_header_valid(const strucreturn false;if (ehdr->e_phentsize !=sizeof (struct elf32_phdr )) -return -EINVAL ; +return false; phend =size_add (size_mul (sizeof (struct elf32_phdr ), ehdr->e_phnum), ehdr->e_phoff);if (phend > fw->size)return false;if (ehdr->e_shentsize !=sizeof (struct elf32_shdr )) -return -EINVAL ; +return false; shend =size_add (size_mul (sizeof (struct elf32_shdr ), ehdr->e_shnum), ehdr->e_shoff);if (shend > fw->size)
Re: [PATCH 6.16 278/457] soc: qcom: mdt_loader: Fix error return values in mdt_header_valid()
Hi Greg,
Quoted 12 lines · Greg Kroah-Hartman
6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit
9f35ab0e53ccbea57bb9cbad8065e0406d516195upstream.This function is supposed to return true for valid headers and false for invalid. In a couple places it returns
-EINVALinstead which means the invalid headers are counted as true. Change it to return false.
Quoted 6 lines
Fixes 9f9967fed9d0 ("soc: qcom: mdt_loader: Ensure we don't read past the ELF header")Signed-off-by Dan Carpenter <[email protected]>Reviewed-by Konrad Dybcio <[email protected]>Signed-off-by Bjorn Andersson <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>
This patch breaks firmware loading on most Qualcomm platforms, see e.g. the replies from Val and Neil on the original patch [1, 2].
There is a fix pending, which should soon land in mainline:
https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git/commit/?h=qcom-drivers-fixes-for-6.17&id=25daf9af0ac1bf12490b723b5efaf8dcc85980bc
For the next 5.4-6.16 stable releases, could you pick up either the fix or revert this patch together with commit "soc: qcom: mdt_loader: Ensure we dont read past the ELF header"?
The problematic commit ("soc: qcom: mdt_loader: Fix error return values in mdt_header_valid()") wasn't backported directly to 5.4-6.1, but a quick look suggests that Sasha squashed the problematic change in the manual backports of "soc: qcom: mdt_loader: Ensure we dont read past the ELF header" (at least for 5.4-5.15). I think we will need the fix for all trees (5.4-6.16), or we should revert the patch(es) to avoid the regression.
Thanks,
Stephan
[1]: https://lore.kernel.org/linux-arm-msm/[email protected]/
[2]: https://lore.kernel.org/linux-arm-msm/[email protected]/
Sasha Levin
maintainerRe: [PATCH 6.16 278/457] soc: qcom: mdt_loader: Fix error return values in mdt_header_valid()
Quoted 32 lines · Stephan Gerhold
Hi Greg,
Quoted 12 lines · Greg Kroah-Hartman
6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit
9f35ab0e53ccbea57bb9cbad8065e0406d516195upstream.This function is supposed to return true for valid headers and false for invalid. In a couple places it returns
-EINVALinstead which means the invalid headers are counted as true. Change it to return false.Quoted 6 lines
Fixes 9f9967fed9d0 ("soc: qcom: mdt_loader: Ensure we don't read past the ELF header")Signed-off-by Dan Carpenter <[email protected]>Reviewed-by Konrad Dybcio <[email protected]>Signed-off-by Bjorn Andersson <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>This patch breaks firmware loading on most Qualcomm platforms, see e.g. the replies from Val and Neil on the original patch [1, 2].
There is a fix pending, which should soon land in mainline:
https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git/commit/?h=qcom-drivers-fixes-for-6.17&id=25daf9af0ac1bf12490b723b5efaf8dcc85980bcFor the next 5.4-6.16 stable releases, could you pick up either the fix or revert this patch together with commit "soc: qcom:
mdt_loader: Ensure we dont read past the ELF header"?
Quoted 7 lines
The problematic commit ("soc: qcom:
mdt_loader: Fix error return values inmdt_header_valid()") wasn't backported directly to 5.4-6.1, but a quick look suggests that Sasha squashed the problematic change in the manual backports of "soc: qcom:mdt_loader: Ensure we dont read past the ELF header" (at least for 5.4-5.15). I think we will need the fix for all trees (5.4-6.16), or we should revert the patch(es) to avoid the regression.
Oh, heh, when I backported it I got a warning from the compiler so I assumed it was because of API differences on older trees, so I just fixed it up. Haven't realized it was broken upstream too.
We can wait for the fix to land and take it in too.
Signature · 2 lines
Thanks, Sasha
Greg Kroah-Hartman
maintainerPATCH 279/457 xfs: fix frozen file system assert in xfs_trans_alloc
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
commit 647b3d59c768d7638dd17c78c8044178364383ca upstream.
Commit 83a80e95e797 ("xfs: decouple xfs_trans_alloc_empty from xfs_trans_alloc") move the place of the assert for a frozen file system after the sb_start_intwrite call that ensures it doesn't run on frozen file systems, and thus allows to incorrect trigger it.
Fix that by moving it back to where it belongs.
--- fs/xfs/xfs_trans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/xfs_trans.c +1 -1
@@ -284,8 +284,8 @@ xfs_trans_alloc(* by doing GFP_KERNEL allocations inside sb_start_intwrite(). */ retry: -WARN_ON (mp->m_super->s_writers.frozen ==SB_FREEZE_COMPLETE ); tp =__xfs_trans_alloc (mp, flags); +WARN_ON (mp->m_super->s_writers.frozen ==SB_FREEZE_COMPLETE ); error =xfs_trans_reserve (tp, resp, blocks, rtextents);if (error == -ENOSPC && want_retry) {xfs_trans_cancel (tp);
Greg Kroah-Hartman
maintainerPATCH 280/457 rust: faux: fix C header link
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit a5ba9ad417254c49ecf06ac5ab36ec4b12ee133f upstream.
Starting with Rust 1.91.0 (expected 2025-10-30), rustdoc has improved some false negatives around intra-doc links [1], and it found a broken intra-doc link we currently have:
error: unresolved link to `include/linux/device/faux.h`
--> rust/kernel/faux.rs:7:17
|
7 | //! C header: [`include/linux/device/faux.h`]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `include/linux/device/faux.h` in scope
|
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
= note: `-D rustdoc::broken-intra-doc-links` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(rustdoc::broken_intra_doc_links)]`Our srctree/ C header links are not intra-doc links, thus they need the link destination.
Thus fix it.
--- rust/kernel/faux.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/faux.rs +1 -1
@@ -4,7 +4,7 @@//! //! This module provides bindings for working with faux devices in kernel modules. //! -//! C header: [`include/linux/device/faux.h`] +//! C header: [`include/linux/device/faux.h`](srctree/include/linux/device/faux.h) use crate ::{bindings, device, error::code::*, prelude::*};use core::ptr::{addr_of_mut, null, null_mut,NonNull };
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 281/457 debugfs: fix mount options not being applied
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charalampos Mitrodimas <[email protected]>
commit ba6cc29351b1fa0cb9adce91b88b9f3c3cbe9c46 upstream.
Mount options (uid, gid, mode) are silently ignored when debugfs is mounted. This is a regression introduced during the conversion to the new mount API.
When the mount API conversion was done, the parsed options were never applied to the superblock when it was reused. As a result, the mount options were ignored when debugfs was mounted.
Fix this by following the same pattern as the tracefs fix in commit e4d32142d1de ("tracing: Fix tracefs mount options"). Call debugfs_reconfigure() in debugfs_get_tree() to apply the mount options to the superblock after it has been created or reused.
As an example, with the bug the "mode" mount option is ignored:
$ mount -o mode=0666 -t debugfs debugfs /tmp/debugfs_test $ mount | grep debugfs_test debugfs on /tmp/debugfs_test type debugfs (rw,relatime) $ ls -ld /tmp/debugfs_test drwx------ 25 root root 0 Aug 4 14:16 /tmp/debugfs_test
With the fix applied, it works as expected:
$ mount -o mode=0666 -t debugfs debugfs /tmp/debugfs_test $ mount | grep debugfs_test debugfs on /tmp/debugfs_test type debugfs (rw,relatime,mode=666) $ ls -ld /tmp/debugfs_test drw-rw-rw- 37 root root 0 Aug 2 17:28 /tmp/debugfs_test
--- fs/debugfs/inode.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
fs/debugfs/inode.c +10 -1
@@ -183,6 +183,9 @@ static int debugfs_reconfigure(struct fsstruct debugfs_fs_info *sb_opts = sb->s_fs_info;struct debugfs_fs_info *new_opts = fc->s_fs_info; +if (!new_opts) +return 0 ; +sync_filesystem (sb);/* structure copy of new mount options to sb */
@@ -282,10 +285,16 @@ static int debugfs_fill_super(struct supstatic int debugfs_get_tree (struct fs_context *fc) { +int err; +if (!(debugfs_allow &DEBUGFS_ALLOW_API ))return -EPERM ; -return get_tree_single (fc, debugfs_fill_super); + err =get_tree_single (fc, debugfs_fill_super); +if (err) +return err; + +return debugfs_reconfigure (fc); }static void debugfs_free_fc (struct fs_context *fc)
Greg Kroah-Hartman
maintainerPATCH 282/457 fs: fix incorrect lflags value in the move_mount syscall
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuntao Wang <[email protected]>
[ Upstream commit 593d9e4c3d634c370f226f55453c376bf43b3684 ]
The lflags value used to look up from_path was overwritten by the one used to look up to_path.
In other words, from_path was looked up with the wrong lflags value. Fix it.
--- fs/namespace.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-)
fs/namespace.c +20 -12
@@ -4657,20 +4657,10 @@ SYSCALL_DEFINE5(move_mount,if (flags &MOVE_MOUNT_SET_GROUP ) mflags |=MNT_TREE_PROPAGATION ;if (flags &MOVE_MOUNT_BENEATH ) mflags |=MNT_TREE_BENEATH ; - lflags =0 ; -if (flags &MOVE_MOUNT_F_SYMLINKS ) lflags |=LOOKUP_FOLLOW ; -if (flags &MOVE_MOUNT_F_AUTOMOUNTS ) lflags |=LOOKUP_AUTOMOUNT ; uflags =0 ; -if (flags &MOVE_MOUNT_F_EMPTY_PATH ) uflags =AT_EMPTY_PATH ; - from_name =getname_maybe_null (from_pathname, uflags); -if (IS_ERR (from_name)) -return PTR_ERR (from_name); +if (flags &MOVE_MOUNT_T_EMPTY_PATH ) + uflags =AT_EMPTY_PATH ; - lflags =0 ; -if (flags &MOVE_MOUNT_T_SYMLINKS ) lflags |=LOOKUP_FOLLOW ; -if (flags &MOVE_MOUNT_T_AUTOMOUNTS ) lflags |=LOOKUP_AUTOMOUNT ; - uflags =0 ; -if (flags &MOVE_MOUNT_T_EMPTY_PATH ) uflags =AT_EMPTY_PATH ; to_name =getname_maybe_null (to_pathname, uflags);if (IS_ERR (to_name))return PTR_ERR (to_name);
@@ -4683,11 +4673,24 @@ SYSCALL_DEFINE5(move_mount, to_path =fd_file (f_to)->f_path;path_get (&to_path); }else { + lflags =0 ; +if (flags &MOVE_MOUNT_T_SYMLINKS ) + lflags |=LOOKUP_FOLLOW ; +if (flags &MOVE_MOUNT_T_AUTOMOUNTS ) + lflags |=LOOKUP_AUTOMOUNT ; ret =filename_lookup (to_dfd, to_name, lflags, &to_path,NULL );if (ret)return ret; } + uflags =0 ; +if (flags &MOVE_MOUNT_F_EMPTY_PATH ) + uflags =AT_EMPTY_PATH ; + + from_name =getname_maybe_null (from_pathname, uflags); +if (IS_ERR (from_name)) +return PTR_ERR (from_name); +if (!from_name && from_dfd >=0 ) {CLASS (fd_raw, f_from)(from_dfd);if (fd_empty (f_from))
@@ -4696,6 +4699,11 @@ SYSCALL_DEFINE5(move_mount,return vfs_move_mount (&fd_file (f_from)->f_path, &to_path, mflags); } + lflags =0 ; +if (flags &MOVE_MOUNT_F_SYMLINKS ) + lflags |=LOOKUP_FOLLOW ; +if (flags &MOVE_MOUNT_F_AUTOMOUNTS ) + lflags |=LOOKUP_AUTOMOUNT ; ret =filename_lookup (from_dfd, from_name, lflags, &from_path,NULL );if (ret)return ret;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 283/457 btrfs: zoned: fix data relocation block group reservation
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naohiro Aota <[email protected]>
[ Upstream commit daa0fde322350b467bc62bc1b141bf62df6123f8 ]
btrfs_zoned_reserve_data_reloc_bg() is called on mount and at that point, all data block groups belong to the primary data space_info. So, we don't find anything in the data relocation space_info.
Also, the condition "bg->used > 0" can select a block group with full of zone_unusable bytes for the candidate. As we cannot allocate from the block group, it is useless to reserve it as the data relocation block group.
Furthermore, because of the space_info separation, we need to migrate the selected block group to the data relocation space_info. If not, the extent allocator cannot use the block group to do the allocation.
This commit fixes these three issues.
--- fs/btrfs/zoned.c | 55 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 8 deletions(-)
fs/btrfs/zoned.c +47 -8
@@ -18,6 +18,7 @@#include "accessors.h" #include "bio.h" #include "transaction.h" +#include "sysfs.h" /* Maximum number of zones to report per blkdev_report_zones() call */ #define BTRFS_REPORT_NR_ZONES 4096
@@ -2510,12 +2511,12 @@ void btrfs_clear_data_reloc_bg(struct btrfs_block_group *bg)void btrfs_zoned_reserve_data_reloc_bg (struct btrfs_fs_info *fs_info) {struct btrfs_space_info *data_sinfo = fs_info->data_sinfo; -struct btrfs_space_info *space_info = data_sinfo->sub_group[0 ]; +struct btrfs_space_info *space_info = data_sinfo;struct btrfs_trans_handle *trans;struct btrfs_block_group *bg;struct list_head *bg_list;u64 alloc_flags; -bool initial = false; +bool first = true;bool did_chunk_alloc = false;int index;int ret;
@@ -2529,21 +2530,52 @@ void btrfs_zoned_reserve_data_reloc_bg(struct btrfs_fs_info *fs_info)if (sb_rdonly (fs_info->sb))return ; -ASSERT (space_info->subgroup_id ==BTRFS_SUB_GROUP_DATA_RELOC ); alloc_flags =btrfs_get_alloc_profile (fs_info, space_info->flags); index =btrfs_bg_flags_to_raid_index (alloc_flags); - bg_list = &data_sinfo->block_groups[index]; +/* Scan the data space_info to find empty block groups. Take the second one. */ again: + bg_list = &space_info->block_groups[index];list_for_each_entry (bg, bg_list, list) { -if (bg->used >0 ) +if (bg->alloc_offset !=0 )continue ; -if (!initial) { - initial = true; +if (first) { + first = false;continue ; } +if (space_info == data_sinfo) { +/* Migrate the block group to the data relocation space_info. */ +struct btrfs_space_info *reloc_sinfo = data_sinfo->sub_group[0 ]; +int factor; + +ASSERT (reloc_sinfo->subgroup_id ==BTRFS_SUB_GROUP_DATA_RELOC ); + factor =btrfs_bg_type_to_factor (bg->flags); + +down_write (&space_info->groups_sem); +list_del_init (&bg->list); +/* We can assume this as we choose the second empty one. */ +ASSERT (!list_empty (&space_info->block_groups[index])); +up_write (&space_info->groups_sem); + +spin_lock (&space_info->lock); + space_info->total_bytes -= bg->length; + space_info->disk_total -= bg->length * factor; +/* There is no allocation ever happened. */ +ASSERT (bg->used ==0 ); +ASSERT (bg->zone_unusable ==0 ); +/* No super block in a block group on the zoned setup. */ +ASSERT (bg->bytes_super ==0 ); +spin_unlock (&space_info->lock); + + bg->space_info = reloc_sinfo; +if (reloc_sinfo->block_group_kobjs[index] ==NULL ) +btrfs_sysfs_add_block_group_type (bg); + +btrfs_add_bg_to_space_info (fs_info, bg); + } + fs_info->data_reloc_bg = bg->start;set_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , &bg->runtime_flags);btrfs_zone_activate (bg);
@@ -2558,11 +2590,18 @@ void btrfs_zoned_reserve_data_reloc_bg(struct btrfs_fs_info *fs_info)if (IS_ERR (trans))return ; +/* Allocate new BG in the data relocation space_info. */ + space_info = data_sinfo->sub_group[0 ]; +ASSERT (space_info->subgroup_id ==BTRFS_SUB_GROUP_DATA_RELOC ); ret =btrfs_chunk_alloc (trans, space_info, alloc_flags,CHUNK_ALLOC_FORCE );btrfs_end_transaction (trans);if (ret ==1 ) { +/* +* We allocated a new block group in the data relocation space_info. We +* can take that one. +*/ + first = false; did_chunk_alloc = true; - bg_list = &space_info->block_groups[index]; goto again; } }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 284/457 fhandle: do_handle_open() should get FD with user flags
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Bertschinger <[email protected]>
[ Upstream commit b5ca88927e353185b3d9ac4362d33e5aeb25771f ]
In f07c7cc4684a, do_handle_open() was switched to use the automatic cleanup method for getting a FD. In that change it was also switched to pass O_CLOEXEC unconditionally to get_unused_fd_flags() instead of passing the user-specified flags.
I don't see anything in that commit description that indicates this was intentional, so I am assuming it was an oversight.
With this fix, the FD will again be opened with, or without, O_CLOEXEC according to what the user requested.
--- fs/fhandle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/fhandle.c +1 -1
@@ -404,7 +404,7 @@ static long do_handle_open(int mountdirfd, struct file_handle __user *ufh,if (retval)return retval; -CLASS (get_unused_fd, fd)(O_CLOEXEC ); +CLASS (get_unused_fd, fd)(open_flag);if (fd <0 )return fd;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 285/457 libfs: massage path_from_stashed() to allow custom stashing behavior
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
[ Upstream commit bda3f1608d993419fa247dc11263fc931ceca58a ]
* Add a callback to struct stashed_operations so it's possible to implement custom behavior for pidfs and allow for it to return errors.
* Teach stashed_dentry_get() to handle error pointers.
Stable-dep-of: 0b2d71a7c826 ("pidfs: Fix memory leak in pidfd_info()")
--- fs/internal.h | 3 +++ fs/libfs.c | 27 ++++++++++++++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-)
fs/internal.h +3 -0
@@ -322,12 +322,15 @@ struct mnt_idmap *alloc_mnt_idmap(struct user_namespace *mnt_userns);struct mnt_idmap *mnt_idmap_get (struct mnt_idmap *idmap);void mnt_idmap_put (struct mnt_idmap *idmap);struct stashed_operations { +struct dentry *(*stash_dentry)(struct dentry **stashed, +struct dentry *dentry);void (*put_data)(void *data);int (*init_inode)(struct inode *inode,void *data); };int path_from_stashed (struct dentry **stashed,struct vfsmount *mnt,void *data,struct path *path);void stashed_dentry_prune (struct dentry *dentry); +struct dentry *stash_dentry (struct dentry **stashed,struct dentry *dentry);struct dentry *stashed_dentry_get (struct dentry **stashed);/** * path_mounted - check whether path is mounted
fs/libfs.c +20 -7
@@ -2126,6 +2126,8 @@ struct dentry *stashed_dentry_get(struct dentry **stashed) dentry =rcu_dereference (*stashed);if (!dentry)return NULL ; +if (IS_ERR (dentry)) +return dentry;if (!lockref_get_not_dead (&dentry->d_lockref))return NULL ;return dentry;
@@ -2174,8 +2176,7 @@ static struct dentry *prepare_anon_dentry(struct dentry **stashed,return dentry; } -static struct dentry *stash_dentry (struct dentry **stashed, -struct dentry *dentry) +struct dentry *stash_dentry (struct dentry **stashed,struct dentry *dentry) {guard (rcu)();for (;;) {
@@ -2216,12 +2217,15 @@ static struct dentry *stash_dentry(struct dentry **stashed,int path_from_stashed (struct dentry **stashed,struct vfsmount *mnt,void *data,struct path *path) { -struct dentry *dentry; +struct dentry *dentry, *res;const struct stashed_operations *sops = mnt->mnt_sb->s_fs_info;/* See if dentry can be reused. */ - path->dentry =stashed_dentry_get (stashed); -if (path->dentry) { + res =stashed_dentry_get (stashed); +if (IS_ERR (res)) +return PTR_ERR (res); +if (res) { + path->dentry = res; sops->put_data (data); goto out_path; }
@@ -2232,8 +2236,17 @@ int path_from_stashed(struct dentry **stashed, struct vfsmount *mnt, void *data,return PTR_ERR (dentry);/* Added a new dentry. @data is now owned by the filesystem. */ - path->dentry =stash_dentry (stashed, dentry); -if (path->dentry != dentry) +if (sops->stash_dentry) + res = sops->stash_dentry (stashed, dentry); +else + res =stash_dentry (stashed, dentry); +if (IS_ERR (res)) { +dput (dentry); +return PTR_ERR (res); + } + path->dentry = res; +/* A dentry was reused. */ +if (res != dentry)dput (dentry); out_path:
Signature · 1 line
2.50.1