6.12.43-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainerPATCH 305/444 RDMA: hfi1: fix possible divide-by-zero in find_hw_thread_mask()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yury Norov [NVIDIA] <[email protected]>
[ Upstream commit 59f7d2138591ef8f0e4e4ab5f1ab674e8181ad3a ]
The function divides number of online CPUs by num_core_siblings, and later checks the divider by zero. This implies a possibility to get and divide-by-zero runtime error. Fix it by moving the check prior to division. This also helps to save one indentation level.
--- drivers/infiniband/hw/hfi1/affinity.c | 44 +++++++++++++++------------ 1 file changed, 24 insertions(+), 20 deletions(-)
drivers/infiniband/hw/hfi1/affinity.c +24 -20
@@ -964,31 +964,35 @@ static void find_hw_thread_mask(uint hw_thread_no, cpumask_var_t hw_thread_mask, struct hfi1_affinity_node_list *affinity) {int possible, curr_cpu, i; -uint num_cores_per_socket = node_affinity.num_online_cpus / +uint num_cores_per_socket; + +cpumask_copy (hw_thread_mask, &affinity->proc.mask); + +if (affinity->num_core_siblings ==0 ) +return ; + + num_cores_per_socket = node_affinity.num_online_cpus / affinity->num_core_siblings / node_affinity.num_online_nodes; -cpumask_copy (hw_thread_mask, &affinity->proc.mask); -if (affinity->num_core_siblings >0 ) { -/* Removing other siblings not needed for now */ - possible =cpumask_weight (hw_thread_mask); - curr_cpu =cpumask_first (hw_thread_mask); -for (i =0 ; - i < num_cores_per_socket * node_affinity.num_online_nodes; - i++) - curr_cpu =cpumask_next (curr_cpu, hw_thread_mask); - -for (; i < possible; i++) { -cpumask_clear_cpu (curr_cpu, hw_thread_mask); - curr_cpu =cpumask_next (curr_cpu, hw_thread_mask); - } +/* Removing other siblings not needed for now */ + possible =cpumask_weight (hw_thread_mask); + curr_cpu =cpumask_first (hw_thread_mask); +for (i =0 ; + i < num_cores_per_socket * node_affinity.num_online_nodes; + i++) + curr_cpu =cpumask_next (curr_cpu, hw_thread_mask); -/* Identifying correct HW threads within physical cores */ -cpumask_shift_left (hw_thread_mask, hw_thread_mask, - num_cores_per_socket * - node_affinity.num_online_nodes * - hw_thread_no); +for (; i < possible; i++) { +cpumask_clear_cpu (curr_cpu, hw_thread_mask); + curr_cpu =cpumask_next (curr_cpu, hw_thread_mask); } + +/* Identifying correct HW threads within physical cores */ +cpumask_shift_left (hw_thread_mask, hw_thread_mask, + num_cores_per_socket * + node_affinity.num_online_nodes * + hw_thread_no); }int hfi1_get_proc_affinity (int node)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 306/444 RDMA/core: reduce stack using in nldev_stat_get_doit()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
[ Upstream commit 43163f4c30f94d2103c948a247cdf2cda5068ca7 ]
In the s390 defconfig, gcc-10 and earlier end up inlining three functions into nldev_stat_get_doit(), and each of them uses some 600 bytes of stack.
The result is a function with an overly large stack frame and a warning:
drivers/infiniband/core/nldev.c:2466:1: error: the frame size of 1720 bytes is larger than 1280 bytes [-Werror=frame-larger-than=]
Mark the three functions noinline_for_stack to prevent this, ensuring that only one copy of the nlattr array is on the stack of each function.
--- drivers/infiniband/core/nldev.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/infiniband/core/nldev.c +12 -10
@@ -1468,10 +1468,11 @@ static const struct nldev_fill_res_entry fill_entries[RDMA_RESTRACK_MAX] = { }; -static int res_get_common_doit (struct sk_buff *skb,struct nlmsghdr *nlh, -struct netlink_ext_ack *extack, -enum rdma_restrack_type res_type, -res_fill_func_t fill_func) +static noinline_for_stack int +res_get_common_doit (struct sk_buff *skb,struct nlmsghdr *nlh, +struct netlink_ext_ack *extack, +enum rdma_restrack_type res_type, +res_fill_func_t fill_func) {const struct nldev_fill_res_entry *fe = &fill_entries[res_type];struct nlattr *tb[RDMA_NLDEV_ATTR_MAX ];
@@ -2256,10 +2257,10 @@ static int nldev_stat_del_doit(struct sk_buff *skb, struct nlmsghdr *nlh,return ret; } -static int stat_get_doit_default_counter (struct sk_buff *skb, -struct nlmsghdr *nlh, -struct netlink_ext_ack *extack, -struct nlattr *tb[]) +static noinline_for_stack int +stat_get_doit_default_counter (struct sk_buff *skb,struct nlmsghdr *nlh, +struct netlink_ext_ack *extack, +struct nlattr *tb[]) {struct rdma_hw_stats *stats;struct nlattr *table_attr;
@@ -2349,8 +2350,9 @@ static int stat_get_doit_default_counter(struct sk_buff *skb,return ret; } -static int stat_get_doit_qp (struct sk_buff *skb,struct nlmsghdr *nlh, -struct netlink_ext_ack *extack,struct nlattr *tb[]) +static noinline_for_stack int +stat_get_doit_qp (struct sk_buff *skb,struct nlmsghdr *nlh, +struct netlink_ext_ack *extack,struct nlattr *tb[]) {static enum rdma_nl_counter_mode mode;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 307/444 scsi: lpfc: Ensure HBA_SETUP flag is used only for SLI4 in dev_loss_tmo_callbk
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Tee <[email protected]>
[ Upstream commit 1cced5779e7a3ff7ec025fc47c76a7bd3bb38877 ]
For SLI3, the HBA_SETUP flag is never set so the lpfc_dev_loss_tmo_callbk always early returns. Add a phba->sli_rev check for SLI4 mode so that the SLI3 path can flow through the original dev_loss_tmo worker thread design to lpfc_dev_loss_tmo_handler instead of early return.
--- drivers/scsi/lpfc/lpfc_hbadisc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/lpfc/lpfc_hbadisc.c +2 -1
@@ -177,7 +177,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)/* Don't schedule a worker thread event if the vport is going down. */ if (test_bit (FC_UNLOADING , &vport->load_flag) || - !test_bit (HBA_SETUP , &phba->hba_flag)) { + (phba->sli_rev ==LPFC_SLI_REV4 && + !test_bit (HBA_SETUP , &phba->hba_flag))) {spin_lock_irqsave (&ndlp->lock, iflags); ndlp->rport =NULL ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 308/444 scsi: lpfc: Check for hdwq null ptr when cleaning up lpfc_vport structure
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Tee <[email protected]>
[ Upstream commit 6698796282e828733cde3329c887b4ae9e5545e9 ]
If a call to lpfc_sli4_read_rev() from lpfc_sli4_hba_setup() fails, the resultant cleanup routine lpfc_sli4_vport_delete_fcp_xri_aborted() may occur before sli4_hba.hdwqs are allocated. This may result in a null pointer dereference when attempting to take the abts_io_buf_list_lock for the first hardware queue. Fix by adding a null ptr check on phba->sli4_hba.hdwq and early return because this situation means there must have been an error during port initialization.
--- drivers/scsi/lpfc/lpfc_scsi.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/scsi/lpfc/lpfc_scsi.c +4 -0
@@ -390,6 +390,10 @@ lpfc_sli4_vport_delete_fcp_xri_aborted(struct lpfc_vport *vport)if (!(vport->cfg_enable_fc4_type &LPFC_ENABLE_FCP ))return ; +/* may be called before queues established if hba_setup fails */ +if (!phba->sli4_hba.hdwq) +return ; +spin_lock_irqsave (&phba->hbalock, iflag);for (idx =0 ; idx < phba->cfg_hdw_queue; idx++) { qp = &phba->sli4_hba.hdwq[idx];
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 309/444 power: supply: qcom_battmgr: Add lithium-polymer entry
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abel Vesa <[email protected]>
[ Upstream commit 202ac22b8e2e015e6c196fd8113f3d2a62dd1afc ]
On some Dell XPS 13 (9345) variants, the battery used is lithium-polymer based. Currently, this is reported as unknown technology due to the entry missing.
[ 4083.135325] Unknown battery technology 'LIP'
Add another check for lithium-polymer in the technology parsing callback and return that instead of unknown.
--- drivers/power/supply/qcom_battmgr.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/power/supply/qcom_battmgr.c +2 -0
@@ -980,6 +980,8 @@ static unsigned int qcom_battmgr_sc8280xp_parse_technology(const char *chemistry {if (!strncmp (chemistry,"LIO" ,BATTMGR_CHEMISTRY_LEN ))return POWER_SUPPLY_TECHNOLOGY_LION ; +if (!strncmp (chemistry,"LIP" ,BATTMGR_CHEMISTRY_LEN )) +return POWER_SUPPLY_TECHNOLOGY_LIPO ;pr_err ("Unknown battery technology '%s'\n" , chemistry);return POWER_SUPPLY_TECHNOLOGY_UNKNOWN ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 310/444 scsi: mpt3sas: Correctly handle ATA device errors
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
[ Upstream commit 15592a11d5a5c8411ac8494ec49736b658f6fbff ]
With the ATA error model, an NCQ command failure always triggers an abort (termination) of all NCQ commands queued on the device. In such case, the SAT or the host must handle the failed command according to the command sense data and immediately retry all other NCQ commands that were aborted due to the failed NCQ command.
For SAS HBAs controlled by the mpt3sas driver, NCQ command aborts are not handled by the HBA SAT and sent back to the host, with an ioc log information equal to 0x31080000 (IOC_LOGINFO_PREFIX_PL with the PL code PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR). The function _scsih_io_done() always forces a retry of commands terminated with the status MPI2_IOCSTATUS_SCSI_IOC_TERMINATED using the SCSI result DID_SOFT_ERROR, regardless of the log_info for the command. This correctly forces the retry of collateral NCQ abort commands, but with the retry counter for the command being incremented. If a command to an ATA device is subject to too many retries due to other NCQ commands failing (e.g. read commands trying to access unreadable sectors), the collateral NCQ abort commands may be terminated with an error as they run out of retries. This violates the SAT specification and causes hard-to-debug command errors.
Solve this issue by modifying the handling of the MPI2_IOCSTATUS_SCSI_IOC_TERMINATED status to check if a command is for an ATA device and if the command loginfo indicates an NCQ collateral abort. If that is the case, force the command retry using the SCSI result DID_IMM_RETRY to avoid incrementing the command retry count.
--- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
drivers/scsi/mpt3sas/mpt3sas_scsih.c +19 -0
@@ -195,6 +195,14 @@ struct sense_info {#define MPT3SAS_PORT_ENABLE_COMPLETE (0xFFFD)#define MPT3SAS_ABRT_TASK_SET (0xFFFE)#define MPT3SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF) + +/* +* SAS Log info code for a NCQ collateral abort after an NCQ error: +* IOC_LOGINFO_PREFIX_PL | PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR +* See: drivers/message/fusion/lsi/mpi_log_sas.h +*/ +#define IOC_LOGINFO_SATA_NCQ_FAIL_AFTER_ERR 0x31080000 +/** * struct fw_event_work - firmware event struct * @list: link list framework
@@ -5814,6 +5822,17 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) scmd->result =DID_TRANSPORT_DISRUPTED <<16 ; goto out; } +if (log_info ==IOC_LOGINFO_SATA_NCQ_FAIL_AFTER_ERR ) { +/* +* This is a ATA NCQ command aborted due to another NCQ +* command failure. We must retry this command +* immediately but without incrementing its retry +* counter. +*/ +WARN_ON_ONCE (xfer_cnt !=0 ); + scmd->result =DID_IMM_RETRY <<16 ; +break ; + }if (log_info ==0x31110630 ) {if (scmd->retries >2 ) { scmd->result =DID_NO_CONNECT <<16 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 311/444 scsi: mpi3mr: Correctly handle ATA device errors
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
[ Upstream commit 04caad5a7ba86e830d04750417a15bad8ac2613c ]
With the ATA error model, an NCQ command failure always triggers an abort (termination) of all NCQ commands queued on the device. In such case, the SAT or the host must handle the failed command according to the command sense data and immediately retry all other NCQ commands that were aborted due to the failed NCQ command.
For SAS HBAs controlled by the mpi3mr driver, NCQ command aborts are not handled by the HBA SAT and sent back to the host, with an ioc log information equal to 0x31080000 (IOC_LOGINFO_PREFIX_PL with the PL code PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR). The function mpi3mr_process_op_reply_desc() always forces a retry of commands terminated with the status MPI3_IOCSTATUS_SCSI_IOC_TERMINATED using the SCSI result DID_SOFT_ERROR, regardless of the ioc_loginfo for the command. This correctly forces the retry of collateral NCQ abort commands, but with the retry counter for the command being incremented. If a command to an ATA device is subject to too many retries due to other NCQ commands failing (e.g. read commands trying to access unreadable sectors), the collateral NCQ abort commands may be terminated with an error as they run out of retries. This violates the SAT specification and causes hard-to-debug command errors.
Solve this issue by modifying the handling of the MPI3_IOCSTATUS_SCSI_IOC_TERMINATED status to check if a command is for an ATA device and if the command ioc_loginfo indicates an NCQ collateral abort. If that is the case, force the command retry using the SCSI result DID_IMM_RETRY to avoid incrementing the command retry count.
--- drivers/scsi/mpi3mr/mpi3mr_os.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
drivers/scsi/mpi3mr/mpi3mr_os.c +19 -1
@@ -49,6 +49,13 @@ static void mpi3mr_send_event_ack(struct mpi3mr_ioc *mrioc, u8 event,#define MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH (0xFFFE) +/* +* SAS Log info code for a NCQ collateral abort after an NCQ error: +* IOC_LOGINFO_PREFIX_PL | PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR +* See: drivers/message/fusion/lsi/mpi_log_sas.h +*/ +#define IOC_LOGINFO_SATA_NCQ_FAIL_AFTER_ERR 0x31080000 +/** * mpi3mr_host_tag_for_scmd - Get host tag for a scmd * @mrioc: Adapter instance reference
@@ -3397,7 +3404,18 @@ void mpi3mr_process_op_reply_desc(struct mpi3mr_ioc *mrioc, scmd->result =DID_NO_CONNECT <<16 ;break ;case MPI3_IOCSTATUS_SCSI_IOC_TERMINATED : - scmd->result =DID_SOFT_ERROR <<16 ; +if (ioc_loginfo ==IOC_LOGINFO_SATA_NCQ_FAIL_AFTER_ERR ) { +/* +* This is a ATA NCQ command aborted due to another NCQ +* command failure. We must retry this command +* immediately but without incrementing its retry +* counter. +*/ +WARN_ON_ONCE (xfer_count !=0 ); + scmd->result =DID_IMM_RETRY <<16 ; + }else { + scmd->result =DID_SOFT_ERROR <<16 ; + }break ;case MPI3_IOCSTATUS_SCSI_TASK_TERMINATED :case MPI3_IOCSTATUS_SCSI_EXT_TERMINATED :
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 312/444 pinctrl: stm32: Manage irq affinity settings
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cheick Traore <[email protected]>
[ Upstream commit 4c5cc2f65386e22166ce006efe515c667aa075e4 ]
Trying to set the affinity of the interrupts associated to stm32 pinctrl results in a write error.
Fill struct irq_chip::irq_set_affinity to use the default helper function.
--- drivers/pinctrl/stm32/pinctrl-stm32.c | 1 + 1 file changed, 1 insertion(+)
drivers/pinctrl/stm32/pinctrl-stm32.c +1 -0
@@ -407,6 +407,7 @@ static struct irq_chip stm32_gpio_irq_chip = { .irq_set_wake = irq_chip_set_wake_parent, .irq_request_resources = stm32_gpio_irq_request_resources, .irq_release_resources = stm32_gpio_irq_release_resources, + .irq_set_affinity = IS_ENABLED(CONFIG_SMP) ? irq_chip_set_affinity_parent : NULL, }; static int stm32_gpio_domain_translate(struct irq_domain *d,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 313/444 media: tc358743: Check I2C succeeded during probe
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Stevenson <[email protected]>
[ Upstream commit 303d81635e1d9c949b370215cc94526ed81f2e3d ]
The probe for the TC358743 reads the CHIPID register from the device and compares it to the expected value of 0. If the I2C request fails then that also returns 0, so the driver loads thinking that the device is there.
Generally I2C communications are reliable so there is limited need to check the return value on every transfer, therefore only amend the one read during probe to check for I2C errors.
--- drivers/media/i2c/tc358743.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-)
drivers/media/i2c/tc358743.c +23 -4
@@ -110,7 +110,7 @@ static inline struct tc358743_state *to_state(struct v4l2_subdev *sd)/* --------------- I2C --------------- */ -static void i2c_rd (struct v4l2_subdev *sd,u16 reg,u8 *values,u32 n) +static int i2c_rd (struct v4l2_subdev *sd,u16 reg,u8 *values,u32 n) {struct tc358743_state *state =to_state (sd);struct i2c_client *client = state->i2c_client;
@@ -136,6 +136,7 @@ static void i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)v4l2_err (sd,"%s: reading register 0x%x from 0x%x failed: %d\n" , __func__, reg, client->addr, err); } +return err !=ARRAY_SIZE (msgs); }static void i2c_wr (struct v4l2_subdev *sd,u16 reg,u8 *values,u32 n)
@@ -192,15 +193,24 @@ static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n) } } -static noinline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n) +static noinline u32 i2c_rdreg_err(struct v4l2_subdev *sd, u16 reg, u32 n, +int *err) { +int error;__le32 val =0 ; -i2c_rd (sd, reg, (u8 __force *)&val, n); + error =i2c_rd (sd, reg, (u8 __force *)&val, n); +if (err) + *err = error;return le32_to_cpu (val); } +static inline u32 i2c_rdreg (struct v4l2_subdev *sd,u16 reg,u32 n) +{ +return i2c_rdreg_err (sd, reg, n,NULL ); +} + static noinline void i2c_wrreg(struct v4l2_subdev *sd, u16 reg, u32 val, u32 n) {__le32 raw =cpu_to_le32 (val);
@@ -229,6 +239,13 @@ static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg)return i2c_rdreg (sd, reg,2 ); } +static int i2c_rd16_err (struct v4l2_subdev *sd,u16 reg,u16 *value) +{ +int err; + *value =i2c_rdreg_err (sd, reg,2 , &err); +return err; +} +static void i2c_wr16 (struct v4l2_subdev *sd,u16 reg,u16 val) {i2c_wrreg (sd, reg, val,2 );
@@ -2030,6 +2047,7 @@ static int tc358743_probe(struct i2c_client *client)struct tc358743_platform_data *pdata = client->dev.platform_data;struct v4l2_subdev *sd;u16 irq_mask =MASK_HDMI_MSK |MASK_CSI_MSK ; +u16 chipid;int err;if (!i2c_check_functionality (client->adapter,I2C_FUNC_SMBUS_BYTE_DATA ))
@@ -2061,7 +2079,8 @@ static int tc358743_probe(struct i2c_client *client) sd->flags |=V4L2_SUBDEV_FL_HAS_DEVNODE |V4L2_SUBDEV_FL_HAS_EVENTS ;/* i2c access */ -if ((i2c_rd16 (sd,CHIPID ) &MASK_CHIPID ) !=0 ) { +if (i2c_rd16_err (sd,CHIPID , &chipid) || + (chipid &MASK_CHIPID ) !=0 ) {v4l2_info (sd,"not a TC358743 on address 0x%x\n" , client->addr <<1 );return -ENODEV ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 314/444 media: tc358743: Return an appropriate colorspace from tc358743_set_fmt
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Stevenson <[email protected]>
[ Upstream commit 377cc006a364dfdab2f3f221cfad63a9265200b8 ]
When calling tc358743_set_fmt, the code was calling tc358743_get_fmt to choose a valid format. However that sets the colorspace based on information read back from the chip, not the colour format requested.
The result was that if you called try or set format for UYVY when the current format was RGB3 then you would get told SRGB, and try RGB3 when current was UYVY and you would get told SMPTE170M.
The value programmed in the VI_REP register for the colorspace is always set by this driver, therefore there is no need to read back the value, and never set to REC709.
Return the colorspace based on the format set/tried instead.
--- drivers/media/i2c/tc358743.c | 44 ++++++++++++++---------------------- 1 file changed, 17 insertions(+), 27 deletions(-)
drivers/media/i2c/tc358743.c +17 -27
@@ -1677,12 +1677,23 @@ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd,return 0 ; } +static u32 tc358743_g_colorspace (u32 code) +{ +switch (code) { +case MEDIA_BUS_FMT_RGB888_1X24 : +return V4L2_COLORSPACE_SRGB ; +case MEDIA_BUS_FMT_UYVY8_1X16 : +return V4L2_COLORSPACE_SMPTE170M ; +default : +return 0 ; + } +} +static int tc358743_get_fmt (struct v4l2_subdev *sd,struct v4l2_subdev_state *sd_state,struct v4l2_subdev_format *format) {struct tc358743_state *state =to_state (sd); -u8 vi_rep =i2c_rd8 (sd,VI_REP );if (format->pad !=0 )return -EINVAL ;
@@ -1692,23 +1703,7 @@ static int tc358743_get_fmt(struct v4l2_subdev *sd, format->format.height = state->timings.bt.height; format->format.field =V4L2_FIELD_NONE ; -switch (vi_rep &MASK_VOUT_COLOR_SEL ) { -case MASK_VOUT_COLOR_RGB_FULL : -case MASK_VOUT_COLOR_RGB_LIMITED : - format->format.colorspace =V4L2_COLORSPACE_SRGB ; -break ; -case MASK_VOUT_COLOR_601_YCBCR_LIMITED : -case MASK_VOUT_COLOR_601_YCBCR_FULL : - format->format.colorspace =V4L2_COLORSPACE_SMPTE170M ; -break ; -case MASK_VOUT_COLOR_709_YCBCR_FULL : -case MASK_VOUT_COLOR_709_YCBCR_LIMITED : - format->format.colorspace =V4L2_COLORSPACE_REC709 ; -break ; -default : - format->format.colorspace =0 ; -break ; - } + format->format.colorspace =tc358743_g_colorspace (format->format.code);return 0 ; }
@@ -1722,19 +1717,14 @@ static int tc358743_set_fmt(struct v4l2_subdev *sd,u32 code = format->format.code;/* is overwritten by get_fmt */ int ret =tc358743_get_fmt (sd, sd_state, format); - format->format.code = code; +if (code ==MEDIA_BUS_FMT_RGB888_1X24 || + code ==MEDIA_BUS_FMT_UYVY8_1X16 ) + format->format.code = code; + format->format.colorspace =tc358743_g_colorspace (format->format.code);if (ret)return ret; -switch (code) { -case MEDIA_BUS_FMT_RGB888_1X24 : -case MEDIA_BUS_FMT_UYVY8_1X16 : -break ; -default : -return -EINVAL ; - } -if (format->which ==V4L2_SUBDEV_FORMAT_TRY )return 0 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 315/444 media: tc358743: Increase FIFO trigger level to 374
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Stevenson <[email protected]>
[ Upstream commit 86addd25314a1e77dbdcfddfeed0bab2f27da0e2 ]
The existing fixed value of 16 worked for UYVY 720P60 over 2 lanes at 594MHz, or UYVY 1080P60 over 4 lanes. (RGB888 1080P60 needs 6 lanes at 594MHz).
It doesn't allow for lower resolutions to work as the FIFO underflows.
374 is required for 1080P24 or 1080P30 UYVY over 2 lanes @ 972Mbit/s, but >374 means that the FIFO underflows on 1080P50 UYVY over 2 lanes @ 972Mbit/s.
Whilst it would be nice to compute it, the required information isn't published by Toshiba.
--- drivers/media/i2c/tc358743.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
drivers/media/i2c/tc358743.c +13 -2
@@ -1948,8 +1948,19 @@ static int tc358743_probe_of(struct tc358743_state *state) state->pdata.refclk_hz =clk_get_rate (refclk); state->pdata.ddc5v_delay =DDC5V_DELAY_100_MS ; state->pdata.enable_hdcp = false; -/* A FIFO level of 16 should be enough for 2-lane 720p60 at 594 MHz. */ - state->pdata.fifo_level =16 ; +/* +* Ideally the FIFO trigger level should be set based on the input and +* output data rates, but the calculations required are buried in +* Toshiba's register settings spreadsheet. +* A value of 16 works with a 594Mbps data rate for 720p60 (using 2 +* lanes) and 1080p60 (using 4 lanes), but fails when the data rate +* is increased, or a lower pixel clock is used that result in CSI +* reading out faster than the data is arriving. +* +* A value of 374 works with both those modes at 594Mbps, and with most +* modes on 972Mbps. +*/ + state->pdata.fifo_level =374 ;/* * The PLL input clock is obtained by dividing refclk by pll_prd. * It must be between 6 MHz and 40 MHz, lower frequency is better.
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 316/444 media: usb: hdpvr: disable zero-length read messages
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wolfram Sang <[email protected]>
[ Upstream commit b5ae5a79825ba8037b0be3ef677a24de8c063abf ]
This driver passes the length of an i2c_msg directly to usb_control_msg(). If the message is now a read and of length 0, it violates the USB protocol and a warning will be printed. Enable the I2C_AQ_NO_ZERO_LEN_READ quirk for this adapter thus forbidding 0-length read messages altogether.
--- drivers/media/usb/hdpvr/hdpvr-i2c.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/media/usb/hdpvr/hdpvr-i2c.c +6 -0
@@ -165,10 +165,16 @@ static const struct i2c_algorithm hdpvr_algo = { .functionality = hdpvr_functionality, }; +/* prevent invalid 0-length usb_control_msg */ +static const struct i2c_adapter_quirks hdpvr_quirks = { + .flags =I2C_AQ_NO_ZERO_LEN_READ , +}; +static const struct i2c_adapter hdpvr_i2c_adapter_template = { .name ="Hauppauge HD PVR I2C" , .owner =THIS_MODULE , .algo = &hdpvr_algo, + .quirks = &hdpvr_quirks, };static int hdpvr_activate_ir (struct hdpvr_device *dev)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 317/444 media: dvb-frontends: dib7090p: fix null-ptr-deref in dib7090p_rw_on_apb()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Guo <[email protected]>
[ Upstream commit ce5cac69b2edac3e3246fee03e8f4c2a1075238b ]
In dib7090p_rw_on_apb, msg is controlled by user. When msg[0].buf is null and msg[0].len is zero, former checks on msg[0].buf would be passed. If accessing msg[0].buf[2] without sanity check, null pointer deref would happen. We add check on msg[0].len to prevent crash. Similar issue occurs when access msg[1].buf[0] and msg[1].buf[1].
Similar commit: commit 0ed554fd769a ("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()")
--- drivers/media/dvb-frontends/dib7000p.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/media/dvb-frontends/dib7000p.c +4 -0
@@ -2256,8 +2256,12 @@ static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap,u16 word;if (num ==1 ) {/* write */ +if (msg[0 ].len <3 ) +return -EOPNOTSUPP ;dib7000p_write_word (state, apb_address, ((msg[0 ].buf[1 ] <<8 ) | (msg[0 ].buf[2 ]))); }else { +if (msg[1 ].len <2 ) +return -EOPNOTSUPP ; word =dib7000p_read_word (state, apb_address); msg[1 ].buf[0 ] = (word >>8 ) &0xff ; msg[1 ].buf[1 ] = (word) &0xff ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 318/444 media: dvb-frontends: w7090p: fix null-ptr-deref in w7090p_tuner_write_serpar and w7090p_tuner_read_serpar
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Guo <[email protected]>
[ Upstream commit ed0234c8458b3149f15e496b48a1c9874dd24a1b ]
In w7090p_tuner_write_serpar, msg is controlled by user. When msg[0].buf is null and msg[0].len is zero, former checks on msg[0].buf would be passed. If accessing msg[0].buf[2] without sanity check, null pointer deref would happen. We add check on msg[0].len to prevent crash.
Similar commit: commit 0ed554fd769a ("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()")
--- drivers/media/dvb-frontends/dib7000p.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/media/dvb-frontends/dib7000p.c +4 -0
@@ -2193,6 +2193,8 @@ static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msstruct dib7000p_state *state =i2c_get_adapdata (i2c_adap);u8 n_overflow =1 ;u16 i =1000 ; +if (msg[0 ].len <3 ) +return -EOPNOTSUPP ;u16 serpar_num = msg[0 ].buf[0 ];while (n_overflow ==1 && i) {
@@ -2212,6 +2214,8 @@ static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msgstruct dib7000p_state *state =i2c_get_adapdata (i2c_adap);u8 n_overflow =1 , n_empty =1 ;u16 i =1000 ; +if (msg[0 ].len <1 || msg[1 ].len <2 ) +return -EOPNOTSUPP ;u16 serpar_num = msg[0 ].buf[0 ];u16 read_word;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 319/444 media: uvcvideo: Add quirk for HP Webcam HD 2300
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
[ Upstream commit 53b0b80e5240fec7c5a420bffb310edc83faf4fd ]
HP Webcam HD 2300 does not seem to flip the FID bit according to spec.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 [unknown]
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x03f0 HP, Inc
idProduct 0xe207 HP Webcam HD 2300
bcdDevice 10.20
iManufacturer 3 Hewlett Packard iProduct 1 HP Webcam HD 2300 iSerial 0 bNumConfigurations 1
--- drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/media/usb/uvc/uvc_driver.c +9 -0
@@ -2487,6 +2487,15 @@ static const struct uvc_device_info uvc_quirk_force_y8 = {* Sort these by vendor/product ID. */ static const struct usb_device_id uvc_ids[] = { +/* HP Webcam HD 2300 */ + { .match_flags =USB_DEVICE_ID_MATCH_DEVICE + |USB_DEVICE_ID_MATCH_INT_INFO , + .idVendor =0x03f0 , + .idProduct =0xe207 , + .bInterfaceClass =USB_CLASS_VIDEO , + .bInterfaceSubClass =1 , + .bInterfaceProtocol =0 , + .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },/* Quanta ACER HD User Facing */ { .match_flags =USB_DEVICE_ID_MATCH_DEVICE |USB_DEVICE_ID_MATCH_INT_INFO ,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 320/444 media: uvcvideo: Fix bandwidth issue for Alcor camera
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: chenchangcheng <[email protected]>
[ Upstream commit 9764401bf6f8a20eb11c2e78470f20fee91a9ea7 ]
Some broken device return wrong dwMaxPayloadTransferSize fields as follows:
[ 218.632537] uvcvideo: Device requested 2752512 B/frame bandwidth. [ 218.632598] uvcvideo: No fast enough alt setting for requested bandwidth.
When dwMaxPayloadTransferSize is greater than maxpsize, it will prevent the camera from starting. So use the bandwidth of maxpsize.
--- drivers/media/usb/uvc/uvc_video.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/media/usb/uvc/uvc_video.c +9 -0
@@ -258,6 +258,15 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, ctrl->dwMaxPayloadTransferSize = bandwidth; } + +if (stream->intf->num_altsetting >1 && + ctrl->dwMaxPayloadTransferSize > stream->maxpsize) { +dev_warn_ratelimited (&stream->intf->dev, +"UVC non compliance: the max payload transmission size (%u) exceeds the size of the ep max packet (%u). Using the max size.\n" , + ctrl->dwMaxPayloadTransferSize, + stream->maxpsize); + ctrl->dwMaxPayloadTransferSize = stream->maxpsize; + } }static size_t uvc_video_ctrl_size (struct uvc_streaming *stream)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 321/444 crypto: octeontx2 - add timeout for load_fvc completion poll
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bharat Bhushan <[email protected]>
[ Upstream commit 2157e50f65d2030f07ea27ef7ac4cfba772e98ac ]
Adds timeout to exit from possible infinite loop, which polls on CPT instruction(load_fvc) completion.
--- .../crypto/marvell/octeontx2/otx2_cptpf_ucode.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c +14 -2
@@ -1493,6 +1493,7 @@ int otx2_cpt_discover_eng_capabilities(struct otx2_cptpf_dev *cptpf)dma_addr_t rptr_baddr;struct pci_dev *pdev;u32 len, compl_rlen; +int timeout =10000 ;int ret, etype;void *rptr;
@@ -1555,16 +1556,27 @@ int otx2_cpt_discover_eng_capabilities(struct otx2_cptpf_dev *cptpf) etype);otx2_cpt_fill_inst (&inst, &iq_cmd, rptr_baddr); lfs->ops->send_cmd (&inst,1 , &cptpf->lfs.lf[0 ]); + timeout =10000 ;while (lfs->ops->cpt_get_compcode (result) == -OTX2_CPT_COMPLETION_CODE_INIT ) +OTX2_CPT_COMPLETION_CODE_INIT ) {cpu_relax (); +udelay (1 ); + timeout--; +if (!timeout) { + ret = -ENODEV ; + cptpf->is_eng_caps_discovered = false; +dev_warn (&pdev->dev,"Timeout on CPT load_fvc completion poll\n" ); + goto error_no_response; + } + } cptpf->eng_caps[etype].u =be64_to_cpup (rptr); } -dma_unmap_single (&pdev->dev, rptr_baddr, len,DMA_BIDIRECTIONAL ); cptpf->is_eng_caps_discovered = true; +error_no_response: +dma_unmap_single (&pdev->dev, rptr_baddr, len,DMA_BIDIRECTIONAL ); free_result:kfree (result); lf_cleanup:
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 322/444 crypto: ccp - Add missing bootloader info reg for pspv6
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
[ Upstream commit aaeff14688d0254b39731d9bb303c79bfd610f7d ]
The bootloader info reg for pspv6 is the same as pspv4 and pspv5.
--- drivers/crypto/ccp/sp-pci.c | 1 + 1 file changed, 1 insertion(+)
drivers/crypto/ccp/sp-pci.c +1 -0
@@ -451,6 +451,7 @@ static const struct psp_vdata pspv6 = { .cmdresp_reg = 0x10944, /* C2PMSG_17 */ .cmdbuff_addr_lo_reg = 0x10948, /* C2PMSG_18 */ .cmdbuff_addr_hi_reg = 0x1094c, /* C2PMSG_19 */ + .bootloader_info_reg = 0x109ec, /* C2PMSG_59 */ .feature_reg = 0x109fc, /* C2PMSG_63 */ .inten_reg = 0x10510, /* P2CMSG_INTEN */ .intsts_reg = 0x10514, /* P2CMSG_INTSTS */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 323/444 clk: renesas: rzg2l: Postpone updating priv->clks[]
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
[ Upstream commit 2f96afdffad4ef74e3c511207058c41c54a2d014 ]
Since the sibling data is filled after the priv->clks[] array entry is populated, the first clock that is probed and has a sibling will temporarily behave as its own sibling until its actual sibling is populated. To avoid any issues, postpone updating priv->clks[] until after the sibling is populated.
--- drivers/clk/renesas/rzg2l-cpg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/clk/renesas/rzg2l-cpg.c +4 -4
@@ -1398,10 +1398,6 @@ rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, goto fail; } - clk = clock->hw.clk; -dev_dbg (dev,"Module clock %pC at %lu Hz\n" , clk,clk_get_rate (clk)); - priv->clks[id] = clk; -if (mod->is_coupled) {struct mstp_clock *sibling;
@@ -1413,6 +1409,10 @@ rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, } } + clk = clock->hw.clk; +dev_dbg (dev,"Module clock %pC at %lu Hz\n" , clk,clk_get_rate (clk)); + priv->clks[id] = clk; +return ; fail:
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 324/444 soundwire: amd: serialize amd manager resume sequence during pm_prepare
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vijendar Mukunda <[email protected]>
[ Upstream commit 03837341790039d6f1cbf7a1ae7dfa2cb77ef0a4 ]
During pm_prepare callback, pm_request_resume() delays SoundWire manager D0 entry sequence. Synchronize runtime resume sequence for amd_manager instance prior to invoking child devices resume sequence for both the amd power modes(ClockStop Mode and Power off mode).
Change the power_mode_mask check and use pm_runtime_resume() in amd_pm_prepare() callback.
--- drivers/soundwire/amd_manager.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/soundwire/amd_manager.c +3 -3
@@ -1076,10 +1076,10 @@ static int __maybe_unused amd_pm_prepare(struct device *dev)* device is not in runtime suspend state, observed that device alerts are missing * without pm_prepare on AMD platforms in clockstop mode0. */ -if (amd_manager->power_mode_mask &AMD_SDW_CLK_STOP_MODE ) { - ret =pm_request_resume (dev); +if (amd_manager->power_mode_mask) { + ret =pm_runtime_resume (dev);if (ret <0 ) { -dev_err (bus->dev,"pm_request_resume failed: %d\n" , ret); +dev_err (bus->dev,"pm_runtime_resume failed: %d\n" , ret);return 0 ; } }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 325/444 soundwire: amd: cancel pending slave status handling workqueue during remove sequence
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vijendar Mukunda <[email protected]>
[ Upstream commit f93b697ed98e3c85d1973ea170d4f4e7a6b2b45d ]
During remove sequence, cancel the pending slave status update workqueue.
--- drivers/soundwire/amd_manager.c | 1 + 1 file changed, 1 insertion(+)
drivers/soundwire/amd_manager.c +1 -0
@@ -972,6 +972,7 @@ static void amd_sdw_manager_remove(struct platform_device *pdev)int ret;pm_runtime_disable (&pdev->dev); +cancel_work_sync (&amd_manager->amd_sdw_work);amd_disable_sdw_interrupts (amd_manager);sdw_bus_master_delete (&amd_manager->bus); ret =amd_disable_sdw_manager (amd_manager);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 326/444 soundwire: Move handle_nested_irq outside of sdw_dev_lock
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Keepax <[email protected]>
[ Upstream commit ccb7bb13c00bcc3178d270da052635c56148bc16 ]
The sdw_dev_lock protects the SoundWire driver callbacks against the probed flag, which is used to skip the callbacks if the driver gets removed. For more information see commit bd29c00edd0a ("soundwire: revisit driver bind/unbind and callbacks").
However, this lock is a frequent source of mutex inversions. Many audio operations eventually hit the hardware resulting in a SoundWire callback, this means that typically the driver has the locking order ALSA/ASoC locks -> sdw_dev_lock. Conversely, the IRQ comes in directly from the SoundWire hardware, but then will often want to access ALSA/ASoC, such as updating something in DAPM or an ALSA control. This gives the other lock order sdw_dev_lock -> ALSA/ASoC locks.
When the IRQ handling was initially added to SoundWire this was through a callback mechanism. As such it required being covered by the lock because the callbacks are part of the sdw_driver structure and are thus present regardless of if the driver is currently probed.
Since then a newer mechanism using the IRQ framework has been added, which is currently covered by the same lock but this isn't actually required. Handlers for the IRQ framework are registered in probe and should by released during remove, thus the IRQ framework will have already unbound the IRQ before the slave driver is removed. Avoid the aforementioned mutex inversion by moving the handle_nested_irq call outside of the sdw_dev_lock.
--- drivers/soundwire/bus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/soundwire/bus.c +3 -3
@@ -1732,15 +1732,15 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)/* Update the Slave driver */ if (slave_notify) { +if (slave->prop.use_domain_irq && slave->irq) +handle_nested_irq (slave->irq); +mutex_lock (&slave->sdw_dev_lock);if (slave->probed) {struct device *dev = &slave->dev;struct sdw_driver *drv =drv_to_sdw_driver (dev->driver); -if (slave->prop.use_domain_irq && slave->irq) -handle_nested_irq (slave->irq); -if (drv->ops && drv->ops->interrupt_callback) { slave_intr.sdca_cascade = sdca_cascade; slave_intr.control_port = clear;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 327/444 md: dm-zoned-target: Initialize return variable r to avoid uninitialized use
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Purva Yeshi <[email protected]>
[ Upstream commit 487767bff572d46f7c37ad846c4078f6d6c9cc55 ]
Fix Smatch-detected error:drivers/md/dm-zoned-target.c:1073 dmz_iterate_devices()
error: uninitialized symbol 'r'.
Smatch detects a possible use of the uninitialized variable 'r' in dmz_iterate_devices() because if dmz->nr_ddevs is zero, the loop is skipped and 'r' is returned without being set, leading to undefined behavior.
Initialize 'r' to 0 before the loop. This ensures that if there are no devices to iterate over, the function still returns a defined value.
--- drivers/md/dm-zoned-target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/dm-zoned-target.c +1 -1
@@ -1061,7 +1061,7 @@ static int dmz_iterate_devices(struct dm_target *ti,struct dmz_target *dmz = ti->private;unsigned int zone_nr_sectors =dmz_zone_nr_sectors (dmz->metadata);sector_t capacity; -int i, r; +int i, r =0 ;for (i =0 ; i < dmz->nr_ddevs; i++) { capacity = dmz->dev[i].capacity & ~(zone_nr_sectors -1 );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 328/444 module: Prevent silent truncation of module name in delete_module(2)
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Pavlu <[email protected]>
[ Upstream commit a6323bd4e611567913e23df5b58f2d4e4da06789 ]
Passing a module name longer than MODULE_NAME_LEN to the delete_module syscall results in its silent truncation. This really isn't much of a problem in practice, but it could theoretically lead to the removal of an incorrect module. It is more sensible to return ENAMETOOLONG or ENOENT in such a case.
Update the syscall to return ENOENT, as documented in the delete_module(2) man page to mean "No module by that name exists." This is appropriate because a module with a name longer than MODULE_NAME_LEN cannot be loaded in the first place.
--- kernel/module/main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
kernel/module/main.c +6 -4
@@ -703,14 +703,16 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,struct module *mod;char name[MODULE_NAME_LEN ];char buf[MODULE_FLAGS_BUF_SIZE ]; -int ret, forced =0 ; +int ret, len, forced =0 ;if (!capable (CAP_SYS_MODULE ) || modules_disabled)return -EPERM ; -if (strncpy_from_user (name, name_user,MODULE_NAME_LEN -1 ) <0 ) -return -EFAULT ; - name[MODULE_NAME_LEN -1 ] ='\0' ; + len =strncpy_from_user (name, name_user,MODULE_NAME_LEN ); +if (len ==0 || len ==MODULE_NAME_LEN ) +return -ENOENT ; +if (len <0 ) +return len;audit_log_kern_module (name);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 329/444 i3c: add missing include to internal header
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wolfram Sang <[email protected]>
[ Upstream commit 3b661ca549b9e5bb11d0bc97ada6110aac3282d2 ]
LKP found a random config which failed to build because IO accessors were not defined:
In file included from drivers/i3c/master.c:21:
drivers/i3c/internals.h: In function 'i3c_writel_fifo':
Quoted 1 line
Quoted 1 line
drivers/i3c/internals.h:35:9: error: implicit declaration of function 'writesl' [-Werror=implicit-function-declaration]
Add the proper header to where the IO accessors are used.
--- drivers/i3c/internals.h | 1 + 1 file changed, 1 insertion(+)
drivers/i3c/internals.h +1 -0
@@ -9,6 +9,7 @@#define I3C_INTERNALS_H #include <linux/i3c/master.h> +#include <linux/io.h> void i3c_bus_normaluse_lock (struct i3c_bus *bus);void i3c_bus_normaluse_unlock (struct i3c_bus *bus);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 330/444 rtc: ds1307: handle oscillator stop flag (OSF) for ds1341
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Meagan Lloyd <[email protected]>
[ Upstream commit 523923cfd5d622b8f4ba893fdaf29fa6adeb8c3e ]
In using CONFIG_RTC_HCTOSYS, rtc_hctosys() will sync the RTC time to the kernel time as long as rtc_read_time() succeeds. In some power loss situations, our supercapacitor-backed DS1342 RTC comes up with either an unpredictable future time or the default 01/01/00 from the datasheet. The oscillator stop flag (OSF) is set in these scenarios due to the power loss and can be used to determine the validity of the RTC data.
This change expands the oscillator stop flag (OSF) handling that has already been implemented for some chips to the ds1341 chip (DS1341 and DS1342 share a datasheet). This handling manages the validity of the RTC data in .read_time and .set_time based on the OSF.
--- drivers/rtc/rtc-ds1307.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/rtc/rtc-ds1307.c +11 -0
@@ -279,6 +279,13 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)if (tmp &DS1340_BIT_OSF )return -EINVAL ;break ; +case ds_1341: + ret =regmap_read (ds1307->regmap,DS1337_REG_STATUS , &tmp); +if (ret) +return ret; +if (tmp &DS1337_BIT_OSF ) +return -EINVAL ; +break ;case ds_1388: ret =regmap_read (ds1307->regmap,DS1388_REG_FLAG , &tmp);if (ret)
@@ -377,6 +384,10 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)regmap_update_bits (ds1307->regmap,DS1340_REG_FLAG ,DS1340_BIT_OSF ,0 );break ; +case ds_1341: +regmap_update_bits (ds1307->regmap,DS1337_REG_STATUS , +DS1337_BIT_OSF ,0 ); +break ;case ds_1388:regmap_update_bits (ds1307->regmap,DS1388_REG_FLAG ,DS1388_BIT_OSF ,0 );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 331/444 apparmor: shift ouid when mediating hard links in userns
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriel Totev <[email protected]>
[ Upstream commit c5bf96d20fd787e4909b755de4705d52f3458836 ]
When using AppArmor profiles inside an unprivileged container, the link operation observes an unshifted ouid. (tested with LXD and Incus)
For example, root inside container and uid 1000000 outside, with owner /root/link l, profile entry for ln:
/root$ touch chain && ln chain link
==> dmesg
apparmor="DENIED" operation="link" class="file" namespace="root//lxd-feet_<var-snap-lxd-common-lxd>" profile="linkit" name="/root/link" pid=1655 comm="ln" requested_mask="l" denied_mask="l" fsuid=1000000 ouid=0 [<== should be 1000000] target="/root/chain"
Fix by mapping inode uid of old_dentry in aa_path_link() rather than using it directly, similarly to how it's mapped in __file_path_perm() later in the file.
--- security/apparmor/file.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
security/apparmor/file.c +4 -2
@@ -423,9 +423,11 @@ int aa_path_link(const struct cred *subj_cred, {struct path link = { .mnt = new_dir->mnt, .dentry = new_dentry };struct path target = { .mnt = new_dir->mnt, .dentry = old_dentry }; +struct inode *inode =d_backing_inode (old_dentry); +vfsuid_t vfsuid =i_uid_into_vfsuid (mnt_idmap (target.mnt), inode);struct path_cond cond = { -d_backing_inode (old_dentry)->i_uid, -d_backing_inode (old_dentry)->i_mode + .uid =vfsuid_into_kuid (vfsuid), + .mode = inode->i_mode, };char *buffer =NULL , *buffer2 =NULL ;struct aa_profile *profile;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 332/444 i3c: dont fail if GETHDRCAP is unsupported
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wolfram Sang <[email protected]>
[ Upstream commit 447270cdb41b1c8c3621bb14b93a6749f942556e ]
'I3C_BCR_HDR_CAP' is still spec v1.0 and has been renamed to 'advanced capabilities' in v1.1 onwards. The ST pressure sensor LPS22DF does not have HDR, but has the 'advanced cap' bit set. The core still wants to get additional information using the CCC 'GETHDRCAP' (or GETCAPS in v1.1 onwards). Not all controllers support this CCC and will notify the upper layers about it. For instantiating the device, we can ignore this unsupported CCC as standard communication will work. Without this patch, the device will not be instantiated at all.
--- drivers/i3c/master.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i3c/master.c +1 -1
@@ -1439,7 +1439,7 @@ static int i3c_master_retrieve_dev_info(struct i3c_dev_desc *dev)if (dev->info.bcr &I3C_BCR_HDR_CAP ) { ret =i3c_master_gethdrcap_locked (master, &dev->info); -if (ret) +if (ret && ret != -ENOTSUPP )return ret; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 333/444 i3c: master: Initialize ret in i3c_i2c_notifier_call()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jorge Marques <[email protected]>
[ Upstream commit 290ce8b2d0745e45a3155268184523a8c75996f1 ]
Set ret to -EINVAL if i3c_i2c_notifier_call() receives an invalid action, resolving uninitialized warning.
--- drivers/i3c/master.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/i3c/master.c +2 -0
@@ -2471,6 +2471,8 @@ static int i3c_i2c_notifier_call(struct notifier_block *nb, unsigned long actioncase BUS_NOTIFY_DEL_DEVICE : ret =i3c_master_i2c_detach (adap, client);break ; +default : + ret = -EINVAL ; }i3c_bus_maintenance_unlock (&master->bus);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 334/444 dm-mpath: dont print the "loaded" message if registering fails
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
[ Upstream commit 6e11952a6abc4641dc8ae63f01b318b31b44e8db ]
If dm_register_path_selector, don't print the "version X loaded" message.
--- drivers/md/dm-ps-historical-service-time.c | 4 +++- drivers/md/dm-ps-queue-length.c | 4 +++- drivers/md/dm-ps-round-robin.c | 4 +++- drivers/md/dm-ps-service-time.c | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-)
drivers/md/dm-ps-historical-service-time.c +3 -1
@@ -541,8 +541,10 @@ static int __init dm_hst_init(void) {int r =dm_register_path_selector (&hst_ps); -if (r <0 ) +if (r <0 ) {DMERR ("register failed %d" , r); +return r; + }DMINFO ("version " HST_VERSION " loaded" );
drivers/md/dm-ps-queue-length.c +3 -1
@@ -260,8 +260,10 @@ static int __init dm_ql_init(void) {int r =dm_register_path_selector (&ql_ps); -if (r <0 ) +if (r <0 ) {DMERR ("register failed %d" , r); +return r; + }DMINFO ("version " QL_VERSION " loaded" );
drivers/md/dm-ps-round-robin.c +3 -1
@@ -220,8 +220,10 @@ static int __init dm_rr_init(void) {int r =dm_register_path_selector (&rr_ps); -if (r <0 ) +if (r <0 ) {DMERR ("register failed %d" , r); +return r; + }DMINFO ("version " RR_VERSION " loaded" );
drivers/md/dm-ps-service-time.c +3 -1
@@ -341,8 +341,10 @@ static int __init dm_st_init(void) {int r =dm_register_path_selector (&st_ps); -if (r <0 ) +if (r <0 ) {DMERR ("register failed %d" , r); +return r; + }DMINFO ("version " ST_VERSION " loaded" );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 335/444 dm-table: fix checking for rq stackable devices
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Marzinski <[email protected]>
[ Upstream commit 8ca719b81987be690f197e82fdb030580c0a07f3 ]
Due to the semantics of iterate_devices(), the current code allows a request-based dm table as long as it includes one request-stackable device. It is supposed to only allow tables where there are no non-request-stackable devices.
--- drivers/md/dm-table.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/md/dm-table.c +5 -5
@@ -894,17 +894,17 @@ static bool dm_table_supports_dax(struct dm_table *t,return true; } -static int device_is_rq_stackable (struct dm_target *ti,struct dm_dev *dev, -sector_t start,sector_t len,void *data) +static int device_is_not_rq_stackable (struct dm_target *ti,struct dm_dev *dev, +sector_t start,sector_t len,void *data) {struct block_device *bdev = dev->bdev;struct request_queue *q =bdev_get_queue (bdev);/* request-based cannot stack on partitions! */ if (bdev_is_partition (bdev)) -return false; +return true; -return queue_is_mq (q); +return !queue_is_mq (q); }static int dm_table_determine_type (struct dm_table *t)
@@ -1000,7 +1000,7 @@ static int dm_table_determine_type(struct dm_table *t)/* Non-request-stackable devices can't be used for request-based dm */ if (!ti->type->iterate_devices || - !ti->type->iterate_devices (ti, device_is_rq_stackable,NULL )) { + ti->type->iterate_devices (ti, device_is_not_rq_stackable,NULL )) {DMERR ("table load rejected: including non-request-stackable devices" );return -EINVAL ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 336/444 apparmor: use the condition in AA_BUG_FMT even with debug disabled
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mateusz Guzik <[email protected]>
[ Upstream commit 67e370aa7f968f6a4f3573ed61a77b36d1b26475 ]
This follows the established practice and fixes a build failure for me:security/apparmor/file.c: In function ‘__file_sock_perm’:security/apparmor/file.c:544:24: error: unused variable ‘sock’ [-Werror=unused-variable]
544 | struct socket *sock = (struct socket *) file->private_data;
| ^~~~
--- security/apparmor/include/lib.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
security/apparmor/include/lib.h +5 -1
@@ -48,7 +48,11 @@ extern struct aa_dfa *stacksplitdfa; #define AA_BUG_FMT(X, fmt, args...) \ WARN((X), "AppArmor WARN %s: (" #X "): " fmt, __func__, ##args)#else -#define AA_BUG_FMT(X, fmt, args...) no_printk(fmt, ##args) +#define AA_BUG_FMT(X, fmt, args...) \ + do { \ + BUILD_BUG_ON_INVALID(X); \ + no_printk(fmt, ##args); \ + } while (0)#endif #define AA_ERROR(fmt, args...) \
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 337/444 apparmor: fix x_table_lookup when stacking is not the first entry
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Johansen <[email protected]>
[ Upstream commit a9eb185be84e998aa9a99c7760534ccc06216705 ]
x_table_lookup currently does stacking during label_parse() if the target specifies a stack but its only caller ensures that it will never be used with stacking.
Refactor to slightly simplify the code in x_to_label(), this also fixes a long standing problem where x_to_labels check on stacking is only on the first element to the table option list, instead of the element that is found and used.
--- security/apparmor/domain.c | 52 +++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 23 deletions(-)
security/apparmor/domain.c +29 -23
@@ -509,6 +509,7 @@ static const char *next_name(int xtype, const char *name)* @name: returns: name tested to find label (NOT NULL) * * Returns: refcounted label, or NULL on failure (MAYBE NULL) +* @name will always be set with the last name tried */ struct aa_label *x_table_lookup (struct aa_profile *profile,u32 xindex,const char **name)
@@ -518,6 +519,7 @@ struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,struct aa_label *label =NULL ;u32 xtype = xindex &AA_X_TYPE_MASK ;int index = xindex &AA_X_INDEX_MASK ; +const char *next;AA_BUG (!name);
@@ -525,25 +527,27 @@ struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,/* TODO: move lookup parsing to unpack time so this is a straight * index into the resultant label */ -for (*name = rules->file->trans.table[index]; !label && *name; - *name =next_name (xtype, *name)) { +for (next = rules->file->trans.table[index]; next; + next =next_name (xtype, next)) { +const char *lookup = (*next =='&' ) ? next +1 : next; + *name = next;if (xindex &AA_X_CHILD ) { -struct aa_profile *new_profile; -/* release by caller */ - new_profile =aa_find_child (profile, *name); -if (new_profile) - label = &new_profile->label; +/* TODO: switich to parse to get stack of child */ +struct aa_profile *new =aa_find_child (profile, lookup); + +if (new) +/* release by caller */ +return &new->label;continue ; } - label =aa_label_parse (&profile->label, *name,GFP_KERNEL , + label =aa_label_parse (&profile->label, lookup,GFP_KERNEL , true, false); -if (IS_ERR (label)) - label =NULL ; +if (!IS_ERR_OR_NULL (label)) +/* release by caller */ +return label; } -/* released by caller */ - -return label; +return NULL ; }/**
@@ -568,9 +572,9 @@ static struct aa_label *x_to_label(struct aa_profile *profile,struct aa_ruleset *rules =list_first_entry (&profile->rules,typeof (*rules), list);struct aa_label *new =NULL ; +struct aa_label *stack =NULL ;struct aa_ns *ns = profile->ns;u32 xtype = xindex &AA_X_TYPE_MASK ; -const char *stack =NULL ;switch (xtype) {case AA_X_NONE :
@@ -579,13 +583,14 @@ static struct aa_label *x_to_label(struct aa_profile *profile,break ;case AA_X_TABLE :/* TODO: fix when perm mapping done at unload */ - stack = rules->file->trans.table[xindex &AA_X_INDEX_MASK ]; -if (*stack !='&' ) { -/* released by caller */ - new =x_table_lookup (profile, xindex, lookupname); - stack =NULL ; +/* released by caller +* if null for both stack and direct want to try fallback +*/ + new =x_table_lookup (profile, xindex, lookupname); +if (!new || **lookupname !='&' )break ; - } + stack = new; + new =NULL ; fallthrough;/* to X_NAME */ case AA_X_NAME :if (xindex &AA_X_CHILD )
@@ -600,6 +605,7 @@ static struct aa_label *x_to_label(struct aa_profile *profile,break ; } +/* fallback transition check */ if (!new) {if (xindex &AA_X_INHERIT ) {/* (p|c|n)ix - don't change profile but do
@@ -618,12 +624,12 @@ static struct aa_label *x_to_label(struct aa_profile *profile,/* base the stack on post domain transition */ struct aa_label *base = new; - new =aa_label_parse (base, stack,GFP_KERNEL , true, false); -if (IS_ERR (new)) - new =NULL ; + new =aa_label_merge (base, stack,GFP_KERNEL ); +/* null on error */ aa_put_label (base); } +aa_put_label (stack);/* released by caller */ return new; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 338/444 i2c: Force DLL0945 touchpad i2c freq to 100khz
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: fangzhong.zhou <[email protected]>
[ Upstream commit 0b7c9528facdb5a73ad78fea86d2e95a6c48dbc4 ]
This patch fixes an issue where the touchpad cursor movement becomes slow on the Dell Precision 5560. Force the touchpad freq to 100khz as a workaround.
Tested on Dell Precision 5560 with 6.14 to 6.14.6. Cursor movement is now smooth and responsive.
--- drivers/i2c/i2c-core-acpi.c | 1 + 1 file changed, 1 insertion(+)
drivers/i2c/i2c-core-acpi.c +1 -0
@@ -370,6 +370,7 @@ static const struct acpi_device_id i2c_acpi_force_100khz_device_ids[] = {* the device works without issues on Windows at what is expected to be * a 400KHz frequency. The root cause of the issue is not known. */ + { "DLL0945", 0 }, { "ELAN06FA", 0 }, {} };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 339/444 exfat: add cluster chain loop check for dir
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuezhang Mo <[email protected]>
[ Upstream commit 99f9a97dce39ad413c39b92c90393bbd6778f3fd ]
An infinite loop may occur if the following conditions occur due to file system corruption.
(1) Condition for exfat_count_dir_entries() to loop infinitely.
- The cluster chain includes a loop.
- There is no UNUSED entry in the cluster chain.
(2) Condition for exfat_create_upcase_table() to loop infinitely.
- The cluster chain of the root directory includes a loop.
- There are no UNUSED entry and up-case table entry in the cluster chain of the root directory.
(3) Condition for exfat_load_bitmap() to loop infinitely.
- The cluster chain of the root directory includes a loop.
- There are no UNUSED entry and bitmap entry in the cluster chain of the root directory.
(4) Condition for exfat_find_dir_entry() to loop infinitely.
- The cluster chain includes a loop.
- The unused directory entries were exhausted by some operation.
(5) Condition for exfat_check_dir_empty() to loop infinitely.
- The cluster chain includes a loop.
- The unused directory entries were exhausted by some operation.
- All files and sub-directories under the directory are deleted.
This commit adds checks to break the above infinite loop.
--- fs/exfat/dir.c | 12 ++++++++++++ fs/exfat/fatent.c | 10 ++++++++++ fs/exfat/namei.c | 5 +++++ fs/exfat/super.c | 32 +++++++++++++++++++++----------- 4 files changed, 48 insertions(+), 11 deletions(-)
fs/exfat/dir.c +12 -0
@@ -1015,6 +1015,7 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,struct exfat_hint_femp candi_empty;struct exfat_sb_info *sbi =EXFAT_SB (sb);int num_entries =exfat_calc_num_entries (p_uniname); +unsigned int clu_count =0 ;if (num_entries <0 )return num_entries;
@@ -1152,6 +1153,10 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, }else {if (exfat_get_next_cluster (sb, &clu.dir))return -EIO ; + +/* break if the cluster chain includes a loop */ +if (unlikely (++clu_count >EXFAT_DATA_CLUSTER_COUNT (sbi))) + goto not_found; } }
@@ -1214,6 +1219,7 @@ int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir)int i, count =0 ;int dentries_per_clu;unsigned int entry_type; +unsigned int clu_count =0 ;struct exfat_chain clu;struct exfat_dentry *ep;struct exfat_sb_info *sbi =EXFAT_SB (sb);
@@ -1246,6 +1252,12 @@ int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir) }else {if (exfat_get_next_cluster (sb, &(clu.dir)))return -EIO ; + +if (unlikely (++clu_count > sbi->used_clusters)) { +exfat_fs_error (sb,"FAT or bitmap is corrupted" ); +return -EIO ; + } + } }
fs/exfat/fatent.c +10 -0
@@ -461,5 +461,15 @@ int exfat_count_num_clusters(struct super_block *sb, } *ret_count = count; + +/* +* since exfat_count_used_clusters() is not called, sbi->used_clusters +* cannot be used here. +*/ +if (unlikely (i == sbi->num_clusters && clu !=EXFAT_EOF_CLUSTER )) { +exfat_fs_error (sb,"The cluster chain has a loop" ); +return -EIO ; + } +return 0 ; }
fs/exfat/namei.c +5 -0
@@ -888,6 +888,7 @@ static int exfat_check_dir_empty(struct super_block *sb, {int i, dentries_per_clu;unsigned int type; +unsigned int clu_count =0 ;struct exfat_chain clu;struct exfat_dentry *ep;struct exfat_sb_info *sbi =EXFAT_SB (sb);
@@ -924,6 +925,10 @@ static int exfat_check_dir_empty(struct super_block *sb, }else {if (exfat_get_next_cluster (sb, &(clu.dir)))return -EIO ; + +/* break if the cluster chain includes a loop */ +if (unlikely (++clu_count >EXFAT_DATA_CLUSTER_COUNT (sbi))) +break ; } }
fs/exfat/super.c +21 -11
@@ -370,13 +370,12 @@ static void exfat_hash_init(struct super_block *sb)INIT_HLIST_HEAD (&sbi->inode_hashtable[i]); } -static int exfat_read_root (struct inode *inode) +static int exfat_read_root (struct inode *inode,struct exfat_chain *root_clu) {struct super_block *sb = inode->i_sb;struct exfat_sb_info *sbi =EXFAT_SB (sb);struct exfat_inode_info *ei =EXFAT_I (inode); -struct exfat_chain cdir; -int num_subdirs, num_clu =0 ; +int num_subdirs;exfat_chain_set (&ei->dir, sbi->root_dir,0 ,ALLOC_FAT_CHAIN ); ei->entry =-1 ;
@@ -389,12 +388,9 @@ static int exfat_read_root(struct inode *inode) ei->hint_stat.clu = sbi->root_dir; ei->hint_femp.eidx =EXFAT_HINT_NONE ; -exfat_chain_set (&cdir, sbi->root_dir,0 ,ALLOC_FAT_CHAIN ); -if (exfat_count_num_clusters (sb, &cdir, &num_clu)) -return -EIO ; -i_size_write (inode, num_clu << sbi->cluster_size_bits); +i_size_write (inode,EXFAT_CLU_TO_B (root_clu->size, sbi)); - num_subdirs =exfat_count_dir_entries (sb, &cdir); + num_subdirs =exfat_count_dir_entries (sb, root_clu);if (num_subdirs <0 )return -EIO ;set_nlink (inode, num_subdirs +EXFAT_MIN_SUBDIR );
@@ -608,7 +604,8 @@ static int exfat_verify_boot_region(struct super_block *sb) }/* mount the file system volume */ -static int __exfat_fill_super (struct super_block *sb) +static int __exfat_fill_super (struct super_block *sb, +struct exfat_chain *root_clu) {int ret;struct exfat_sb_info *sbi =EXFAT_SB (sb);
@@ -625,6 +622,18 @@ static int __exfat_fill_super(struct super_block *sb) goto free_bh; } +/* +* Call exfat_count_num_cluster() before searching for up-case and +* bitmap directory entries to avoid infinite loop if they are missing +* and the cluster chain includes a loop. +*/ +exfat_chain_set (root_clu, sbi->root_dir,0 ,ALLOC_FAT_CHAIN ); + ret =exfat_count_num_clusters (sb, root_clu, &root_clu->size); +if (ret) { +exfat_err (sb,"failed to count the number of clusters in root" ); + goto free_bh; + } + ret =exfat_create_upcase_table (sb);if (ret) {exfat_err (sb,"failed to load upcase table" );
@@ -657,6 +666,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)struct exfat_sb_info *sbi = sb->s_fs_info;struct exfat_mount_options *opts = &sbi->options;struct inode *root_inode; +struct exfat_chain root_clu;int err;if (opts->allow_utime == (unsigned short )-1 )
@@ -675,7 +685,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc) sb->s_time_min =EXFAT_MIN_TIMESTAMP_SECS ; sb->s_time_max =EXFAT_MAX_TIMESTAMP_SECS ; - err =__exfat_fill_super (sb); + err =__exfat_fill_super (sb, &root_clu);if (err) {exfat_err (sb,"failed to recognize exfat type" ); goto check_nls_io;
@@ -710,7 +720,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc) root_inode->i_ino =EXFAT_ROOT_INO ;inode_set_iversion (root_inode,1 ); - err =exfat_read_root (root_inode); + err =exfat_read_root (root_inode, &root_clu);if (err) {exfat_err (sb,"failed to initialize root inode" ); goto put_inode;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 340/444 f2fs: check the generic conditions first
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaegeuk Kim <[email protected]>
[ Upstream commit e23ab8028de0d92df5921a570f5212c0370db3b5 ]
Let's return errors caught by the generic checks. This fixes generic/494 where it expects to see EBUSY by setattr_prepare instead of EINVAL by f2fs for active swapfile.
--- fs/f2fs/file.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
fs/f2fs/file.c +12 -12
@@ -1003,6 +1003,18 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,if (unlikely (f2fs_cp_error (F2FS_I_SB (inode))))return -EIO ; + err =setattr_prepare (idmap, dentry, attr); +if (err) +return err; + + err =fscrypt_prepare_setattr (dentry, attr); +if (err) +return err; + + err =fsverity_prepare_setattr (dentry, attr); +if (err) +return err; +if (unlikely (IS_IMMUTABLE (inode)))return -EPERM ;
@@ -1020,18 +1032,6 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,return -EINVAL ; } - err =setattr_prepare (idmap, dentry, attr); -if (err) -return err; - - err =fscrypt_prepare_setattr (dentry, attr); -if (err) -return err; - - err =fsverity_prepare_setattr (dentry, attr); -if (err) -return err; -if (is_quota_modification (idmap, inode, attr)) { err =f2fs_dquot_initialize (inode);if (err)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 341/444 printk: nbcon: Allow reacquire during panic
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Ogness <[email protected]>
[ Upstream commit 571c1ea91a73db56bd94054fabecd0f070dc90db ]
If a console printer is interrupted during panic, it will never be able to reacquire ownership in order to perform and cleanup. That in itself is not a problem, since the non-panic CPU will simply quiesce in an endless loop within nbcon_reacquire_nobuf().
However, in this state, platforms that do not support a true NMI to interrupt the quiesced CPU will not be able to shutdown that CPU from within panic(). This then causes problems for such as being unable to load and run a kdump kernel.
Fix this by allowing non-panic CPUs to reacquire ownership using a direct acquire. Then the non-panic CPUs can successfullyl exit the nbcon_reacquire_nobuf() loop and the console driver can perform any necessary cleanup. But more importantly, the CPU is no longer quiesced and is free to process any interrupts necessary for panic() to shutdown the CPU.
All other forms of acquire are still not allowed for non-panic CPUs since it is safer to have them avoid gaining console ownership that is not strictly necessary.
--- kernel/printk/nbcon.c | 63 ++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 22 deletions(-)
kernel/printk/nbcon.c +41 -22
@@ -214,8 +214,9 @@ static void nbcon_seq_try_update(struct nbcon_context *ctxt, u64 new_seq)/** * nbcon_context_try_acquire_direct - Try to acquire directly -* @ctxt: The context of the caller -* @cur: The current console state +* @ctxt: The context of the caller +* @cur: The current console state +* @is_reacquire: This acquire is a reacquire * * Acquire the console when it is released. Also acquire the console when * the current owner has a lower priority and the console is in a safe state.
@@ -225,17 +226,17 @@ static void nbcon_seq_try_update(struct nbcon_context *ctxt, u64 new_seq)* * Errors: * -* -EPERM: A panic is in progress and this is not the panic CPU. -* Or the current owner or waiter has the same or higher -* priority. No acquire method can be successful in -* this case. +* -EPERM: A panic is in progress and this is neither the panic +* CPU nor is this a reacquire. Or the current owner or +* waiter has the same or higher priority. No acquire +* method can be successful in these cases. * * -EBUSY: The current owner has a lower priority but the console * in an unsafe state. The caller should try using * the handover acquire method. */ static int nbcon_context_try_acquire_direct (struct nbcon_context *ctxt, -struct nbcon_state *cur) +struct nbcon_state *cur,bool is_reacquire) {unsigned int cpu =smp_processor_id ();struct console *con = ctxt->console;
@@ -243,14 +244,20 @@ static int nbcon_context_try_acquire_direct(struct nbcon_context *ctxt, do { /* - * Panic does not imply that the console is owned. However, it - * is critical that non-panic CPUs during panic are unable to - * acquire ownership in order to satisfy the assumptions of - * nbcon_waiter_matches(). In particular, the assumption that - * lower priorities are ignored during panic. + * Panic does not imply that the console is owned. However, + * since all non-panic CPUs are stopped during panic(), it + * is safer to have them avoid gaining console ownership. + * + * If this acquire is a reacquire (and an unsafe takeover + * has not previously occurred) then it is allowed to attempt + * a direct acquire in panic. This gives console drivers an + * opportunity to perform any necessary cleanup if they were + * interrupted by the panic CPU while printing. */ - if (other_cpu_in_panic()) + if (other_cpu_in_panic() && + (!is_reacquire || cur->unsafe_takeover)) { return -EPERM; + } if (ctxt->prio <= cur->prio || ctxt->prio <= cur->req_prio) return -EPERM;
@@ -301,8 +308,9 @@ static bool nbcon_waiter_matches(struct nbcon_state *cur, int expected_prio)* Event #1 implies this context is EMERGENCY. * Event #2 implies the new context is PANIC. * Event #3 occurs when panic() has flushed the console. -* Events #4 and #5 are not possible due to the other_cpu_in_panic() -* check in nbcon_context_try_acquire_direct(). +* Event #4 occurs when a non-panic CPU reacquires. +* Event #5 is not possible due to the other_cpu_in_panic() check +* in nbcon_context_try_acquire_handover(). */ return (cur->req_prio == expected_prio);
@@ -431,6 +439,16 @@ static int nbcon_context_try_acquire_handover(struct nbcon_context *ctxt,WARN_ON_ONCE (ctxt->prio <= cur->prio || ctxt->prio <= cur->req_prio);WARN_ON_ONCE (!cur->unsafe); +/* +* Panic does not imply that the console is owned. However, it +* is critical that non-panic CPUs during panic are unable to +* wait for a handover in order to satisfy the assumptions of +* nbcon_waiter_matches(). In particular, the assumption that +* lower priorities are ignored during panic. +*/ +if (other_cpu_in_panic ()) +return -EPERM ; +/* Handover is not possible on the same CPU. */ if (cur->cpu == cpu)return -EBUSY ;
@@ -558,7 +576,8 @@ static struct printk_buffers panic_nbcon_pbufs;/** * nbcon_context_try_acquire - Try to acquire nbcon console -* @ctxt: The context of the caller +* @ctxt: The context of the caller +* @is_reacquire: This acquire is a reacquire * * Context: Under @ctxt->con->device_lock() or local_irq_save(). * Return: True if the console was acquired. False otherwise.
@@ -568,7 +587,7 @@ static struct printk_buffers panic_nbcon_pbufs;* in an unsafe state. Otherwise, on success the caller may assume * the console is not in an unsafe state. */ -static bool nbcon_context_try_acquire (struct nbcon_context *ctxt) +static bool nbcon_context_try_acquire (struct nbcon_context *ctxt,bool is_reacquire) {unsigned int cpu =smp_processor_id ();struct console *con = ctxt->console;
@@ -577,7 +596,7 @@ static bool nbcon_context_try_acquire(struct nbcon_context *ctxt)nbcon_state_read (con, &cur); try_again: - err =nbcon_context_try_acquire_direct (ctxt, &cur); + err =nbcon_context_try_acquire_direct (ctxt, &cur, is_reacquire);if (err != -EBUSY ) goto out;
@@ -913,7 +932,7 @@ void nbcon_reacquire_nobuf(struct nbcon_write_context *wctxt) {struct nbcon_context *ctxt = &ACCESS_PRIVATE (wctxt, ctxt); -while (!nbcon_context_try_acquire (ctxt)) +while (!nbcon_context_try_acquire (ctxt, true))cpu_relax ();nbcon_write_context_set_buf (wctxt,NULL ,0 );
@@ -1101,7 +1120,7 @@ static bool nbcon_emit_one(struct nbcon_write_context *wctxt, bool use_atomic)cant_migrate (); } -if (!nbcon_context_try_acquire (ctxt)) +if (!nbcon_context_try_acquire (ctxt, false)) goto out;/*
@@ -1486,7 +1505,7 @@ static int __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq, ctxt->prio =nbcon_get_default_prio (); ctxt->allow_unsafe_takeover = allow_unsafe_takeover; -if (!nbcon_context_try_acquire (ctxt)) +if (!nbcon_context_try_acquire (ctxt, false))return -EPERM ;while (nbcon_seq_read (con) < stop_seq) {
@@ -1762,7 +1781,7 @@ bool nbcon_device_try_acquire(struct console *con) ctxt->console = con; ctxt->prio =NBCON_PRIO_NORMAL ; -if (!nbcon_context_try_acquire (ctxt)) +if (!nbcon_context_try_acquire (ctxt, false))return false;if (!nbcon_context_enter_unsafe (ctxt))
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 342/444 kconfig: lxdialog: replace strcpy() with strncpy() in inputbox.c
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suchit Karunakaran <[email protected]>
[ Upstream commit 5ac726653a1029a2eccba93bbe59e01fc9725828 ]
strcpy() performs no bounds checking and can lead to buffer overflows if the input string exceeds the destination buffer size. This patch replaces it with strncpy(), and null terminates the input string.
--- scripts/kconfig/lxdialog/inputbox.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
scripts/kconfig/lxdialog/inputbox.c +4 -2
@@ -39,8 +39,10 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int widthif (!init) instr[0 ] ='\0' ; -else -strcpy (instr, init); +else { +strncpy (instr, init,sizeof (dialog_input_result) -1 ); + instr[sizeof (dialog_input_result) -1 ] ='\0' ; + } do_resize:if (getmaxy (stdscr) <= (height -INPUTBOX_HEIGHT_MIN ))
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 343/444 vfio/type1: conditional rescheduling while pinning
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Keith Busch <[email protected]>
[ Upstream commit b1779e4f209c7ff7e32f3c79d69bca4e3a3a68b6 ]
A large DMA mapping request can loop through dma address pinning for many pages. In cases where THP can not be used, the repeated vmf_insert_pfn can be costly, so let the task reschedule as need to prevent CPU stalls. Failure to do so has potential harmful side effects, like increased memory pressure as unrelated rcu tasks are unable to make their reclaim callbacks and result in OOM conditions.
rcu: INFO: rcu_sched self-detected stall on CPU rcu: 36-....: (20999 ticks this GP) idle=b01c/1/0x4000000000000000 softirq=35839/35839 fqs=3538 rcu: hardirqs softirqs csw/system rcu: number: 0 107 0 rcu: cputime: 50 0 10446 ==> 10556(ms) rcu: (t=21075 jiffies g=377761 q=204059 ncpus=384) ... <TASK> ? asm_sysvec_apic_timer_interrupt+0x16/0x20 ? walk_system_ram_range+0x63/0x120 ? walk_system_ram_range+0x46/0x120 ? pgprot_writethrough+0x20/0x20 lookup_memtype+0x67/0xf0 track_pfn_insert+0x20/0x40 vmf_insert_pfn_prot+0x88/0x140 vfio_pci_mmap_huge_fault+0xf9/0x1b0 [vfio_pci_core] __do_fault+0x28/0x1b0 handle_mm_fault+0xef1/0x2560 fixup_user_fault+0xf5/0x270 vaddr_get_pfns+0x169/0x2f0 [vfio_iommu_type1] vfio_pin_pages_remote+0x162/0x8e0 [vfio_iommu_type1] vfio_iommu_type1_ioctl+0x1121/0x1810 [vfio_iommu_type1] ? futex_wake+0x1c1/0x260 x64_sys_call+0x234/0x17a0 do_syscall_64+0x63/0x130 ? exc_page_fault+0x63/0x130 entry_SYSCALL_64_after_hwframe+0x4b/0x53
--- drivers/vfio/vfio_iommu_type1.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/vfio/vfio_iommu_type1.c +7 -0
@@ -619,6 +619,13 @@ static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr,while (npage) {if (!batch->size) { +/* +* Large mappings may take a while to repeatedly refill +* the batch, so conditionally relinquish the CPU when +* needed to avoid stalls. +*/ +cond_resched (); +/* Empty batch, so refill it. */ long req_pages =min_t (long, npage, batch->capacity);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 344/444 kconfig: nconf: Ensure null termination where strncpy is used
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shankari Anand <[email protected]>
[ Upstream commit f468992936894c9ce3b1659cf38c230d33b77a16 ]
strncpy() does not guarantee null-termination if the source string is longer than the destination buffer.
Ensure the buffer is explicitly null-terminated to prevent potential string overflows or undefined behavior.
--- scripts/kconfig/nconf.c | 2 ++ scripts/kconfig/nconf.gui.c | 1 + 2 files changed, 3 insertions(+)
scripts/kconfig/nconf.c +2 -0
@@ -593,6 +593,8 @@ static void item_add_str(const char *fmt, ...) tmp_str, sizeof(k_menu_items[index].str)); + k_menu_items[index].str[sizeof (k_menu_items[index].str) -1 ] ='\0' ; +free_item (curses_menu_items[index]); curses_menu_items[index] = new_item( k_menu_items[index].str,
scripts/kconfig/nconf.gui.c +1 -0
@@ -350,6 +350,7 @@ int dialog_inputbox(WINDOW *main_window, x = (columns-win_cols)/2 ;strncpy (result, init, *result_len); + result[*result_len -1 ] ='\0' ;/* create the windows */ win =newwin (win_lines, win_cols, y, x);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 345/444 scsi: Fix sas_user_scan() to handle wildcard and multi-channel scans
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranjan Kumar <[email protected]>
[ Upstream commit 37c4e72b0651e7697eb338cd1fb09feef472cc1a ]
sas_user_scan() did not fully process wildcard channel scans (SCAN_WILD_CARD) when a transport-specific user_scan() callback was present. Only channel 0 would be scanned via user_scan(), while the remaining channels were skipped, potentially missing devices.
user_scan() invokes updated sas_user_scan() for channel 0, and if successful, iteratively scans remaining channels (1 to shost->max_channel) via scsi_scan_host_selected(). This ensures complete wildcard scanning without affecting transport-specific scanning behavior.
--- drivers/scsi/scsi_scan.c | 2 +- drivers/scsi/scsi_transport_sas.c | 60 ++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 13 deletions(-)
drivers/scsi/scsi_scan.c +1 -1
@@ -1881,7 +1881,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,return 0 ; } - +EXPORT_SYMBOL (scsi_scan_host_selected);static void scsi_sysfs_add_devices (struct Scsi_Host *shost) {struct scsi_device *sdev;
drivers/scsi/scsi_transport_sas.c +48 -12
86 lines not on this page · raw message
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 346/444 scsi: target: core: Generate correct identifiers for PR OUT transport IDs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maurizio Lombardi <[email protected]>
[ Upstream commit 6e0f6aa44b68335df404a2df955055f416b5f2aa ]
Fix target_parse_pr_out_transport_id() to return a string representing the transport ID in a human-readable format (e.g., naa.xxxxxxxx...) for various SCSI protocol types (SAS, FCP, SRP, SBP).
Previously, the function returned a pointer to the raw binary buffer, which was incorrectly compared against human-readable strings, causing comparisons to fail. Now, the function writes a properly formatted string into a buffer provided by the caller. The output format depends on the transport protocol:
* SAS: 64-bit identifier, "naa." prefix.
* FCP: 64-bit identifier, colon separated values.
* SBP: 64-bit identifier, no prefix.
* SRP: 128-bit identifier, "0x" prefix.
* iSCSI: IQN string.
--- drivers/target/target_core_fabric_lib.c | 63 +++++++++++++++++++------ drivers/target/target_core_internal.h | 4 +- drivers/target/target_core_pr.c | 18 +++---- 3 files changed, 60 insertions(+), 25 deletions(-)
drivers/target/target_core_fabric_lib.c +48 -15
@@ -257,11 +257,41 @@ static int iscsi_get_pr_transport_id_len(return len; } -static char *iscsi_parse_pr_out_transport_id ( +static void sas_parse_pr_out_transport_id (char *buf,char *i_str) +{ +char hex[17 ] = {}; + +bin2hex (hex, buf +4 ,8 ); +snprintf (i_str,TRANSPORT_IQN_LEN ,"naa.%s" , hex); +} + +static void srp_parse_pr_out_transport_id (char *buf,char *i_str) +{ +char hex[33 ] = {}; + +bin2hex (hex, buf +8 ,16 ); +snprintf (i_str,TRANSPORT_IQN_LEN ,"0x%s" , hex); +} + +static void fcp_parse_pr_out_transport_id (char *buf,char *i_str) +{ +snprintf (i_str,TRANSPORT_IQN_LEN ,"%8phC" , buf +8 ); +} + +static void sbp_parse_pr_out_transport_id (char *buf,char *i_str) +{ +char hex[17 ] = {}; + +bin2hex (hex, buf +8 ,8 ); +snprintf (i_str,TRANSPORT_IQN_LEN ,"%s" , hex); +} + +static bool iscsi_parse_pr_out_transport_id (struct se_portal_group *se_tpg,char *buf,u32 *out_tid_len, -char **port_nexus_ptr) +char **port_nexus_ptr, +char *i_str) {char *p;int i;
@@ -282,7 +312,7 @@ static char *iscsi_parse_pr_out_transport_id(if ((format_code !=0x00 ) && (format_code !=0x40 )) {pr_err ("Illegal format code: 0x%02x for iSCSI" " Initiator Transport ID\n" , format_code); -return NULL ; +return false; }/* * If the caller wants the TransportID Length, we set that value for the
@@ -306,7 +336,7 @@ static char *iscsi_parse_pr_out_transport_id(pr_err ("Unable to locate \",i,0x\" separator" " for Initiator port identifier: %s\n" , &buf[4 ]); -return NULL ; +return false; } *p ='\0' ;/* Terminate iSCSI Name */ p +=5 ;/* Skip over ",i,0x" separator */
@@ -339,7 +369,8 @@ static char *iscsi_parse_pr_out_transport_id( }else *port_nexus_ptr =NULL ; -return &buf[4 ]; +strscpy (i_str, &buf[4 ],TRANSPORT_IQN_LEN ); +return true; } int target_get_pr_transport_id_len(struct se_node_acl *nacl,
@@ -387,33 +418,35 @@ int target_get_pr_transport_id(struct se_node_acl *nacl, } } -const char *target_parse_pr_out_transport_id (struct se_portal_group *tpg, -char *buf,u32 *out_tid_len,char **port_nexus_ptr) +bool target_parse_pr_out_transport_id (struct se_portal_group *tpg, +char *buf,u32 *out_tid_len,char **port_nexus_ptr,char *i_str) { -u32 offset; -switch (tpg->proto_id) {case SCSI_PROTOCOL_SAS :/* * Assume the FORMAT CODE 00b from spc4r17, 7.5.4.7 TransportID * for initiator ports using SCSI over SAS Serial SCSI Protocol. */ - offset =4 ; +sas_parse_pr_out_transport_id (buf, i_str);break ; -case SCSI_PROTOCOL_SBP :case SCSI_PROTOCOL_SRP : +srp_parse_pr_out_transport_id (buf, i_str); +break ;case SCSI_PROTOCOL_FCP : - offset =8 ; +fcp_parse_pr_out_transport_id (buf, i_str); +break ; +case SCSI_PROTOCOL_SBP : +sbp_parse_pr_out_transport_id (buf, i_str);break ;case SCSI_PROTOCOL_ISCSI :return iscsi_parse_pr_out_transport_id (tpg, buf, out_tid_len, - port_nexus_ptr); + port_nexus_ptr, i_str);default :pr_err ("Unknown proto_id: 0x%02x\n" , tpg->proto_id); -return NULL ; +return false; } *port_nexus_ptr =NULL ; *out_tid_len =24 ; -return buf + offset; +return true; }
drivers/target/target_core_internal.h +2 -2
@@ -103,8 +103,8 @@ int target_get_pr_transport_id_len(struct se_node_acl *nacl,int target_get_pr_transport_id (struct se_node_acl *nacl,struct t10_pr_registration *pr_reg,int *format_code,unsigned char *buf); -const char *target_parse_pr_out_transport_id (struct se_portal_group *tpg, -char *buf,u32 *out_tid_len,char **port_nexus_ptr); +bool target_parse_pr_out_transport_id (struct se_portal_group *tpg, +char *buf,u32 *out_tid_len,char **port_nexus_ptr,char *i_str);/* target_core_hba.c */ struct se_hba *core_alloc_hba (const char *,u32 ,u32 );
drivers/target/target_core_pr.c +10 -8
@@ -1478,11 +1478,12 @@ core_scsi3_decode_spec_i_port(LIST_HEAD (tid_dest_list);struct pr_transport_id_holder *tidh_new, *tidh, *tidh_tmp;unsigned char *buf, *ptr, proto_ident; -const unsigned char *i_str =NULL ; +unsigned char i_str[TRANSPORT_IQN_LEN ];char *iport_ptr =NULL , i_buf[PR_REG_ISID_ID_LEN ];sense_reason_t ret;u32 tpdl, tid_len =0 ;u32 dest_rtpi =0 ; +bool tid_found;/* * Allocate a struct pr_transport_id_holder and setup the
@@ -1571,9 +1572,9 @@ core_scsi3_decode_spec_i_port( dest_rtpi = tmp_lun->lun_tpg->tpg_rtpi; iport_ptr =NULL ; - i_str =target_parse_pr_out_transport_id (tmp_tpg, - ptr, &tid_len, &iport_ptr); -if (!i_str) + tid_found =target_parse_pr_out_transport_id (tmp_tpg, + ptr, &tid_len, &iport_ptr, i_str); +if (!tid_found)continue ;/* * Determine if this SCSI device server requires that
@@ -3153,13 +3154,14 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key,struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg;struct t10_reservation *pr_tmpl = &dev->t10_pr;unsigned char *buf; -const unsigned char *initiator_str; +unsigned char initiator_str[TRANSPORT_IQN_LEN ];char *iport_ptr =NULL , i_buf[PR_REG_ISID_ID_LEN ] = { };u32 tid_len, tmp_tid_len;int new_reg =0 , type, scope, matching_iname;sense_reason_t ret;unsigned short rtpi;unsigned char proto_ident; +bool tid_found;if (!se_sess || !se_lun) {pr_err ("SPC-3 PR: se_sess || struct se_lun is NULL!\n" );
@@ -3278,9 +3280,9 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, ret =TCM_INVALID_PARAMETER_LIST ; goto out; } - initiator_str =target_parse_pr_out_transport_id (dest_se_tpg, - &buf[24 ], &tmp_tid_len, &iport_ptr); -if (!initiator_str) { + tid_found =target_parse_pr_out_transport_id (dest_se_tpg, + &buf[24 ], &tmp_tid_len, &iport_ptr, initiator_str); +if (!tid_found) {pr_err ("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" " initiator_str from Transport ID\n" ); ret =TCM_INVALID_PARAMETER_LIST ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 347/444 scsi: aacraid: Stop using PCI_IRQ_AFFINITY
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Garry <[email protected]>
[ Upstream commit dafeaf2c03e71255438ffe5a341d94d180e6c88e ]
When PCI_IRQ_AFFINITY is set for calling pci_alloc_irq_vectors(), it means interrupts are spread around the available CPUs. It also means that the interrupts become managed, which means that an interrupt is shutdown when all the CPUs in the interrupt affinity mask go offline.
Using managed interrupts in this way means that we should ensure that completions should not occur on HW queues where the associated interrupt is shutdown. This is typically achieved by ensuring only CPUs which are online can generate IO completion traffic to the HW queue which they are mapped to (so that they can also serve completion interrupts for that HW queue).
The problem in the driver is that a CPU can generate completions to a HW queue whose interrupt may be shutdown, as the CPUs in the HW queue interrupt affinity mask may be offline. This can cause IOs to never complete and hang the system. The driver maintains its own CPU <-> HW queue mapping for submissions, see aac_fib_vector_assign(), but this does not reflect the CPU <-> HW queue interrupt affinity mapping.
Commit 9dc704dcc09e ("scsi: aacraid: Reply queue mapping to CPUs based on IRQ affinity") tried to remedy this issue may mapping CPUs properly to HW queue interrupts. However this was later reverted in commit c5becf57dd56 ("Revert "scsi: aacraid: Reply queue mapping to CPUs based on IRQ affinity") - it seems that there were other reports of hangs. I guess that this was due to some implementation issue in the original commit or maybe a HW issue.
Fix the very original hang by just not using managed interrupts by not setting PCI_IRQ_AFFINITY. In this way, all CPUs will be in each HW queue affinity mask, so should not create completion problems if any CPUs go offline.
--- drivers/scsi/aacraid/comminit.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/scsi/aacraid/comminit.c +1 -2
@@ -481,8 +481,7 @@ void aac_define_int_mode(struct aac_dev *dev) pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX)) { min_msix =2 ; i =pci_alloc_irq_vectors (dev->pdev, - min_msix, msi_count, -PCI_IRQ_MSIX |PCI_IRQ_AFFINITY ); + min_msix, msi_count,PCI_IRQ_MSIX );if (i >0 ) { dev->msi_enabled =1 ; msi_count = i;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 348/444 vfio/mlx5: fix possible overflow in tracking max message size
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artem Sadovnikov <[email protected]>
[ Upstream commit b3060198483bac43ec113c62ae3837076f61f5de ]
MLX cap pg_track_log_max_msg_size consists of 5 bits, value of which is used as power of 2 for max_msg_size. This can lead to multiplication overflow between max_msg_size (u32) and integer constant, and afterwards incorrect value is being written to rq_size.
Fix this issue by extending integer constant to u64 type.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/vfio/pci/mlx5/cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/vfio/pci/mlx5/cmd.c +2 -2
@@ -1538,8 +1538,8 @@ int mlx5vf_start_page_tracker(struct vfio_device *vdev, log_max_msg_size =MLX5_CAP_ADV_VIRTUALIZATION (mdev, pg_track_log_max_msg_size); max_msg_size = (1ULL << log_max_msg_size);/* The RQ must hold at least 4 WQEs/messages for successful QP creation */ -if (rq_size <4 * max_msg_size) - rq_size =4 * max_msg_size; +if (rq_size <4ULL * max_msg_size) + rq_size =4ULL * max_msg_size;memset (tracker,0 ,sizeof (*tracker)); tracker->uar =mlx5_get_uars_page (mdev);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 349/444 ipmi: Use dev_warn_ratelimited() for incorrect message warnings
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit ec50ec378e3fd83bde9b3d622ceac3509a60b6b5 ]
During BMC firmware upgrades on live systems, the ipmi_msghandler generates excessive "BMC returned incorrect response" warnings while the BMC is temporarily offline. This can flood system logs in large deployments.
Replace dev_warn() with dev_warn_ratelimited() to throttle these warnings and prevent log spam during BMC maintenance operations.
Message-ID: <[email protected]>
--- drivers/char/ipmi/ipmi_msghandler.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/char/ipmi/ipmi_msghandler.c +4 -4
@@ -4617,10 +4617,10 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,* The NetFN and Command in the response is not even * marginally correct. */ -dev_warn (intf->si_dev, -"BMC returned incorrect response, expected netfn %x cmd %x, got netfn %x cmd %x\n" , - (msg->data[0 ] >>2 ) |1 , msg->data[1 ], - msg->rsp[0 ] >>2 , msg->rsp[1 ]); +dev_warn_ratelimited (intf->si_dev, +"BMC returned incorrect response, expected netfn %x cmd %x, got netfn %x cmd %x\n" , + (msg->data[0 ] >>2 ) |1 , msg->data[1 ], + msg->rsp[0 ] >>2 , msg->rsp[1 ]); goto return_unspecified; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 350/444 kconfig: gconf: avoid hardcoding model2 in on_treeview2_cursor_changed()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit cae9cdbcd9af044810bcceeb43a87accca47c71d ]
The on_treeview2_cursor_changed() handler is connected to both the left and right tree views, but it hardcodes model2 (the GtkTreeModel of the right tree view). This is incorrect. Get the associated model from the view.
--- scripts/kconfig/gconf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
scripts/kconfig/gconf.c +3 -2
@@ -942,13 +942,14 @@ on_treeview2_key_press_event(GtkWidget * widget,void on_treeview2_cursor_changed (GtkTreeView * treeview,gpointer user_data) { +GtkTreeModel *model =gtk_tree_view_get_model (treeview);GtkTreeSelection *selection;GtkTreeIter iter;struct menu *menu; selection =gtk_tree_view_get_selection (treeview); -if (gtk_tree_selection_get_selected (selection, &model2, &iter)) { -gtk_tree_model_get (model2, &iter,COL_MENU , &menu,-1 ); +if (gtk_tree_selection_get_selected (selection, &model, &iter)) { +gtk_tree_model_get (model, &iter,COL_MENU , &menu,-1 );text_insert_help (menu); } }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 351/444 kconfig: gconf: fix potential memory leak in renderer_edited()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit f72ed4c6a375e52a3f4b75615e4a89d29d8acea7 ]
If gtk_tree_model_get_iter() fails, gtk_tree_path_free() is not called.
--- scripts/kconfig/gconf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
scripts/kconfig/gconf.c +2 -1
@@ -748,7 +748,7 @@ static void renderer_edited(GtkCellRendererText * cell,struct symbol *sym;if (!gtk_tree_model_get_iter (model2, &iter, path)) -return ; + goto free;gtk_tree_model_get (model2, &iter,COL_MENU , &menu,-1 ); sym = menu->sym;
@@ -760,6 +760,7 @@ static void renderer_edited(GtkCellRendererText * cell,update_tree (&rootmenu,NULL ); +free:gtk_tree_path_free (path); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 352/444 kconfig: lxdialog: fix space to (de)select options
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yann E. MORIN <[email protected]>
[ Upstream commit 694174f94ebeeb5ec5cc0e9de9b40c82057e1d95 ]
In case a menu has comment without letters/numbers (eg. characters matching the regexp '^[^[:alpha:][:digit:]]+$', for example - or *), hitting space will cycle through those comments, rather than selecting/deselecting the currently-highlighted option.
This is the behaviour of hitting any letter/digit: jump to the next option which prompt starts with that letter. The only letters that do not behave as such are 'y' 'm' and 'n'. Prompts that start with one of those three letters are instead matched on the first letter that is not 'y', 'm' or 'n'.
Fix that by treating 'space' as we treat y/m/n, ie. as an action key, not as shortcut to jump to prompt.
--- scripts/kconfig/lxdialog/menubox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/kconfig/lxdialog/menubox.c +1 -1
@@ -264,7 +264,7 @@ int dialog_menu(const char *title, const char *prompt,if (key <256 &&isalpha (key)) key =tolower (key); -if (strchr ("ynmh" , key)) +if (strchr ("ynmh " , key)) i = max_choice;else {for (i = choice +1 ; i < max_choice; i++) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 353/444 ipmi: Fix strcpy source and destination the same
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Corey Minyard <[email protected]>
[ Upstream commit 8ffcb7560b4a15faf821df95e3ab532b2b020f8c ]
The source and destination of some strcpy operations was the same. Split out the part of the operations that needed to be done for those particular calls so the unnecessary copy wasn't done.
--- drivers/char/ipmi/ipmi_watchdog.c | 59 ++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 17 deletions(-)
drivers/char/ipmi/ipmi_watchdog.c +42 -17
@@ -1189,14 +1189,8 @@ static struct ipmi_smi_watcher smi_watcher = { .smi_gone = ipmi_smi_gone }; -static int action_op (const char *inval,char *outval) +static int action_op_set_val (const char *inval) { -if (outval) -strcpy (outval, action); - -if (!inval) -return 0 ; -if (strcmp (inval,"reset" ) ==0 ) action_val =WDOG_TIMEOUT_RESET ;else if (strcmp (inval,"none" ) ==0 )
@@ -1207,18 +1201,26 @@ static int action_op(const char *inval, char *outval) action_val =WDOG_TIMEOUT_POWER_DOWN ; else return -EINVAL; -strcpy (action, inval);return 0 ; } -static int preaction_op (const char *inval,char *outval) +static int action_op (const char *inval,char *outval) { +int rv; +if (outval) -strcpy (outval, preaction); +strcpy (outval, action);if (!inval)return 0 ; + rv =action_op_set_val (inval); +if (!rv) +strcpy (action, inval); +return rv; +} +static int preaction_op_set_val (const char *inval) +{if (strcmp (inval,"pre_none" ) ==0 ) preaction_val =WDOG_PRETIMEOUT_NONE ;else if (strcmp (inval,"pre_smi" ) ==0 )
@@ -1231,18 +1233,26 @@ static int preaction_op(const char *inval, char *outval) preaction_val =WDOG_PRETIMEOUT_MSG_INT ; else return -EINVAL; -strcpy (preaction, inval);return 0 ; } -static int preop_op (const char *inval,char *outval) +static int preaction_op (const char *inval,char *outval) { +int rv; +if (outval) -strcpy (outval, preop); +strcpy (outval, preaction);if (!inval)return 0 ; + rv =preaction_op_set_val (inval); +if (!rv) +strcpy (preaction, inval); +return 0 ; +} +static int preop_op_set_val (const char *inval) +{if (strcmp (inval,"preop_none" ) ==0 ) preop_val =WDOG_PREOP_NONE ;else if (strcmp (inval,"preop_panic" ) ==0 )
@@ -1251,7 +1261,22 @@ static int preop_op(const char *inval, char *outval) preop_val =WDOG_PREOP_GIVE_DATA ; else return -EINVAL; -strcpy (preop, inval); +return 0 ; +} + +static int preop_op (const char *inval,char *outval) +{ +int rv; + +if (outval) +strcpy (outval, preop); + +if (!inval) +return 0 ; + + rv =preop_op_set_val (inval); +if (!rv) +strcpy (preop, inval);return 0 ; }
@@ -1288,18 +1313,18 @@ static int __init ipmi_wdog_init(void) {int rv; -if (action_op (action,NULL )) { +if (action_op_set_val (action)) {action_op ("reset" ,NULL );pr_info ("Unknown action '%s', defaulting to reset\n" , action); } -if (preaction_op (preaction,NULL )) { +if (preaction_op_set_val (preaction)) {preaction_op ("pre_none" ,NULL );pr_info ("Unknown preaction '%s', defaulting to none\n" , preaction); } -if (preop_op (preop,NULL )) { +if (preop_op_set_val (preop)) {preop_op ("preop_none" ,NULL );pr_info ("Unknown preop '%s', defaulting to none\n" , preop); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 354/444 tools/power turbostat: Handle non-root legacy-uncore sysfs permissions
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Len Brown <[email protected]>
[ Upstream commit e60a13bcef206795d3ddf82f130fe8f570176d06 ]
/sys/devices/system/cpu/intel_uncore_frequency/package_X_die_Y/ may be readable by all, but /sys/devices/system/cpu/intel_uncore_frequency/package_X_die_Y/current_freq_khz may be readable only by root.
Non-root turbostat users see complaints in this scenario.
Fail probe of the interface if we can't read current_freq_khz.
--- tools/power/x86/turbostat/turbostat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/power/x86/turbostat/turbostat.c +2 -1
@@ -6409,7 +6409,8 @@ static void probe_intel_uncore_frequency_legacy(void)sprintf (path_base,"/sys/devices/system/cpu/intel_uncore_frequency/package_%02d_die_%02d" , i, j); -if (access (path_base,R_OK )) +sprintf (path,"%s/current_freq_khz" , path_base); +if (access (path,R_OK ))continue ;BIC_PRESENT (BIC_UNCORE_MHZ );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 355/444 tools/power turbostat: Fix build with musl
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Calvin Owens <[email protected]>
[ Upstream commit 6ea0ec1b958a84aff9f03fb0ae4613a4d5bed3ea ]
turbostat.c: In function 'parse_int_file':
turbostat.c:5567:19: error: 'PATH_MAX' undeclared (first use in this function)
5567 | char path[PATH_MAX];
| ^~~~~~~~
turbostat.c: In function 'probe_graphics':
turbostat.c:6787:19: error: 'PATH_MAX' undeclared (first use in this function)
6787 | char path[PATH_MAX];
| ^~~~~~~~--- tools/power/x86/turbostat/turbostat.c | 1 + 1 file changed, 1 insertion(+)
tools/power/x86/turbostat/turbostat.c +1 -0
@@ -67,6 +67,7 @@#include <stdbool.h> #include <assert.h> #include <linux/kernel.h> +#include <limits.h> #define UNUSED (x) (void)(x)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 356/444 tools/power turbostat: Handle cap_get_proc() ENOSYS
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Calvin Owens <[email protected]>
[ Upstream commit d34fe509f5f76d9dc36291242d67c6528027ebbd ]
Kernels configured with CONFIG_MULTIUSER=n have no cap_get_proc(). Check for ENOSYS to recognize this case, and continue on to attempt to access the requested MSRs (such as temperature).
--- tools/power/x86/turbostat/turbostat.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
tools/power/x86/turbostat/turbostat.c +9 -1
@@ -6246,8 +6246,16 @@ int check_for_cap_sys_rawio(void)int ret =0 ; caps =cap_get_proc (); -if (caps ==NULL ) +if (caps ==NULL ) { +/* +* CONFIG_MULTIUSER=n kernels have no cap_get_proc() +* Allow them to continue and attempt to access MSRs +*/ +if (errno ==ENOSYS ) +return 0 ; +return 1 ; + }if (cap_get_flag (caps,CAP_SYS_RAWIO ,CAP_EFFECTIVE , &cap_flag_value)) { ret =1 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 357/444 smb: client: dont call init_waitqueue_head(&info->conn_wait) twice in _smbd_get_connection
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Metzmacher <[email protected]>
[ Upstream commit 550a194c5998e4e77affc6235e80d3766dc2d27e ]
It is already called long before we may hit this cleanup code path.
--- fs/smb/client/smbdirect.c | 1 - 1 file changed, 1 deletion(-)
fs/smb/client/smbdirect.c +0 -1
@@ -1689,7 +1689,6 @@ static struct smbd_connection *_smbd_get_connection(cancel_delayed_work_sync (&info->idle_timer_work);destroy_caches_and_workqueue (info); sc->status =SMBDIRECT_SOCKET_NEGOTIATE_FAILED ; -init_waitqueue_head (&info->conn_wait);rdma_disconnect (sc->rdma.cm_id);wait_event (info->conn_wait, sc->status ==SMBDIRECT_SOCKET_DISCONNECTED );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 358/444 lib/sbitmap: convert shallow_depth from one word to the whole sbitmap
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit 42e6c6ce03fd3e41e39a0f93f9b1a1d9fa664338 ]
Currently elevators will record internal 'async_depth' to throttle asynchronous requests, and they both calculate shallow_dpeth based on sb->shift, with the respect that sb->shift is the available tags in one word.
However, sb->shift is not the availbale tags in the last word, see __map_depth:
if (index == sb->map_nr - 1)
return sb->depth - (index << sb->shift);
For consequence, if the last word is used, more tags can be get than expected, for example, assume nr_requests=256 and there are four words, in the worst case if user set nr_requests=32, then the first word is the last word, and still use bits per word, which is 64, to calculate async_depth is wrong.
One the ohter hand, due to cgroup qos, bfq can allow only one request to be allocated, and set shallow_dpeth=1 will still allow the number of words request to be allocated.
Fix this problems by using shallow_depth to the whole sbitmap instead of per word, also change kyber, mq-deadline and bfq to follow this, a new helper __map_depth_with_shallow() is introduced to calculate available bits in each word.
--- block/bfq-iosched.c | 35 ++++++++++++-------------- block/bfq-iosched.h | 3 +-- block/kyber-iosched.c | 9 ++----- block/mq-deadline.c | 16 +----------- include/linux/sbitmap.h | 6 ++--- lib/sbitmap.c | 56 +++++++++++++++++++++-------------------- 6 files changed, 52 insertions(+), 73 deletions(-)
block/bfq-iosched.c +16 -19
@@ -701,17 +701,13 @@ static void bfq_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data) {struct bfq_data *bfqd = data->q->elevator->elevator_data;struct bfq_io_cq *bic =bfq_bic_lookup (data->q); -int depth; -unsigned limit = data->q->nr_requests; -unsigned int act_idx; +unsigned int limit, act_idx;/* Sync reads have full depth available */ -if (op_is_sync (opf) && !op_is_write (opf)) { - depth =0 ; - }else { - depth = bfqd->word_depths[!!bfqd->wr_busy_queues][op_is_sync (opf)]; - limit = (limit * depth) >> bfqd->full_depth_shift; - } +if (op_is_sync (opf) && !op_is_write (opf)) + limit = data->q->nr_requests; +else + limit = bfqd->async_depths[!!bfqd->wr_busy_queues][op_is_sync (opf)];for (act_idx =0 ; bic && act_idx < bfqd->num_actuators; act_idx++) {/* Fast path to check if bfqq is already allocated. */
@@ -725,14 +721,16 @@ static void bfq_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data)* available requests and thus starve other entities. */ if (bfqq_request_over_limit (bfqd, bic, opf, act_idx, limit)) { - depth =1 ; + limit =1 ;break ; } } +bfq_log (bfqd,"[%s] wr_busy %d sync %d depth %u" , - __func__, bfqd->wr_busy_queues,op_is_sync (opf), depth); -if (depth) - data->shallow_depth = depth; + __func__, bfqd->wr_busy_queues,op_is_sync (opf), limit); + +if (limit < data->q->nr_requests) + data->shallow_depth = limit; } static struct bfq_queue *
@@ -7128,9 +7126,8 @@ void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg)*/ static void bfq_update_depths (struct bfq_data *bfqd,struct sbitmap_queue *bt) { -unsigned int depth =1U << bt->sb.shift; +unsigned int nr_requests = bfqd->queue->nr_requests; - bfqd->full_depth_shift = bt->sb.shift;/* * In-word depths if no bfq_queue is being weight-raised: * leaving 25% of tags only for sync reads.
@@ -7142,13 +7139,13 @@ static void bfq_update_depths(struct bfq_data *bfqd, struct sbitmap_queue *bt)* limit 'something'. */ /* no more than 50% of tags for async I/O */ - bfqd->word_depths[0 ][0 ] =max (depth >>1 ,1U ); + bfqd->async_depths[0 ][0 ] =max (nr_requests >>1 ,1U );/* * no more than 75% of tags for sync writes (25% extra tags * w.r.t. async I/O, to prevent async I/O from starving sync * writes) */ - bfqd->word_depths[0 ][1 ] =max ((depth *3 ) >>2 ,1U ); + bfqd->async_depths[0 ][1 ] =max ((nr_requests *3 ) >>2 ,1U );/* * In-word depths in case some bfq_queue is being weight-
@@ -7158,9 +7155,9 @@ static void bfq_update_depths(struct bfq_data *bfqd, struct sbitmap_queue *bt)* shortage. */ /* no more than ~18% of tags for async I/O */ - bfqd->word_depths[1 ][0 ] =max ((depth *3 ) >>4 ,1U ); + bfqd->async_depths[1 ][0 ] =max ((nr_requests *3 ) >>4 ,1U );/* no more than ~37% of tags for sync writes (~20% extra tags) */ - bfqd->word_depths[1 ][1 ] =max ((depth *6 ) >>4 ,1U ); + bfqd->async_depths[1 ][1 ] =max ((nr_requests *6 ) >>4 ,1U ); }static void bfq_depth_updated (struct blk_mq_hw_ctx *hctx)
block/bfq-iosched.h +1 -2
@@ -813,8 +813,7 @@ struct bfq_data {* Depth limits used in bfq_limit_depth (see comments on the * function) */ -unsigned int word_depths[2 ][2 ]; -unsigned int full_depth_shift; +unsigned int async_depths[2 ][2 ];/* * Number of independent actuators. This is equal to 1 in
block/kyber-iosched.c +2 -7
@@ -157,10 +157,7 @@ struct kyber_queue_data {*/ struct sbitmap_queue domain_tokens[KYBER_NUM_DOMAINS ]; -/* -* Async request percentage, converted to per-word depth for -* sbitmap_get_shallow(). -*/ +/* Number of allowed async requests. */ unsigned int async_depth;struct kyber_cpu_latency __percpu *cpu_latency;
@@ -454,10 +451,8 @@ static void kyber_depth_updated(struct blk_mq_hw_ctx *hctx) {struct kyber_queue_data *kqd = hctx->queue->elevator->elevator_data;struct blk_mq_tags *tags = hctx->sched_tags; -unsigned int shift = tags->bitmap_tags.sb.shift; - - kqd->async_depth = (1U << shift) *KYBER_ASYNC_PERCENT /100U ; + kqd->async_depth = hctx->queue->nr_requests *KYBER_ASYNC_PERCENT /100U ;sbitmap_queue_min_shallow_depth (&tags->bitmap_tags, kqd->async_depth); }
block/mq-deadline.c +1 -15
@@ -487,20 +487,6 @@ static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx)return rq; } -/* -* 'depth' is a number in the range 1..INT_MAX representing a number of -* requests. Scale it with a factor (1 << bt->sb.shift) / q->nr_requests since -* 1..(1 << bt->sb.shift) is the range expected by sbitmap_get_shallow(). -* Values larger than q->nr_requests have the same effect as q->nr_requests. -*/ -static int dd_to_word_depth (struct blk_mq_hw_ctx *hctx,unsigned int qdepth) -{ -struct sbitmap_queue *bt = &hctx->sched_tags->bitmap_tags; -const unsigned int nrr = hctx->queue->nr_requests; - -return ((qdepth << bt->sb.shift) + nrr -1 ) / nrr; -} -/* * Called by __blk_mq_alloc_request(). The shallow_depth value set by this * function is used by __blk_mq_get_tag().
@@ -517,7 +503,7 @@ static void dd_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data)* Throttle asynchronous requests and writes such that these requests * do not block the allocation of synchronous requests. */ - data->shallow_depth =dd_to_word_depth (data->hctx, dd->async_depth); + data->shallow_depth = dd->async_depth; }/* Called by blk_mq_update_nr_requests(). */
include/linux/sbitmap.h +3 -3
@@ -213,12 +213,12 @@ int sbitmap_get(struct sbitmap *sb);* sbitmap_get_shallow() - Try to allocate a free bit from a &struct sbitmap, * limiting the depth used from each word. * @sb: Bitmap to allocate from. -* @shallow_depth: The maximum number of bits to allocate from a single word. +* @shallow_depth: The maximum number of bits to allocate from the bitmap. * * This rather specific operation allows for having multiple users with * different allocation limits. E.g., there can be a high-priority class that * uses sbitmap_get() and a low-priority class that uses sbitmap_get_shallow() -* with a @shallow_depth of (1 << (@sb->shift - 1)). Then, the low-priority +* with a @shallow_depth of (sb->depth >> 1). Then, the low-priority * class can only allocate half of the total bits in the bitmap, preventing it * from starving out the high-priority class. *
@@ -478,7 +478,7 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags,* sbitmap_queue, limiting the depth used from each word, with preemption * already disabled. * @sbq: Bitmap queue to allocate from. -* @shallow_depth: The maximum number of bits to allocate from a single word. +* @shallow_depth: The maximum number of bits to allocate from the queue. * See sbitmap_get_shallow(). * * If you call this, make sure to call sbitmap_queue_min_shallow_depth() after
lib/sbitmap.c +29 -27
76 lines not on this page · raw message
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 359/444 ALSA: hda/realtek: add LG gram 16Z90R-A to alc269 fixup table
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Croft <[email protected]>
[ Upstream commit dbe05428c4e54068a86e7e02405f3b30b1d2b3dd ]
Several months ago, Joshua Grisham submitted a patch [1] for several ALC298 based sound cards.
The entry for the LG gram 16 in the alc269_fixup_tbl only matches the Subsystem ID for the 16Z90R-Q and 16Z90R-K models [2]. My 16Z90R-A has a different Subsystem ID [3]. I'm not sure why these IDs differ, but I speculate it's due to the NVIDIA GPU included in the 16Z90R-A model that isn't present in the other models.
I applied the patch to the latest Arch Linux kernel and the card was initialized as expected.
[1]: https://lore.kernel.org/linux-sound/[email protected]/
[2]: https://linux-hardware.org/?id=pci:8086-51ca-1854-0488
[3]: https://linux-hardware.org/?id=pci:8086-51ca-1854-0489
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -11302,6 +11302,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x1854 ,0x0440 ,"LG CQ6" ,ALC256_FIXUP_HEADPHONE_AMP_VOL ),SND_PCI_QUIRK (0x1854 ,0x0441 ,"LG CQ6 AIO" ,ALC256_FIXUP_HEADPHONE_AMP_VOL ),SND_PCI_QUIRK (0x1854 ,0x0488 ,"LG gram 16 (16Z90R)" ,ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS ), +SND_PCI_QUIRK (0x1854 ,0x0489 ,"LG gram 16 (16Z90R-A)" ,ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS ),SND_PCI_QUIRK (0x1854 ,0x048a ,"LG gram 17 (17ZD90R)" ,ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS ),SND_PCI_QUIRK (0x19e5 ,0x3204 ,"Huawei MACH-WX9" ,ALC256_FIXUP_HUAWEI_MACH_WX9_PINS ), SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 360/444 net: phy: smsc: add proper reset flags for LAN8710A
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Buday Csaba <[email protected]>
[ Upstream commit 57ec5a8735dc5dccd1ee68afdb1114956a3fce0d ]
According to the LAN8710A datasheet (Rev. B, section 3.8.5.1), a hardware reset is required after power-on, and the reference clock (REF_CLK) must be established before asserting reset.
--- drivers/net/phy/smsc.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/phy/smsc.c +1 -0
@@ -784,6 +784,7 @@ static struct phy_driver smsc_phy_driver[] = {/* PHY_BASIC_FEATURES */ + .flags = PHY_RST_AFTER_CLK_EN, .probe = smsc_phy_probe,/* basic functions */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 361/444 ASoC: Intel: avs: Fix uninitialized pointer error in probe()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <[email protected]>
[ Upstream commit 11f74f48c14c1f4fe16541900ea5944c42e30ccf ]
If pcim_request_all_regions() fails, error path operates on uninitialized 'bus' pointer. Found out by Coverity static analyzer.
--- sound/soc/intel/avs/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/intel/avs/core.c +2 -1
@@ -439,6 +439,8 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) adev =devm_kzalloc (dev,sizeof (*adev),GFP_KERNEL );if (!adev)return -ENOMEM ; + bus = &adev->base.core; + ret =avs_bus_init (adev, pci, id);if (ret <0 ) {dev_err (dev,"failed to init avs bus: %d\n" , ret);
@@ -449,7 +451,6 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)if (ret <0 )return ret; - bus = &adev->base.core; bus->addr =pci_resource_start (pci,0 ); bus->remap_addr =pci_ioremap_bar (pci,0 );if (!bus->remap_addr) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 362/444 block: avoid possible overflow for chunk_sectors check in blk_stack_limits()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Garry <[email protected]>
[ Upstream commit 448dfecc7ff807822ecd47a5c052acedca7d09e8 ]
In blk_stack_limits(), we check that the t->chunk_sectors value is a multiple of the t->physical_block_size value.
However, by finding the chunk_sectors value in bytes, we may overflow the unsigned int which holds chunk_sectors, so change the check to be based on sectors.
--- block/blk-settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
block/blk-settings.c +1 -1
@@ -623,7 +623,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, }/* chunk_sectors a multiple of the physical block size? */ -if ((t->chunk_sectors <<9 ) & (t->physical_block_size -1 )) { +if (t->chunk_sectors % (t->physical_block_size >>SECTOR_SHIFT )) { t->chunk_sectors =0 ; t->flags |=BLK_FLAG_MISALIGNED ; ret =-1 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 363/444 pNFS: Fix stripe mapping in block/scsi layout
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Bashirov <[email protected]>
[ Upstream commit 81438498a285759f31e843ac4800f82a5ce6521f ]
Because of integer division, we need to carefully calculate the disk offset. Consider the example below for a stripe of 6 volumes, a chunk size of 4096, and an offset of 70000.
chunk = div_u64(offset, dev->chunk_size) = 70000 / 4096 = 17 offset = chunk * dev->chunk_size = 17 * 4096 = 69632 disk_offset_wrong = div_u64(offset, dev->nr_children) = 69632 / 6 = 11605 disk_chunk = div_u64(chunk, dev->nr_children) = 17 / 6 = 2 disk_offset = disk_chunk * dev->chunk_size = 2 * 4096 = 8192
--- fs/nfs/blocklayout/dev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/nfs/blocklayout/dev.c +3 -2
@@ -257,10 +257,11 @@ static bool bl_map_stripe(struct pnfs_block_dev *dev, u64 offset,struct pnfs_block_dev *child;u64 chunk;u32 chunk_idx; +u64 disk_chunk;u64 disk_offset; chunk =div_u64 (offset, dev->chunk_size); -div_u64_rem (chunk, dev->nr_children, &chunk_idx); + disk_chunk =div_u64_rem (chunk, dev->nr_children, &chunk_idx);if (chunk_idx >= dev->nr_children) { dprintk("%s: invalid chunk idx %d (%lld/%lld)\n",
@@ -273,7 +274,7 @@ static bool bl_map_stripe(struct pnfs_block_dev *dev, u64 offset, offset = chunk * dev->chunk_size;/* disk offset of the stripe */ - disk_offset =div_u64 (offset, dev->nr_children); + disk_offset = disk_chunk * dev->chunk_size; child = &dev->children[chunk_idx]; child->map (child, disk_offset, map);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 364/444 pNFS: Fix disk addr range check in block/scsi layout
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Bashirov <[email protected]>
[ Upstream commit 7db6e66663681abda54f81d5916db3a3b8b1a13d ]
At the end of the isect translation, disc_addr represents the physical disk offset. Thus, end calculated from disk_addr is also a physical disk offset. Therefore, range checking should be done using map->disk_offset, not map->start.
--- fs/nfs/blocklayout/blocklayout.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/nfs/blocklayout/blocklayout.c +2 -2
@@ -149,8 +149,8 @@ do_add_page_to_bio(struct bio *bio, int npg, enum req_op op, sector_t isect,/* limit length to what the device mapping allows */ end = disk_addr + *len; -if (end >= map->start + map->len) - *len = map->start + map->len - disk_addr; +if (end >= map->disk_offset + map->len) + *len = map->disk_offset + map->len - disk_addr; retry:if (!bio) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 365/444 pNFS: Handle RPC size limit for layoutcommits
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Bashirov <[email protected]>
[ Upstream commit d897d81671bc4615c80f4f3bd5e6b218f59df50c ]
When there are too many block extents for a layoutcommit, they may not all fit into the maximum-sized RPC. This patch allows the generic pnfs code to properly handle -ENOSPC returned by the block/scsi layout driver and trigger additional layoutcommits if necessary.
--- fs/nfs/pnfs.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
fs/nfs/pnfs.c +8 -3
@@ -3332,6 +3332,7 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)struct nfs_inode *nfsi =NFS_I (inode);loff_t end_pos;int status; +bool mark_as_dirty = false;if (!pnfs_layoutcommit_outstanding (inode))return 0 ;
@@ -3383,19 +3384,23 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)if (ld->prepare_layoutcommit) { status = ld->prepare_layoutcommit (&data->args);if (status) { -put_cred (data->cred); +if (status != -ENOSPC ) +put_cred (data->cred);spin_lock (&inode->i_lock);set_bit (NFS_INO_LAYOUTCOMMIT , &nfsi->flags);if (end_pos > nfsi->layout->plh_lwb) nfsi->layout->plh_lwb = end_pos; - goto out_unlock; +if (status != -ENOSPC ) + goto out_unlock; +spin_unlock (&inode->i_lock); + mark_as_dirty = true; } } status =nfs4_proc_layoutcommit (data, sync); out: -if (status) +if (status || mark_as_dirty)mark_inode_dirty_sync (inode);dprintk ("<-- %s status %d\n" , __func__, status);return status;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 366/444 pNFS: Fix uninited ptr deref in block/scsi layout
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Bashirov <[email protected]>
[ Upstream commit 9768797c219326699778fba9cd3b607b2f1e7950 ]
The error occurs on the third attempt to encode extents. When function ext_tree_prepare_commit() reallocates a larger buffer to retry encoding extents, the "layoutupdate_pages" page array is initialized only after the retry loop. But ext_tree_free_commitdata() is called on every iteration and tries to put pages in the array, thus dereferencing uninitialized pointers.
An additional problem is that there is no limit on the maximum possible buffer_size. When there are too many extents, the client may create a layoutcommit that is larger than the maximum possible RPC size accepted by the server.
During testing, we observed two typical scenarios. First, one memory page for extents is enough when we work with small files, append data to the end of the file, or preallocate extents before writing. But when we fill a new large file without preallocating, the number of extents can be huge, and counting the number of written extents in ext_tree_encode_commit() does not help much. Since this number increases even more between unlocking and locking of ext_tree, the reallocated buffer may not be large enough again and again.
--- fs/nfs/blocklayout/extent_tree.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
fs/nfs/blocklayout/extent_tree.c +15 -5
@@ -552,6 +552,15 @@ static int ext_tree_encode_commit(struct pnfs_block_layout *bl, __be32 *p,return ret; } +/** +* ext_tree_prepare_commit - encode extents that need to be committed +* @arg: layout commit data +* +* Return values: +* %0: Success, all required extents are encoded +* %-ENOSPC: Some extents are encoded, but not all, due to RPC size limit +* %-ENOMEM: Out of memory, extents not encoded +*/ int ext_tree_prepare_commit (struct nfs4_layoutcommit_args *arg) {
@@ -568,12 +577,12 @@ ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg) start_p =page_address (arg->layoutupdate_page); arg->layoutupdate_pages = &arg->layoutupdate_page; -retry: - ret =ext_tree_encode_commit (bl, start_p +1 , buffer_size, &count, &arg->lastbytewritten); + ret =ext_tree_encode_commit (bl, start_p +1 , buffer_size, + &count, &arg->lastbytewritten);if (unlikely (ret)) {ext_tree_free_commitdata (arg, buffer_size); - buffer_size =ext_tree_layoutupdate_size (bl, count); + buffer_size =NFS_SERVER (arg->inode)->wsize; count =0 ; arg->layoutupdate_pages =
@@ -588,7 +597,8 @@ ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg)return -ENOMEM ; } - goto retry; + ret =ext_tree_encode_commit (bl, start_p +1 , buffer_size, + &count, &arg->lastbytewritten); } *start_p =cpu_to_be32 (count);
@@ -608,7 +618,7 @@ ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg) }dprintk ("%s found %zu ranges\n" , __func__, count); -return 0 ; +return ret; }void
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 367/444 rtc: ds1307: remove clear of oscillator stop flag (OSF) in probe
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Meagan Lloyd <[email protected]>
[ Upstream commit 48458654659c9c2e149c211d86637f1592470da5 ]
In using CONFIG_RTC_HCTOSYS, rtc_hctosys() will sync the RTC time to the kernel time as long as rtc_read_time() succeeds. In some power loss situations, our supercapacitor-backed DS1342 RTC comes up with either an unpredictable future time or the default 01/01/00 from the datasheet. The oscillator stop flag (OSF) is set in these scenarios due to the power loss and can be used to determine the validity of the RTC data.
Some chip types in the ds1307 driver already have OSF handling to determine whether .read_time provides valid RTC data or returns -EINVAL.
This change removes the clear of the OSF in .probe as the OSF needs to be preserved to expand the OSF handling to the ds1341 chip type (note that DS1341 and DS1342 share a datasheet).
--- drivers/rtc/rtc-ds1307.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/rtc/rtc-ds1307.c +1 -3
@@ -1824,10 +1824,8 @@ static int ds1307_probe(struct i2c_client *client)regmap_write (ds1307->regmap,DS1337_REG_CONTROL , regs[0 ]); -/* oscillator fault? clear flag, and warn */ +/* oscillator fault? warn */ if (regs[1 ] &DS1337_BIT_OSF ) { -regmap_write (ds1307->regmap,DS1337_REG_STATUS , - regs[1 ] & ~DS1337_BIT_OSF );dev_warn (ds1307->dev,"SET TIME!\n" ); }break ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 368/444 scsi: lpfc: Remove redundant assignment to avoid memory leak
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiasheng Jiang <[email protected]>
[ Upstream commit eea6cafb5890db488fce1c69d05464214616d800 ]
Remove the redundant assignment if kzalloc() succeeds to avoid memory leak.
--- drivers/scsi/lpfc/lpfc_debugfs.c | 1 - 1 file changed, 1 deletion(-)
drivers/scsi/lpfc/lpfc_debugfs.c +0 -1
@@ -6289,7 +6289,6 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) } phba->nvmeio_trc_on =1 ; phba->nvmeio_trc_output_idx =0 ; - phba->nvmeio_trc =NULL ; }else { nvmeio_off: phba->nvmeio_trc_size =0 ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 369/444 ASoC: fsl_sai: replace regmap_write with regmap_update_bits
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 0e270f32975fd21874185ba53653630dd40bf560 ]
Use the regmap_write() for software reset in fsl_sai_config_disable would cause the FSL_SAI_CSR_BCE bit to be cleared. Refer to
commit 197c53c8ecb34 ("ASoC: fsl_sai: Don't disable bitclock for i.MX8MP") FSL_SAI_CSR_BCE should not be cleared. So need to use regmap_update_bits() instead of regmap_write() for these bit operations.
--- sound/soc/fsl/fsl_sai.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
sound/soc/fsl/fsl_sai.c +10 -10
@@ -777,9 +777,9 @@ static void fsl_sai_config_disable(struct fsl_sai *sai, int dir)* are running concurrently. */ /* Software Reset */ -regmap_write (sai->regmap,FSL_SAI_xCSR (tx, ofs),FSL_SAI_CSR_SR ); +regmap_update_bits (sai->regmap,FSL_SAI_xCSR (tx, ofs),FSL_SAI_CSR_SR ,FSL_SAI_CSR_SR );/* Clear SR bit to finish the reset */ -regmap_write (sai->regmap,FSL_SAI_xCSR (tx, ofs),0 ); +regmap_update_bits (sai->regmap,FSL_SAI_xCSR (tx, ofs),FSL_SAI_CSR_SR ,0 ); } static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -898,11 +898,11 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)unsigned int ofs = sai->soc_data->reg_offset;/* Software Reset for both Tx and Rx */ -regmap_write (sai->regmap,FSL_SAI_TCSR (ofs),FSL_SAI_CSR_SR ); -regmap_write (sai->regmap,FSL_SAI_RCSR (ofs),FSL_SAI_CSR_SR ); +regmap_update_bits (sai->regmap,FSL_SAI_TCSR (ofs),FSL_SAI_CSR_SR ,FSL_SAI_CSR_SR ); +regmap_update_bits (sai->regmap,FSL_SAI_RCSR (ofs),FSL_SAI_CSR_SR ,FSL_SAI_CSR_SR );/* Clear SR bit to finish the reset */ -regmap_write (sai->regmap,FSL_SAI_TCSR (ofs),0 ); -regmap_write (sai->regmap,FSL_SAI_RCSR (ofs),0 ); +regmap_update_bits (sai->regmap,FSL_SAI_TCSR (ofs),FSL_SAI_CSR_SR ,0 ); +regmap_update_bits (sai->regmap,FSL_SAI_RCSR (ofs),FSL_SAI_CSR_SR ,0 ); regmap_update_bits(sai->regmap, FSL_SAI_TCR1(ofs), FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),
@@ -1785,11 +1785,11 @@ static int fsl_sai_runtime_resume(struct device *dev)regcache_cache_only (sai->regmap, false);regcache_mark_dirty (sai->regmap); -regmap_write (sai->regmap,FSL_SAI_TCSR (ofs),FSL_SAI_CSR_SR ); -regmap_write (sai->regmap,FSL_SAI_RCSR (ofs),FSL_SAI_CSR_SR ); +regmap_update_bits (sai->regmap,FSL_SAI_TCSR (ofs),FSL_SAI_CSR_SR ,FSL_SAI_CSR_SR ); +regmap_update_bits (sai->regmap,FSL_SAI_RCSR (ofs),FSL_SAI_CSR_SR ,FSL_SAI_CSR_SR );usleep_range (1000 ,2000 ); -regmap_write (sai->regmap,FSL_SAI_TCSR (ofs),0 ); -regmap_write (sai->regmap,FSL_SAI_RCSR (ofs),0 ); +regmap_update_bits (sai->regmap,FSL_SAI_TCSR (ofs),FSL_SAI_CSR_SR ,0 ); +regmap_update_bits (sai->regmap,FSL_SAI_RCSR (ofs),FSL_SAI_CSR_SR ,0 ); ret =regcache_sync (sai->regmap);if (ret)
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 370/444 cifs: Fix collect_sample() to handle any iterator type
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit b63335fb3d32579c5ff0b7038b9cc23688fff528 ]
collect_sample() is used to gather samples of the data in a Write op for analysis to try and determine if the compression algorithm is likely to achieve anything more quickly than actually running the compression algorithm.
However, collect_sample() assumes that the data it is going to be sampling is stored in an ITER_XARRAY-type iterator (which it now should never be) and doesn't actually check that it is before accessing the underlying xarray directly.
Fix this by replacing the code with a loop that just uses the standard iterator functions to sample every other 2KiB block, skipping the intervening ones. It's not quite the same as the previous algorithm as it doesn't necessarily align to the pages within an ordinary write from the pagecache.
Note that the btrfs code from which this was derived samples the inode's pagecache directly rather than the iterator - but that doesn't necessarily work for network filesystems if O_DIRECT is in operation.
--- fs/smb/client/compress.c | 71 ++++++++++++---------------------------- 1 file changed, 21 insertions(+), 50 deletions(-)
fs/smb/client/compress.c +21 -50
@@ -155,58 +155,29 @@ static int cmp_bkt(const void *_a, const void *_b) }/* -* TODO: -* Support other iter types, if required. -* Only ITER_XARRAY is supported for now. +* Collect some 2K samples with 2K gaps between. */ -static int collect_sample (const struct iov_iter *iter,ssize_t max,u8 *sample) +static int collect_sample (const struct iov_iter *source,ssize_t max,u8 *sample) { -struct folio *folios[16 ], *folio; -unsigned int nr, i, j, npages; -loff_t start = iter->xarray_start + iter->iov_offset; -pgoff_t last, index = start /PAGE_SIZE ; -size_t len, off, foff; -void *p; -int s =0 ; - - last = (start + max -1 ) /PAGE_SIZE ; -do { - nr =xa_extract (iter->xarray, (void **)folios, index, last,ARRAY_SIZE (folios), -XA_PRESENT ); -if (nr ==0 ) -return -EIO ; - -for (i =0 ; i < nr; i++) { - folio = folios[i]; - npages =folio_nr_pages (folio); - foff = start -folio_pos (folio); - off = foff %PAGE_SIZE ; - -for (j = foff /PAGE_SIZE ; j < npages; j++) { -size_t len2; - - len =min_t (size_t, max,PAGE_SIZE - off); - len2 =min_t (size_t, len,SZ_2K ); - - p =kmap_local_page (folio_page (folio, j)); -memcpy (&sample[s], p, len2); -kunmap_local (p); - - s += len2; - -if (len2 <SZ_2K || s >= max -SZ_2K ) -return s; - - max -= len; -if (max <=0 ) -return s; - - start += len; - off =0 ; - index++; - } - } - }while (nr ==ARRAY_SIZE (folios)); +struct iov_iter iter = *source; +size_t s =0 ; + +while (iov_iter_count (&iter) >=SZ_2K ) { +size_t part =umin (umin (iov_iter_count (&iter),SZ_2K ), max); +size_t n; + + n =copy_from_iter (sample + s, part, &iter); +if (n != part) +return -EFAULT ; + + s += n; + max -= n; + +if (iov_iter_count (&iter) <PAGE_SIZE -SZ_2K ) +break ; + +iov_iter_advance (&iter,SZ_2K ); + }return s; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 371/444 drm/amdgpu: fix vram reservation issue
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: YiPeng Chai <[email protected]>
[ Upstream commit 10ef476aad1c848449934e7bec2ab2374333c7b6 ]
The vram block allocation flag must be cleared before making vram reservation, otherwise reserving addresses within the currently freed memory range will always fail.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +1 -2
@@ -648,9 +648,8 @@ static void amdgpu_vram_mgr_del(struct ttm_resource_manager *man,list_for_each_entry (block, &vres->blocks, link) vis_usage +=amdgpu_vram_mgr_vis_size (adev, block); -amdgpu_vram_mgr_do_reserve (man); -drm_buddy_free_list (mm, &vres->blocks, vres->flags); +amdgpu_vram_mgr_do_reserve (man);mutex_unlock (&mgr->lock);atomic64_sub (vis_usage, &mgr->vis_usage);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 372/444 drm/amdgpu: fix incorrect vm flags to map bo
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jack Xiao <[email protected]>
[ Upstream commit 040bc6d0e0e9c814c9c663f6f1544ebaff6824a8 ]
It should use vm flags instead of pte flags
to specify bo vm attributes.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c +2 -2
@@ -88,8 +88,8 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, } r =amdgpu_vm_bo_map (adev, *bo_va, csa_addr,0 , size, -AMDGPU_PTE_READABLE |AMDGPU_PTE_WRITEABLE | -AMDGPU_PTE_EXECUTABLE ); +AMDGPU_VM_PAGE_READABLE |AMDGPU_VM_PAGE_WRITEABLE | +AMDGPU_VM_PAGE_EXECUTABLE );if (r) {DRM_ERROR ("failed to do bo_map on static CSA, err=%d\n" , r);
Signature · 1 line
2.50.1
RE: [PATCH 6.12 372/444] drm/amdgpu: fix incorrect vm flags to map bo
[Public]
Quoted 13 lines
-----Original Message-----
From: Greg Kroah-Hartman <[email protected]>
Sent: Monday, August 18, 2025 8:47 AM
To: [email protected]
Cc: Greg Kroah-Hartman <[email protected]>; [email protected]; Xiao, Jack <[email protected]>; Gao, Likun <[email protected]>; Deucher, Alexander <[email protected]>; Sasha Levin <[email protected]>
Subject: [PATCH 6.12 372/444] drm/amdgpu: fix incorrect vm flags to map bo6.12-stable review patch. If anyone has any objections, please let me know.
------------------
Quoted 7 lines
From: Jack Xiao <[email protected]>
[ Upstream commit
040bc6d0e0e9c814c9c663f6f1544ebaff6824a8]It should use vm flags instead of pte flags to specify bo vm attributes.
Fixes 7946340fa389 ("drm/amdgpu: Move csa related code to separate file")
I accidently tagged this with the wrong fixes tag. This patch should not go to anything other than 6.17. Sorry for the confusion. Please revert for older kernels.
Thanks,
Alex
Quoted 32 lines
Signed-off-by Jack Xiao <[email protected]>Reviewed-by Likun Gao <[email protected]>Signed-off-by Alex Deucher <[email protected]> (cherry picked fromcommit
b08425fa77ad2f305fe57a33dceb456be03b653f)Signed-off-by Sasha Levin <[email protected]>--- drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c +0
-1@@ -88,8 +88,8 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev,struct amdgpu_vm *vm, } r = amdgpu_vm_bo_map(adev, *bo_va, csa_addr, 0, size, - AMDGPU_PTE_READABLE |
AMDGPU_PTE_WRITEABLE|drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c +1
-1- AMDGPU_PTE_EXECUTABLE); + AMDGPU_VM_PAGE_READABLE |
AMDGPU_VM_PAGE_WRITEABLE|
+AMDGPU_VM_PAGE_EXECUTABLE);if (r) { DRM_ERROR("failed to do bo_map on static CSA, err=%d\n", r);--
2.50.1
Greg Kroah-Hartman
maintainerPATCH 373/444 mm/damon/core: commit damos->target_nid
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bijan Tabatabai <[email protected]>
commit 579bd5006fe7f4a7abb32da0160d376476cab67d upstream.
When committing new scheme parameters from the sysfs, the target_nid field of the damos struct would not be copied. This would result in the target_nid field to retain its original value, despite being updated in the sysfs interface.
This patch fixes this issue by copying target_nid in damos_commit().
--- mm/damon/core.c | 1 + 1 file changed, 1 insertion(+)
mm/damon/core.c +1 -0
@@ -837,6 +837,7 @@ static int damos_commit(struct damos *dsreturn err; dst->wmarks = src->wmarks; + dst->target_nid = src->target_nid; err =damos_commit_filters (dst, src);return err;
Greg Kroah-Hartman
maintainerPATCH 374/444 block: Introduce bio_needs_zone_write_plugging()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
commit f70291411ba20d50008db90a6f0731efac27872c upstream.
In preparation for fixing device mapper zone write handling, introduce the inline helper function bio_needs_zone_write_plugging() to test if a BIO requires handling through zone write plugging using the function blk_zone_plug_bio(). This function returns true for any write (op_is_write(bio) == true) operation directed at a zoned block device using zone write plugging, that is, a block device with a disk that has a zone write plug hash table.
This helper allows simplifying the check on entry to blk_zone_plug_bio() and used in to protect calls to it for blk-mq devices and DM devices.
--- block/blk-mq.c | 6 +++-- block/blk-zoned.c | 20 ----------------- drivers/md/dm.c | 4 ++- include/linux/blkdev.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 22 deletions(-)
block/blk-mq.c +4 -2
@@ -3114,8 +3114,10 @@ void blk_mq_submit_bio(struct bio *bio)if (blk_mq_attempt_bio_merge (q, bio, nr_segs)) goto queue_exit; -if (blk_queue_is_zoned (q) &&blk_zone_plug_bio (bio, nr_segs)) - goto queue_exit; +if (bio_needs_zone_write_plugging (bio)) { +if (blk_zone_plug_bio (bio, nr_segs)) + goto queue_exit; + } new_request:if (!rq) {
block/blk-zoned.c +1 -19
@@ -1131,25 +1131,7 @@ bool blk_zone_plug_bio(struct bio *bio, {struct block_device *bdev = bio->bi_bdev; -if (!bdev->bd_disk->zone_wplugs_hash) -return false; - -/* -* If the BIO already has the plugging flag set, then it was already -* handled through this path and this is a submission from the zone -* plug bio submit work. -*/ -if (bio_flagged (bio,BIO_ZONE_WRITE_PLUGGING )) -return false; - -/* -* We do not need to do anything special for empty flush BIOs, e.g -* BIOs such as issued by blkdev_issue_flush(). The is because it is -* the responsibility of the user to first wait for the completion of -* write operations for flush to have any effect on the persistence of -* the written data. -*/ -if (op_is_flush (bio->bi_opf) && !bio_sectors (bio)) +if (WARN_ON_ONCE (!bdev->bd_disk->zone_wplugs_hash))return false;/*
drivers/md/dm.c +3 -1
@@ -1800,7 +1800,9 @@ static inline bool dm_zone_bio_needs_spl }static inline bool dm_zone_plug_bio (struct mapped_device *md,struct bio *bio) { -return dm_emulate_zone_append (md) &&blk_zone_plug_bio (bio,0 ); +if (!bio_needs_zone_write_plugging (bio)) +return false; +return blk_zone_plug_bio (bio,0 ); } static blk_status_t __send_zone_reset_all_emulated(struct clone_info *ci,
include/linux/blkdev.h +55 -0
67 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 375/444 dm: Always split write BIOs to zoned device limits
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
commit 2df7168717b7d2d32bcf017c68be16e4aae9dd13 upstream.
Any zoned DM target that requires zone append emulation will use the block layer zone write plugging. In such case, DM target drivers must not split BIOs using dm_accept_partial_bio() as doing so can potentially lead to deadlocks with queue freeze operations. Regular write operations used to emulate zone append operations also cannot be split by the target driver as that would result in an invalid writen sector value return using the BIO sector.
In order for zoned DM target drivers to avoid such incorrect BIO splitting, we must ensure that large BIOs are split before being passed to the map() function of the target, thus guaranteeing that the limits for the mapped device are not exceeded.
dm-crypt and dm-flakey are the only target drivers supporting zoned devices and using dm_accept_partial_bio().
In the case of dm-crypt, this function is used to split BIOs to the internal max_write_size limit (which will be suppressed in a different patch). However, since crypt_alloc_buffer() uses a bioset allowing only up to BIO_MAX_VECS (256) vectors in a BIO. The dm-crypt device max_segments limit, which is not set and so default to BLK_MAX_SEGMENTS (128), must thus be respected and write BIOs split accordingly.
In the case of dm-flakey, since zone append emulation is not required, the block layer zone write plugging is not used and no splitting of BIOs required.
Modify the function dm_zone_bio_needs_split() to use the block layer helper function bio_needs_zone_write_plugging() to force a call to bio_split_to_limits() in dm_split_and_process_bio(). This allows DM target drivers to avoid using dm_accept_partial_bio() for write operations on zoned DM devices.
--- drivers/md/dm.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-)
drivers/md/dm.c +22 -7
@@ -1792,12 +1792,29 @@ static inline bool dm_zone_bio_needs_spl struct bio *bio) {/* -* For mapped device that need zone append emulation, we must -* split any large BIO that straddles zone boundaries. +* Special case the zone operations that cannot or should not be split. */ -return dm_emulate_zone_append (md) &&bio_straddles_zones (bio) && - !bio_flagged (bio,BIO_ZONE_WRITE_PLUGGING ); +switch (bio_op (bio)) { +case REQ_OP_ZONE_APPEND : +case REQ_OP_ZONE_FINISH : +case REQ_OP_ZONE_RESET : +case REQ_OP_ZONE_RESET_ALL : +return false; +default : +break ; + } + +/* +* Mapped devices that require zone append emulation will use the block +* layer zone write plugging. In such case, we must split any large BIO +* to the mapped device limits to avoid potential deadlocks with queue +* freeze operations. +*/ +if (!dm_emulate_zone_append (md)) +return false; +return bio_needs_zone_write_plugging (bio) ||bio_straddles_zones (bio); } +static inline bool dm_zone_plug_bio (struct mapped_device *md,struct bio *bio) {if (!bio_needs_zone_write_plugging (bio))
@@ -1946,9 +1963,7 @@ static void dm_split_and_process_bio(str is_abnormal =is_abnormal_io (bio);if (static_branch_unlikely (&zoned_enabled)) { -/* Special case REQ_OP_ZONE_RESET_ALL as it cannot be split. */ - need_split = (bio_op (bio) !=REQ_OP_ZONE_RESET_ALL ) && - (is_abnormal ||dm_zone_bio_needs_split (md, bio)); + need_split = is_abnormal ||dm_zone_bio_needs_split (md, bio); }else { need_split = is_abnormal; }
Greg Kroah-Hartman
maintainerPATCH 376/444 clk: qcom: gcc-ipq8074: fix broken freq table for nss_port6_tx_clk_src
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Marangi <[email protected]>
commit 077ec7bcec9a8987d2a133afb7e13011878c7576 upstream.
With the conversion done by commit e88f03230dc0 ("clk: qcom: gcc-ipq8074:
rework nss_port5/6 clock to multiple conf") a Copy-Paste error was made for the nss_port6_tx_clk_src frequency table.
This was caused by the wrong setting of the parent in ftbl_nss_port6_tx_clk_src that was wrongly set to P_UNIPHY1_RX instead of P_UNIPHY2_TX.
This cause the UNIPHY2 port to malfunction when it needs to be scaled to higher clock. The malfunction was observed with the example scenario with an Aquantia 10G PHY connected and a speed higher than 1G (example 2.5G)
Fix the broken frequency table to restore original functionality.
--- drivers/clk/qcom/gcc-ipq8074.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/qcom/gcc-ipq8074.c +3 -3
@@ -1895,10 +1895,10 @@ static const struct freq_conf ftbl_nss_port6_tx_clk_src_125[] = {static const struct freq_multi_tbl ftbl_nss_port6_tx_clk_src[] = {FMS (19200000 ,P_XO ,1 ,0 ,0 ),FM (25000000 , ftbl_nss_port6_tx_clk_src_25), -FMS (78125000 ,P_UNIPHY1_RX ,4 ,0 ,0 ), +FMS (78125000 ,P_UNIPHY2_TX ,4 ,0 ,0 ),FM (125000000 , ftbl_nss_port6_tx_clk_src_125), -FMS (156250000 ,P_UNIPHY1_RX ,2 ,0 ,0 ), -FMS (312500000 ,P_UNIPHY1_RX ,1 ,0 ,0 ), +FMS (156250000 ,P_UNIPHY2_TX ,2 ,0 ,0 ), +FMS (312500000 ,P_UNIPHY2_TX ,1 ,0 ,0 ), { } };
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 377/444 cifs: reset iface weights when we cannot find a candidate
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shyam Prasad N <[email protected]>
commit 9d5eff7821f6d70f7d1b4d8a60680fba4de868a7 upstream.
We now do a weighted selection of server interfaces when allocating new channels. The weights are decided based on the speed advertised. The fulfilled weight for an interface is a counter that is used to track the interface selection. It should be reset back to zero once all interfaces fulfilling their weight.
In cifs_chan_update_iface, this reset logic was missing. As a result when the server interface list changes, the client may not be able to find a new candidate for other channels after all interfaces have been fulfilled.
--- fs/smb/client/sess.c | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/smb/client/sess.c +9 -0
@@ -360,6 +360,7 @@ cifs_chan_update_iface(struct cifs_ses *struct cifs_server_iface *old_iface =NULL ;struct cifs_server_iface *last_iface =NULL ;struct sockaddr_storage ss; +int retry =0 ;spin_lock (&ses->chan_lock); chan_index =cifs_ses_get_chan_index (ses, server);
@@ -388,6 +389,7 @@ cifs_chan_update_iface(struct cifs_ses *return ; } +try_again: last_iface = list_last_entry(&ses->iface_list, struct cifs_server_iface, iface_head); iface_min_speed = last_iface->speed;
@@ -425,6 +427,13 @@ cifs_chan_update_iface(struct cifs_ses * }if (list_entry_is_head (iface, &ses->iface_list, iface_head)) { +list_for_each_entry (iface, &ses->iface_list, iface_head) + iface->weight_fulfilled =0 ; + +/* see if it can be satisfied in second attempt */ +if (!retry++) + goto try_again; + iface =NULL ;cifs_dbg (FYI ,"unable to find a suitable iface\n" ); }
Greg Kroah-Hartman
maintainerPATCH 378/444 iommu/vt-d: Optimize iotlb_sync_map for non-caching/non-RWBF modes
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lu Baolu <[email protected]>
commit 12724ce3fe1a3d8f30d56e48b4f272d8860d1970 upstream.
The iotlb_sync_map iommu ops allows drivers to perform necessary cache flushes when new mappings are established. For the Intel iommu driver, this callback specifically serves two purposes:
- To flush caches when a second-stage page table is attached to a device whose iommu is operating in caching mode (CAP_REG.CM==1).
- To explicitly flush internal write buffers to ensure updates to memory- resident remapping structures are visible to hardware (CAP_REG.RWBF==1).
However, in scenarios where neither caching mode nor the RWBF flag is active, the cache_tag_flush_range_np() helper, which is called in the iotlb_sync_map path, effectively becomes a no-op.
Despite being a no-op, cache_tag_flush_range_np() involves iterating through all cache tags of the iommu's attached to the domain, protected by a spinlock. This unnecessary execution path introduces overhead, leading to a measurable I/O performance regression. On systems with NVMes under the same bridge, performance was observed to drop from approximately ~6150 MiB/s down to ~4985 MiB/s.
Introduce a flag in the dmar_domain structure. This flag will only be set when iotlb_sync_map is required (i.e., when CM or RWBF is set). The cache_tag_flush_range_np() is called only for domains where this flag is set. This flag, once set, is immutable, given that there won't be mixed configurations in real-world scenarios where some IOMMUs in a system operate in caching mode while others do not. Theoretically, the immutability of this flag does not impact functionality.
--- drivers/iommu/intel/iommu.c | 19 ++++++++++++++++++- drivers/iommu/intel/iommu.h | 3 +++ 2 files changed, 21 insertions(+), 1 deletion(-)
drivers/iommu/intel/iommu.c +18 -1
@@ -1957,6 +1957,18 @@ static bool dev_is_real_dma_subdevice(stpci_real_dma_dev (to_pci_dev (dev)) !=to_pci_dev (dev); } +static bool domain_need_iotlb_sync_map (struct dmar_domain *domain, +struct intel_iommu *iommu) +{ +if (cap_caching_mode (iommu->cap) && !domain->use_first_level) +return true; + +if (rwbf_quirk ||cap_rwbf (iommu->cap)) +return true; + +return false; +} +static int dmar_domain_attach_device (struct dmar_domain *domain,struct device *dev) {
@@ -1994,6 +2006,8 @@ static int dmar_domain_attach_device(strif (ret) goto out_block_translation; + domain->iotlb_sync_map |=domain_need_iotlb_sync_map (domain, iommu); +return 0 ; out_block_translation:
@@ -4278,7 +4292,10 @@ static bool risky_device(struct pci_devstatic int intel_iommu_iotlb_sync_map (struct iommu_domain *domain,unsigned long iova,size_t size) { -cache_tag_flush_range_np (to_dmar_domain (domain), iova, iova + size -1 ); +struct dmar_domain *dmar_domain =to_dmar_domain (domain); + +if (dmar_domain->iotlb_sync_map) +cache_tag_flush_range_np (dmar_domain, iova, iova + size -1 );return 0 ; }
drivers/iommu/intel/iommu.h +3 -0
@@ -614,6 +614,9 @@ struct dmar_domain { u8 has_mappings:1; /* Has mappings configured through* iommu_map() interface. */ + u8 iotlb_sync_map:1; /* Need to flush IOTLB cache or write +* buffer when creating mappings. +*/ spinlock_t lock;/* Protect device tracking lists */ struct list_head devices;/* all devices' list */
Greg Kroah-Hartman
maintainerPATCH 379/444 iommu/arm-smmu-qcom: Add SM6115 MDSS compatible
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Klimov <[email protected]>
commit f7fa8520f30373ce99c436c4d57c76befdacbef3 upstream.
Add the SM6115 MDSS compatible to clients compatible list, as it also needs that workaround.
Without this workaround, for example, QRB4210 RB2 which is based on SM4250/SM6115 generates a lot of smmu unhandled context faults during boot:
arm_smmu_context_fault: 116854 callbacks suppressed arm-smmu c600000.iommu: Unhandled context fault: fsr=0x402, iova=0x5c0ec600, fsynr=0x320021, cbfrsynra=0x420, cb=5
arm-smmu c600000.iommu: FSR = 00000402 [Format=2 TF], SID=0x420
arm-smmu c600000.iommu: FSYNR0 = 00320021 [S1CBNDX=50 PNU PLVL=1] arm-smmu c600000.iommu: Unhandled context fault: fsr=0x402, iova=0x5c0d7800, fsynr=0x320021, cbfrsynra=0x420, cb=5
arm-smmu c600000.iommu: FSR = 00000402 [Format=2 TF], SID=0x420
and also failed initialisation of lontium lt9611uxc, gpu and dpu is observed:
(binding MDSS components triggered by lt9611uxc have failed)
------------[ cut here ]------------ !aspace WARNING: CPU: 6 PID: 324 at drivers/gpu/drm/msm/msm_gem_vma.c:130 msm_gem_vma_init+0x150/0x18c [msm] Modules linked in: ... (long list of modules) CPU: 6 UID: 0 PID: 324 Comm: (udev-worker) Not tainted 6.15.0-03037-gaacc73ceeb8b #4 PREEMPT Hardware name: Qualcomm Technologies, Inc. QRB4210 RB2 (DT) pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : msm_gem_vma_init+0x150/0x18c [msm] lr : msm_gem_vma_init+0x150/0x18c [msm] sp : ffff80008144b280 ... Call trace: msm_gem_vma_init+0x150/0x18c [msm] (P) get_vma_locked+0xc0/0x194 [msm] msm_gem_get_and_pin_iova_range+0x4c/0xdc [msm] msm_gem_kernel_new+0x48/0x160 [msm] msm_gpu_init+0x34c/0x53c [msm] adreno_gpu_init+0x1b0/0x2d8 [msm] a6xx_gpu_init+0x1e8/0x9e0 [msm] adreno_bind+0x2b8/0x348 [msm] component_bind_all+0x100/0x230 msm_drm_bind+0x13c/0x3d0 [msm] try_to_bring_up_aggregate_device+0x164/0x1d0 __component_add+0xa4/0x174 component_add+0x14/0x20 dsi_dev_attach+0x20/0x34 [msm] dsi_host_attach+0x58/0x98 [msm] devm_mipi_dsi_attach+0x34/0x90 lt9611uxc_attach_dsi.isra.0+0x94/0x124 [lontium_lt9611uxc] lt9611uxc_probe+0x540/0x5fc [lontium_lt9611uxc] i2c_device_probe+0x148/0x2a8 really_probe+0xbc/0x2c0 __driver_probe_device+0x78/0x120 driver_probe_device+0x3c/0x154 __driver_attach+0x90/0x1a0 bus_for_each_dev+0x68/0xb8 driver_attach+0x24/0x30 bus_add_driver+0xe4/0x208 driver_register+0x68/0x124 i2c_register_driver+0x48/0xcc lt9611uxc_driver_init+0x20/0x1000 [lontium_lt9611uxc] do_one_initcall+0x60/0x1d4 do_init_module+0x54/0x1fc load_module+0x1748/0x1c8c init_module_from_file+0x74/0xa0 __arm64_sys_finit_module+0x130/0x2f8 invoke_syscall+0x48/0x104 el0_svc_common.constprop.0+0xc0/0xe0 do_el0_svc+0x1c/0x28 el0_svc+0x2c/0x80 el0t_64_sync_handler+0x10c/0x138 el0t_64_sync+0x198/0x19c ---[ end trace 0000000000000000 ]--- msm_dpu 5e01000.display-controller: [drm:msm_gpu_init [msm]] *ERROR* could not allocate memptrs: -22 msm_dpu 5e01000.display-controller: failed to load adreno gpu platform a400000.remoteproc:glink-edge:apr:service@7:dais: Adding to iommu group 19 msm_dpu 5e01000.display-controller: failed to bind 5900000.gpu (ops a3xx_ops [msm]): -22 msm_dpu 5e01000.display-controller: adev bind failed: -22 lt9611uxc 0-002b: failed to attach dsi to host lt9611uxc 0-002b: probe with driver lt9611uxc failed with error -22
--- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 1 + 1 file changed, 1 insertion(+)
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +1 -0
@@ -258,6 +258,7 @@ static const struct of_device_id qcom_sm { .compatible = "qcom,sdm670-mdss" }, { .compatible = "qcom,sdm845-mdss" }, { .compatible = "qcom,sdm845-mss-pil" }, + { .compatible = "qcom,sm6115-mdss" }, { .compatible = "qcom,sm6350-mdss" }, { .compatible = "qcom,sm6375-mdss" }, { .compatible = "qcom,sm8150-mdss" },
Greg Kroah-Hartman
maintainerPATCH 380/444 iommufd: Report unmapped bytes in the error path of iopt_unmap_iova_range
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolin Chen <[email protected]>
commit b23e09f9997771b4b739c1c694fa832b5fa2de02 upstream.
There are callers that read the unmapped bytes even when rc != 0. Thus, do not forget to report it in the error path too.
--- drivers/iommu/iommufd/io_pagetable.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/iommu/iommufd/io_pagetable.c +5 -2
@@ -696,8 +696,10 @@ again:iommufd_access_notify_unmap (iopt, area_first, length);/* Something is not responding to unmap requests. */ tries++; -if (WARN_ON (tries >100 )) -return -EDEADLOCK ; +if (WARN_ON (tries >100 )) { + rc = -EDEADLOCK ; + goto out_unmapped; + } goto again; }
@@ -719,6 +721,7 @@ again: out_unlock_iova:up_write (&iopt->iova_rwsem);up_read (&iopt->domains_rwsem); +out_unmapped:if (unmapped) *unmapped = unmapped_bytes;return rc;
Greg Kroah-Hartman
maintainerPATCH 381/444 iommufd: Prevent ALIGN() overflow
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
commit b42497e3c0e74db061eafad41c0cd7243c46436b upstream.
When allocating IOVA the candidate range gets aligned to the target alignment. If the range is close to ULONG_MAX then the ALIGN() can wrap resulting in a corrupted iova.
Open code the ALIGN() using get_add_overflow() to prevent this. This simplifies the checks as we don't need to check for length earlier either.
Consolidate the two copies of this code under a single helper.
This bug would allow userspace to create a mapping that overlaps with some other mapping or a reserved range.
--- drivers/iommu/iommufd/io_pagetable.c | 41 +++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 16 deletions(-)
drivers/iommu/iommufd/io_pagetable.c +25 -16
@@ -70,36 +70,45 @@ struct iopt_area *iopt_area_contig_next(return iter->area; } -static bool __alloc_iova_check_hole (struct interval_tree_double_span_iter *span, -unsigned long length, -unsigned long iova_alignment, -unsigned long page_offset) +static bool __alloc_iova_check_range (unsigned long *start,unsigned long last, +unsigned long length, +unsigned long iova_alignment, +unsigned long page_offset) { -if (span->is_used || span->last_hole - span->start_hole < length -1 ) +unsigned long aligned_start; + +/* ALIGN_UP() */ +if (check_add_overflow (*start, iova_alignment -1 , &aligned_start))return false; + aligned_start &= ~(iova_alignment -1 ); + aligned_start |= page_offset; - span->start_hole =ALIGN (span->start_hole, iova_alignment) | - page_offset; -if (span->start_hole > span->last_hole || - span->last_hole - span->start_hole < length -1 ) +if (aligned_start >= last || last - aligned_start < length -1 )return false; + *start = aligned_start;return true; } -static bool __alloc_iova_check_used (struct interval_tree_span_iter *span, +static bool __alloc_iova_check_hole (struct interval_tree_double_span_iter *span,unsigned long length,unsigned long iova_alignment,unsigned long page_offset) { -if (span->is_hole || span->last_used - span->start_used < length -1 ) +if (span->is_used)return false; +return __alloc_iova_check_range (&span->start_hole, span->last_hole, + length, iova_alignment, page_offset); +} - span->start_used =ALIGN (span->start_used, iova_alignment) | - page_offset; -if (span->start_used > span->last_used || - span->last_used - span->start_used < length -1 ) +static bool __alloc_iova_check_used (struct interval_tree_span_iter *span, +unsigned long length, +unsigned long iova_alignment, +unsigned long page_offset) +{ +if (span->is_hole)return false; -return true; +return __alloc_iova_check_range (&span->start_used, span->last_used, + length, iova_alignment, page_offset); }/*
Greg Kroah-Hartman
maintainerPATCH 382/444 ext4: fix zombie groups in average fragment size lists
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 1c320d8e92925bb7615f83a7b6e3f402a5c2ca63 upstream.
Groups with no free blocks shouldn't be in any average fragment size list. However, when all blocks in a group are allocated(i.e., bb_fragments or bb_free is 0), we currently skip updating the average fragment size, which means the group isn't removed from its previous s_mb_avg_fragment_size[old] list.
This created "zombie" groups that were always skipped during traversal as they couldn't satisfy any block allocation requests, negatively impacting traversal efficiency.
Therefore, when a group becomes completely full, bb_avg_fragment_size_order is now set to -1. If the old order was not -1, a removal operation is performed; if the new order is not -1, an insertion is performed.
--- fs/ext4/mballoc.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)
fs/ext4/mballoc.c +17 -17
@@ -841,30 +841,30 @@ static void mb_update_avg_fragment_size(struct super_block *sb, struct ext4_group_info *grp) { struct ext4_sb_info *sbi = EXT4_SB(sb); -int new_order; +int new, old; -if (!test_opt2 (sb,MB_OPTIMIZE_SCAN ) || grp->bb_fragments ==0 ) +if (!test_opt2 (sb,MB_OPTIMIZE_SCAN ))return ; - new_order =mb_avg_fragment_size_order (sb, - grp->bb_free / grp->bb_fragments); -if (new_order == grp->bb_avg_fragment_size_order) + old = grp->bb_avg_fragment_size_order; + new = grp->bb_fragments ==0 ?-1 : +mb_avg_fragment_size_order (sb, grp->bb_free / grp->bb_fragments); +if (new == old)return ; -if (grp->bb_avg_fragment_size_order !=-1 ) { -write_lock (&sbi->s_mb_avg_fragment_size_locks[ - grp->bb_avg_fragment_size_order]); +if (old >=0 ) { +write_lock (&sbi->s_mb_avg_fragment_size_locks[old]);list_del (&grp->bb_avg_fragment_size_node); -write_unlock (&sbi->s_mb_avg_fragment_size_locks[ - grp->bb_avg_fragment_size_order]); +write_unlock (&sbi->s_mb_avg_fragment_size_locks[old]); + } + + grp->bb_avg_fragment_size_order = new; +if (new >=0 ) { +write_lock (&sbi->s_mb_avg_fragment_size_locks[new]); +list_add_tail (&grp->bb_avg_fragment_size_node, + &sbi->s_mb_avg_fragment_size[new]); +write_unlock (&sbi->s_mb_avg_fragment_size_locks[new]); } - grp->bb_avg_fragment_size_order = new_order; -write_lock (&sbi->s_mb_avg_fragment_size_locks[ - grp->bb_avg_fragment_size_order]); -list_add_tail (&grp->bb_avg_fragment_size_node, - &sbi->s_mb_avg_fragment_size[grp->bb_avg_fragment_size_order]); -write_unlock (&sbi->s_mb_avg_fragment_size_locks[ - grp->bb_avg_fragment_size_order]); }/*
Greg Kroah-Hartman
maintainerPATCH 383/444 ext4: fix largest free orders lists corruption on mb_optimize_scan switch
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 7d345aa1fac4c2ec9584fbd6f389f2c2368671d5 upstream.
The grp->bb_largest_free_order is updated regardless of whether mb_optimize_scan is enabled. This can lead to inconsistencies between grp->bb_largest_free_order and the actual s_mb_largest_free_orders list index when mb_optimize_scan is repeatedly enabled and disabled via remount.
For example, if mb_optimize_scan is initially enabled, largest free order is 3, and the group is in s_mb_largest_free_orders[3]. Then, mb_optimize_scan is disabled via remount, block allocations occur, updating largest free order to 2. Finally, mb_optimize_scan is re-enabled via remount, more block allocations update largest free order to 1.
At this point, the group would be removed from s_mb_largest_free_orders[3] under the protection of s_mb_largest_free_orders_locks[2]. This lock mismatch can lead to list corruption.
To fix this, whenever grp->bb_largest_free_order changes, we now always attempt to remove the group from its old order list. However, we only insert the group into the new order list if mb_optimize_scan is enabled. This approach helps prevent lock inconsistencies and ensures the data in the order lists remains reliable.
--- fs/ext4/mballoc.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-)
fs/ext4/mballoc.c +14 -19
@@ -1150,33 +1150,28 @@ static void mb_set_largest_free_order(struct super_block *sb, struct ext4_group_info *grp) { struct ext4_sb_info *sbi = EXT4_SB(sb); -int i; +int new, old = grp->bb_largest_free_order; -for (i =MB_NUM_ORDERS (sb) -1 ; i >=0 ; i--) -if (grp->bb_counters[i] >0 ) +for (new =MB_NUM_ORDERS (sb) -1 ; new >=0 ; new--) +if (grp->bb_counters[new] >0 )break ; +/* No need to move between order lists? */ -if (!test_opt2 (sb,MB_OPTIMIZE_SCAN ) || - i == grp->bb_largest_free_order) { - grp->bb_largest_free_order = i; +if (new == old)return ; - } -if (grp->bb_largest_free_order >=0 ) { -write_lock (&sbi->s_mb_largest_free_orders_locks[ - grp->bb_largest_free_order]); +if (old >=0 && !list_empty (&grp->bb_largest_free_order_node)) { +write_lock (&sbi->s_mb_largest_free_orders_locks[old]);list_del_init (&grp->bb_largest_free_order_node); -write_unlock (&sbi->s_mb_largest_free_orders_locks[ - grp->bb_largest_free_order]); +write_unlock (&sbi->s_mb_largest_free_orders_locks[old]); } - grp->bb_largest_free_order = i; -if (grp->bb_largest_free_order >=0 && grp->bb_free) { -write_lock (&sbi->s_mb_largest_free_orders_locks[ - grp->bb_largest_free_order]); + + grp->bb_largest_free_order = new; +if (test_opt2 (sb,MB_OPTIMIZE_SCAN ) && new >=0 && grp->bb_free) { +write_lock (&sbi->s_mb_largest_free_orders_locks[new]);list_add_tail (&grp->bb_largest_free_order_node, - &sbi->s_mb_largest_free_orders[grp->bb_largest_free_order]); -write_unlock (&sbi->s_mb_largest_free_orders_locks[ - grp->bb_largest_free_order]); + &sbi->s_mb_largest_free_orders[new]); +write_unlock (&sbi->s_mb_largest_free_orders_locks[new]); } }
Greg Kroah-Hartman
maintainerPATCH 384/444 ext4: initialize superblock fields in the kballoc-test.c kunit tests
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Yi <[email protected]>
commit 82e6381e23f1ea7a14f418215068aaa2ca046c84 upstream.
Various changes in the "ext4: better scalability for ext4 block allocation" patch series have resulted in kunit test failures, most notably in the test_new_blocks_simple and the test_mb_mark_used tests. The root cause of these failures is that various in-memory ext4 data structures were not getting initialized, and while previous versions of the functions exercised by the unit tests didn't use these structure members, this was arguably a test bug.
Since one of the patches in the block allocation scalability patches is a fix which is has a cc:stable tag, this commit also has a cc:stable tag.
--- fs/ext4/mballoc-test.c | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/ext4/mballoc-test.c +9 -0
@@ -155,6 +155,7 @@ static struct super_block *mbt_ext4_allobgl_lock_init (sbi->s_blockgroup_lock); sbi->s_es = &fsb->es; + sbi->s_sb = sb; sb->s_fs_info = sbi;up_write (&sb->s_umount);
@@ -801,6 +802,10 @@ static void test_mb_mark_used(struct kunKUNIT_ASSERT_EQ (test, ret,0 ); grp->bb_free =EXT4_CLUSTERS_PER_GROUP (sb); + grp->bb_largest_free_order =-1 ; + grp->bb_avg_fragment_size_order =-1 ; +INIT_LIST_HEAD (&grp->bb_largest_free_order_node); +INIT_LIST_HEAD (&grp->bb_avg_fragment_size_node);mbt_generate_test_ranges (sb, ranges,TEST_RANGE_COUNT );for (i =0 ; i <TEST_RANGE_COUNT ; i++) test_mb_mark_used_range(test, &e4b, ranges[i].start,
@@ -873,6 +878,10 @@ static void test_mb_free_blocks(struct kext4_unlock_group (sb,TEST_GOAL_GROUP ); grp->bb_free =0 ; + grp->bb_largest_free_order =-1 ; + grp->bb_avg_fragment_size_order =-1 ; +INIT_LIST_HEAD (&grp->bb_largest_free_order_node); +INIT_LIST_HEAD (&grp->bb_avg_fragment_size_node);memset (bitmap,0xff , sb->s_blocksize);mbt_generate_test_ranges (sb, ranges,TEST_RANGE_COUNT );
Greg Kroah-Hartman
maintainerPATCH 385/444 usb: core: config: Prevent OOB read in SS endpoint companion parsing
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xinyu Liu <[email protected]>
commit cf16f408364efd8a68f39011a3b073c83a03612d upstream.
usb_parse_ss_endpoint_companion() checks descriptor type before length, enabling a potentially odd read outside of the buffer size.
Fix this up by checking the size first before looking at any of the fields in the descriptor.
--- drivers/usb/core/config.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/usb/core/config.c +8 -2
@@ -81,8 +81,14 @@ static void usb_parse_ss_endpoint_compan*/ desc = (struct usb_ss_ep_comp_descriptor *) buffer; -if (desc->bDescriptorType !=USB_DT_SS_ENDPOINT_COMP || - size <USB_DT_SS_EP_COMP_SIZE ) { +if (size <USB_DT_SS_EP_COMP_SIZE ) { +dev_notice (ddev, +"invalid SuperSpeed endpoint companion descriptor " +"of length %d, skipping\n" , size); +return ; + } + +if (desc->bDescriptorType !=USB_DT_SS_ENDPOINT_COMP ) { dev_notice(ddev, "No SuperSpeed endpoint companion for config %d " " interface %d altsetting %d ep %d: " "using minimum values\n",
Greg Kroah-Hartman
maintainerPATCH 386/444 misc: rtsx: usb: Ensure mmc child device is active when card is present
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricky Wu <[email protected]>
commit 966c5cd72be8989c8a559ddef8e8ff07a37c5eb0 upstream.
When a card is present in the reader, the driver currently defers autosuspend by returning -EAGAIN during the suspend callback to trigger USB remote wakeup signaling. However, this does not guarantee that the mmc child device has been resumed, which may cause issues if it remains suspended while the card is accessible.
This patch ensures that all child devices, including the mmc host controller, are explicitly resumed before returning -EAGAIN. This fixes a corner case introduced by earlier remote wakeup handling, improving reliability of runtime PM when a card is inserted.
--- drivers/misc/cardreader/rtsx_usb.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/misc/cardreader/rtsx_usb.c +9 -7
@@ -698,6 +698,12 @@ static void rtsx_usb_disconnect(struct u }#ifdef CONFIG_PM +static int rtsx_usb_resume_child (struct device *dev,void *data) +{ +pm_request_resume (dev); +return 0 ; +} +static int rtsx_usb_suspend (struct usb_interface *intf,pm_message_t message) { struct rtsx_ucr *ucr =
@@ -713,8 +719,10 @@ static int rtsx_usb_suspend(struct usb_imutex_unlock (&ucr->dev_mutex);/* Defer the autosuspend if card exists */ -if (val & (SD_CD |MS_CD )) +if (val & (SD_CD |MS_CD )) { +device_for_each_child (&intf->dev,NULL , rtsx_usb_resume_child);return -EAGAIN ; + } }else {/* There is an ongoing operation*/ return -EAGAIN ;
@@ -724,12 +732,6 @@ static int rtsx_usb_suspend(struct usb_ireturn 0 ; } -static int rtsx_usb_resume_child (struct device *dev,void *data) -{ -pm_request_resume (dev); -return 0 ; -} -static int rtsx_usb_resume (struct usb_interface *intf) {device_for_each_child (&intf->dev,NULL , rtsx_usb_resume_child);
Greg Kroah-Hartman
maintainerPATCH 387/444 usb: typec: ucsi: Update power_supply on power role change
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myrrh Periwinkle <[email protected]>
commit 7616f006db07017ef5d4ae410fca99279aaca7aa upstream.
The current power direction of an USB-C port also influences the power_supply's online status, so a power role change should also update the power_supply.
Fixes an issue on some systems where plugging in a normal USB device in for the first time after a reboot will cause upower to erroneously consider the system to be connected to AC power.
--- drivers/usb/typec/ucsi/ucsi.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/typec/ucsi/ucsi.c +1 -0
@@ -1225,6 +1225,7 @@ static void ucsi_handle_connector_changeif (con->status.change &UCSI_CONSTAT_POWER_DIR_CHANGE ) {typec_set_pwr_role (con->port, role); +ucsi_port_psy_changed (con);/* Complete pending power role swap */ if (!completion_done (&con->complete))
Greg Kroah-Hartman
maintainerPATCH 388/444 comedi: fix race between polling and detaching
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott <[email protected]>
commit 35b6fc51c666fc96355be5cd633ed0fe4ccf68b2 upstream.
syzbot reports a use-after-free in comedi in the below link, which is due to comedi gladly removing the allocated async area even though poll requests are still active on the wait_queue_head inside of it. This can cause a use-after-free when the poll entries are later triggered or removed, as the memory for the wait_queue_head has been freed. We need to check there are no tasks queued on any of the subdevices' wait queues before allowing the device to be detached by the COMEDI_DEVCONFIG ioctl.
Tasks will read-lock dev->attach_lock before adding themselves to the subdevice wait queue, so fix the problem in the COMEDI_DEVCONFIG ioctl handler by write-locking dev->attach_lock before checking that all of the subdevices are safe to be deleted. This includes testing for any sleepers on the subdevices' wait queues. It remains locked until the device has been detached. This requires the comedi_device_detach() function to be refactored slightly, moving the bulk of it into new function comedi_device_detach_locked().
Note that the refactor of comedi_device_detach() results in comedi_device_cancel_all() now being called while dev->attach_lock is write-locked, which wasn't the case previously, but that does not matter.
Thanks to Jens Axboe for diagnosing the problem and co-developing this patch.
--- drivers/comedi/comedi_fops.c | 33 +++++++++++++++++++++++++-------- drivers/comedi/comedi_internal.h | 1 + drivers/comedi/drivers.c | 13 ++++++++++--- 3 files changed, 36 insertions(+), 11 deletions(-)
drivers/comedi/comedi_fops.c +25 -8
@@ -787,6 +787,7 @@ static int is_device_busy(struct comedi_struct comedi_subdevice *s;int i; +lockdep_assert_held_write (&dev->attach_lock);lockdep_assert_held (&dev->mutex);if (!dev->attached)return 0 ;
@@ -795,7 +796,16 @@ static int is_device_busy(struct comedi_ s = &dev->subdevices[i];if (s->busy)return 1 ; -if (s->async &&comedi_buf_is_mmapped (s)) +if (!s->async) +continue ; +if (comedi_buf_is_mmapped (s)) +return 1 ; +/* +* There may be tasks still waiting on the subdevice's wait +* queue, although they should already be about to be removed +* from it since the subdevice has no active async command. +*/ +if (wq_has_sleeper (&s->async->wait_head))return 1 ; }
@@ -825,15 +835,22 @@ static int do_devconfig_ioctl(struct comreturn -EPERM ;if (!arg) { -if (is_device_busy (dev)) -return -EBUSY ; -if (dev->attached) { -struct module *driver_module = dev->driver->module; +int rc =0 ; -comedi_device_detach (dev); -module_put (driver_module); +if (dev->attached) { +down_write (&dev->attach_lock); +if (is_device_busy (dev)) { + rc = -EBUSY ; + }else { +struct module *driver_module = + dev->driver->module; + +comedi_device_detach_locked (dev); +module_put (driver_module); + } +up_write (&dev->attach_lock); } -return 0 ; +return rc; }if (copy_from_user (&it, arg,sizeof (it)))
drivers/comedi/comedi_internal.h +1 -0
@@ -50,6 +50,7 @@ extern struct mutex comedi_drivers_list_int insn_inval (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); +void comedi_device_detach_locked (struct comedi_device *dev);void comedi_device_detach (struct comedi_device *dev);int comedi_device_attach (struct comedi_device *dev,struct comedi_devconfig *it);
drivers/comedi/drivers.c +10 -3
@@ -158,7 +158,7 @@ static void comedi_device_detach_cleanupint i;struct comedi_subdevice *s; -lockdep_assert_held (&dev->attach_lock); +lockdep_assert_held_write (&dev->attach_lock);lockdep_assert_held (&dev->mutex);if (dev->subdevices) {for (i =0 ; i < dev->n_subdevices; i++) {
@@ -196,16 +196,23 @@ static void comedi_device_detach_cleanupcomedi_clear_hw_dev (dev); } -void comedi_device_detach (struct comedi_device *dev) +void comedi_device_detach_locked (struct comedi_device *dev) { +lockdep_assert_held_write (&dev->attach_lock);lockdep_assert_held (&dev->mutex);comedi_device_cancel_all (dev); -down_write (&dev->attach_lock); dev->attached = false; dev->detach_count++;if (dev->driver) dev->driver->detach (dev);comedi_device_detach_cleanup (dev); +} + +void comedi_device_detach (struct comedi_device *dev) +{ +lockdep_assert_held (&dev->mutex); +down_write (&dev->attach_lock); +comedi_device_detach_locked (dev);up_write (&dev->attach_lock); }
Greg Kroah-Hartman
maintainerPATCH 389/444 thunderbolt: Fix copy+paste error in match_service_id()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit 5cc1f66cb23cccc704e3def27ad31ed479e934a5 upstream.
The second instance of TBSVC_MATCH_PROTOCOL_VERSION seems to have been intended to be TBSVC_MATCH_PROTOCOL_REVISION.
--- drivers/thunderbolt/domain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thunderbolt/domain.c +1 -1
@@ -36,7 +36,7 @@ static bool match_service_id(const strucreturn false; } -if (id->match_flags &TBSVC_MATCH_PROTOCOL_VERSION ) { +if (id->match_flags &TBSVC_MATCH_PROTOCOL_REVISION ) {if (id->protocol_revision != svc->prtcrevs)return false; }
Greg Kroah-Hartman
maintainerPATCH 390/444 cdc-acm: fix race between initial clearing halt and open
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit 64690a90cd7c6db16d3af8616be1f4bf8d492850 upstream.
On the devices that need their endpoints to get an initial clear_halt, this needs to be done before the devices can be opened. That means it needs to be before the devices are registered.
--- drivers/usb/class/cdc-acm.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/usb/class/cdc-acm.c +6 -5
@@ -1520,6 +1520,12 @@ skip_countries: goto err_remove_files; } +if (quirks &CLEAR_HALT_CONDITIONS ) { +/* errors intentionally ignored */ +usb_clear_halt (usb_dev, acm->in); +usb_clear_halt (usb_dev, acm->out); + } + tty_dev =tty_port_register_device (&acm->port, acm_tty_driver, minor, &control_interface->dev);if (IS_ERR (tty_dev)) {
@@ -1527,11 +1533,6 @@ skip_countries: goto err_release_data_interface; } -if (quirks &CLEAR_HALT_CONDITIONS ) { -usb_clear_halt (usb_dev, acm->in); -usb_clear_halt (usb_dev, acm->out); - } -dev_info (&intf->dev,"ttyACM%d: USB ACM device\n" , minor);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 391/444 btrfs: zoned: use filesystem size not disk size for reclaim decision
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Thumshirn <[email protected]>
commit 55f7c65b2f69c7e4cb7aa7c1654a228ccf734fd8 upstream.
When deciding if a zoned filesystem is reaching the threshold to reclaim data block groups, look at the size of the filesystem not to potentially total available size of all drives in the filesystem.
Especially if a filesystem was created with mkfs' -b option, constraining it to only a portion of the block device, the numbers won't match and potentially garbage collection is kicking in too late.
--- fs/btrfs/zoned.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/btrfs/zoned.c +1 -2
@@ -2456,8 +2456,8 @@ bool btrfs_zoned_should_reclaim(const st {struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;struct btrfs_device *device; +u64 total =btrfs_super_total_bytes (fs_info->super_copy);u64 used =0 ; -u64 total =0 ;u64 factor;ASSERT (btrfs_is_zoned (fs_info));
@@ -2470,7 +2470,6 @@ bool btrfs_zoned_should_reclaim(const stif (!device->bdev)continue ; - total += device->disk_total_bytes; used += device->bytes_used; }mutex_unlock (&fs_devices->device_list_mutex);
Greg Kroah-Hartman
maintainerPATCH 392/444 btrfs: abort transaction during log replay if walk_log_tree() failed
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 2a5898c4aac67494c2f0f7fe38373c95c371c930 upstream.
If we failed walking a log tree during replay, we have a missing transaction abort to prevent committing a transaction where we didn't fully replay all the changes from a log tree and therefore can leave the respective subvolume tree in some inconsistent state. So add the missing transaction abort.
--- fs/btrfs/tree-log.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/btrfs/tree-log.c +5 -2
@@ -7295,11 +7295,14 @@ again: wc.replay_dest->log_root = log; ret =btrfs_record_root_in_trans (trans, wc.replay_dest); -if (ret) +if (ret) {/* The loop needs to continue due to the root refs */ btrfs_abort_transaction (trans, ret); -else + }else { ret =walk_log_tree (trans, log, &wc); +if (ret) +btrfs_abort_transaction (trans, ret); + }if (!ret && wc.stage ==LOG_WALK_REPLAY_ALL ) { ret = fixup_inode_link_counts(trans, wc.replay_dest,
Greg Kroah-Hartman
maintainerPATCH 393/444 btrfs: zoned: do not remove unwritten non-data block group
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naohiro Aota <[email protected]>
commit 3061801420469610c8fa6080a950e56770773ef1 upstream.
There are some reports of "unable to find chunk map for logical 2147483648 length 16384" error message appears in dmesg. This means some IOs are occurring after a block group is removed.
When a metadata tree node is cleaned on a zoned setup, we keep that node still dirty and write it out not to create a write hole. However, this can make a block group's used bytes == 0 while there is a dirty region left.
Such an unused block group is moved into the unused_bg list and processed for removal. When the removal succeeds, the block group is removed from the transaction->dirty_bgs list, so the unused dirty nodes in the block group are not sent at the transaction commit time. It will be written at some later time e.g, sync or umount, and causes "unable to find chunk map" errors.
This can happen relatively easy on SMR whose zone size is 256MB. However, calling do_zone_finish() on such block group returns -EAGAIN and keep that block group intact, which is why the issue is hidden until now.
--- fs/btrfs/block-group.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-)
fs/btrfs/block-group.c +25 -2
@@ -34,6 +34,19 @@ int btrfs_should_fragment_free_space(con }#endif +static inline bool has_unwritten_metadata (struct btrfs_block_group *block_group) +{ +/* The meta_write_pointer is available only on the zoned setup. */ +if (!btrfs_is_zoned (block_group->fs_info)) +return false; + +if (block_group->flags &BTRFS_BLOCK_GROUP_DATA ) +return false; + +return block_group->start + block_group->alloc_offset > + block_group->meta_write_pointer; +} +/* * Return target flags in extended format or 0 if restripe for this chunk_type * is not in progress
@@ -1249,6 +1262,15 @@ int btrfs_remove_block_group(struct btrf goto out;spin_lock (&block_group->lock); +/* +* Hitting this WARN means we removed a block group with an unwritten +* region. It will cause "unable to find chunk map for logical" errors. +*/ +if (WARN_ON (has_unwritten_metadata (block_group))) +btrfs_warn (fs_info, +"block group %llu is removed before metadata write out" , + block_group->start); +set_bit (BLOCK_GROUP_FLAG_REMOVED , &block_group->runtime_flags);/*
@@ -1567,8 +1589,9 @@ void btrfs_delete_unused_bgs(struct btrf* needing to allocate extents from the block group. */ used =btrfs_space_info_used (space_info, true); -if (space_info->total_bytes - block_group->length < used && - block_group->zone_unusable < block_group->length) { +if ((space_info->total_bytes - block_group->length < used && + block_group->zone_unusable < block_group->length) || +has_unwritten_metadata (block_group)) {/* * Add a reference for the list, compensate for the ref * drop under the "next" label for the
Greg Kroah-Hartman
maintainerPATCH 394/444 btrfs: qgroup: set quota enabled bit if quota disable fails flushing reservations
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit e41c75ca3189341e76e6af64b857c05b68a1d7db upstream.
Before waiting for the rescan worker to finish and flushing reservations, we clear the BTRFS_FS_QUOTA_ENABLED flag from fs_info. If we fail flushing reservations we leave with the flag not set which is not correct since quotas are still enabled - we must set back the flag on error paths, such as when we fail to start a transaction, except for error paths that abort a transaction. The reservation flushing happens very early before we do any operation that actually disables quotas and before we start a transaction, so set back BTRFS_FS_QUOTA_ENABLED if it fails.
--- fs/btrfs/qgroup.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/btrfs/qgroup.c +5 -2
@@ -1373,11 +1373,14 @@ int btrfs_quota_disable(struct btrfs_fs_/* * We have nothing held here and no trans handle, just return the error -* if there is one. +* if there is one and set back the quota enabled bit since we didn't +* actually disable quotas. */ ret =flush_reservations (fs_info); -if (ret) +if (ret) { +set_bit (BTRFS_FS_QUOTA_ENABLED , &fs_info->flags);return ret; + }/* * 1 For the root item
Greg Kroah-Hartman
maintainerPATCH 395/444 btrfs: dont ignore inode missing when replaying log tree
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 7ebf381a69421a88265d3c49cd0f007ba7336c9d upstream.
During log replay, at add_inode_ref(), we return -ENOENT if our current inode isn't found on the subvolume tree or if a parent directory isn't found. The error comes from btrfs_iget_logging() <- btrfs_iget() <- btrfs_read_locked_inode().
The single caller of add_inode_ref(), replay_one_buffer(), ignores an -ENOENT error because it expects that error to mean only that a parent directory wasn't found and that is ok.
Before commit 5f61b961599a ("btrfs: fix inode lookup error handling during log replay") we were converting any error when getting a parent directory to -ENOENT and any error when getting the current inode to -EIO, so our caller would fail log replay in case we can't find the current inode. After that commit however in case the current inode is not found we return -ENOENT to the caller and therefore it ignores the critical fact that the current inode was not found in the subvolume tree.
Fix this by converting -ENOENT to 0 when we don't find a parent directory, returning -ENOENT when we don't find the current inode and making the caller, replay_one_buffer(), not ignore -ENOENT anymore.
--- fs/btrfs/tree-log.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
fs/btrfs/tree-log.c +12 -2
@@ -1396,6 +1396,8 @@ static noinline int add_inode_ref(struct dir =btrfs_iget_logging (parent_objectid, root);if (IS_ERR (dir)) { ret =PTR_ERR (dir); +if (ret == -ENOENT ) + ret =0 ; dir =NULL ; goto out; }
@@ -1420,6 +1422,15 @@ static noinline int add_inode_ref(structif (IS_ERR (dir)) { ret =PTR_ERR (dir); dir =NULL ; +/* +* A new parent dir may have not been +* logged and not exist in the subvolume +* tree, see the comment above before +* the loop when getting the first +* parent dir. +*/ +if (ret == -ENOENT ) + ret =0 ; goto out; } }
@@ -2532,9 +2543,8 @@ static int replay_one_buffer(struct btrf key.type == BTRFS_INODE_EXTREF_KEY) { ret =add_inode_ref (wc->trans, root, log, path, eb, i, &key); -if (ret && ret != -ENOENT ) +if (ret)break ; - ret =0 ; } else if (key.type == BTRFS_EXTENT_DATA_KEY) { ret =replay_one_extent (wc->trans, root, path, eb, i, &key);
Greg Kroah-Hartman
maintainerPATCH 396/444 btrfs: fix ssd_spread overallocation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <[email protected]>
commit 807d9023e75fc20bfd6dd2ac0408ce4af53f1648 upstream.
If the ssd_spread mount option is enabled, then we run the so called clustered allocator for data block groups. In practice, this results in creating a btrfs_free_cluster which caches a block_group and borrows its free extents for allocation.
Since the introduction of allocation size classes in 6.1, there has been a bug in the interaction between that feature and ssd_spread. find_free_extent() has a number of nested loops. The loop going over the allocation stages, stored in ffe_ctl->loop and managed by find_free_extent_update_loop(), the loop over the raid levels, and the loop over all the block_groups in a space_info. The size class feature relies on the block_group loop to ensure it gets a chance to see a block_group of a given size class. However, the clustered allocator uses the cached cluster block_group and breaks that loop. Each call to do_allocation() will really just go back to the same cached block_group. Normally, this is OK, as the allocation either succeeds and we don't want to loop any more or it fails, and we clear the cluster and return its space to the block_group.
But with size classes, the allocation can succeed, then later fail, outside of do_allocation() due to size class mismatch. That latter failure is not properly handled due to the highly complex multi loop logic. The result is a painful loop where we continue to allocate the same num_bytes from the cluster in a tight loop until it fails and releases the cluster and lets us try a new block_group. But by then, we have skipped great swaths of the available block_groups and are likely to fail to allocate, looping the outer loop. In pathological cases like the reproducer below, the cached block_group is often the very last one, in which case we don't perform this tight bg loop but instead rip through the ffe stages to LOOP_CHUNK_ALLOC and allocate a chunk, which is now the last one, and we enter the tight inner loop until an allocation failure. Then allocation succeeds on the final block_group and if the next allocation is a size mismatch, the exact same thing happens again.
Triggering this is as easy as mounting with -o ssd_spread and then running:
mount -o ssd_spread $dev $mnt
dd if=/dev/zero of=$mnt/big bs=16M count=1 &>/dev/null dd if=/dev/zero of=$mnt/med bs=4M count=1 &>/dev/null sync
if you do the two writes + sync in a loop, you can force btrfs to spin an excessive amount on semi-successful clustered allocations, before ultimately failing and advancing to the stage where we force a chunk allocation. This results in 2G of data allocated per iteration, despite only using ~20M of data. By using a small size classed extent, the inner loop takes longer and we can spin for longer.
The simplest, shortest term fix to unbreak this is to make the clustered allocator size_class aware in the dumbest way, where it fails on size class mismatch. This may hinder the operation of the clustered allocator, but better hindered than completely broken and terribly overallocating.
Further re-design improvements are also in the works.
--- fs/btrfs/extent-tree.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-)
fs/btrfs/extent-tree.c +17 -16
@@ -3654,6 +3654,21 @@ btrfs_release_block_group(struct btrfs_bbtrfs_put_block_group (cache); } +static bool find_free_extent_check_size_class (const struct find_free_extent_ctl *ffe_ctl, +const struct btrfs_block_group *bg) +{ +if (ffe_ctl->policy ==BTRFS_EXTENT_ALLOC_ZONED ) +return true; +if (!btrfs_block_group_should_use_size_class (bg)) +return true; +if (ffe_ctl->loop >=LOOP_WRONG_SIZE_CLASS ) +return true; +if (ffe_ctl->loop >=LOOP_UNSET_SIZE_CLASS && + bg->size_class ==BTRFS_BG_SZ_NONE ) +return true; +return ffe_ctl->size_class == bg->size_class; +} +/* * Helper function for find_free_extent(). *
@@ -3675,7 +3690,8 @@ static int find_free_extent_clustered(stif (!cluster_bg) goto refill_cluster;if (cluster_bg != bg && (cluster_bg->ro || - !block_group_bits (cluster_bg, ffe_ctl->flags))) + !block_group_bits (cluster_bg, ffe_ctl->flags) || + !find_free_extent_check_size_class (ffe_ctl, cluster_bg))) goto release_cluster; offset = btrfs_alloc_from_cluster(cluster_bg, last_ptr,
@@ -4231,21 +4247,6 @@ static int find_free_extent_update_loop(return -ENOSPC ; } -static bool find_free_extent_check_size_class (struct find_free_extent_ctl *ffe_ctl, -struct btrfs_block_group *bg) -{ -if (ffe_ctl->policy ==BTRFS_EXTENT_ALLOC_ZONED ) -return true; -if (!btrfs_block_group_should_use_size_class (bg)) -return true; -if (ffe_ctl->loop >=LOOP_WRONG_SIZE_CLASS ) -return true; -if (ffe_ctl->loop >=LOOP_UNSET_SIZE_CLASS && - bg->size_class ==BTRFS_BG_SZ_NONE ) -return true; -return ffe_ctl->size_class == bg->size_class; -} - static int prepare_allocation_clustered(struct btrfs_fs_info *fs_info, struct find_free_extent_ctl *ffe_ctl, struct btrfs_space_info *space_info,
Greg Kroah-Hartman
maintainerPATCH 397/444 btrfs: populate otime when logging an inode item
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit 1ef94169db0958d6de39f9ea6e063ce887342e2d upstream.
[TEST FAILURE WITH EXPERIMENTAL FEATURES]
When running test case generic/508, the test case will fail with the new btrfs shutdown support:
generic/508 - output mismatch (see /home/adam/xfstests/results//generic/508.out.bad)
# --- tests/generic/508.out 2022-05-11 11:25:30.806666664 +0930 # +++ /home/adam/xfstests/results//generic/508.out.bad 2025-07-02 14:53:22.401824212 +0930 # @@ -1,2 +1,6 @@ # QA output created by 508 # Silence is golden # +Before: # +After : stat.btime = Thu Jan 1 09:30:00 1970 # +Before: # +After : stat.btime = Wed Jul 2 14:53:22 2025 # ... # (Run 'diff -u /home/adam/xfstests/tests/generic/508.out /home/adam/xfstests/results//generic/508.out.bad' to see the entire diff)
Ran: generic/508
Failures: generic/508
Failed 1 of 1 tests
Please note that the test case requires shutdown support, thus the test case will be skipped using the current upstream kernel, as it doesn't have shutdown ioctl support.
[CAUSE]
The direct cause the 0 time stamp in the log tree:
leaf 30507008 items 2 free space 16057 generation 9 owner TREE_LOG leaf 30507008 flags 0x1(WRITTEN) backref revision 1 checksum stored e522548d
checksum calced e522548d
fs uuid 57d45451-481e-43e4-aa93-289ad707a3a0
chunk uuid d52bd3fd-5163-4337-98a7-7986993ad398
item 0 key (257 INODE_ITEM 0) itemoff 16123 itemsize 160 generation 9 transid 9 size 0 nbytes 0 block group 0 mode 100644 links 1 uid 0 gid 0 rdev 0 sequence 1 flags 0x0(none) atime 1751432947.492000000 (2025-07-02 14:39:07) ctime 1751432947.492000000 (2025-07-02 14:39:07) mtime 1751432947.492000000 (2025-07-02 14:39:07) otime 0.0 (1970-01-01 09:30:00) <<<
But the old fs tree has all the correct time stamp:
btrfs-progs v6.12
fs tree key (FS_TREE ROOT_ITEM 0)
leaf 30425088 items 2 free space 16061 generation 5 owner FS_TREE leaf 30425088 flags 0x1(WRITTEN) backref revision 1 checksum stored 48f6c57e
checksum calced 48f6c57e
fs uuid 57d45451-481e-43e4-aa93-289ad707a3a0
chunk uuid d52bd3fd-5163-4337-98a7-7986993ad398
item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160 generation 3 transid 0 size 0 nbytes 16384 block group 0 mode 40755 links 1 uid 0 gid 0 rdev 0 sequence 0 flags 0x0(none) atime 1751432947.0 (2025-07-02 14:39:07) ctime 1751432947.0 (2025-07-02 14:39:07) mtime 1751432947.0 (2025-07-02 14:39:07) otime 1751432947.0 (2025-07-02 14:39:07) <<<
The root cause is that fill_inode_item() in tree-log.c is only populating a/c/m time, not the otime (or btime in statx output).
Part of the reason is that, the vfs inode only has a/c/m time, no native btime support yet.
[FIX]
Thankfully btrfs has its otime stored in btrfs_inode::i_otime_sec and btrfs_inode::i_otime_nsec.
So what we really need is just fill the otime time stamp in fill_inode_item() of tree-log.c
There is another fill_inode_item() in inode.c, which is doing the proper otime population.
--- fs/btrfs/tree-log.c | 3 +++ 1 file changed, 3 insertions(+)
fs/btrfs/tree-log.c +3 -0
@@ -4235,6 +4235,9 @@ static void fill_inode_item(struct btrfsbtrfs_set_token_timespec_nsec (&token, &item->ctime,inode_get_ctime_nsec (inode)); +btrfs_set_timespec_sec (leaf, &item->otime,BTRFS_I (inode)->i_otime_sec); +btrfs_set_timespec_nsec (leaf, &item->otime,BTRFS_I (inode)->i_otime_nsec); +/* * We do not need to set the nbytes field, in fact during a fast fsync * its value may not even be correct, since a fast fsync does not wait
Greg Kroah-Hartman
maintainerPATCH 398/444 btrfs: qgroup: fix qgroup create ioctl returning success after quotas disabled
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 08530d6e638427e7e1344bd67bacc03882ba95b9 upstream.
When quotas are disabled qgroup ioctls are supposed to return -ENOTCONN, but the qgroup create ioctl stopped doing that when it races with a quota disable operation, returning 0 instead. This change of behaviour happened in commit 6ed05643ddb1 ("btrfs: create qgroup earlier in snapshot creation").
The issue happens as follows:
1) Task A enters btrfs_ioctl_qgroup_create(), qgroups are enabled and so qgroup_enabled() returns true since fs_info->quota_root is not NULL;
2) Task B enters btrfs_ioctl_quota_ctl() -> btrfs_quota_disable() and disables qgroups, so now fs_info->quota_root is NULL;
3) Task A enters btrfs_create_qgroup() and calls btrfs_qgroup_mode(), which returns BTRFS_QGROUP_MODE_DISABLED since quotas are disabled, and then btrfs_create_qgroup() returns 0 to the caller, which makes the ioctl return 0 instead of -ENOTCONN.
The check for fs_info->quota_root and returning -ENOTCONN if it's NULL is made only after the call btrfs_qgroup_mode().
Fix this by moving the check for disabled quotas with btrfs_qgroup_mode() into transaction.c:create_pending_snapshot(), so that we don't abort the transaction if btrfs_create_qgroup() returns -ENOTCONN and quotas are disabled.
--- fs/btrfs/qgroup.c | 3 --- fs/btrfs/transaction.c | 6 ++++-- 2 files changed, 4 insertions(+), 5 deletions(-)
fs/btrfs/qgroup.c +0 -3
@@ -1701,9 +1701,6 @@ int btrfs_create_qgroup(struct btrfs_trastruct btrfs_qgroup *prealloc =NULL ;int ret =0 ; -if (btrfs_qgroup_mode (fs_info) ==BTRFS_QGROUP_MODE_DISABLED ) -return 0 ; -mutex_lock (&fs_info->qgroup_ioctl_lock);if (!fs_info->quota_root) { ret = -ENOTCONN ;
fs/btrfs/transaction.c +4 -2
@@ -1739,8 +1739,10 @@ static noinline int create_pending_snaps ret =btrfs_create_qgroup (trans, objectid);if (ret && ret != -EEXIST ) { -btrfs_abort_transaction (trans, ret); - goto fail; +if (ret != -ENOTCONN ||btrfs_qgroup_enabled (fs_info)) { +btrfs_abort_transaction (trans, ret); + goto fail; + } }/*
Greg Kroah-Hartman
maintainerPATCH 399/444 btrfs: dont skip remaining extrefs if dir not found during log replay
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 24e066ded45b8147b79c7455ac43a5bff7b5f378 upstream.
During log replay, at add_inode_ref(), if we have an extref item that contains multiple extrefs and one of them points to a directory that does not exist in the subvolume tree, we are supposed to ignore it and process the remaining extrefs encoded in the extref item, since each extref can point to a different parent inode. However when that happens we just return from the function and ignore the remaining extrefs.
The problem has been around since extrefs were introduced, in commit f186373fef00 ("btrfs: extended inode refs"), but it's hard to hit in practice because getting extref items encoding multiple extref requires getting a hash collision when computing the offset of the extref's key. The offset if computed like this:
key.offset = btrfs_extref_hash(dir_ino, name->name, name->len);
and btrfs_extref_hash() is just a wrapper around crc32c().
Fix this by moving to next iteration of the loop when we don't find the parent directory that an extref points to.
--- fs/btrfs/tree-log.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
fs/btrfs/tree-log.c +14 -4
@@ -1413,6 +1413,8 @@ static noinline int add_inode_ref(structif (log_ref_ver) { ret =extref_get_fields (eb, ref_ptr, &name, &ref_index, &parent_objectid); +if (ret) + goto out;/* * parent object can change from one array * item to another.
@@ -1429,16 +1431,23 @@ static noinline int add_inode_ref(struct* the loop when getting the first * parent dir. */ -if (ret == -ENOENT ) +if (ret == -ENOENT ) { +/* +* The next extref may refer to +* another parent dir that +* exists, so continue. +*/ ret =0 ; + goto next; + } goto out; } } }else { ret =ref_get_fields (eb, ref_ptr, &name, &ref_index); +if (ret) + goto out; } -if (ret) - goto out; ret =inode_in_dir (root, path,btrfs_ino (dir),btrfs_ino (inode), ref_index, &name);
@@ -1472,10 +1481,11 @@ static noinline int add_inode_ref(struct }/* Else, ret == 1, we already have a perfect match, we're done. */ +next: ref_ptr = (unsigned long )(ref_ptr + ref_struct_size) + name.len;kfree (name.name); name.name =NULL ; -if (log_ref_ver) { +if (log_ref_ver && dir) {iput (&dir->vfs_inode); dir =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 400/444 btrfs: clear dirty status from extent buffer on error at insert_new_root()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit c0d013495a80cbb53e2288af7ae0ec4170aafd7c upstream.
If we failed to insert the tree mod log operation, we are not removing the dirty status from the allocated and dirtied extent buffer before we free it. Removing the dirty status is needed for several reasons such as to adjust the fs_info->dirty_metadata_bytes counter and remove the dirty status from the respective folios. So add the missing call to btrfs_clear_buffer_dirty().
--- fs/btrfs/ctree.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/ctree.c +1 -0
@@ -2901,6 +2901,7 @@ static noinline int insert_new_root(struif (ret <0 ) {int ret2; +btrfs_clear_buffer_dirty (trans, c); ret2 =btrfs_free_tree_block (trans,btrfs_root_id (root), c,0 ,1 );if (ret2 <0 )btrfs_abort_transaction (trans, ret2);
Greg Kroah-Hartman
maintainerPATCH 401/444 btrfs: fix log tree replay failure due to file with 0 links and extents
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 0a32e4f0025a74c70dcab4478e9b29c22f5ecf2f upstream.
If we log a new inode (not persisted in a past transaction) that has 0 links and extents, then log another inode with an higher inode number, we end up with failing to replay the log tree with -EINVAL. The steps for this are:
1) create new file A
2) write some data to file A
3) open an fd on file A
4) unlink file A
5) fsync file A using the previously open fd
6) create file B (has higher inode number than file A)
7) fsync file B
8) power fail before current transaction commits
Now when attempting to mount the fs, the log replay will fail with -ENOENT at replay_one_extent() when attempting to replay the first extent of file A. The failure comes when trying to open the inode for file A in the subvolume tree, since it doesn't exist.
Before commit 5f61b961599a ("btrfs: fix inode lookup error handling during log replay"), the returned error was -EIO instead of -ENOENT, since we converted any errors when attempting to read an inode during log replay to -EIO.
The reason for this is that the log replay procedure fails to ignore the current inode when we are at the stage LOG_WALK_REPLAY_ALL, our current inode has 0 links and last inode we processed in the previous stage has a non 0 link count. In other words, the issue is that at replay_one_extent() we only update wc->ignore_cur_inode if the current replay stage is LOG_WALK_REPLAY_INODES.
Fix this by updating wc->ignore_cur_inode whenever we find an inode item regardless of the current replay stage. This is a simple solution and easy to backport, but later we can do other alternatives like avoid logging extents or inode items other than the inode item for inodes with a link count of 0.
The problem with the wc->ignore_cur_inode logic has been around since commit f2d72f42d5fa ("Btrfs: fix warning when replaying log after fsync of a tmpfile") but it only became frequent to hit since the more recent commit 5e85262e542d ("btrfs: fix fsync of files with no hard links not persisting deletion"), because we stopped skipping inodes with a link count of 0 when logging, while before the problem would only be triggered if trying to replay a log tree created with an older kernel which has a logged inode with 0 links.
A test case for fstests will be submitted soon.
--- fs/btrfs/tree-log.c | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-)
fs/btrfs/tree-log.c +30 -18
@@ -324,8 +324,7 @@ struct walk_control {/* * Ignore any items from the inode currently being processed. Needs -* to be set every time we find a BTRFS_INODE_ITEM_KEY and we are in -* the LOG_WALK_REPLAY_INODES stage. +* to be set every time we find a BTRFS_INODE_ITEM_KEY. */ bool ignore_cur_inode;
@@ -2447,23 +2446,30 @@ static int replay_one_buffer(struct btrf nritems =btrfs_header_nritems (eb);for (i =0 ; i < nritems; i++) { -btrfs_item_key_to_cpu (eb, &key, i); +struct btrfs_inode_item *inode_item; -/* inode keys are done during the first stage */ -if (key.type ==BTRFS_INODE_ITEM_KEY && - wc->stage ==LOG_WALK_REPLAY_INODES ) { -struct btrfs_inode_item *inode_item; -u32 mode; +btrfs_item_key_to_cpu (eb, &key, i); - inode_item =btrfs_item_ptr (eb, i, - struct btrfs_inode_item); +if (key.type ==BTRFS_INODE_ITEM_KEY ) { + inode_item = btrfs_item_ptr(eb, i, struct btrfs_inode_item);/* -* If we have a tmpfile (O_TMPFILE) that got fsync'ed -* and never got linked before the fsync, skip it, as -* replaying it is pointless since it would be deleted -* later. We skip logging tmpfiles, but it's always -* possible we are replaying a log created with a kernel -* that used to log tmpfiles. +* An inode with no links is either: +* +* 1) A tmpfile (O_TMPFILE) that got fsync'ed and never +* got linked before the fsync, skip it, as replaying +* it is pointless since it would be deleted later. +* We skip logging tmpfiles, but it's always possible +* we are replaying a log created with a kernel that +* used to log tmpfiles; +* +* 2) A non-tmpfile which got its last link deleted +* while holding an open fd on it and later got +* fsynced through that fd. We always log the +* parent inodes when inode->last_unlink_trans is +* set to the current transaction, so ignore all the +* inode items for this inode. We will delete the +* inode when processing the parent directory with +* replay_dir_deletes(). */ if (btrfs_inode_nlink (eb, inode_item) ==0 ) { wc->ignore_cur_inode = true;
@@ -2471,8 +2477,14 @@ static int replay_one_buffer(struct btrf }else { wc->ignore_cur_inode = false; } - ret =replay_xattr_deletes (wc->trans, root, log, - path, key.objectid); + } + +/* Inode keys are done during the first stage. */ +if (key.type ==BTRFS_INODE_ITEM_KEY && + wc->stage ==LOG_WALK_REPLAY_INODES ) { +u32 mode; + + ret =replay_xattr_deletes (wc->trans, root, log, path, key.objectid);if (ret)break ; mode =btrfs_inode_mode (eb, inode_item);
Greg Kroah-Hartman
maintainerPATCH 402/444 btrfs: error on missing block group when unaccounting log tree extent buffers
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit fc5799986fbca957e2e3c0480027f249951b7bcf upstream.
Currently we only log an error message if we can't find the block group for a log tree extent buffer when unaccounting it (while freeing a log tree). A missing block group means something is seriously wrong and we end up leaking space from the metadata space info. So return -ENOENT in case we don't find the block group.
--- fs/btrfs/tree-log.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
fs/btrfs/tree-log.c +7 -12
@@ -2587,14 +2587,14 @@ static int replay_one_buffer(struct btrf/* * Correctly adjust the reserved bytes occupied by a log tree extent buffer */ -static void unaccount_log_buffer (struct btrfs_fs_info *fs_info,u64 start) +static int unaccount_log_buffer (struct btrfs_fs_info *fs_info,u64 start) {struct btrfs_block_group *cache; cache =btrfs_lookup_block_group (fs_info, start);if (!cache) {btrfs_err (fs_info,"unable to find block group for %llu" , start); -return ; +return -ENOENT ; }spin_lock (&cache->space_info->lock);
@@ -2605,27 +2605,22 @@ static void unaccount_log_buffer(structspin_unlock (&cache->space_info->lock);btrfs_put_block_group (cache); + +return 0 ; }static int clean_log_buffer (struct btrfs_trans_handle *trans,struct extent_buffer *eb) { -int ret; -btrfs_tree_lock (eb);btrfs_clear_buffer_dirty (trans, eb);wait_on_extent_buffer_writeback (eb);btrfs_tree_unlock (eb); -if (trans) { - ret =btrfs_pin_reserved_extent (trans, eb); -if (ret) -return ret; - }else { -unaccount_log_buffer (eb->fs_info, eb->start); - } +if (trans) +return btrfs_pin_reserved_extent (trans, eb); -return 0 ; +return unaccount_log_buffer (eb->fs_info, eb->start); } static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
Greg Kroah-Hartman
maintainerPATCH 403/444 btrfs: zoned: do not select metadata BG as finish target
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naohiro Aota <[email protected]>
commit 3a931e9b39c7ff8066657042f5f00d3b7e6ad315 upstream.
We call btrfs_zone_finish_one_bg() to zone finish one block group and make room to activate another block group. Currently, we can choose a metadata block group as a target. But, as we reserve an active metadata block group, we no longer want to select a metadata block group. So, skip it in the loop.
--- fs/btrfs/zoned.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/zoned.c +1 -1
@@ -2523,7 +2523,7 @@ int btrfs_zone_finish_one_bg(struct btrfspin_lock (&block_group->lock);if (block_group->reserved || block_group->alloc_offset ==0 || - (block_group->flags &BTRFS_BLOCK_GROUP_SYSTEM ) || + !(block_group->flags &BTRFS_BLOCK_GROUP_DATA ) ||test_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , &block_group->runtime_flags)) {spin_unlock (&block_group->lock);continue ;
Greg Kroah-Hartman
maintainerPATCH 404/444 btrfs: fix iteration bug in __qgroup_excl_accounting()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <[email protected]>
commit 7b632596188e1973c6b3ac1c9f8252f735e1039f upstream.
__qgroup_excl_accounting() uses the qgroup iterator machinery to update the account of one qgroups usage for all its parent hierarchy, when we either add or remove a relation and have only exclusive usage.
However, there is a small bug there: we loop with an extra iteration temporary qgroup called cur but never actually refer to that in the body of the loop. As a result, we redundantly account the same usage to the first qgroup in the list.
This can be reproduced in the following way:
mkfs.btrfs -f -O squota <dev>
mount <dev> <mnt>
btrfs subvol create <mnt>/sv
dd if=/dev/zero of=<mnt>/sv/f bs=1M count=1
sync
btrfs qgroup create 1/100 <mnt>
btrfs qgroup create 2/200 <mnt>
btrfs qgroup assign 1/100 2/200 <mnt>
btrfs qgroup assign 0/256 1/100 <mnt>
btrfs qgroup show <mnt>
and the broken result is (note the 2MiB on 1/100 and 0Mib on 2/100):
Qgroupid Referenced Exclusive Path -------- ---------- --------- ---- 0/5 16.00KiB 16.00KiB <toplevel> 0/256 1.02MiB 1.02MiB sv
Qgroupid Referenced Exclusive Path -------- ---------- --------- ---- 0/5 16.00KiB 16.00KiB <toplevel> 0/256 1.02MiB 1.02MiB sv 1/100 2.03MiB 2.03MiB 2/100<1 member qgroup> 2/100 0.00B 0.00B <0 member qgroups>
With this fix, which simply re-uses qgroup as the iteration variable, we see the expected result:
Qgroupid Referenced Exclusive Path -------- ---------- --------- ---- 0/5 16.00KiB 16.00KiB <toplevel> 0/256 1.02MiB 1.02MiB sv
Qgroupid Referenced Exclusive Path -------- ---------- --------- ---- 0/5 16.00KiB 16.00KiB <toplevel> 0/256 1.02MiB 1.02MiB sv 1/100 1.02MiB 1.02MiB 2/100<1 member qgroup> 2/100 1.02MiB 1.02MiB <0 member qgroups>
The existing fstests did not exercise two layer inheritance so this bug was missed. I intend to add that testing there, as well.
--- fs/btrfs/qgroup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/btrfs/qgroup.c +1 -2
@@ -1492,7 +1492,6 @@ static int __qgroup_excl_accounting(stru struct btrfs_qgroup *src, int sign) {struct btrfs_qgroup *qgroup; -struct btrfs_qgroup *cur;LIST_HEAD (qgroup_list);u64 num_bytes = src->excl;int ret =0 ;
@@ -1502,7 +1501,7 @@ static int __qgroup_excl_accounting(stru goto out;qgroup_iterator_add (&qgroup_list, qgroup); -list_for_each_entry (cur, &qgroup_list, iterator) { +list_for_each_entry (qgroup, &qgroup_list, iterator) {struct btrfs_qgroup_list *glist; qgroup->rfer += sign * num_bytes;
Greg Kroah-Hartman
maintainerPATCH 405/444 btrfs: do not allow relocation of partially dropped subvolumes
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit 4289b494ac553e74e86fed1c66b2bf9530bc1082 upstream.
[BUG]
There is an internal report that balance triggered transaction abort, with the following call trace:
item 85 key (594509824 169 0) itemoff 12599 itemsize 33
extent refs 1 gen 197740 flags 2
ref#0: tree block backref root 7
item 86 key (594558976 169 0) itemoff 12566 itemsize 33
extent refs 1 gen 197522 flags 2
ref#0: tree block backref root 7
...
BTRFS error (device loop0): extent item not found for insert, bytenr 594526208 num_bytes 16384 parent 449921024 root_objectid 934 owner 1 offset 0 BTRFS error (device loop0): failed to run delayed ref for logical 594526208 num_bytes 16384 type 182 action 1 ref_mod 1: -117
------------[ cut here ]------------ BTRFS: Transaction aborted (error -117) WARNING: CPU: 1 PID: 6963 at ../fs/btrfs/extent-tree.c:2168 btrfs_run_delayed_refs+0xfa/0x110 [btrfs]
And btrfs check doesn't report anything wrong related to the extent tree.
[CAUSE]
The cause is a little complex, firstly the extent tree indeed doesn't have the backref for 594526208.
The extent tree only have the following two backrefs around that bytenr on-disk:
item 65 key (594509824 METADATA_ITEM 0) itemoff 13880 itemsize 33
refs 1 gen 197740 flags TREE_BLOCK
tree block skinny level 0
(176 0x7) tree block backref root CSUM_TREE
item 66 key (594558976 METADATA_ITEM 0) itemoff 13847 itemsize 33
refs 1 gen 197522 flags TREE_BLOCK
tree block skinny level 0
(176 0x7) tree block backref root CSUM_TREE
But the such missing backref item is not an corruption on disk, as the offending delayed ref belongs to subvolume 934, and that subvolume is being dropped:
item 0 key (934 ROOT_ITEM 198229) itemoff 15844 itemsize 439
generation 198229 root_dirid 256 bytenr 10741039104 byte_limit 0 bytes_used 345571328
last_snapshot 198229 flags 0x1000000000001(RDONLY) refs 0
drop_progress key (206324 EXTENT_DATA 2711650304) drop_level 2
level 2 generation_v2 198229And that offending tree block 594526208 is inside the dropped range of that subvolume. That explains why there is no backref item for that bytenr and why btrfs check is not reporting anything wrong.
But this also shows another problem, as btrfs will do all the orphan subvolume cleanup at a read-write mount.
So half-dropped subvolume should not exist after an RW mount, and balance itself is also exclusive to subvolume cleanup, meaning we shouldn't hit a subvolume half-dropped during relocation.
The root cause is, there is no orphan item for this subvolume. In fact there are 5 subvolumes from around 2021 that have the same problem.
It looks like the original report has some older kernels running, and caused those zombie subvolumes.
Thankfully upstream commit 8d488a8c7ba2 ("btrfs: fix subvolume/snapshot deletion not triggered on mount") has long fixed the bug.
[ENHANCEMENT]
For repairing such old fs, btrfs-progs will be enhanced.
Considering how delayed the problem will show up (at run delayed ref time) and at that time we have to abort transaction already, it is too late.
Instead here we reject any half-dropped subvolume for reloc tree at the earliest time, preventing confusion and extra time wasted on debugging similar bugs.
--- fs/btrfs/relocation.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
fs/btrfs/relocation.c +19 -0
@@ -687,6 +687,25 @@ static struct btrfs_root *create_reloc_rif (btrfs_root_id (root) == objectid) {u64 commit_root_gen; +/* +* Relocation will wait for cleaner thread, and any half-dropped +* subvolume will be fully cleaned up at mount time. +* So here we shouldn't hit a subvolume with non-zero drop_progress. +* +* If this isn't the case, error out since it can make us attempt to +* drop references for extents that were already dropped before. +*/ +if (unlikely (btrfs_disk_key_objectid (&root->root_item.drop_progress))) { +struct btrfs_key cpu_key; + +btrfs_disk_key_to_cpu (&cpu_key, &root->root_item.drop_progress); +btrfs_err (fs_info, +"cannot relocate partially dropped subvolume %llu, drop progress key (%llu %u %llu)" , + objectid, cpu_key.objectid, cpu_key.type, cpu_key.offset); + ret = -EUCLEAN ; + goto fail; + } +/* called by btrfs_init_reloc_root */ ret =btrfs_copy_root (trans, root, root->commit_root, &eb,BTRFS_TREE_RELOC_OBJECTID );
Greg Kroah-Hartman
maintainerPATCH 406/444 xfs: fix scrub trace with null pointer in quotacheck
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrey Albershteyn <[email protected]>
commit 5d94b19f066480addfcdcb5efde66152ad5a7c0e upstream.
The quotacheck doesn't initialize sc->ip.
--- fs/xfs/scrub/trace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/scrub/trace.h +1 -1
@@ -467,7 +467,7 @@ DECLARE_EVENT_CLASS(xchk_dqiter_class,__field (xfs_exntst_t, state) ),TP_fast_assign ( - __entry->dev = cursor->sc->ip->i_mount->m_super->s_dev; + __entry->dev = cursor->sc->mp->m_super->s_dev; __entry->dqtype = cursor->dqtype; __entry->ino = cursor->quota_ip->i_ino; __entry->cur_id = cursor->id;
Greg Kroah-Hartman
maintainerPATCH 407/444 userfaultfd: fix a crash in UFFDIO_MOVE when PMD is a migration entry
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suren Baghdasaryan <[email protected]>
commit aba6faec0103ed8f169be8dce2ead41fcb689446 upstream.
When UFFDIO_MOVE encounters a migration PMD entry, it proceeds with obtaining a folio and accessing it even though the entry is swp_entry_t. Add the missing check and let split_huge_pmd() handle migration entries. While at it also remove unnecessary folio check.
--- mm/userfaultfd.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
mm/userfaultfd.c +9 -6
@@ -1800,13 +1800,16 @@ ssize_t move_pages(struct userfaultfd_ct/* Check if we can move the pmd without splitting it. */ if (move_splits_huge_pmd (dst_addr, src_addr, src_start + len) || !pmd_none (dst_pmdval)) { -struct folio *folio =pmd_folio (*src_pmd); +/* Can be a migration entry */ +if (pmd_present (*src_pmd)) { +struct folio *folio =pmd_folio (*src_pmd); -if (!folio || (!is_huge_zero_folio (folio) && - !PageAnonExclusive (&folio->page))) { -spin_unlock (ptl); - err = -EBUSY ; -break ; +if (!is_huge_zero_folio (folio) && + !PageAnonExclusive (&folio->page)) { +spin_unlock (ptl); + err = -EBUSY ; +break ; + } }spin_unlock (ptl);
Greg Kroah-Hartman
maintainerPATCH 408/444 fbdev: Fix vmalloc out-of-bounds write in fast_imageblit
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sravan Kumar Gundu <[email protected]>
commit af0db3c1f898144846d4c172531a199bb3ca375d upstream.
This issue triggers when a userspace program does an ioctl FBIOPUT_CON2FBMAP by passing console number and frame buffer number. Ideally this maps console to frame buffer and updates the screen if console is visible.
As part of mapping it has to do resize of console according to frame buffer info. if this resize fails and returns from vc_do_resize() and continues further. At this point console and new frame buffer are mapped and sets display vars. Despite failure still it continue to proceed updating the screen at later stages where vc_data is related to previous frame buffer and frame buffer info and display vars are mapped to new frame buffer and eventully leading to out-of-bounds write in fast_imageblit(). This bheviour is excepted only when fg_console is equal to requested console which is a visible console and updates screen with invalid struct references in fbcon_putcs().
--- drivers/video/fbdev/core/fbcon.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/video/fbdev/core/fbcon.c +5 -4
@@ -826,7 +826,8 @@ static void con2fb_init_display(struct v fg_vc->vc_rows); } -update_screen (vc_cons[fg_console].d); +if (fg_console != unit) +update_screen (vc_cons[fg_console].d); }/**
@@ -1363,6 +1364,7 @@ static void fbcon_set_disp(struct fb_infstruct vc_data *svc;struct fbcon_ops *ops = info->fbcon_par;int rows, cols; +unsigned long ret =0 ; p = &fb_display[unit];
@@ -1413,11 +1415,10 @@ static void fbcon_set_disp(struct fb_inf rows =FBCON_SWAP (ops->rotate, info->var.yres, info->var.xres); cols /= vc->vc_font.width; rows /= vc->vc_font.height; -vc_resize (vc, cols, rows); + ret =vc_resize (vc, cols, rows); -if (con_is_visible (vc)) { +if (con_is_visible (vc) && !ret)update_screen (vc); - } }static __inline__void ywrap_up (struct vc_data *vc,int count)
Greg Kroah-Hartman
maintainerPATCH 409/444 net/sched: ets: use old nbands while purging unused classes
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davide Caratti <[email protected]>
commit 87c6efc5ce9c126ae4a781bc04504b83780e3650 upstream.
Shuang reported sch_ets test-case [1] crashing in ets_class_qlen_notify() after recent changes from Lion [2]. The problem is: in ets_qdisc_change() we purge unused DWRR queues; the value of 'q->nbands' is the new one, and the cleanup should be done with the old one. The problem is here since my first attempts to fix ets_qdisc_change(), but it surfaced again after the recent qdisc len accounting fixes. Fix it purging idle DWRR queues before assigning a new value of 'q->nbands', so that all purge operations find a consistent configuration:
- old 'q->nbands' because it's needed by ets_class_find()
- old 'q->nstrict' because it's needed by ets_class_is_strict()
BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 62 UID: 0 PID: 39457 Comm: tc Kdump: loaded Not tainted 6.12.0-116.el10.x86_64 #1 PREEMPT(voluntary) Hardware name: Dell Inc. PowerEdge R640/06DKY5, BIOS 2.12.2 07/09/2021 RIP: 0010:__list_del_entry_valid_or_report+0x4/0x80 Code: ff 4c 39 c7 0f 84 39 19 8e ff b8 01 00 00 00 c3 cc cc cc cc 66 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa <48> 8b 17 48 8b 4f 08 48 85 d2 0f 84 56 19 8e ff 48 85 c9 0f 84 ab RSP: 0018:ffffba186009f400 EFLAGS: 00010202 RAX: 00000000000000d6 RBX: 0000000000000000 RCX: 0000000000000004 RDX: ffff9f0fa29b69c0 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffffffffc12c2400 R08: 0000000000000008 R09: 0000000000000004 R10: ffffffffffffffff R11: 0000000000000004 R12: 0000000000000000 R13: ffff9f0f8cfe0000 R14: 0000000000100005 R15: 0000000000000000 FS: 00007f2154f37480(0000) GS:ffff9f269c1c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000001530be001 CR4: 00000000007726f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <TASK> ets_class_qlen_notify+0x65/0x90 [sch_ets] qdisc_tree_reduce_backlog+0x74/0x110 ets_qdisc_change+0x630/0xa40 [sch_ets] __tc_modify_qdisc.constprop.0+0x216/0x7f0 tc_modify_qdisc+0x7c/0x120 rtnetlink_rcv_msg+0x145/0x3f0 netlink_rcv_skb+0x53/0x100 netlink_unicast+0x245/0x390 netlink_sendmsg+0x21b/0x470 ____sys_sendmsg+0x39d/0x3d0 ___sys_sendmsg+0x9a/0xe0 __sys_sendmsg+0x7a/0xd0 do_syscall_64+0x7d/0x160 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7f2155114084 Code: 89 02 b8 ff ff ff ff eb bb 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa 80 3d 25 f0 0c 00 00 74 13 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 48 83 ec 28 89 54 24 1c 48 89 RSP: 002b:00007fff1fd7a988 EFLAGS: 00000202 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 0000560ec063e5e0 RCX: 00007f2155114084 RDX: 0000000000000000 RSI: 00007fff1fd7a9f0 RDI: 0000000000000003 RBP: 00007fff1fd7aa60 R08: 0000000000000010 R09: 000000000000003f R10: 0000560ee9b3a010 R11: 0000000000000202 R12: 00007fff1fd7aae0 R13: 000000006891ccde R14: 0000560ec063e5e0 R15: 00007fff1fd7aad0 </TASK>
[1] https://lore.kernel.org/netdev/e08c7f4a6882f260011909a868311c6e9b54f3e4.1639153474.git.dcaratti@redhat.com/
[2] https://lore.kernel.org/netdev/[email protected]/
--- net/sched/sch_ets.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
net/sched/sch_ets.c +6 -5
@@ -651,6 +651,12 @@ static int ets_qdisc_change(struct Qdiscsch_tree_lock (sch); +for (i = nbands; i < oldbands; i++) { +if (i >= q->nstrict && q->classes[i].qdisc->q.qlen) +list_del_init (&q->classes[i].alist); +qdisc_purge_queue (q->classes[i].qdisc); + } +WRITE_ONCE (q->nbands, nbands);for (i = nstrict; i < q->nstrict; i++) {if (q->classes[i].qdisc->q.qlen) {
@@ -658,11 +664,6 @@ static int ets_qdisc_change(struct Qdisc q->classes[i].deficit = quanta[i]; } } -for (i = q->nbands; i < oldbands; i++) { -if (i >= q->nstrict && q->classes[i].qdisc->q.qlen) -list_del_init (&q->classes[i].alist); -qdisc_purge_queue (q->classes[i].qdisc); - }WRITE_ONCE (q->nstrict, nstrict);memcpy (q->prio2band, priomap,sizeof (priomap));
Greg Kroah-Hartman
maintainerPATCH 410/444 hv_netvsc: Fix panic during namespace deletion with VF
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haiyang Zhang <[email protected]>
commit 33caa208dba6fa639e8a92fd0c8320b652e5550c upstream.
The existing code move the VF NIC to new namespace when NETDEV_REGISTER is received on netvsc NIC. During deletion of the namespace, default_device_exit_batch() >> default_device_exit_net() is called. When netvsc NIC is moved back and registered to the default namespace, it automatically brings VF NIC back to the default namespace. This will cause the default_device_exit_net() >> for_each_netdev_safe loop unable to detect the list end, and hit NULL ptr:
[ 231.449420] mana 7870:00:00.0 enP30832s1: Moved VF to namespace with: eth0 [ 231.449656] BUG: kernel NULL pointer dereference, address: 0000000000000010 [ 231.450246] #PF: supervisor read access in kernel mode [ 231.450579] #PF: error_code(0x0000) - not-present page [ 231.450916] PGD 17b8a8067 P4D 0 [ 231.451163] Oops: Oops: 0000 [#1] SMP NOPTI [ 231.451450] CPU: 82 UID: 0 PID: 1394 Comm: kworker/u768:1 Not tainted 6.16.0-rc4+ #3 VOLUNTARY [ 231.452042] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 11/21/2024 [ 231.452692] Workqueue: netns cleanup_net [ 231.452947] RIP: 0010:default_device_exit_batch+0x16c/0x3f0 [ 231.453326] Code: c0 0c f5 b3 e8 d5 db fe ff 48 85 c0 74 15 48 c7 c2 f8 fd ca b2 be 10 00 00 00 48 8d 7d c0 e8 7b 77 25 00 49 8b 86 28 01 00 00 <48> 8b 50 10 4c 8b 2a 4c 8d 62 f0 49 83 ed 10 4c 39 e0 0f 84 d6 00 [ 231.454294] RSP: 0018:ff75fc7c9bf9fd00 EFLAGS: 00010246 [ 231.454610] RAX: 0000000000000000 RBX: 0000000000000002 RCX: 61c8864680b583eb [ 231.455094] RDX: ff1fa9f71462d800 RSI: ff75fc7c9bf9fd38 RDI: 0000000030766564 [ 231.455686] RBP: ff75fc7c9bf9fd78 R08: 0000000000000000 R09: 0000000000000000 [ 231.456126] R10: 0000000000000001 R11: 0000000000000004 R12: ff1fa9f70088e340 [ 231.456621] R13: ff1fa9f70088e340 R14: ffffffffb3f50c20 R15: ff1fa9f7103e6340 [ 231.457161] FS: 0000000000000000(0000) GS:ff1faa6783a08000(0000) knlGS:0000000000000000 [ 231.457707] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 231.458031] CR2: 0000000000000010 CR3: 0000000179ab2006 CR4: 0000000000b73ef0 [ 231.458434] Call Trace: [ 231.458600] <TASK> [ 231.458777] ops_undo_list+0x100/0x220 [ 231.459015] cleanup_net+0x1b8/0x300 [ 231.459285] process_one_work+0x184/0x340
To fix it, move the ns change to a workqueue, and take rtnl_lock to avoid changing the netdev list when default_device_exit_net() is using it.
--- drivers/net/hyperv/hyperv_net.h | 3 +++ drivers/net/hyperv/netvsc_drv.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-)
drivers/net/hyperv/hyperv_net.h +3 -0
@@ -1061,6 +1061,7 @@ struct net_device_context {struct net_device __rcu *vf_netdev;struct netvsc_vf_pcpu_stats __percpu *vf_stats;struct delayed_work vf_takeover; +struct delayed_work vfns_work;/* 1: allocated, serial number is valid. 0: not allocated */ u32 vf_alloc;
@@ -1075,6 +1076,8 @@ struct net_device_context {struct netvsc_device_info *saved_netvsc_dev_info; }; +void netvsc_vfns_work (struct work_struct *w); +/* Azure hosts don't support non-TCP port numbers in hashing for fragmented * packets. We can use ethtool to change UDP hash level when necessary. */
drivers/net/hyperv/netvsc_drv.c +28 -1
@@ -2516,6 +2516,7 @@ static int netvsc_probe(struct hv_devicespin_lock_init (&net_device_ctx->lock);INIT_LIST_HEAD (&net_device_ctx->reconfig_events);INIT_DELAYED_WORK (&net_device_ctx->vf_takeover, netvsc_vf_setup); +INIT_DELAYED_WORK (&net_device_ctx->vfns_work, netvsc_vfns_work); net_device_ctx->vf_stats = netdev_alloc_pcpu_stats(struct netvsc_vf_pcpu_stats);
@@ -2658,6 +2659,8 @@ static void netvsc_remove(struct hv_devicancel_delayed_work_sync (&ndev_ctx->dwork);rtnl_lock (); +cancel_delayed_work_sync (&ndev_ctx->vfns_work); + nvdev =rtnl_dereference (ndev_ctx->nvdev);if (nvdev) {cancel_work_sync (&nvdev->subchan_work);
@@ -2699,6 +2702,7 @@ static int netvsc_suspend(struct hv_devicancel_delayed_work_sync (&ndev_ctx->dwork);rtnl_lock (); +cancel_delayed_work_sync (&ndev_ctx->vfns_work); nvdev =rtnl_dereference (ndev_ctx->nvdev);if (nvdev ==NULL ) {
@@ -2792,6 +2796,27 @@ static void netvsc_event_set_vf_ns(struc } } +void netvsc_vfns_work (struct work_struct *w) +{ +struct net_device_context *ndev_ctx = + container_of(w, struct net_device_context, vfns_work.work); +struct net_device *ndev; + +if (!rtnl_trylock ()) { +schedule_delayed_work (&ndev_ctx->vfns_work,1 ); +return ; + } + + ndev =hv_get_drvdata (ndev_ctx->device_ctx); +if (!ndev) + goto out; + +netvsc_event_set_vf_ns (ndev); + +out: +rtnl_unlock (); +} +/* * On Hyper-V, every VF interface is matched with a corresponding * synthetic interface. The synthetic interface is presented first
@@ -2802,10 +2827,12 @@ static int netvsc_netdev_event(struct no unsigned long event, void *ptr) { struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); +struct net_device_context *ndev_ctx;int ret =0 ;if (event_dev->netdev_ops == &device_ops && event ==NETDEV_REGISTER ) { -netvsc_event_set_vf_ns (event_dev); + ndev_ctx =netdev_priv (event_dev); +schedule_delayed_work (&ndev_ctx->vfns_work,0 );return NOTIFY_DONE ; }
Greg Kroah-Hartman
maintainerPATCH 411/444 parisc: Makefile: fix a typo in palo.conf
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randy Dunlap <[email protected]>
commit 963f1b20a8d2a098954606b9725cd54336a2a86c upstream.
Correct "objree" to "objtree". "objree" is not defined.
--- arch/parisc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/parisc/Makefile +1 -1
@@ -139,7 +139,7 @@ palo lifimage: vmlinuz fi @if test ! -f "$(PALOCONF)"; then \ cp $(srctree)/arch/parisc/defpalo.conf $(objtree)/palo.conf; \ - echo 'A generic palo config file ($(objree)/palo.conf) has been created for you.'; \ + echo 'A generic palo config file ($(objtree)/palo.conf) has been created for you.'; \ echo 'You should check it and re-run "make palo".'; \ echo 'WARNING: the "lifimage" file is now placed in this directory by default!'; \ false; \
Greg Kroah-Hartman
maintainerPATCH 412/444 mm, slab: restore NUMA policy support for large kmalloc
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vlastimil Babka <[email protected]>
commit e2d18cbf178775ad377ad88ee55e6e183c38d262 upstream.
The slab allocator observes the task's NUMA policy in various places such as allocating slab pages. Large kmalloc() allocations used to do that too, until an unintended change by c4cab557521a ("mm/slab_common:
cleanup kmalloc_large()") resulted in ignoring mempolicy and just preferring the local node. Restore the NUMA policy support.
--- mm/slub.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
mm/slub.c +6 -1
@@ -4225,7 +4225,12 @@ static void *___kmalloc_large_node(size_ flags =kmalloc_fix_flags (flags); flags |= __GFP_COMP; - folio = (struct folio *)alloc_pages_node_noprof (node, flags, order); + +if (node ==NUMA_NO_NODE ) + folio = (struct folio *)alloc_pages_noprof (flags, order); +else + folio = (struct folio *)__alloc_pages_noprof (flags, order, node,NULL ); +if (folio) { ptr =folio_address (folio); lruvec_stat_mod_folio(folio, NR_SLAB_UNRECLAIMABLE_B,
Greg Kroah-Hartman
maintainerPATCH 413/444 mm/ptdump: take the memory hotplug lock inside ptdump_walk_pgd()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anshuman Khandual <[email protected]>
commit 59305202c67fea50378dcad0cc199dbc13a0e99a upstream.
Memory hot remove unmaps and tears down various kernel page table regions as required. The ptdump code can race with concurrent modifications of the kernel page tables. When leaf entries are modified concurrently, the dump code may log stale or inconsistent information for a VA range, but this is otherwise not harmful.
But when intermediate levels of kernel page table are freed, the dump code will continue to use memory that has been freed and potentially reallocated for another purpose. In such cases, the ptdump code may dereference bogus addresses, leading to a number of potential problems.
To avoid the above mentioned race condition, platforms such as arm64, riscv and s390 take memory hotplug lock, while dumping kernel page table via the sysfs interface /sys/kernel/debug/kernel_page_tables.
Similar race condition exists while checking for pages that might have been marked W+X via /sys/kernel/debug/kernel_page_tables/check_wx_pages which in turn calls ptdump_check_wx(). Instead of solving this race condition again, let's just move the memory hotplug lock inside generic ptdump_check_wx() which will benefit both the scenarios.
Drop get_online_mems() and put_online_mems() combination from all existing platform ptdump code paths.
--- arch/arm64/mm/ptdump_debugfs.c | 3 --- arch/riscv/mm/ptdump.c | 3 --- arch/s390/mm/dump_pagetables.c | 2 -- mm/ptdump.c | 2 ++ 4 files changed, 2 insertions(+), 8 deletions(-)
arch/arm64/mm/ptdump_debugfs.c +0 -3
@@ -1,6 +1,5 @@// SPDX-License-Identifier: GPL-2.0 #include <linux/debugfs.h> -#include <linux/memory_hotplug.h> #include <linux/seq_file.h> #include <asm/ptdump.h>
@@ -9,9 +8,7 @@ static int ptdump_show(struct seq_file * {struct ptdump_info *info = m->private; -get_online_mems ();ptdump_walk (m, info); -put_online_mems ();return 0 ; }DEFINE_SHOW_ATTRIBUTE (ptdump);
arch/riscv/mm/ptdump.c +0 -3
@@ -6,7 +6,6 @@#include <linux/efi.h> #include <linux/init.h> #include <linux/debugfs.h> -#include <linux/memory_hotplug.h> #include <linux/seq_file.h> #include <linux/ptdump.h>
@@ -371,9 +370,7 @@ bool ptdump_check_wx(void)static int ptdump_show (struct seq_file *m,void *v) { -get_online_mems ();ptdump_walk (m, m->private); -put_online_mems ();return 0 ; }
arch/s390/mm/dump_pagetables.c +0 -2
@@ -203,11 +203,9 @@ static int ptdump_show(struct seq_file * .marker = markers, }; -get_online_mems ();mutex_lock (&cpa_mutex);ptdump_walk_pgd (&st.ptdump, &init_mm,NULL );mutex_unlock (&cpa_mutex); -put_online_mems ();return 0 ; }DEFINE_SHOW_ATTRIBUTE (ptdump);
mm/ptdump.c +2 -0
@@ -153,6 +153,7 @@ void ptdump_walk_pgd(struct ptdump_state {const struct ptdump_range *range = st->range; +get_online_mems ();mmap_write_lock (mm);while (range->start != range->end) { walk_page_range_novma(mm, range->start, range->end,
@@ -160,6 +161,7 @@ void ptdump_walk_pgd(struct ptdump_state range++; }mmap_write_unlock (mm); +put_online_mems ();/* Flush out the last page */ st->note_page (st,0 ,-1 ,0 );
Greg Kroah-Hartman
maintainerPATCH 414/444 mm/kmemleak: avoid soft lockup in __kmemleak_do_cleanup()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <[email protected]>
commit d1534ae23c2b6be350c8ab060803fbf6e9682adc upstream.
A soft lockup warning was observed on a relative small system x86-64 system with 16 GB of memory when running a debug kernel with kmemleak enabled.
watchdog: BUG: soft lockup - CPU#8 stuck for 33s! [kworker/8:1:134]
The test system was running a workload with hot unplug happening in parallel. Then kemleak decided to disable itself due to its inability to allocate more kmemleak objects. The debug kernel has its CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE set to 40,000.
The soft lockup happened in kmemleak_do_cleanup() when the existing kmemleak objects were being removed and deleted one-by-one in a loop via a workqueue. In this particular case, there are at least 40,000 objects that need to be processed and given the slowness of a debug kernel and the fact that a raw_spinlock has to be acquired and released in __delete_object(), it could take a while to properly handle all these objects.
As kmemleak has been disabled in this case, the object removal and deletion process can be further optimized as locking isn't really needed. However, it is probably not worth the effort to optimize for such an edge case that should rarely happen. So the simple solution is to call cond_resched() at periodic interval in the iteration loop to avoid soft lockup.
--- mm/kmemleak.c | 5 +++++ 1 file changed, 5 insertions(+)
mm/kmemleak.c +5 -0
@@ -2107,6 +2107,7 @@ static const struct file_operations kmemstatic void __kmemleak_do_cleanup (void ) {struct kmemleak_object *object, *tmp; +unsigned int cnt =0 ;/* * Kmemleak has already been disabled, no need for RCU list traversal
@@ -2115,6 +2116,10 @@ static void __kmemleak_do_cleanup(void)list_for_each_entry_safe (object, tmp, &object_list, object_list) {__remove_object (object);__delete_object (object); + +/* Call cond_resched() once per 64 iterations to avoid soft lockup */ +if (!(++cnt &0x3f )) +cond_resched (); } }
Greg Kroah-Hartman
maintainerPATCH 415/444 mm/kmemleak: avoid deadlock by moving pr_warn() outside kmemleak_lock
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
commit 47b0f6d8f0d2be4d311a49e13d2fd5f152f492b2 upstream.
When netpoll is enabled, calling pr_warn_once() while holding kmemleak_lock in mem_pool_alloc() can cause a deadlock due to lock inversion with the netconsole subsystem. This occurs because pr_warn_once() may trigger netpoll, which eventually leads to __alloc_skb() and back into kmemleak code, attempting to reacquire kmemleak_lock.
This is the path for the deadlock.
mem_pool_alloc()
-> raw_spin_lock_irqsave(&kmemleak_lock, flags);
-> pr_warn_once()
-> netconsole subsystem
-> netpoll
-> __alloc_skb
-> __create_object
-> raw_spin_lock_irqsave(&kmemleak_lock, flags);Fix this by setting a flag and issuing the pr_warn_once() after kmemleak_lock is released.
--- mm/kmemleak.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
mm/kmemleak.c +4 -1
@@ -465,6 +465,7 @@ static struct kmemleak_object *mem_pool_ {unsigned long flags;struct kmemleak_object *object; +bool warn = false;/* try the slab allocator first */ if (object_cache) {
@@ -483,8 +484,10 @@ static struct kmemleak_object *mem_pool_else if (mem_pool_free_count) object = &mem_pool[--mem_pool_free_count];else -pr_warn_once ("Memory pool empty, consider increasing CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE\n" ); + warn = true;raw_spin_unlock_irqrestore (&kmemleak_lock, flags); +if (warn) +pr_warn_once ("Memory pool empty, consider increasing CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE\n" );return object; }
Greg Kroah-Hartman
maintainerPATCH 416/444 media: uvcvideo: Fix 1-byte out-of-bounds read in uvc_parse_format()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Youngjun Lee <[email protected]>
commit 782b6a718651eda3478b1824b37a8b3185d2740c upstream.
The buffer length check before calling uvc_parse_format() only ensured that the buffer has at least 3 bytes (buflen > 2), buf the function accesses buffer[3], requiring at least 4 bytes.
This can lead to an out-of-bounds read if the buffer has exactly 3 bytes.
Fix it by checking that the buffer has at least 4 bytes in uvc_parse_format().
--- drivers/media/usb/uvc/uvc_driver.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/media/usb/uvc/uvc_driver.c +3 -0
@@ -235,6 +235,9 @@ static int uvc_parse_format(struct uvc_dunsigned int i, n;u8 ftype; +if (buflen <4 ) +return -EINVAL ; + format->type = buffer[2 ]; format->index = buffer[3 ]; format->frames = frames;
Greg Kroah-Hartman
maintainerPATCH 417/444 media: venus: Fix OOB read due to missing payload bound check
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vedang Nagar <[email protected]>
commit 06d6770ff0d8cc8dfd392329a8cc03e2a83e7289 upstream.
Currently, The event_seq_changed() handler processes a variable number of properties sent by the firmware. The number of properties is indicated by the firmware and used to iterate over the payload. However, the payload size is not being validated against the actual message length.
This can lead to out-of-bounds memory access if the firmware provides a property count that exceeds the data available in the payload. Such a condition can result in kernel crashes or potential information leaks if memory beyond the buffer is accessed.
Fix this by properly validating the remaining size of the payload before each property access and updating bounds accordingly as properties are parsed.
This ensures that property parsing is safely bounded within the received message buffer and protects against malformed or malicious firmware behavior.
--- drivers/media/platform/qcom/venus/hfi_msgs.c | 83 ++++++++++++++++++--------- 1 file changed, 58 insertions(+), 25 deletions(-)
drivers/media/platform/qcom/venus/hfi_msgs.c +58 -25
@@ -33,8 +33,9 @@ static void event_seq_changed(struct venstruct hfi_buffer_requirements *bufreq;struct hfi_extradata_input_crop *crop;struct hfi_dpb_counts *dpb_count; +u32 ptype, rem_bytes; +u32 size_read =0 ;u8 *data_ptr; -u32 ptype; inst->error =HFI_ERR_NONE ;
@@ -44,86 +45,118 @@ static void event_seq_changed(struct venbreak ;default : inst->error =HFI_ERR_SESSION_INVALID_PARAMETER ; - goto done; + inst->ops->event_notify (inst,EVT_SYS_EVENT_CHANGE , &event); +return ; } event.event_type = pkt->event_data1; num_properties_changed = pkt->event_data2; -if (!num_properties_changed) { - inst->error =HFI_ERR_SESSION_INSUFFICIENT_RESOURCES ; - goto done; - } +if (!num_properties_changed) + goto error; data_ptr = (u8 *)&pkt->ext_event_data[0 ]; + rem_bytes = pkt->shdr.hdr.size -sizeof (*pkt); +do { +if (rem_bytes <sizeof (u32)) + goto error; ptype = *((u32 *)data_ptr); + + data_ptr +=sizeof (u32); + rem_bytes -=sizeof (u32); +switch (ptype) {case HFI_PROPERTY_PARAM_FRAME_SIZE : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_framesize )) + goto error; + frame_sz = (struct hfi_framesize *)data_ptr; event.width = frame_sz->width; event.height = frame_sz->height; - data_ptr +=sizeof (*frame_sz); + size_read =sizeof (struct hfi_framesize );break ;case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_profile_level )) + goto error; + profile_level = (struct hfi_profile_level *)data_ptr; event.profile = profile_level->profile; event.level = profile_level->level; - data_ptr +=sizeof (*profile_level); + size_read =sizeof (struct hfi_profile_level );break ;case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_bit_depth )) + goto error; + pixel_depth = (struct hfi_bit_depth *)data_ptr; event.bit_depth = pixel_depth->bit_depth; - data_ptr +=sizeof (*pixel_depth); + size_read =sizeof (struct hfi_bit_depth );break ;case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_pic_struct )) + goto error; + pic_struct = (struct hfi_pic_struct *)data_ptr; event.pic_struct = pic_struct->progressive_only; - data_ptr +=sizeof (*pic_struct); + size_read =sizeof (struct hfi_pic_struct );break ;case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_colour_space )) + goto error; + colour_info = (struct hfi_colour_space *)data_ptr; event.colour_space = colour_info->colour_space; - data_ptr +=sizeof (*colour_info); + size_read =sizeof (struct hfi_colour_space );break ;case HFI_PROPERTY_CONFIG_VDEC_ENTROPY : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (u32)) + goto error; + event.entropy_mode = *(u32 *)data_ptr; - data_ptr +=sizeof (u32); + size_read =sizeof (u32);break ;case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_buffer_requirements )) + goto error; + bufreq = (struct hfi_buffer_requirements *)data_ptr; event.buf_count =hfi_bufreq_get_count_min (bufreq, ver); - data_ptr +=sizeof (*bufreq); + size_read =sizeof (struct hfi_buffer_requirements );break ;case HFI_INDEX_EXTRADATA_INPUT_CROP : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_extradata_input_crop )) + goto error; + crop = (struct hfi_extradata_input_crop *)data_ptr; event.input_crop.left = crop->left; event.input_crop.top = crop->top; event.input_crop.width = crop->width; event.input_crop.height = crop->height; - data_ptr +=sizeof (*crop); + size_read =sizeof (struct hfi_extradata_input_crop );break ;case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_dpb_counts )) + goto error; + dpb_count = (struct hfi_dpb_counts *)data_ptr; event.buf_count = dpb_count->fw_min_cnt; - data_ptr +=sizeof (*dpb_count); + size_read =sizeof (struct hfi_dpb_counts );break ;default : + size_read =0 ;break ; } + data_ptr += size_read; + rem_bytes -= size_read; num_properties_changed--; }while (num_properties_changed >0 ); -done: + inst->ops->event_notify (inst,EVT_SYS_EVENT_CHANGE , &event); +return ; + +error: + inst->error =HFI_ERR_SESSION_INSUFFICIENT_RESOURCES ; inst->ops->event_notify (inst,EVT_SYS_EVENT_CHANGE , &event); }
Greg Kroah-Hartman
maintainerPATCH 418/444 media: uvcvideo: Do not mark valid metadata as invalid
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
commit bda2859bff0b9596a19648f3740c697ce4c71496 upstream.
Currently, the driver performs a length check of the metadata buffer before the actual metadata size is known and before the metadata is decided to be copied. This results in valid metadata buffers being incorrectly marked as invalid.
Move the length check to occur after the metadata size is determined and is decided to be copied.
--- drivers/media/usb/uvc/uvc_video.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/media/usb/uvc/uvc_video.c +6 -6
@@ -1437,12 +1437,6 @@ static void uvc_video_decode_meta(structif (!meta_buf || length ==2 )return ; -if (meta_buf->length - meta_buf->bytesused < - length +sizeof (meta->ns) +sizeof (meta->sof)) { - meta_buf->error =1 ; -return ; - } - has_pts = mem[1 ] &UVC_STREAM_PTS ; has_scr = mem[1 ] &UVC_STREAM_SCR ;
@@ -1463,6 +1457,12 @@ static void uvc_video_decode_meta(struct !memcmp(scr, stream->clock.last_scr, 6)))return ; +if (meta_buf->length - meta_buf->bytesused < + length +sizeof (meta->ns) +sizeof (meta->sof)) { + meta_buf->error =1 ; +return ; + } + meta = (struct uvc_meta_buf *)((u8 *)meta_buf->mem + meta_buf->bytesused);local_irq_save (flags); time =uvc_video_get_time ();
Greg Kroah-Hartman
maintainerPATCH 419/444 media: v4l2: Add support for NV12M tiled variants to v4l2_format_info()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski <[email protected]>
commit f7546da1d6eb8928efb89b7faacbd6c2f8f0de5c upstream.
Commit 6f1466123d73 ("media: s5p-mfc: Add YV12 and I420 multiplanar format support") added support for the new formats to s5p-mfc driver, what in turn required some internal calls to the v4l2_format_info() function while setting up formats. This in turn broke support for the "old" tiled NV12MT* formats, which are not recognized by this function. Fix this by adding those variants of NV12M pixel format to v4l2_format_info() function database.
--- drivers/media/v4l2-core/v4l2-common.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/media/v4l2-core/v4l2-common.c +6 -0
@@ -312,6 +312,12 @@ const struct v4l2_format_info *v4l2_form { .format = V4L2_PIX_FMT_NV61M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, { .format = V4L2_PIX_FMT_P012M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, + /* Tiled YUV formats, non contiguous variant */ + { .format = V4L2_PIX_FMT_NV12MT, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2, + .block_w = { 64, 32, 0, 0 }, .block_h = { 32, 16, 0, 0 }}, + { .format = V4L2_PIX_FMT_NV12MT_16X16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2, + .block_w = { 16, 8, 0, 0 }, .block_h = { 16, 8, 0, 0 }}, + /* Bayer RGB formats */ { .format = V4L2_PIX_FMT_SBGGR8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, { .format = V4L2_PIX_FMT_SGBRG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
Greg Kroah-Hartman
maintainerPATCH 420/444 tools/nolibc: fix spelling of FD_SETBITMASK in FD_* macros
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willy Tarreau <[email protected]>
commit a477629baa2a0e9991f640af418e8c973a1c08e3 upstream.
While nolibc-test does test syscalls, it doesn't test as much the rest of the macros, and a wrong spelling of FD_SETBITMASK in commit feaf75658783a broke programs using either FD_SET() or FD_CLR() without being noticed. Let's fix these macros.
--- tools/include/nolibc/types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/include/nolibc/types.h +2 -2
@@ -127,7 +127,7 @@ typedef struct {int __fd = (fd); \if (__fd >=0 ) \ __set->fds[__fd /FD_SETIDXMASK ] &= \ - ~(1U << (__fd &FX_SETBITMASK )); \ + ~(1U << (__fd &FD_SETBITMASK )); \ } while (0)#define FD_SET (fd, set) do { \
@@ -144,7 +144,7 @@ typedef struct {int __r =0 ; \if (__fd >=0 ) \ __r = !!(__set->fds[__fd /FD_SETIDXMASK ] & \ -1U << (__fd &FD_SET_BITMASK )); \ +1U << (__fd &FD_SETBITMASK )); \ __r; \ })
Greg Kroah-Hartman
maintainerPATCH 421/444 RDMA/siw: Fix the sendmsg byte count in siw_tcp_sendpages
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pedro Falcato <[email protected]>
commit c18646248fed07683d4cee8a8af933fc4fe83c0d upstream.
Ever since commit c2ff29e99a76 ("siw: Inline do_tcp_sendpages()"), we have been doing this:
static int siw_tcp_sendpages(struct socket *s, struct page **page, int offset,
size_t size)
[...]
/* Calculate the number of bytes we need to push, for this page
* specifically */
size_t bytes = min_t(size_t, PAGE_SIZE - offset, size);
/* If we can't splice it, then copy it in, as normal */
if (!sendpage_ok(page[i]))
msg.msg_flags &= ~MSG_SPLICE_PAGES;
/* Set the bvec pointing to the page, with len $bytes */
bvec_set_page(&bvec, page[i], bytes, offset);
/* Set the iter to $size, aka the size of the whole sendpages (!!!) */
iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size);
try_page_again:
lock_sock(sk);
/* Sendmsg with $size size (!!!) */
rv = tcp_sendmsg_locked(sk, &msg, size);This means we've been sending oversized iov_iters and tcp_sendmsg calls for a while. This has a been a benign bug because sendpage_ok() always returned true. With the recent slab allocator changes being slowly introduced into next (that disallow sendpage on large kmalloc allocations), we have recently hit out-of-bounds crashes, due to slight differences in iov_iter behavior between the MSG_SPLICE_PAGES and "regular" copy paths:
(MSG_SPLICE_PAGES)skb_splice_from_iter
iov_iter_extract_pages
iov_iter_extract_bvec_pages
uses i->nr_segs to correctly stop in its tracks before OoB'ing everywhere skb_splice_from_iter gets a "short" read
(!MSG_SPLICE_PAGES)skb_copy_to_page_nocache copy=iov_iter_count
[...]
copy_from_iter
/* this doesn't help */
if (unlikely(iter->count < len))
len = iter->count;
iterate_bvec
... and we run off the bvecsFix this by properly setting the iov_iter's byte count, plus sending the correct byte count to tcp_sendmsg_locked.
--- drivers/infiniband/sw/siw/siw_qp_tx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/infiniband/sw/siw/siw_qp_tx.c +2 -3
@@ -334,18 +334,17 @@ static int siw_tcp_sendpages(struct sockif (!sendpage_ok (page[i])) msg.msg_flags &= ~MSG_SPLICE_PAGES ;bvec_set_page (&bvec, page[i], bytes, offset); -iov_iter_bvec (&msg.msg_iter,ITER_SOURCE , &bvec,1 , size); +iov_iter_bvec (&msg.msg_iter,ITER_SOURCE , &bvec,1 , bytes); try_page_again:lock_sock (sk); - rv =tcp_sendmsg_locked (sk, &msg, size); + rv =tcp_sendmsg_locked (sk, &msg, bytes);release_sock (sk);if (rv >0 ) { size -= rv; sent += rv;if (rv != bytes) { - offset += rv; bytes -= rv; goto try_page_again; }
Greg Kroah-Hartman
maintainerPATCH 422/444 HID: magicmouse: avoid setting up battery timer when not needed
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aditya Garg <[email protected]>
commit 9bdc30e35cbc1aa78ccf01040354209f1e11ca22 upstream.
Currently, the battery timer is set up for all devices using hid-magicmouse, irrespective of whether they actually need it or not.
The current implementation requires the battery timer for Magic Mouse 2 and Magic Trackpad 2 when connected via USB only. Add checks to ensure that the battery timer is only set up when they are connected via USB.
---
--- drivers/hid/hid-magicmouse.c | 58 ++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 20 deletions(-)
drivers/hid/hid-magicmouse.c +38 -20
@@ -775,16 +775,30 @@ static void magicmouse_enable_mt_work(sthid_err (msc->hdev,"unable to request touch data (%d)\n" , ret); } +static bool is_usb_magicmouse2 (__u32 vendor,__u32 product) +{ +if (vendor !=USB_VENDOR_ID_APPLE ) +return false; +return product ==USB_DEVICE_ID_APPLE_MAGICMOUSE2 ; +} + +static bool is_usb_magictrackpad2 (__u32 vendor,__u32 product) +{ +if (vendor !=USB_VENDOR_ID_APPLE ) +return false; +return product ==USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 || + product ==USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC ; +} +static int magicmouse_fetch_battery (struct hid_device *hdev) {#ifdef CONFIG_HID_BATTERY_STRENGTH struct hid_report_enum *report_enum;struct hid_report *report; -if (!hdev->battery || hdev->vendor !=USB_VENDOR_ID_APPLE || - (hdev->product !=USB_DEVICE_ID_APPLE_MAGICMOUSE2 && - hdev->product !=USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 && - hdev->product !=USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC )) +if (!hdev->battery || + (!is_usb_magicmouse2 (hdev->vendor, hdev->product) && + !is_usb_magictrackpad2 (hdev->vendor, hdev->product)))return -1 ; report_enum = &hdev->report_enum[hdev->battery_report_type];
@@ -846,16 +860,17 @@ static int magicmouse_probe(struct hid_dreturn ret; } -timer_setup (&msc->battery_timer, magicmouse_battery_timer_tick,0 ); -mod_timer (&msc->battery_timer, - jiffies +msecs_to_jiffies (USB_BATTERY_TIMEOUT_MS )); -magicmouse_fetch_battery (hdev); - -if (id->vendor ==USB_VENDOR_ID_APPLE && - (id->product ==USB_DEVICE_ID_APPLE_MAGICMOUSE2 || - ((id->product ==USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 || - id->product ==USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC ) && - hdev->type !=HID_TYPE_USBMOUSE ))) +if (is_usb_magicmouse2 (id->vendor, id->product) || +is_usb_magictrackpad2 (id->vendor, id->product)) { +timer_setup (&msc->battery_timer, magicmouse_battery_timer_tick,0 ); +mod_timer (&msc->battery_timer, + jiffies +msecs_to_jiffies (USB_BATTERY_TIMEOUT_MS )); +magicmouse_fetch_battery (hdev); + } + +if (is_usb_magicmouse2 (id->vendor, id->product) || + (is_usb_magictrackpad2 (id->vendor, id->product) && + hdev->type !=HID_TYPE_USBMOUSE ))return 0 ;if (!msc->input) {
@@ -911,7 +926,10 @@ static int magicmouse_probe(struct hid_dreturn 0 ; err_stop_hw: -del_timer_sync (&msc->battery_timer); +if (is_usb_magicmouse2 (id->vendor, id->product) || +is_usb_magictrackpad2 (id->vendor, id->product)) +del_timer_sync (&msc->battery_timer); +hid_hw_stop (hdev);return ret; }
@@ -922,7 +940,9 @@ static void magicmouse_remove(struct hidif (msc) {cancel_delayed_work_sync (&msc->work); -del_timer_sync (&msc->battery_timer); +if (is_usb_magicmouse2 (hdev->vendor, hdev->product) || +is_usb_magictrackpad2 (hdev->vendor, hdev->product)) +del_timer_sync (&msc->battery_timer); }hid_hw_stop (hdev);
@@ -939,10 +959,8 @@ static const __u8 *magicmouse_report_fix* 0x05, 0x01, // Usage Page (Generic Desktop) 0 * 0x09, 0x02, // Usage (Mouse) 2 */ -if (hdev->vendor ==USB_VENDOR_ID_APPLE && - (hdev->product ==USB_DEVICE_ID_APPLE_MAGICMOUSE2 || - hdev->product ==USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 || - hdev->product ==USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC ) && +if ((is_usb_magicmouse2 (hdev->vendor, hdev->product) || +is_usb_magictrackpad2 (hdev->vendor, hdev->product)) && *rsize ==83 && rdesc[46 ] ==0x84 && rdesc[58 ] ==0x85 ) {hid_info (hdev,"fixing up magicmouse battery report descriptor\n" );
Greg Kroah-Hartman
maintainerPATCH 423/444 wifi: mac80211: check basic rates validity in sta_link_apply_parameters
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Lobanov <[email protected]>
commit 16ee3ea8faef8ff042acc15867a6c458c573de61 upstream.
When userspace sets supported rates for a new station via NL80211_CMD_NEW_STATION, it might send a list that's empty or contains only invalid values. Currently, we process these values in sta_link_apply_parameters() without checking the result of ieee80211_parse_bitrates(), which can lead to an empty rates bitmap.
A similar issue was addressed for NL80211_CMD_SET_BSS in commit ce04abc3fcc6 ("wifi: mac80211: check basic rates validity"). This patch applies the same approach in sta_link_apply_parameters() for NL80211_CMD_NEW_STATION, ensuring there is at least one valid rate by inspecting the result of ieee80211_parse_bitrates().
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
--- net/mac80211/cfg.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
net/mac80211/cfg.c +6 -6
@@ -1879,12 +1879,12 @@ static int sta_link_apply_parameters(str }if (params->supported_rates && - params->supported_rates_len) { -ieee80211_parse_bitrates (link->conf->chanreq.oper.width, - sband, params->supported_rates, - params->supported_rates_len, - &link_sta->pub->supp_rates[sband->band]); - } + params->supported_rates_len && + !ieee80211_parse_bitrates (link->conf->chanreq.oper.width, + sband, params->supported_rates, + params->supported_rates_len, + &link_sta->pub->supp_rates[sband->band])) +return -EINVAL ;if (params->ht_capa) ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
Greg Kroah-Hartman
maintainerPATCH 424/444 tools/hv: fcopy: Fix irregularities with size of ring buffer
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naman Jain <[email protected]>
commit a4131a50d072b369bfed0b41e741c41fd8048641 upstream.
Size of ring buffer, as defined in uio_hv_generic driver, is no longer fixed to 16 KB. This creates a problem in fcopy, since this size was hardcoded. With the change in place to make ring sysfs node actually reflect the size of underlying ring buffer, it is safe to get the size of ring sysfs file and use it for ring buffer size in fcopy daemon. Fix the issue of disparity in ring buffer size, by making it dynamic in fcopy uio daemon.
Message-ID: <[email protected]>
--- tools/hv/hv_fcopy_uio_daemon.c | 91 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 10 deletions(-)
tools/hv/hv_fcopy_uio_daemon.c +81 -10
@@ -35,7 +35,10 @@#define WIN8_SRV_MINOR 1#define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR) -#define FCOPY_UIO "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/uio" +#define FCOPY_DEVICE_PATH (subdir) \ + "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/" #subdir +#define FCOPY_UIO_PATH FCOPY_DEVICE_PATH(uio) +#define FCOPY_CHANNELS_PATH FCOPY_DEVICE_PATH(channels)#define FCOPY_VER_COUNT 1static const int fcopy_versions[] = {
@@ -47,9 +50,62 @@ static const int fw_versions[] = {UTIL_FW_VERSION }; -#define HV_RING_SIZE 0x4000/* 16KB ring buffer size */ +static uint32_t get_ring_buffer_size (void ) +{ +char ring_path[PATH_MAX ]; +DIR *dir; +struct dirent *entry; +struct stat st; +uint32_t ring_size =0 ; +int retry_count =0 ; -static unsigned char desc[HV_RING_SIZE ]; +/* Find the channel directory */ + dir =opendir (FCOPY_CHANNELS_PATH ); +if (!dir) { +usleep (100 *1000 );/* Avoid race with kernel, wait 100ms and retry once */ + dir =opendir (FCOPY_CHANNELS_PATH ); +if (!dir) { +syslog (LOG_ERR ,"Failed to open channels directory: %s" ,strerror (errno)); +return 0 ; + } + } + +retry_once: +while ((entry =readdir (dir)) !=NULL ) { +if (entry->d_type ==DT_DIR &&strcmp (entry->d_name,"." ) !=0 && +strcmp (entry->d_name,".." ) !=0 ) { +snprintf (ring_path,sizeof (ring_path),"%s/%s/ring" , +FCOPY_CHANNELS_PATH , entry->d_name); + +if (stat (ring_path, &st) ==0 ) { +/* +* stat returns size of Tx, Rx rings combined, +* so take half of it for individual ring size. +*/ + ring_size = (uint32_t )st.st_size /2 ; +syslog (LOG_INFO ,"Ring buffer size from %s: %u bytes" , + ring_path, ring_size); +break ; + } + } + } + +if (!ring_size && retry_count ==0 ) { + retry_count =1 ; +rewinddir (dir); +usleep (100 *1000 );/* Wait 100ms and retry once */ + goto retry_once; + } + +closedir (dir); + +if (!ring_size) +syslog (LOG_ERR ,"Could not determine ring size" ); + +return ring_size; +} + +static unsigned char *desc;static int target_fd;static char target_fname[PATH_MAX ];
@@ -397,7 +453,7 @@ int main(int argc, char *argv[])int daemonize =1 , long_index =0 , opt, ret = -EINVAL ;struct vmbus_br txbr, rxbr;void *ring; -uint32_t len =HV_RING_SIZE ; +uint32_t ring_size, len;char uio_name[NAME_MAX ] = {0 };char uio_dev_path[PATH_MAX ] = {0 };
@@ -428,7 +484,20 @@ int main(int argc, char *argv[])openlog ("HV_UIO_FCOPY" ,0 ,LOG_USER );syslog (LOG_INFO ,"starting; pid is:%d" ,getpid ()); -fcopy_get_first_folder (FCOPY_UIO , uio_name); + ring_size =get_ring_buffer_size (); +if (!ring_size) { + ret = -ENODEV ; + goto exit; + } + + desc =malloc (ring_size *sizeof (unsigned char )); +if (!desc) { +syslog (LOG_ERR ,"malloc failed for desc buffer" ); + ret = -ENOMEM ; + goto exit; + } + +fcopy_get_first_folder (FCOPY_UIO_PATH , uio_name);snprintf (uio_dev_path,sizeof (uio_dev_path),"/dev/%s" , uio_name); fcopy_fd =open (uio_dev_path,O_RDWR );
@@ -436,17 +505,17 @@ int main(int argc, char *argv[])syslog (LOG_ERR ,"open %s failed; error: %d %s" , uio_dev_path, errno,strerror (errno)); ret = fcopy_fd; - goto exit; + goto free_desc; } - ring =vmbus_uio_map (&fcopy_fd,HV_RING_SIZE ); + ring =vmbus_uio_map (&fcopy_fd, ring_size);if (!ring) { ret = errno;syslog (LOG_ERR ,"mmap ringbuffer failed; error: %d %s" , ret,strerror (ret)); goto close; } -vmbus_br_setup (&txbr, ring,HV_RING_SIZE ); -vmbus_br_setup (&rxbr, (char *)ring +HV_RING_SIZE ,HV_RING_SIZE ); +vmbus_br_setup (&txbr, ring, ring_size); +vmbus_br_setup (&rxbr, (char *)ring + ring_size, ring_size); rxbr.vbr->imask =0 ;
@@ -461,7 +530,7 @@ int main(int argc, char *argv[])continue ; } - len =HV_RING_SIZE ; + len = ring_size; ret =rte_vmbus_chan_recv_raw (&rxbr, desc, &len);if (unlikely (ret <=0 )) {/* This indicates a failure to communicate (or worse) */
@@ -481,6 +550,8 @@ int main(int argc, char *argv[]) } close:close (fcopy_fd); +free_desc: +free (desc); exit:return ret; }
Greg Kroah-Hartman
maintainerPATCH 425/444 HID: apple: avoid setting up battery timer for devices without battery
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aditya Garg <[email protected]>
commit c061046fe9ce3ff31fb9a807144a2630ad349c17 upstream.
Currently, the battery timer is set up for all devices using hid-apple, irrespective of whether they actually have a battery or not.
APPLE_RDESC_BATTERY is a quirk that indicates the device has a battery and needs the battery timer. This patch checks for this quirk before setting up the timer, ensuring that only devices with a battery will have the timer set up.
--- drivers/hid/hid-apple.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/hid/hid-apple.c +11 -6
@@ -934,10 +934,12 @@ static int apple_probe(struct hid_devicereturn ret; } -timer_setup (&asc->battery_timer, apple_battery_timer_tick,0 ); -mod_timer (&asc->battery_timer, - jiffies +msecs_to_jiffies (APPLE_BATTERY_TIMEOUT_MS )); -apple_fetch_battery (hdev); +if (quirks &APPLE_RDESC_BATTERY ) { +timer_setup (&asc->battery_timer, apple_battery_timer_tick,0 ); +mod_timer (&asc->battery_timer, + jiffies +msecs_to_jiffies (APPLE_BATTERY_TIMEOUT_MS )); +apple_fetch_battery (hdev); + }if (quirks &APPLE_BACKLIGHT_CTL )apple_backlight_init (hdev);
@@ -951,7 +953,9 @@ static int apple_probe(struct hid_devicereturn 0 ; out_err: -del_timer_sync (&asc->battery_timer); +if (quirks &APPLE_RDESC_BATTERY ) +del_timer_sync (&asc->battery_timer); +hid_hw_stop (hdev);return ret; }
@@ -960,7 +964,8 @@ static void apple_remove(struct hid_devi {struct apple_sc *asc =hid_get_drvdata (hdev); -del_timer_sync (&asc->battery_timer); +if (asc->quirks &APPLE_RDESC_BATTERY ) +del_timer_sync (&asc->battery_timer);hid_hw_stop (hdev); }
Greg Kroah-Hartman
maintainerPATCH 426/444 mfd: cros_ec: Separate charge-control probing from USB-PD
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
commit e40fc1160d491c3bcaf8e940ae0dde0a7c5e8e14 upstream.
The charge-control subsystem in the ChromeOS EC is not strictly tied to its USB-PD subsystem.
Since commit 7613bc0d116a ("mfd: cros_ec: Don't load charger with UCSI") the presence of EC_FEATURE_UCSI_PPM would inhibit the probing of the charge-control driver.
Furthermore recent versions of the EC firmware in Framework laptops hard-disable EC_FEATURE_USB_PD to avoid probing cros-usbpd-charger, which then also breaks cros-charge-control.
Instead use the dedicated EC_FEATURE_CHARGER.
--- drivers/mfd/cros_ec_dev.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/mfd/cros_ec_dev.c +9 -1
@@ -87,7 +87,6 @@ static const struct mfd_cell cros_ec_sen };static const struct mfd_cell cros_usbpd_charger_cells[] = { - { .name ="cros-charge-control" , }, { .name ="cros-usbpd-charger" , }, { .name ="cros-usbpd-logger" , }, };
@@ -108,6 +107,10 @@ static const struct mfd_cell cros_ec_key { .name = "cros-keyboard-leds", }, }; +static const struct mfd_cell cros_ec_charge_control_cells[] = { + { .name ="cros-charge-control" , }, +}; +static const struct cros_feature_to_cells cros_subdevices[] = { { .id =EC_FEATURE_CEC ,
@@ -144,6 +147,11 @@ static const struct cros_feature_to_cell .mfd_cells = cros_ec_keyboard_leds_cells, .num_cells = ARRAY_SIZE(cros_ec_keyboard_leds_cells), }, + { + .id = EC_FEATURE_CHARGER, + .mfd_cells = cros_ec_charge_control_cells, + .num_cells = ARRAY_SIZE(cros_ec_charge_control_cells), + }, };static const struct mfd_cell cros_ec_platform_cells[] = {
Greg Kroah-Hartman
maintainerPATCH 427/444 net: Add net_passive_inc() and net_passive_dec().
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit e57a6320215c3967f51ab0edeff87db2095440e4 ]
net_drop_ns() is NULL when CONFIG_NET_NS is disabled.
The next patch introduces a function that increments and decrements net->passive.
As a prep, let's rename and export net_free() tonet_passive_dec() and add net_passive_inc().
Stable-dep-of: 59b33fab4ca4 ("smb: client: fix netns refcount leak after net_passive changes")
--- include/net/net_namespace.h | 16 ++++++++++++++++ net/core/net_namespace.c | 8 ++++---- 2 files changed, 20 insertions(+), 4 deletions(-)
include/net/net_namespace.h +16 -0
@@ -291,6 +291,7 @@ static inline int check_net(const struct }void net_drop_ns (void *); +void net_passive_dec (struct net *net);#else
@@ -320,8 +321,23 @@ static inline int check_net(const struct }#define net_drop_ns NULL + +static inline void net_passive_dec (struct net *net) +{ +refcount_dec (&net->passive); +}#endif +static inline void net_passive_inc (struct net *net) +{ +refcount_inc (&net->passive); +} + +/* Returns true if the netns initialization is completed successfully */ +static inline bool net_initialized (const struct net *net) +{ +return READ_ONCE (net->list.next); +} static inline void __netns_tracker_alloc(struct net *net, netns_tracker *tracker,
net/core/net_namespace.c +4 -4
@@ -458,7 +458,7 @@ static void net_complete_free(void) } -static void net_free (struct net *net) +void net_passive_dec (struct net *net) {if (refcount_dec_and_test (&net->passive)) {kfree (rcu_access_pointer (net->gen));
@@ -476,7 +476,7 @@ void net_drop_ns(void *p)struct net *net = (struct net *)p;if (net) -net_free (net); +net_passive_dec (net); } struct net *copy_net_ns(unsigned long flags,
@@ -517,7 +517,7 @@ put_userns:key_remove_domain (net->key_domain);#endif put_user_ns (user_ns); -net_free (net); +net_passive_dec (net); dec_ucounts:dec_net_namespaces (ucounts);return ERR_PTR (rv);
@@ -662,7 +662,7 @@ static void cleanup_net(struct work_strukey_remove_domain (net->key_domain);#endif put_user_ns (net->user_ns); -net_free (net); +net_passive_dec (net); } }
Greg Kroah-Hartman
maintainerPATCH 428/444 net: better track kernel sockets lifetime
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 5c70eb5c593d64d93b178905da215a9fd288a4b5 ]
While kernel sockets are dismantled during pernet_operations->exit(), their freeing can be delayed by any tx packets still held in qdisc or device queues, due to skb_set_owner_w() prior calls.
This then trigger the following warning from ref_tracker_dir_exit() [1]
To fix this, make sure that kernel sockets own a reference on net->passive.
Add sk_net_refcnt_upgrade() helper, used whenever a kernel socket is converted to a refcounted one.
[1]
[ 136.263918][ T35] ref_tracker: net notrefcnt@ffff8880638f01e0 has 1/2 users at [ 136.263918][ T35] sk_alloc+0x2b3/0x370 [ 136.263918][ T35] inet6_create+0x6ce/0x10f0 [ 136.263918][ T35] __sock_create+0x4c0/0xa30 [ 136.263918][ T35] inet_ctl_sock_create+0xc2/0x250 [ 136.263918][ T35] igmp6_net_init+0x39/0x390 [ 136.263918][ T35] ops_init+0x31e/0x590 [ 136.263918][ T35] setup_net+0x287/0x9e0 [ 136.263918][ T35] copy_net_ns+0x33f/0x570 [ 136.263918][ T35] create_new_namespaces+0x425/0x7b0 [ 136.263918][ T35] unshare_nsproxy_namespaces+0x124/0x180 [ 136.263918][ T35] ksys_unshare+0x57d/0xa70 [ 136.263918][ T35] __x64_sys_unshare+0x38/0x40 [ 136.263918][ T35] do_syscall_64+0xf3/0x230 [ 136.263918][ T35] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 136.263918][ T35] [ 136.343488][ T35] ref_tracker: net notrefcnt@ffff8880638f01e0 has 1/2 users at [ 136.343488][ T35] sk_alloc+0x2b3/0x370 [ 136.343488][ T35] inet6_create+0x6ce/0x10f0 [ 136.343488][ T35] __sock_create+0x4c0/0xa30 [ 136.343488][ T35] inet_ctl_sock_create+0xc2/0x250 [ 136.343488][ T35] ndisc_net_init+0xa7/0x2b0 [ 136.343488][ T35] ops_init+0x31e/0x590 [ 136.343488][ T35] setup_net+0x287/0x9e0 [ 136.343488][ T35] copy_net_ns+0x33f/0x570 [ 136.343488][ T35] create_new_namespaces+0x425/0x7b0 [ 136.343488][ T35] unshare_nsproxy_namespaces+0x124/0x180 [ 136.343488][ T35] ksys_unshare+0x57d/0xa70 [ 136.343488][ T35] __x64_sys_unshare+0x38/0x40 [ 136.343488][ T35] do_syscall_64+0xf3/0x230 [ 136.343488][ T35] entry_SYSCALL_64_after_hwframe+0x77/0x7f
--- include/net/sock.h | 1 + net/core/sock.c | 27 ++++++++++++++++++++++----- net/mptcp/subflow.c | 5 +---- net/netlink/af_netlink.c | 10 ---------- net/rds/tcp.c | 8 ++------ net/smc/af_smc.c | 5 +---- net/sunrpc/svcsock.c | 5 +---- net/sunrpc/xprtsock.c | 8 ++------ 8 files changed, 30 insertions(+), 39 deletions(-)
include/net/sock.h +1 -0
@@ -1780,6 +1780,7 @@ static inline bool sock_allow_reclassifistruct sock *sk_alloc (struct net *net,int family,gfp_t priority,struct proto *prot,int kern);void sk_free (struct sock *sk); +void sk_net_refcnt_upgrade (struct sock *sk);void sk_destruct (struct sock *sk);struct sock *sk_clone_lock (const struct sock *sk,const gfp_t priority);void sk_free_unlock_clone (struct sock *sk);
net/core/sock.c +22 -5
@@ -2243,6 +2243,7 @@ struct sock *sk_alloc(struct net *net, iget_net_track (net, &sk->ns_tracker, priority);sock_inuse_add (net,1 ); }else { +net_passive_inc (net);__netns_tracker_alloc (net, &sk->ns_tracker, false, priority); }
@@ -2267,6 +2268,7 @@ EXPORT_SYMBOL(sk_alloc);static void __sk_destruct (struct rcu_head *head) { struct sock *sk = container_of(head, struct sock, sk_rcu); +struct net *net =sock_net (sk);struct sk_filter *filter;if (sk->sk_destruct)
@@ -2298,14 +2300,28 @@ static void __sk_destruct(struct rcu_heaput_cred (sk->sk_peer_cred);put_pid (sk->sk_peer_pid); -if (likely (sk->sk_net_refcnt)) -put_net_track (sock_net (sk), &sk->ns_tracker); -else -__netns_tracker_free (sock_net (sk), &sk->ns_tracker, false); - +if (likely (sk->sk_net_refcnt)) { +put_net_track (net, &sk->ns_tracker); + }else { +__netns_tracker_free (net, &sk->ns_tracker, false); +net_passive_dec (net); + }sk_prot_free (sk->sk_prot_creator, sk); } +void sk_net_refcnt_upgrade (struct sock *sk) +{ +struct net *net =sock_net (sk); + +WARN_ON_ONCE (sk->sk_net_refcnt); +__netns_tracker_free (net, &sk->ns_tracker, false); +net_passive_dec (net); + sk->sk_net_refcnt =1 ; +get_net_track (net, &sk->ns_tracker,GFP_KERNEL ); +sock_inuse_add (net,1 ); +} +EXPORT_SYMBOL_GPL (sk_net_refcnt_upgrade); +void sk_destruct (struct sock *sk) {bool use_call_rcu =sock_flag (sk,SOCK_RCU_FREE );
@@ -2402,6 +2418,7 @@ struct sock *sk_clone_lock(const struct* is not properly dismantling its kernel sockets at netns * destroy time. */ +net_passive_inc (sock_net (newsk));__netns_tracker_alloc (sock_net (newsk), &newsk->ns_tracker, false, priority); }
net/mptcp/subflow.c +1 -4
@@ -1768,10 +1768,7 @@ int mptcp_subflow_create_socket(struct s* needs it. * Update ns_tracker to current stack trace and refcounted tracker. */ -__netns_tracker_free (net, &sf->sk->ns_tracker, false); - sf->sk->sk_net_refcnt =1 ; -get_net_track (net, &sf->sk->ns_tracker,GFP_KERNEL ); -sock_inuse_add (net,1 ); +sk_net_refcnt_upgrade (sf->sk); err =tcp_set_ulp (sf->sk,"mptcp" );if (err) goto err_free;
net/netlink/af_netlink.c +0 -10
@@ -794,16 +794,6 @@ static int netlink_release(struct socketsock_prot_inuse_add (sock_net (sk), &netlink_proto,-1 ); -/* Because struct net might disappear soon, do not keep a pointer. */ -if (!sk->sk_net_refcnt &&sock_net (sk) != &init_net) { -__netns_tracker_free (sock_net (sk), &sk->ns_tracker, false); -/* Because of deferred_put_nlk_sk and use of work queue, -* it is possible netns will be freed before this socket. -*/ -sock_net_set (sk, &init_net); -__netns_tracker_alloc (&init_net, &sk->ns_tracker, - false,GFP_KERNEL ); - }call_rcu (&nlk->rcu, deferred_put_nlk_sk);return 0 ; }
net/rds/tcp.c +2 -6
@@ -504,12 +504,8 @@ bool rds_tcp_tune(struct socket *sock)release_sock (sk);return false; } -/* Update ns_tracker to current stack trace and refcounted tracker */ -__netns_tracker_free (net, &sk->ns_tracker, false); - - sk->sk_net_refcnt =1 ; -netns_tracker_alloc (net, &sk->ns_tracker,GFP_KERNEL ); -sock_inuse_add (net,1 ); +sk_net_refcnt_upgrade (sk); +put_net (net); } rtn =net_generic (net, rds_tcp_netid);if (rtn->sndbuf_size >0 ) {
net/smc/af_smc.c +1 -4
@@ -3353,10 +3353,7 @@ int smc_create_clcsk(struct net *net, st* which need net ref. */ sk = smc->clcsock->sk; -__netns_tracker_free (net, &sk->ns_tracker, false); - sk->sk_net_refcnt =1 ; -get_net_track (net, &sk->ns_tracker,GFP_KERNEL ); -sock_inuse_add (net,1 ); +sk_net_refcnt_upgrade (sk);return 0 ; }
net/sunrpc/svcsock.c +1 -4
@@ -1568,10 +1568,7 @@ static struct svc_xprt *svc_create_socke newlen = error;if (protocol ==IPPROTO_TCP ) { -__netns_tracker_free (net, &sock->sk->ns_tracker, false); - sock->sk->sk_net_refcnt =1 ; -get_net_track (net, &sock->sk->ns_tracker,GFP_KERNEL ); -sock_inuse_add (net,1 ); +sk_net_refcnt_upgrade (sock->sk);if ((error =kernel_listen (sock,64 )) <0 ) goto bummer; }
net/sunrpc/xprtsock.c +2 -6
@@ -1960,12 +1960,8 @@ static struct socket *xs_create_sock(str goto out; } -if (protocol ==IPPROTO_TCP ) { -__netns_tracker_free (xprt->xprt_net, &sock->sk->ns_tracker, false); - sock->sk->sk_net_refcnt =1 ; -get_net_track (xprt->xprt_net, &sock->sk->ns_tracker,GFP_KERNEL ); -sock_inuse_add (xprt->xprt_net,1 ); - } +if (protocol ==IPPROTO_TCP ) +sk_net_refcnt_upgrade (sock->sk); filp =sock_alloc_file (sock,O_NONBLOCK ,NULL );if (IS_ERR (filp))
Greg Kroah-Hartman
maintainerPATCH 429/444 smb: client: fix netns refcount leak after net_passive changes
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Zhaolong <[email protected]>
[ Upstream commit 59b33fab4ca4d7dacc03367082777627e05d0323 ]
After commit 5c70eb5c593d ("net: better track kernel sockets lifetime"), kernel sockets now use net_passive reference counting. However, commit 95d2b9f693ff ("Revert "smb: client: fix TCP timers deadlock after rmmod"") restored the manual socket refcount manipulation without adapting to this new mechanism, causing a memory leak.
The issue can be reproduced by[1]:
1. Creating a network namespace
2. Mounting and Unmounting CIFS within the namespace
3. Deleting the namespace
Some memory leaks may appear after a period of time following step 3.
unreferenced object 0xffff9951419f6b00 (size 256):
comm "ip", pid 447, jiffies 4294692389 (age 14.730s) hex dump (first 32 bytes):
1b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 80 77 c2 44 51 99 ff ff .........w.DQ...
backtrace:
__kmem_cache_alloc_node+0x30e/0x3d0
__kmalloc+0x52/0x120
net_alloc_generic+0x1d/0x30
copy_net_ns+0x86/0x200
create_new_namespaces+0x117/0x300
unshare_nsproxy_namespaces+0x60/0xa0
ksys_unshare+0x148/0x360
__x64_sys_unshare+0x12/0x20
do_syscall_64+0x59/0x110
entry_SYSCALL_64_after_hwframe+0x78/0xe2...
unreferenced object 0xffff9951442e7500 (size 32):
comm "mount.cifs", pid 475, jiffies 4294693782 (age 13.343s) hex dump (first 32 bytes):
40 c5 38 46 51 99 ff ff 18 01 96 42 51 99 ff ff @.8FQ......BQ...
01 00 00 00 6f 00 c5 07 6f 00 d8 07 00 00 00 00 ....o...o.......
backtrace:
__kmem_cache_alloc_node+0x30e/0x3d0
kmalloc_trace+0x2a/0x90
ref_tracker_alloc+0x8e/0x1d0
sk_alloc+0x18c/0x1c0
inet_create+0xf1/0x370
__sock_create+0xd7/0x1e0
generic_ip_connect+0x1d4/0x5a0 [cifs]
cifs_get_tcp_session+0x5d0/0x8a0 [cifs]
cifs_mount_get_session+0x47/0x1b0 [cifs]
dfs_mount_share+0xfa/0xa10 [cifs]
cifs_mount+0x68/0x2b0 [cifs]
cifs_smb3_do_mount+0x10b/0x760 [cifs]
smb3_get_tree+0x112/0x2e0 [cifs]
vfs_get_tree+0x29/0xf0
path_mount+0x2d4/0xa00
__se_sys_mount+0x165/0x1d0Root cause:
When creating kernel sockets, sk_alloc() calls net_passive_inc() for sockets with sk_net_refcnt=0. The CIFS code manually converts kernel sockets to user sockets by setting sk_net_refcnt=1, but doesn't call the corresponding net_passive_dec(). This creates an imbalance in the net_passive counter, which prevents the network namespace from being destroyed when its last user reference is dropped. As a result, the entire namespace and all its associated resources remain allocated.
Timeline of patches leading to this issue:
- commit ef7134c7fc48 ("smb: client: Fix use-after-free of network namespace.") in v6.12 fixed the original netns UAF by manually managing socket refcounts
- commit e9f2517a3e18 ("smb: client: fix TCP timers deadlock after rmmod") in v6.13 attempted to use kernel sockets but introduced TCP timer issues
- commit 5c70eb5c593d ("net: better track kernel sockets lifetime") in v6.14-rc5 introduced the net_passive mechanism with sk_net_refcnt_upgrade() for proper socket conversion
- commit 95d2b9f693ff ("Revert "smb: client: fix TCP timers deadlock after rmmod"") in v6.15-rc3 reverted to manual refcount management without adapting to the new net_passive changes
Fix this by using sk_net_refcnt_upgrade() which properly handles the net_passive counter when converting kernel sockets to user sockets.
--- fs/smb/client/connect.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
fs/smb/client/connect.c +3 -6
@@ -3165,18 +3165,15 @@ generic_ip_connect(struct TCP_Server_Infstruct net *net =cifs_net_ns (server);struct sock *sk; - rc =__sock_create (net, sfamily,SOCK_STREAM , -IPPROTO_TCP , &server->ssocket,1 ); + rc =sock_create_kern (net, sfamily,SOCK_STREAM , +IPPROTO_TCP , &server->ssocket);if (rc <0 ) {cifs_server_dbg (VFS ,"Error %d creating socket\n" , rc);return rc; } sk = server->ssocket->sk; -__netns_tracker_free (net, &sk->ns_tracker, false); - sk->sk_net_refcnt =1 ; -get_net_track (net, &sk->ns_tracker,GFP_KERNEL ); -sock_inuse_add (net,1 ); +sk_net_refcnt_upgrade (sk);/* BB other socket options to set KEEPALIVE, NODELAY? */ cifs_dbg (FYI ,"Socket created\n" );
Re: [PATCH 6.12 429/444] smb: client: fix netns refcount leak after net_passive changes
Quoted 16 lines
Timeline of patches leading to this issue:
- commitef7134c7fc48("smb: client: Fix use-after-free of network namespace.") in v6.12 fixed the original netns UAF by manually managing socket refcounts
- commite9f2517a3e18("smb: client: fix TCP timers deadlock after rmmod") in v6.13 attempted to use kernel sockets but introduced TCP timer issues
- commit5c70eb5c593d("net: better track kernel sockets lifetime") in v6.14-rc5 introduced thenet_passivemechanism withsk_net_refcnt_upgrade()for proper socket conversion
- commit95d2b9f693ff("Revert "smb: client: fix TCP timers deadlock after rmmod"") in v6.15-rc3 reverted to manual refcount management without adapting to the newnet_passivechanges
Hi Greg,
This patch depends on the preceding patch 5c70eb5c593d ("net: better track kernel sockets lifetime").
I have noticed that version 6.12.y has not imported this patch, so I believe it should not be merged.
Best regards,
Wang Zhaolong
Greg Kroah-Hartman
maintainerRe: [PATCH 6.12 429/444] smb: client: fix netns refcount leak after net_passive changes
Quoted 18 lines · Wang Zhaolong
Quoted 16 lines
Timeline of patches leading to this issue:
- commitef7134c7fc48("smb: client: Fix use-after-free of network namespace.") in v6.12 fixed the original netns UAF by manually managing socket refcounts
- commite9f2517a3e18("smb: client: fix TCP timers deadlock after rmmod") in v6.13 attempted to use kernel sockets but introduced TCP timer issues
- commit5c70eb5c593d("net: better track kernel sockets lifetime") in v6.14-rc5 introduced thenet_passivemechanism withsk_net_refcnt_upgrade()for proper socket conversion
- commit95d2b9f693ff("Revert "smb: client: fix TCP timers deadlock after rmmod"") in v6.15-rc3 reverted to manual refcount management without adapting to the newnet_passivechanges
Quoted 7 lines
Hi Greg,
This patch depends on the preceding patch
5c70eb5c593d("net: better track kernel sockets lifetime").I have noticed that version 6.12.y has not imported this patch, so I believe it should not be merged.
This is in the 6.12-rc release as well, so all should be good.
thanks,
greg k-h
Greg Kroah-Hartman
maintainerPATCH 430/444 PCI: Store all PCIe Supported Link Speeds
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo J�rvinen <[email protected]>
[ Upstream commit d2bd39c0456b75be9dfc7d774b8d021355c26ae3 ]
The PCIe bandwidth controller added by a subsequent commit will require selecting PCIe Link Speeds that are lower than the Maximum Link Speed.
The struct pci_bus only stores max_bus_speed. Even if PCIe r6.1 sec 8.2.1 currently disallows gaps in supported Link Speeds, the Implementation Note in PCIe r6.1 sec 7.5.3.18, recommends determining supported Link Speeds using the Supported Link Speeds Vector in the Link Capabilities 2 Register (when available) to "avoid software being confused if a future specification defines Links that do not require support for all slower speeds."
Reuse code in pcie_get_speed_cap() to add pcie_get_supported_speeds() to query the Supported Link Speeds Vector of a PCIe device. The value is taken directly from the Supported Link Speeds Vector or synthesized from the Max Link Speed in the Link Capabilities Register when the Link Capabilities 2 Register is not available.
The Supported Link Speeds Vector in the Link Capabilities Register 2 corresponds to the bus below on Root Ports and Downstream Ports, whereas it corresponds to the bus above on Upstream Ports and Endpoints (PCIe r6.1 sec 7.5.3.18):
Supported Link Speeds Vector - This field indicates the supported Link speed(s) of the associated Port.
Add supported_speeds into the struct pci_dev that caches the Supported Link Speeds Vector.
supported_speeds contains a set of Link Speeds only in the case where PCIe Link Speed can be determined. Root Complex Integrated Endpoints do not have a well-defined Link Speed because they do not implement either of the Link Capabilities Registers, which is allowed by PCIe r6.1 sec 7.5.3 (the same limitation applies to determining cur_bus_speed and max_bus_speed that are PCI_SPEED_UNKNOWN in such case). This is of no concern from PCIe bandwidth controller point of view because such devices are not attached into a PCIe Root Port that could be controlled.
The supported_speeds field keeps the extra reserved zero at the least significant bit to match the Link Capabilities 2 Register layout.
An attempt was made to store supported_speeds field into the struct pci_bus as an intersection of both ends of the Link, however, the subordinate struct pci_bus is not available early enough. The Target Speed quirk (in pcie_failed_link_retrain()) can run either during initial scan or later, requiring it to use the API provided by the PCIe bandwidth controller to set the Target Link Speed in order to co-exist with the bandwidth controller. When the Target Speed quirk is calling the bandwidth controller during initial scan, the struct pci_bus is not yet initialized. As such, storing supported_speeds into the struct pci_bus is not viable.
Stable-dep-of: 6cff20ce3b92 ("PCI/ACPI: Fix runtime PM ref imbalance on Hot-Plug Capable ports")
--- drivers/pci/pci.c | 58 ++++++++++++++++++++++++++++++------------ drivers/pci/pci.h | 1 drivers/pci/probe.c | 3 ++ include/linux/pci.h | 10 ++++++- include/uapi/linux/pci_regs.h | 1 5 files changed, 56 insertions(+), 17 deletions(-)
drivers/pci/pci.c +42 -16
@@ -6199,38 +6199,64 @@ u32 pcie_bandwidth_available(struct pci_EXPORT_SYMBOL (pcie_bandwidth_available);/** -* pcie_get_speed_cap - query for the PCI device's link speed capability +* pcie_get_supported_speeds - query Supported Link Speed Vector * @dev: PCI device to query * -* Query the PCI device speed capability. Return the maximum link speed -* supported by the device. +* Query @dev supported link speeds. +* +* Implementation Note in PCIe r6.0 sec 7.5.3.18 recommends determining +* supported link speeds using the Supported Link Speeds Vector in the Link +* Capabilities 2 Register (when available). +* +* Link Capabilities 2 was added in PCIe r3.0, sec 7.8.18. +* +* Without Link Capabilities 2, i.e., prior to PCIe r3.0, Supported Link +* Speeds field in Link Capabilities is used and only 2.5 GT/s and 5.0 GT/s +* speeds were defined. +* +* For @dev without Supported Link Speed Vector, the field is synthesized +* from the Max Link Speed field in the Link Capabilities Register. +* +* Return: Supported Link Speeds Vector (+ reserved 0 at LSB). */ -enum pci_bus_speed pcie_get_speed_cap (struct pci_dev *dev) +u8 pcie_get_supported_speeds (struct pci_dev *dev) {u32 lnkcap2, lnkcap; +u8 speeds;/* -* Link Capabilities 2 was added in PCIe r3.0, sec 7.8.18. The -* implementation note there recommends using the Supported Link -* Speeds Vector in Link Capabilities 2 when supported. -* -* Without Link Capabilities 2, i.e., prior to PCIe r3.0, software -* should use the Supported Link Speeds field in Link Capabilities, -* where only 2.5 GT/s and 5.0 GT/s speeds were defined. +* Speeds retain the reserved 0 at LSB before PCIe Supported Link +* Speeds Vector to allow using SLS Vector bit defines directly. */ pcie_capability_read_dword (dev,PCI_EXP_LNKCAP2 , &lnkcap2); + speeds = lnkcap2 &PCI_EXP_LNKCAP2_SLS ;/* PCIe r3.0-compliant */ -if (lnkcap2) -return PCIE_LNKCAP2_SLS2SPEED (lnkcap2); +if (speeds) +return speeds;pcie_capability_read_dword (dev,PCI_EXP_LNKCAP , &lnkcap); + +/* Synthesize from the Max Link Speed field */ if ((lnkcap &PCI_EXP_LNKCAP_SLS ) ==PCI_EXP_LNKCAP_SLS_5_0GB ) -return PCIE_SPEED_5_0GT ; + speeds =PCI_EXP_LNKCAP2_SLS_5_0GB |PCI_EXP_LNKCAP2_SLS_2_5GB ;else if ((lnkcap &PCI_EXP_LNKCAP_SLS ) ==PCI_EXP_LNKCAP_SLS_2_5GB ) -return PCIE_SPEED_2_5GT ; + speeds =PCI_EXP_LNKCAP2_SLS_2_5GB ; + +return speeds; +} -return PCI_SPEED_UNKNOWN ; +/** +* pcie_get_speed_cap - query for the PCI device's link speed capability +* @dev: PCI device to query +* +* Query the PCI device speed capability. +* +* Return: the maximum link speed supported by the device. +*/ +enum pci_bus_speed pcie_get_speed_cap (struct pci_dev *dev) +{ +return PCIE_LNKCAP2_SLS2SPEED (dev->supported_speeds); }EXPORT_SYMBOL (pcie_get_speed_cap);
drivers/pci/pci.h +1 -0
@@ -390,6 +390,7 @@ static inline int pcie_dev_speed_mbps(enreturn -EINVAL ; } +u8 pcie_get_supported_speeds (struct pci_dev *dev);const char *pci_speed_string (enum pci_bus_speed speed);enum pci_bus_speed pcie_get_speed_cap (struct pci_dev *dev);enum pcie_link_width pcie_get_width_cap (struct pci_dev *dev);
drivers/pci/probe.c +3 -0
@@ -1972,6 +1972,9 @@ int pci_setup_device(struct pci_dev *devset_pcie_untrusted (dev); +if (pci_is_pcie (dev)) + dev->supported_speeds =pcie_get_supported_speeds (dev); +/* "Unknown power state" */ dev->current_state =PCI_UNKNOWN ;
include/linux/pci.h +9 -1
@@ -320,7 +320,14 @@ struct pci_sriov;struct pci_p2pdma ;struct rcec_ea ; -/* The pci_dev structure describes PCI devices */ +/* struct pci_dev - describes a PCI device +* +* @supported_speeds: PCIe Supported Link Speeds Vector (+ reserved 0 at +* LSB). 0 when the supported speeds cannot be +* determined (e.g., for Root Complex Integrated +* Endpoints without the relevant Capability +* Registers). +*/ struct pci_dev {struct list_head bus_list;/* Node in per-bus list */ struct pci_bus *bus;/* Bus this device is on */
@@ -524,6 +531,7 @@ struct pci_dev {struct npem *npem;/* Native PCIe Enclosure Management */ #endif u16 acs_cap;/* ACS Capability offset */ +u8 supported_speeds;/* Supported Link Speeds Vector */ phys_addr_t rom;/* Physical address if not from BAR */ size_t romlen;/* Length if not from BAR */ /*
include/uapi/linux/pci_regs.h +1 -0
@@ -678,6 +678,7 @@#define PCI_EXP_DEVSTA2 0x2a/* Device Status 2 */ #define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 0x2c/* end of v2 EPs w/o link */ #define PCI_EXP_LNKCAP2 0x2c/* Link Capabilities 2 */ +#define PCI_EXP_LNKCAP2_SLS 0x000000fe/* Supported Link Speeds Vector */ #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002/* Supported Speed 2.5GT/s */ #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004/* Supported Speed 5GT/s */ #define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008/* Supported Speed 8GT/s */
Greg Kroah-Hartman
maintainerPATCH 431/444 PCI: Allow PCI bridges to go to D3Hot on all non-x86
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manivannan Sadhasivam <[email protected]>
[ Upstream commit a5fb3ff632876d63ee1fc5ed3af2464240145a00 ]
Currently, pci_bridge_d3_possible() encodes a variety of decision factors when deciding whether a given bridge can be put into D3. A particular one of note is for "recent enough PCIe ports." Per Rafael [0]:
"There were hardware issues related to PM on x86 platforms predating
the introduction of Connected Standby in Windows. For instance, programming a port into D3hot by writing to its PMCSR might cause the PCIe link behind it to go down and the only way to revive it was to power cycle the Root Complex. And similar."
Thus, this function contains a DMI-based check for post-2015 BIOS.
The above factors (Windows, x86) don't really apply to non-x86 systems, and also, many such systems don't have BIOS or DMI. However, we'd like to be able to suspend bridges on non-x86 systems too.
Restrict the "recent enough" check to x86. If we find further incompatibilities, it probably makes sense to expand on the deny-list approach (i.e., bridge_d3_blacklist or similar).
Stable-dep-of: 6cff20ce3b92 ("PCI/ACPI: Fix runtime PM ref imbalance on Hot-Plug Capable ports")
--- drivers/pci/pci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/pci/pci.c +4 -4
@@ -3024,7 +3024,7 @@ static const struct dmi_system_id bridge* @bridge: Bridge to check * * This function checks if it is possible to move the bridge to D3. -* Currently we only allow D3 for recent enough PCIe ports and Thunderbolt. +* Currently we only allow D3 for some PCIe ports and for Thunderbolt. */ bool pci_bridge_d3_possible (struct pci_dev *bridge) {
@@ -3068,10 +3068,10 @@ bool pci_bridge_d3_possible(struct pci_dreturn false;/* -* It should be safe to put PCIe ports from 2015 or newer -* to D3. +* Out of caution, we only allow PCIe ports from 2015 or newer +* into D3 on x86. */ -if (dmi_get_bios_year () >=2015 ) +if (!IS_ENABLED (CONFIG_X86 ) ||dmi_get_bios_year () >=2015 )return true;break ; }
Greg Kroah-Hartman
maintainerPATCH 432/444 PCI/ACPI: Fix runtime PM ref imbalance on Hot-Plug Capable ports
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner <[email protected]>
[ Upstream commit 6cff20ce3b92ffbf2fc5eb9e5a030b3672aa414a ]
pci_bridge_d3_possible() is called from both pcie_portdrv_probe() and pcie_portdrv_remove() to determine whether runtime power management shall be enabled (on probe) or disabled (on remove) on a PCIe port.
The underlying assumption is that pci_bridge_d3_possible() always returns the same value, else a runtime PM reference imbalance would occur. That assumption is not given if the PCIe port is inaccessible on remove due to
hot-unplug: pci_bridge_d3_possible() calls pciehp_is_native(), which accesses Config Space to determine whether the port is Hot-Plug Capable. An inaccessible port returns "all ones", which is converted to "all zeroes" by pcie_capability_read_dword(). Hence the port no longer seems Hot-Plug Capable on remove even though it was on probe.
The resulting runtime PM ref imbalance causes warning messages such as:
pcieport 0000:02:04.0: Runtime PM usage count underflow!
Avoid the Config Space access (and thus the runtime PM ref imbalance) by caching the Hot-Plug Capable bit in struct pci_dev.
The struct already contains an "is_hotplug_bridge" flag, which however is not only set on Hot-Plug Capable PCIe ports, but also Conventional PCI Hot-Plug bridges and ACPI slots. The flag identifies bridges which are allocated additional MMIO and bus number resources to allow for hierarchy expansion.
The kernel is somewhat sloppily using "is_hotplug_bridge" in a number of places to identify Hot-Plug Capable PCIe ports, even though the flag encompasses other devices. Subsequent commits replace these occurrences with the new flag to clearly delineate Hot-Plug Capable PCIe ports from other kinds of hotplug bridges.
Document the existing "is_hotplug_bridge" and the new "is_pciehp" flag and document the (non-obvious) requirement that pci_bridge_d3_possible() always returns the same value across the entire lifetime of a bridge, including its hot-removal.
--- drivers/pci/pci-acpi.c | 4 +--- drivers/pci/pci.c | 6 +++++- drivers/pci/probe.c | 2 +- include/linux/pci.h | 6 ++++++ 4 files changed, 13 insertions(+), 5 deletions(-)
drivers/pci/pci-acpi.c +1 -3
@@ -816,13 +816,11 @@ int pci_acpi_program_hp_params(struct pcbool pciehp_is_native (struct pci_dev *bridge) {const struct pci_host_bridge *host; -u32 slot_cap;if (!IS_ENABLED (CONFIG_HOTPLUG_PCI_PCIE ))return false; -pcie_capability_read_dword (bridge,PCI_EXP_SLTCAP , &slot_cap); -if (!(slot_cap &PCI_EXP_SLTCAP_HPC )) +if (!bridge->is_pciehp)return false;if (pcie_ports_native)
drivers/pci/pci.c +5 -1
@@ -3023,8 +3023,12 @@ static const struct dmi_system_id bridge* pci_bridge_d3_possible - Is it possible to put the bridge into D3 * @bridge: Bridge to check * -* This function checks if it is possible to move the bridge to D3. * Currently we only allow D3 for some PCIe ports and for Thunderbolt. +* +* Return: Whether it is possible to move the bridge to D3. +* +* The return value is guaranteed to be constant across the entire lifetime +* of the bridge, including its hot-removal. */ bool pci_bridge_d3_possible (struct pci_dev *bridge) {
drivers/pci/probe.c +1 -1
@@ -1627,7 +1627,7 @@ void set_pcie_hotplug_bridge(struct pci_pcie_capability_read_dword (pdev,PCI_EXP_SLTCAP , ®32);if (reg32 &PCI_EXP_SLTCAP_HPC ) - pdev->is_hotplug_bridge =1 ; + pdev->is_hotplug_bridge = pdev->is_pciehp =1 ; }static void set_pcie_thunderbolt (struct pci_dev *dev)
include/linux/pci.h +6 -0
@@ -327,6 +327,11 @@ struct rcec_ea;* determined (e.g., for Root Complex Integrated * Endpoints without the relevant Capability * Registers). +* @is_hotplug_bridge: Hotplug bridge of any kind (e.g. PCIe Hot-Plug Capable, +* Conventional PCI Hot-Plug, ACPI slot). +* Such bridges are allocated additional MMIO and bus +* number resources to allow for hierarchy expansion. +* @is_pciehp: PCIe Hot-Plug Capable bridge. */ struct pci_dev {struct list_head bus_list;/* Node in per-bus list */
@@ -450,6 +455,7 @@ struct pci_dev { unsigned int is_physfn:1; unsigned int is_virtfn:1; unsigned int is_hotplug_bridge:1; + unsigned int is_pciehp:1; unsigned int shpc_managed:1; /* SHPC owned by shpchp */ unsigned int is_thunderbolt:1; /* Thunderbolt controller *//*
Greg Kroah-Hartman
maintainerPATCH 433/444 arm64: dts: ti: k3-j722s-evm: Fix USB2.0_MUX_SEL to select Type-C
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hrushikesh Salunke <[email protected]>
[ Upstream commit bc8d9e6b5821c40ab5dd3a81e096cb114939de50 ]
J722S SOC has two usb controllers USB0 and USB1. USB0 is brought out on the EVM as a stacked USB connector which has one Type-A and one Type-C port. These Type-A and Type-C ports are connected to MUX so only one of them can be enabled at a time.
Commit under Fixes, tries to enable the USB0 instance of USB to interface with the Type-C port via the USB hub, by configuring the USB2.0_MUX_SEL to GPIO_ACTIVE_HIGH. But it is observed on J722S-EVM that Type-A port is enabled instead of Type-C port.
Fix this by setting USB2.0_MUX_SEL to GPIO_ACTIVE_LOW to enable Type-C port.
Stable-dep-of: 65ba2a6e77e9 ("arm64: dts: ti: k3-j722s-evm: Fix USB gpio-hog level for Type-C")
--- arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/ti/k3-j722s-evm.dts +1 -1
@@ -495,7 +495,7 @@ p05-hog { /* P05 - USB2.0_MUX_SEL */ gpio-hog; - gpios = <5 GPIO_ACTIVE_HIGH>; + gpios = <5 GPIO_ACTIVE_LOW>; output-high; };
Greg Kroah-Hartman
maintainerPATCH 434/444 arm64: dts: ti: k3-j722s-evm: Fix USB gpio-hog level for Type-C
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Siddharth Vadapalli <[email protected]>
[ Upstream commit 65ba2a6e77e9e5c843a591055789050e77b5c65e ]
According to the "GPIO Expander Map / Table" section of the J722S EVM Schematic within the Evaluation Module Design Files package [0], the GPIO Pin P05 located on the GPIO Expander 1 (I2C0/0x23) has to be pulled down to select the Type-C interface. Since commit under Fixes claims to enable the Type-C interface, update the property within "p05-hog" from "output-high" to "output-low", thereby switching from the Type-A interface to the Type-C interface.
[0]: https://www.ti.com/lit/zip/sprr495
--- arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/ti/k3-j722s-evm.dts +1 -1
@@ -496,7 +496,7 @@ /* P05 - USB2.0_MUX_SEL */ gpio-hog; gpios = <5 GPIO_ACTIVE_LOW>; - output-high; + output-low; }; p01_hog: p01-hog {
Greg Kroah-Hartman
maintainerPATCH 435/444 rust: kbuild: clean output before running `rustdoc`
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit 252fea131e15aba2cd487119d1a8f546471199e2 upstream.
rustdoc can get confused when generating documentation into a folder that contains generated files from other rustdoc versions.
For instance, running something like:
rustup default 1.78.0
make LLVM=1 rustdoc
rustup default 1.88.0
make LLVM=1 rustdoc
may generate errors like:
error: couldn't generate documentation: invalid template: last line expected to start with a comment
|
= note: failed to create or modify "./Documentation/output/rust/rustdoc/src-files.js"
Thus just always clean the output folder before generating the documentation -- we are anyway regenerating it every time the rustdoc target gets called, at least for the time being.
--- rust/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
rust/Makefile +5 -2
@@ -92,14 +92,14 @@ rustdoc: rustdoc-core rustdoc-macros rus rustdoc-macros: private rustdoc_host = yes rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \ --extern proc_macro -rustdoc-macros: $(src)/macros/lib.rs FORCE +rustdoc-macros: $(src)/macros/lib.rs rustdoc-clean FORCE +$(call if_changed,rustdoc) # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should # not be needed -- see https://github.com/rust-lang/rust/pull/128307. rustdoc-core: private skip_flags = --edition=2021 -Wrustdoc::unescaped_backticks rustdoc-core: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs) -rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE +rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs rustdoc-clean FORCE +$(call if_changed,rustdoc) rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE
@@ -116,6 +116,9 @@ rustdoc-kernel: $(src)/kernel/lib.rs rus $(obj)/bindings.o FORCE +$(call if_changed,rustdoc) +rustdoc-clean: FORCE + $(Q)rm -rf $(rustdoc_output) + quiet_cmd_rustc_test_library = RUSTC TL $< cmd_rustc_test_library = \ OBJTREE=$(abspath $(objtree)) \
Greg Kroah-Hartman
maintainerPATCH 436/444 rust: workaround `rustdoc` target modifiers bug
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit abbf9a44944171ca99c150adad9361a2f517d3b6 upstream.
Starting with Rust 1.88.0 (released 2025-06-26), rustdoc complains about a target modifier mismatch in configurations where -Zfixed-x18 is passed:
error: mixing -Zfixed-x18 will cause an ABI mismatch in crate rust_out
|
= help: the -Zfixed-x18 flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely = note: unset -Zfixed-x18 in this crate is incompatible with -Zfixed-x18= in dependency core
= help: set -Zfixed-x18= in this crate or unset -Zfixed-x18 in core
= help: if you are sure this will not cause problems, you may use -Cunsafe-allow-abi-mismatch=fixed-x18 to silence this error
The reason is that rustdoc was not passing the target modifiers when configuring the session options, and thus it would report a mismatch that did not exist as soon as a target modifier is used in a dependency.
We did not notice it in the kernel until now because -Zfixed-x18 has been a target modifier only since 1.88.0 (and it is the only one we use so far).
The issue has been reported upstream [1] and a fix has been submitted [2], including a test similar to the kernel case.
[ This is now fixed upstream (thanks Guillaume for the quick review),
so it will be fixed in Rust 1.90.0 (expected 2025-09-18).
- Miguel ]
Meanwhile, conditionally pass -Cunsafe-allow-abi-mismatch=fixed-x18 to workaround the issue on our side.
--- rust/Makefile | 6 ++++++ 1 file changed, 6 insertions(+)
rust/Makefile +6 -0
@@ -55,6 +55,10 @@ core-cfgs = \ core-edition := $(if $(call rustc-min-version,108700),2024,2021) +# `rustdoc` did not save the target modifiers, thus workaround for +# the time being (https://github.com/rust-lang/rust/issues/144521). +rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18) + quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< cmd_rustdoc = \ OBJTREE=$(abspath $(objtree)) \
@@ -63,6 +67,7 @@ quiet_cmd_rustdoc = RUSTDOC $(if $(rustd -Zunstable-options --generate-link-to-definition \ --output $(rustdoc_output) \ --crate-name $(subst rustdoc-,,$@) \ + $(rustdoc_modifiers_workaround) \ $(if $(rustdoc_host),,--sysroot=/dev/null) \ @$(objtree)/include/generated/rustc_cfg $<
@@ -178,6 +183,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC --extern bindings --extern uapi \ --no-run --crate-name kernel -Zunstable-options \ --sysroot=/dev/null \ + $(rustdoc_modifiers_workaround) \ --test-builder $(objtree)/scripts/rustdoc_test_builder \ $< $(rustdoc_test_kernel_quiet); \ $(objtree)/scripts/rustdoc_test_gen
Greg Kroah-Hartman
maintainerPATCH 437/444 ata: libata-sata: Add link_power_management_supported sysfs attribute
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
commit 0060beec0bfa647c4b510df188b1c4673a197839 upstream.
A port link power management (LPM) policy can be controlled using the link_power_management_policy sysfs host attribute. However, this attribute exists also for hosts that do not support LPM and in such case, attempting to change the LPM policy for the host (port) will fail with -EOPNOTSUPP.
Introduce the new sysfs link_power_management_supported host attribute to indicate to the user if a the port and the devices connected to the port for the host support LPM, which implies that the link_power_management_policy attribute can be used.
Since checking that a port and its devices support LPM is common between the new ata_scsi_lpm_supported_show() function and the existing ata_scsi_lpm_store() function, the new helper ata_scsi_lpm_supported() is introduced.
--- drivers/ata/ata_piix.c | 1 drivers/ata/libahci.c | 1 drivers/ata/libata-sata.c | 53 +++++++++++++++++++++++++++++++++++----------- include/linux/libata.h | 1 4 files changed, 44 insertions(+), 12 deletions(-)
drivers/ata/ata_piix.c +1 -0
@@ -1089,6 +1089,7 @@ static struct ata_port_operations ich_pa };static struct attribute *piix_sidpr_shost_attrs[] = { + &dev_attr_link_power_management_supported.attr, &dev_attr_link_power_management_policy.attr,NULL };
drivers/ata/libahci.c +1 -0
@@ -111,6 +111,7 @@ static DEVICE_ATTR(em_buffer, S_IWUSR | static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL);static struct attribute *ahci_shost_attrs[] = { + &dev_attr_link_power_management_supported.attr, &dev_attr_link_power_management_policy.attr, &dev_attr_em_message_type.attr, &dev_attr_em_message.attr,
drivers/ata/libata-sata.c +41 -12
75 lines not on this page · raw message
include/linux/libata.h +1 -0
@@ -547,6 +547,7 @@ typedef void (*ata_postreset_fn_t)(strucextern struct device_attribute dev_attr_unload_heads;#ifdef CONFIG_SATA_HOST +extern struct device_attribute dev_attr_link_power_management_supported;extern struct device_attribute dev_attr_link_power_management_policy;extern struct device_attribute dev_attr_ncq_prio_supported;extern struct device_attribute dev_attr_ncq_prio_enable;
Greg Kroah-Hartman
maintainerPATCH 438/444 io_uring/rw: cast rw->flags assignment to rwf_t
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
commit 825aea662b492571877b32aeeae13689fd9fbee4 upstream.
kernel test robot reports that a recent change of the sqe->rw_flags field throws a sparse warning on 32-bit archs:
Quoted 1 line
Quoted 1 line
io_uring/rw.c:291:19: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted__kernel_rwf_t[usertype] flags @@ got unsigned int @@
io_uring/rw.c:291:19: sparse: expected restricted __kernel_rwf_t [usertype] flags
io_uring/rw.c:291:19: sparse: got unsigned int
Force cast it to rwf_t to silence that new sparse warning.
--- io_uring/rw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
io_uring/rw.c +1 -1
@@ -282,7 +282,7 @@ static int io_prep_rw(struct io_kiocb *r rw->addr =READ_ONCE (sqe->addr); rw->len =READ_ONCE (sqe->len); - rw->flags =READ_ONCE (sqe->rw_flags); + rw->flags = (__force rwf_t )READ_ONCE (sqe->rw_flags);return io_prep_rw_setup (req, ddir, do_import); }
Greg Kroah-Hartman
maintainerPATCH 439/444 firmware: arm_scmi: Convert to SYSTEM_SLEEP_PM_OPS
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit 62d6b81e8bd207ad44eff39d1a0fe17f0df510a5 upstream.
The old SET_SYSTEM_SLEEP_PM_OPS() macro leads to a warning about an unused function:
| drivers/firmware/arm_scmi/scmi_power_control.c:363:12: error: | 'scmi_system_power_resume' defined but not used [-Werror=unused-function] | static int scmi_system_power_resume(struct device *dev)
The proper way to do this these days is to use SYSTEM_SLEEP_PM_OPS() and pm_sleep_ptr().
Message-Id: <[email protected]>
--- drivers/firmware/arm_scmi/scmi_power_control.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/firmware/arm_scmi/scmi_power_control.c +2 -2
@@ -369,7 +369,7 @@ static int scmi_system_power_resume(stru }static const struct dev_pm_ops scmi_system_power_pmops = { -SET_SYSTEM_SLEEP_PM_OPS (NULL , scmi_system_power_resume) +SYSTEM_SLEEP_PM_OPS (NULL , scmi_system_power_resume) };static const struct scmi_device_id scmi_id_table[] = {
@@ -380,7 +380,7 @@ MODULE_DEVICE_TABLE(scmi, scmi_id_table)static struct scmi_driver scmi_system_power_driver = { .driver = { - .pm = &scmi_system_power_pmops, + .pm =pm_sleep_ptr (&scmi_system_power_pmops), }, .name ="scmi-system-power" , .probe = scmi_syspower_probe,
Greg Kroah-Hartman
maintainerPATCH 440/444 drm/amd/display: Allow DCN301 to clear update flags
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Lipski <[email protected]>
commit 2d418e4fd9f1eca7dfce80de86dd702d36a06a25 upstream.
[Why & How]
Not letting DCN301 to clear after surface/stream update results in artifacts when switching between active overlay planes. The issue is known and has been solved initially. See below:
(https://gitlab.freedesktop.org/drm/amd/-/issues/3441)
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +2 -1
@@ -5121,7 +5121,8 @@ bool dc_update_planes_and_stream(structelse ret =update_planes_and_stream_v2 (dc, srf_updates, surface_count, stream, stream_update); -if (ret && dc->ctx->dce_version >=DCN_VERSION_3_2 ) +if (ret && (dc->ctx->dce_version >=DCN_VERSION_3_2 || + dc->ctx->dce_version ==DCN_VERSION_3_01 ))clear_update_flags (srf_updates, surface_count, stream);return ret;
Greg Kroah-Hartman
maintainerPATCH 441/444 md: fix create on open mddev lifetime regression
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
commit 1df1fc845d221eb646539836dbf509eb96b41afd upstream.
Commit 9e59d609763f ("md: call del_gendisk in control path") moves setting MD_DELETED from __mddev_put() to do_md_stop(), however, for the case create on open, mddev can be freed without do_md_stop():
1) open
md_probe
md_alloc_and_put
md_alloc
mddev_alloc
atomic_set(&mddev->active, 1);
mddev->hold_active = UNTIL_IOCTL
mddev_put
atomic_dec_and_test(&mddev->active)
if (mddev->hold_active)
-> active is 0, hold_active is setmd_open
mddev_get
atomic_inc(&mddev->active);
2) ioctl that is not STOP_ARRAY, for example, GET_ARRAY_INFO:
md_ioctl
mddev->hold_active = 0
3) close
md_release
mddev_put(mddev);
atomic_dec_and_lock(&mddev->active, &all_mddevs_lock) __mddev_put
-> hold_active is cleared, mddev will be freed queue_work(md_misc_wq, &mddev->del_work)
Now that MD_DELETED is not set, before mddev is freed by mddev_delayed_delete(), md_open can still succeed and break mddev lifetime, causing mddev->kobj refcount underflow or mddev uaf problem.
Fix this problem by setting MD_DELETED before queuing del_work.
--- drivers/md/md.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/md/md.c +6 -0
@@ -620,6 +620,12 @@ static void __mddev_put(struct mddev *mdreturn ;/* +* If array is freed by stopping array, MD_DELETED is set by +* do_md_stop(), MD_DELETED is still set here in case mddev is freed +* directly by closing a mddev that is created by create_on_open. +*/ +set_bit (MD_DELETED , &mddev->flags); +/* * Call queue_work inside the spinlock so that flush_workqueue() after * mddev_find will succeed in waiting for the work to be done. */
Greg Kroah-Hartman
maintainerPATCH 442/444 rcu: Fix racy re-initialization of irq_work causing hangs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frederic Weisbecker <[email protected]>
commit 61399e0c5410567ef60cb1cda34cca42903842e3 upstream.
RCU re-initializes the deferred QS irq work everytime before attempting to queue it. However there are situations where the irq work is attempted to be queued even though it is already queued. In that case re-initializing messes-up with the irq work queue that is about to be handled.
The chances for that to happen are higher when the architecture doesn't support self-IPIs and irq work are then all lazy, such as with the following sequence:
1) rcu_read_unlock() is called when IRQs are disabled and there is a grace period involving blocked tasks on the node. The irq work is then initialized and queued.
2) The related tasks are unblocked and the CPU quiescent state is reported. rdp->defer_qs_iw_pending is reset to DEFER_QS_IDLE, allowing the irq work to be requeued in the future (note the previous one hasn't fired yet).
3) A new grace period starts and the node has blocked tasks.
4) rcu_read_unlock() is called when IRQs are disabled again. The irq work is re-initialized (but it's queued! and its node is cleared) and requeued. Which means it's requeued to itself.
5) The irq work finally fires with the tick. But since it was requeued to itself, it loops and hangs.
Fix this with initializing the irq work only once before the CPU boots.
--- kernel/rcu/tree.c | 2 ++ kernel/rcu/tree.h | 1 + kernel/rcu/tree_plugin.h | 8 ++++++-- 3 files changed, 9 insertions(+), 2 deletions(-)
kernel/rcu/tree.c +2 -0
@@ -5027,6 +5027,8 @@ int rcutree_prepare_cpu(unsigned int cpu rdp->rcu_iw_gp_seq = rdp->gp_seq -1 ;trace_rcu_grace_period (rcu_state.name, rdp->gp_seq,TPS ("cpuonl" ));raw_spin_unlock_irqrestore_rcu_node (rnp, flags); + +rcu_preempt_deferred_qs_init (rdp);rcu_spawn_rnp_kthreads (rnp);rcu_spawn_cpu_nocb_kthread (cpu);ASSERT_EXCLUSIVE_WRITER (rcu_state.n_online_cpus);
kernel/rcu/tree.h +1 -0
@@ -487,6 +487,7 @@ static int rcu_print_task_exp_stall(strustatic void rcu_preempt_check_blocked_tasks (struct rcu_node *rnp);static void rcu_flavor_sched_clock_irq (int user);static void dump_blkd_tasks (struct rcu_node *rnp,int ncheck); +static void rcu_preempt_deferred_qs_init (struct rcu_data *rdp);static void rcu_initiate_boost (struct rcu_node *rnp,unsigned long flags);static void rcu_preempt_boost_start_gp (struct rcu_node *rnp);static bool rcu_is_callbacks_kthread (struct rcu_data *rdp);
kernel/rcu/tree_plugin.h +6 -2
@@ -698,8 +698,6 @@ static void rcu_read_unlock_special(stru cpu_online(rdp->cpu)) {// Get scheduler to re-evaluate and call hooks. // If !IRQ_WORK, FQS scan will eventually IPI. - rdp->defer_qs_iw = -IRQ_WORK_INIT_HARD (rcu_preempt_deferred_qs_handler); rdp->defer_qs_iw_pending =DEFER_QS_PENDING ;irq_work_queue_on (&rdp->defer_qs_iw, rdp->cpu); }
@@ -839,6 +837,10 @@ dump_blkd_tasks(struct rcu_node *rnp, in } } +static void rcu_preempt_deferred_qs_init (struct rcu_data *rdp) +{ + rdp->defer_qs_iw =IRQ_WORK_INIT_HARD (rcu_preempt_deferred_qs_handler); +}#else /* #ifdef CONFIG_PREEMPT_RCU */ /*
@@ -1038,6 +1040,8 @@ dump_blkd_tasks(struct rcu_node *rnp, in WARN_ON_ONCE(!list_empty(&rnp->blkd_tasks)); } +static void rcu_preempt_deferred_qs_init (struct rcu_data *rdp) { } +#endif /* #else #ifdef CONFIG_PREEMPT_RCU */ /*
Greg Kroah-Hartman
maintainerPATCH 443/444 dm: split write BIOs on zone boundaries when zone append is not emulated
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shin'ichiro Kawasaki <[email protected]>
commit 675f940576351bb049f5677615140b9d0a7712d0 upstream.
Commit 2df7168717b7 ("dm: Always split write BIOs to zoned device limits") updates the device-mapper driver to perform splits for the write BIOs. However, it did not address the cases where DM targets do not emulate zone append, such as in the cases of dm-linear or dm-flakey. For these targets, when the write BIOs span across zone boundaries, they trigger WARN_ON_ONCE(bio_straddles_zones(bio)) in blk_zone_wplug_handle_write(). This results in I/O errors. The errors are reproduced by running blktests test case zbd/004 using zoned dm-linear or dm-flakey devices.
To avoid the I/O errors, handle the write BIOs regardless whether DM targets emulate zone append or not, so that all write BIOs are split at zone boundaries. For that purpose, drop the check for zone append emulation in dm_zone_bio_needs_split(). Its argument 'md' is no longer used then drop it also.
--- drivers/md/dm.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-)
drivers/md/dm.c +7 -11
@@ -1788,8 +1788,7 @@ static void init_clone_info(struct clone }#ifdef CONFIG_BLK_DEV_ZONED -static inline bool dm_zone_bio_needs_split (struct mapped_device *md, -struct bio *bio) +static inline bool dm_zone_bio_needs_split (struct bio *bio) {/* * Special case the zone operations that cannot or should not be split.
@@ -1805,13 +1804,11 @@ static inline bool dm_zone_bio_needs_spl }/* -* Mapped devices that require zone append emulation will use the block -* layer zone write plugging. In such case, we must split any large BIO -* to the mapped device limits to avoid potential deadlocks with queue -* freeze operations. +* When mapped devices use the block layer zone write plugging, we must +* split any large BIO to the mapped device limits to not submit BIOs +* that span zone boundaries and to avoid potential deadlocks with +* queue freeze operations. */ -if (!dm_emulate_zone_append (md)) -return false;return bio_needs_zone_write_plugging (bio) ||bio_straddles_zones (bio); }
@@ -1935,8 +1932,7 @@ static blk_status_t __send_zone_reset_al }#else -static inline bool dm_zone_bio_needs_split (struct mapped_device *md, -struct bio *bio) +static inline bool dm_zone_bio_needs_split (struct bio *bio) {return false; }
@@ -1963,7 +1959,7 @@ static void dm_split_and_process_bio(str is_abnormal =is_abnormal_io (bio);if (static_branch_unlikely (&zoned_enabled)) { - need_split = is_abnormal ||dm_zone_bio_needs_split (md, bio); + need_split = is_abnormal ||dm_zone_bio_needs_split (bio); }else { need_split = is_abnormal; }
Greg Kroah-Hartman
maintainerPATCH 444/444 PCI: Honor Max Link Speed when determining supported speeds
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner <[email protected]>
commit 3202ca221578850f34e0fea39dc6cfa745ed7aac upstream.
The Supported Link Speeds Vector in the Link Capabilities 2 Register indicates the *supported* link speeds. The Max Link Speed field in the Link Capabilities Register indicates the *maximum* of those speeds.
pcie_get_supported_speeds() neglects to honor the Max Link Speed field and will thus incorrectly deem higher speeds as supported. Fix it.
One user-visible issue addressed here is an incorrect value in the sysfs attribute "max_link_speed".
But the main motivation is a boot hang reported by Niklas: Intel JHL7540 "Titan Ridge 2018" Thunderbolt controllers supports 2.5-8 GT/s speeds, but indicate 2.5 GT/s as maximum. Ilpo recalls seeing this on more devices. It can be explained by the controller's Downstream Ports supporting 8 GT/s if an Endpoint is attached, but limiting to 2.5 GT/s if the port interfaces to a PCIe Adapter, in accordance with USB4 v2 sec 11.2.1:
"This section defines the functionality of an Internal PCIe Port that
interfaces to a PCIe Adapter. [...]
The Logical sub-block shall update the PCIe configuration registers with the following characteristics: [...]
Max Link Speed field in the Link Capabilities Register set to 0001b (data rate of 2.5 GT/s only).
Note: These settings do not represent actual throughput. Throughput is implementation specific and based on the USB4 Fabric performance."
The present commit is not sufficient on its own to fix Niklas' boot hang, but it is a prerequisite: A subsequent commit will fix the boot hang by enabling bandwidth control only if more than one speed is supported.
The GENMASK() macro used herein specifies 0 as lowest bit, even though the Supported Link Speeds Vector ends at bit 1. This is done on purpose to avoid a GENMASK(0, 1) macro if Max Link Speed is zero. That macro would be invalid as the lowest bit is greater than the highest bit. Ilpo has witnessed a zero Max Link Speed on Root Complex Integrated Endpoints in particular, so it does occur in practice. (The Link Capabilities Register is optional on RCiEPs per PCIe r6.2 sec 7.5.3.)
--- drivers/pci/pci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/pci/pci.c +4 -2
@@ -6235,12 +6235,14 @@ u8 pcie_get_supported_speeds(struct pci_pcie_capability_read_dword (dev,PCI_EXP_LNKCAP2 , &lnkcap2); speeds = lnkcap2 &PCI_EXP_LNKCAP2_SLS ; +/* Ignore speeds higher than Max Link Speed */ +pcie_capability_read_dword (dev,PCI_EXP_LNKCAP , &lnkcap); + speeds &=GENMASK (lnkcap &PCI_EXP_LNKCAP_SLS ,0 ); +/* PCIe r3.0-compliant */ if (speeds)return speeds; -pcie_capability_read_dword (dev,PCI_EXP_LNKCAP , &lnkcap); -/* Synthesize from the Max Link Speed field */ if ((lnkcap &PCI_EXP_LNKCAP_SLS ) ==PCI_EXP_LNKCAP_SLS_5_0GB ) speeds =PCI_EXP_LNKCAP2_SLS_5_0GB |PCI_EXP_LNKCAP2_SLS_2_5GB ;
# Librecast Test Results
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 6.12.43-rc1-gd65072433784 #42 SMP PREEMPT_DYNAMIC Mon Aug 18 15:58:39 -00 2025 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.43 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 20 Aug 2025 12:43:43 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.43-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.43 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 20 Aug 2025 12:43:43 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.43-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.thanks,
greg k-h
Boot regression occurs on the Qualcomm DragonBoard 410c (arm64) with stable-rc 6.12.43-rc1. The kernel crashes during early boot with a NULL pointer dereference in the Qualcomm SCM/TZMEM subsystem.
The crash originates in qcom_scm_shm_bridge_enable() (drivers/firmware/qcom/qcom_scm.c) and is invoked by qcom_tzmem_enable() (drivers/firmware/qcom/qcom_tzmem.c). This happens while probing SCM during platform initialization, preventing the board from reaching userspace due to kernel panic.
Regression Analysis:
- New regression? yes
- Reproducibility? yes
Boot regression: stable-rc 6.12.43-rc1 arm64 Qualcomm Dragonboard 410c kernel NULL pointer dereference qcom_scm_shm_bridge_enable qcom_tzmem_enable
## Test log
[ 1.136454] scmi_core: SCMI protocol bus registered [ 1.138666] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 [ 1.142955] Mem abort info: [ 1.151940] ESR = 0x0000000096000004 [ 1.154445] EC = 0x25: DABT (current EL), IL = 32 bits [ 1.158283] SET = 0, FnV = 0 [ 1.163744] EA = 0, S1PTW = 0 [ 1.166596] FSC = 0x04: level 0 translation fault [ 1.169654] Data abort info: [ 1.174508] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 [ 1.177627] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 1.182937] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 1.188062] [0000000000000000] user address but active_mm is swapper [ 1.193447] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP [ 1.199761] Modules linked in: [ 1.205740] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.12.43-rc1 #1 [ 1.208875] Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT) [ 1.215733] pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 1.222676] pc : qcom_scm_shm_bridge_enable (drivers/firmware/qcom/qcom_scm.c:1378) [ 1.229356] lr : qcom_tzmem_enable (drivers/firmware/qcom/qcom_tzmem.c:97 drivers/firmware/qcom/qcom_tzmem.c:474) [ 1.234561] sp : ffff80008002b720 [ 1.238984] x29: ffff80008002b7b0 x28: 0000000000000000 x27: 0000000000000000 [ 1.242294] x26: 0000000000000000 x25: 0000000000000000 x24: ffff00003fafaf18 [ 1.249412] x23: ffff00003facfc98 x22: 0000000000000000 x21: ffff0000036b2410 [ 1.256531] x20: ffff0000036b2400 x19: ffff800083031000 x18: ffff0000036e8000 [ 1.263649] x17: 0000000000000100 x16: 0000000000000160 x15: fffffffffffffffe [ 1.270767] x14: ffffffffffffffff x13: ffff800080028000 x12: ffff80008002c000 [ 1.277885] x11: 0000000000000000 x10: 0000000000000019 x9 : ffff80008136164c [ 1.285002] x8 : 0000000000000000 x7 : 7f7f7f7f7f7f7f7f x6 : fefefeff35302f37 [ 1.292121] x5 : 8080808000000000 x4 : 0000000000000020 x3 : ffff80008002b710 [ 1.299240] x2 : 000000000000001c x1 : 000000000000000c x0 : 0000000000000000 [ 1.306359] Call trace: [ 1.313462] qcom_scm_shm_bridge_enable (drivers/firmware/qcom/qcom_scm.c:1378) [ 1.315726] qcom_tzmem_enable (drivers/firmware/qcom/qcom_tzmem.c:97 drivers/firmware/qcom/qcom_tzmem.c:474) [ 1.320584] qcom_scm_probe (drivers/firmware/qcom/qcom_scm.c:2009) [ 1.324663] platform_probe (drivers/base/platform.c:1405) [ 1.328309] really_probe (drivers/base/dd.c:581 drivers/base/dd.c:657) [ 1.332128] __driver_probe_device (drivers/base/dd.c:0) [ 1.335777] driver_probe_device (drivers/base/dd.c:829) [ 1.340116] __driver_attach (drivers/base/dd.c:1216) [ 1.344107] bus_for_each_dev (drivers/base/bus.c:369) [ 1.347928] driver_attach (drivers/base/dd.c:1233) [ 1.352094] bus_add_driver (drivers/base/bus.c:676) [ 1.355653] driver_register (drivers/base/driver.c:247) [ 1.359212] __platform_driver_register (drivers/base/platform.c:867) [ 1.363035] qcom_scm_init (drivers/firmware/qcom/qcom_scm.c:2115) [ 1.367891] do_one_initcall (init/main.c:1269) [ 1.371538] do_initcall_level (init/main.c:1330) [ 1.375097] do_initcalls (init/main.c:1344) [ 1.379262] do_basic_setup (init/main.c:1367) [ 1.382563] kernel_init_freeable (init/main.c:1584) [ 1.386384] kernel_init (init/main.c:1471) [ 1.390722] ret_from_fork (arch/arm64/kernel/entry.S:846) [ 1.393940] Code: a905ffff a904ffff a903ffff f9001bff (f9400100)
All code
========
Code starting with the faulting instruction
===========================================
[ 1.397767] ---[ end trace 0000000000000000 ]--- [ 1.403793] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b [ 1.408446] SMP: stopping secondary CPUs [ 1.415825] ---[ end Kernel panic - not syncing: Attempted to kill
init! exitcode=0x0000000b ]---
Please refer the full test log information in the below links.
## Source
* Kernel version: 6.12.43-rc1
* Git tree: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
* Git describe: v6.12.41-814-gd65072433784
* Git commit: d6507243378459e7fbd4a142a0b195f4cd3f713b
* Architectures: arm64 Dragonboard 410c
* Toolchains: gcc-13, clang-20
* Kconfigs: defconfig+lkft
## Test
* Boot log: https://qa-reports.linaro.org/api/testruns/29585571/log_file/
* Boot lava log: https://lkft.validation.linaro.org/scheduler/job/8407180#L2638
* Boot details:
https://regressions.linaro.org/lkft/linux-stable-rc-linux-6.12.y/v6.12.41-814-gd65072433784/log-parser-boot/panic-multiline-kernel-panic-not-syncing-attempted-to-kill-init-exitcode/
* Boot plan: https://tuxapi.tuxsuite.com/v1/groups/linaro/projects/lkft/tests/31SgOm3HeBT4mwsDOOESkOLRK93
* Build link: https://storage.tuxsuite.com/public/linaro/lkft/builds/31SgLgEU5QMBwix6uJ2Xzs56tq3/
* Kernel config:
https://storage.tuxsuite.com/public/linaro/lkft/builds/31SgLgEU5QMBwix6uJ2Xzs56tq3/config
--
Linaro LKFT
https://lkft.linaro.org
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.43 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 20 Aug 2025 12:43:43 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.43-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
The kernel, bpf tool, perf tool, and kselftest builds fine for v6.12.43-rc1 on x86 and arm64 Azure VM.
Thanks,
Hardik
Am 18.08.2025 um 14:40 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.12.43 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.
Beste Grüße,
Peter Schneider
Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge, enjoy the air and behold the view. Climb it so you can see the world, not so the world can see you. -- David McCullough Jr. OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244 Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc https://keys.mailvelope.com/pks/lookup?op=get&[email protected] https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 6.12.43 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
CIP testing did not find any problems here:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6.12.y
Best regards,
Pavel
Signature · 2 lines
In cooperation with DENX Software Engineering GmbH, HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.43 release. There are 444 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 20 Aug 2025 12:43:43 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.43-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).