5.15.61-rc1 review
Subsystems (11)
Greg Kroah-Hartman
maintainerPATCH 415/779 usb: ohci-nxp: Fix refcount leak in ohci_hcd_nxp_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 302970b4cad3ebfda2c05ce06c322ccdc447d17e ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
--- drivers/usb/host/ohci-nxp.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/host/ohci-nxp.c +1 -0
@@ -164,6 +164,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev) } isp1301_i2c_client =isp1301_get_client (isp1301_node); +of_node_put (isp1301_node);if (!isp1301_i2c_client)return -EPROBE_DEFER ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 416/779 usb: gadget: tegra-xudc: Fix error check in tegra_xudc_powerdomain_init()
In reply to Greg Kroah-HartmanFrom: Tang Bin <[email protected]>
[ Upstream commit f08aa7c80dac27ee00fa6827f447597d2fba5465 ]
dev_pm_domain_attach_by_name() may return NULL in some cases, so IS_ERR() doesn't meet the requirements. Thus fix it.
--- drivers/usb/gadget/udc/tegra-xudc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/gadget/udc/tegra-xudc.c +4 -4
@@ -3689,15 +3689,15 @@ static int tegra_xudc_powerdomain_init(struct tegra_xudc *xudc)int err; xudc->genpd_dev_device =dev_pm_domain_attach_by_name (dev,"dev" ); -if (IS_ERR (xudc->genpd_dev_device)) { - err =PTR_ERR (xudc->genpd_dev_device); +if (IS_ERR_OR_NULL (xudc->genpd_dev_device)) { + err =PTR_ERR (xudc->genpd_dev_device) ? : -ENODATA ;dev_err (dev,"failed to get device power domain: %d\n" , err);return err; } xudc->genpd_dev_ss =dev_pm_domain_attach_by_name (dev,"ss" ); -if (IS_ERR (xudc->genpd_dev_ss)) { - err =PTR_ERR (xudc->genpd_dev_ss); +if (IS_ERR_OR_NULL (xudc->genpd_dev_ss)) { + err =PTR_ERR (xudc->genpd_dev_ss) ? : -ENODATA ;dev_err (dev,"failed to get SuperSpeed power domain: %d\n" , err);return err; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 417/779 usb: xhci: tegra: Fix error check
In reply to Greg Kroah-HartmanFrom: Tang Bin <[email protected]>
[ Upstream commit 18fc7c435be3f17ea26a21b2e2312fcb9088e01f ]
In the function tegra_xusb_powerdomain_init(), dev_pm_domain_attach_by_name() may return NULL in some cases, so IS_ERR() doesn't meet the requirements. Thus fix it.
--- drivers/usb/host/xhci-tegra.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/host/xhci-tegra.c +4 -4
@@ -1010,15 +1010,15 @@ static int tegra_xusb_powerdomain_init(struct device *dev,int err; tegra->genpd_dev_host =dev_pm_domain_attach_by_name (dev,"xusb_host" ); -if (IS_ERR (tegra->genpd_dev_host)) { - err =PTR_ERR (tegra->genpd_dev_host); +if (IS_ERR_OR_NULL (tegra->genpd_dev_host)) { + err =PTR_ERR (tegra->genpd_dev_host) ? : -ENODATA ;dev_err (dev,"failed to get host pm-domain: %d\n" , err);return err; } tegra->genpd_dev_ss =dev_pm_domain_attach_by_name (dev,"xusb_ss" ); -if (IS_ERR (tegra->genpd_dev_ss)) { - err =PTR_ERR (tegra->genpd_dev_ss); +if (IS_ERR_OR_NULL (tegra->genpd_dev_ss)) { + err =PTR_ERR (tegra->genpd_dev_ss) ? : -ENODATA ;dev_err (dev,"failed to get superspeed pm-domain: %d\n" , err);return err; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 418/779 netfilter: xtables: Bring SPDX identifier back
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
[ Upstream commit 20646f5b1e798bcc20044ae90ac3702f177bf254 ]
Commit e2be04c7f995 ("License cleanup: add SPDX license identifier to uapi header files with a license") added the correct SPDX identifier to include/uapi/linux/netfilter/xt_IDLETIMER.h.
A subsequent commit removed it for no reason and reintroduced the UAPI license incorrectness as the file is now missing the UAPI exception again.
Add it back and remove the GPLv2 boilerplate while at it.
--- include/uapi/linux/netfilter/xt_IDLETIMER.h | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-)
include/uapi/linux/netfilter/xt_IDLETIMER.h +1 -16
@@ -1,6 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* -* linux/include/linux/netfilter/xt_IDLETIMER.h -* * Header file for Xtables timer target module. * * Copyright (C) 2004, 2010 Nokia Corporation
@@ -10,20 +9,6 @@* by Luciano Coelho <[email protected]> * * Contact: Luciano Coelho <[email protected]> -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* version 2 as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -* 02110-1301 USA */ #ifndef _XT_IDLETIMER_H
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 419/779 scsi: qla2xxx: edif: Send LOGO for unexpected IKE message
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit 2b659ed67a12f39f56d8dcad9b5d5a74d67c01b3 ]
If the session is down and the local port continues to receive AUTH ELS messages, the driver needs to send back LOGO so that the remote device knows to tear down its session. Terminate and clean up the AUTH ELS exchange followed by a passthrough LOGO.
--- drivers/scsi/qla2xxx/qla_edif.c | 19 +++++++++++++++++-- drivers/scsi/qla2xxx/qla_fw.h | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-)
drivers/scsi/qla2xxx/qla_edif.c +17 -2
@@ -2496,8 +2496,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp) fcport =qla2x00_find_fcport_by_pid (host, &purex->pur_info.pur_sid); -if (DBELL_INACTIVE (vha) || - (fcport &&EDIF_SESSION_DOWN (fcport))) { +if (DBELL_INACTIVE (vha)) {ql_dbg (ql_dbg_edif, host,0x0910c ,"%s e_dbell.db_flags =%x %06x\n" , __func__, host->e_dbell.db_flags, fcport ? fcport->d_id.b24 :0 );
@@ -2507,6 +2506,22 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)return ; } +if (fcport &&EDIF_SESSION_DOWN (fcport)) { +ql_dbg (ql_dbg_edif, host,0x13b6 , +"%s terminate exchange. Send logo to 0x%x\n" , + __func__, a.did.b24); + + a.tx_byte_count = a.tx_len =0 ; + a.tx_addr =0 ; + a.control_flags =EPD_RX_XCHG ;/* EPD_RX_XCHG = terminate cmd */ +qla_els_reject_iocb (host, (*rsp)->qpair, &a); +qla_enode_free (host, ptr); +/* send logo to let remote port knows to tear down session */ + fcport->send_els_logo =1 ; +qlt_schedule_sess_for_deletion (fcport); +return ; + } +/* add the local enode to the list */ qla_enode_add (host, ptr);
drivers/scsi/qla2xxx/qla_fw.h +1 -1
@@ -807,7 +807,7 @@ struct els_entry_24xx {#define EPD_ELS_COMMAND (0 << 13)#define EPD_ELS_ACC (1 << 13)#define EPD_ELS_RJT (2 << 13) -#define EPD_RX_XCHG (3 << 13) +#define EPD_RX_XCHG (3 << 13)/* terminate exchange */ #define ECF_CLR_PASSTHRU_PEND BIT_12#define ECF_INCL_FRAME_HDR BIT_11#define ECF_SEC_LOGIN BIT_3
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 420/779 scsi: qla2xxx: edif: Reduce disruption due to multiple app start
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit 0dbfce5255fe8d069a1a3b712a25b263264cfa58 ]
Multiple app start can trigger a session bounce. Make driver skip over session teardown if app start is seen more than once.
--- drivers/scsi/qla2xxx/qla_edif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/qla2xxx/qla_edif.c +2 -2
@@ -486,8 +486,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)/* mark doorbell as active since an app is now present */ vha->e_dbell.db_flags |=EDB_ACTIVE ; }else { -ql_dbg (ql_dbg_edif, vha,0x911e ,"%s doorbell already active\n" , - __func__); + goto out; }if (N2N_TOPO (vha->hw)) {
@@ -555,6 +554,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) __func__); } +out: appreply.host_support_edif = vha->hw->flags.edif_enabled; appreply.edif_enode_active = vha->pur_cinfo.enode_flags; appreply.edif_edb_active = vha->e_dbell.db_flags;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 421/779 scsi: qla2xxx: edif: Fix no login after app start
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit 24c796098f5395477f7f7ebf8e24f3f08a139f71 ]
The scenario is this: User loaded driver but has not started authentication app. All sessions to secure device will exhaust all login attempts, fail, and in stay in deleted state. Then some time later the app is started. The driver will replenish the login retry count, trigger delete to prepare for secure login. After deletion, relogin is triggered.
For the session that is already deleted, the delete trigger is a no-op. If none of the sessions trigger a relogin, no progress is made.
Add a relogin trigger.
--- drivers/scsi/qla2xxx/qla_edif.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/qla2xxx/qla_edif.c +1 -0
@@ -544,6 +544,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)qlt_schedule_sess_for_deletion (fcport);qla_edif_sa_ctl_init (vha, fcport); } +set_bit (RELOGIN_NEEDED , &vha->dpc_flags); }if (vha->pur_cinfo.enode_flags !=ENODE_ACTIVE ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 422/779 scsi: qla2xxx: edif: Tear down session if keys have been removed
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit d7e2e4a68fc047a025afcd200e6b7e1fbc8b1999 ]
If all keys for a session have been deleted, trigger a session teardown.
--- drivers/scsi/qla2xxx/qla_def.h | 5 +++++ drivers/scsi/qla2xxx/qla_isr.c | 1 + 2 files changed, 6 insertions(+)
drivers/scsi/qla2xxx/qla_def.h +5 -0
@@ -2158,6 +2158,11 @@ typedef struct {#define CS_IOCB_ERROR 0x31/* Generic error for IOCB request failure */ #define CS_REJECT_RECEIVED 0x4E/* Reject received */ +#define CS_EDIF_AUTH_ERROR 0x63/* decrypt error */ +#define CS_EDIF_PAD_LEN_ERROR 0x65/* pad > frame size, not 4byte align */ +#define CS_EDIF_INV_REQ 0x66/* invalid request */ +#define CS_EDIF_SPI_ERROR 0x67/* rx frame unable to locate sa */ +#define CS_EDIF_HDR_ERROR 0x69/* data frame != expected len */ #define CS_BAD_PAYLOAD 0x80/* Driver defined */ #define CS_UNKNOWN 0x81/* Driver defined */ #define CS_RETRY 0x82/* Driver defined */
drivers/scsi/qla2xxx/qla_isr.c +1 -0
@@ -3420,6 +3420,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)case CS_PORT_UNAVAILABLE :case CS_TIMEOUT :case CS_RESET : +case CS_EDIF_INV_REQ :/* * We are going to have the fc class block the rport
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 423/779 scsi: qla2xxx: edif: Fix session thrash
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit a8fdfb0b39c2b31722c70bdf2272b949d5af4b7b ]
Current code prematurely sends out PRLI before authentication application has given the OK to do so. This causes PRLI failure and session teardown.
Prevents PRLI from going out before authentication app gives the OK.
--- drivers/scsi/qla2xxx/qla_edif.c | 2 +- drivers/scsi/qla2xxx/qla_edif.h | 4 ++++ drivers/scsi/qla2xxx/qla_init.c | 10 +++++++++- 3 files changed, 14 insertions(+), 2 deletions(-)
drivers/scsi/qla2xxx/qla_edif.c +1 -1
@@ -3437,7 +3437,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)if (qla_bsg_check (vha, bsg_job, fcport))return 0 ; -if (fcport->loop_id ==FC_NO_LOOP_ID ) { +if (EDIF_SESS_DELETE (fcport)) {ql_dbg (ql_dbg_edif, vha,0x910d ,"%s ELS code %x, no loop id.\n" , __func__, bsg_request->rqst_data.r_els.els_code);
drivers/scsi/qla2xxx/qla_edif.h +4 -0
@@ -140,4 +140,8 @@ struct enode { (DBELL_ACTIVE (_fcport->vha) && \ (_fcport->disc_state == DSC_LOGIN_AUTH_PEND)) +#define EDIF_SESS_DELETE (_s) \ + (qla_ini_mode_enabled(_s->vha) && (_s->disc_state == DSC_DELETE_PEND || \ + _s->disc_state == DSC_DELETED)) +#endif /* __QLA_EDIF_H */
drivers/scsi/qla2xxx/qla_init.c +9 -1
@@ -1764,8 +1764,16 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)break ;case DSC_LOGIN_PEND : -if (fcport->fw_login_state ==DSC_LS_PLOGI_COMP ) +if (vha->hw->flags.edif_enabled) +break ; + +if (fcport->fw_login_state ==DSC_LS_PLOGI_COMP ) { +ql_dbg (ql_dbg_disc, vha,0x2118 , +"%s %d %8phC post %s PRLI\n" , + __func__, __LINE__, fcport->port_name, +NVME_TARGET (vha->hw, fcport) ?"NVME" :"FC" );qla24xx_post_prli_work (vha, fcport); + }break ;case DSC_UPD_FCPORT :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 424/779 scsi: qla2xxx: edif: Fix no logout on delete for N2N
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit ec538eb838f334453b10e7e9b260f0c358018a37 ]
The driver failed to send implicit logout on session delete. For edif, this failed to flush any lingering SA index in FW.
Set a flag to turn on implicit logout early in the session recovery to make sure the logout will go out in case of error.
--- drivers/scsi/qla2xxx/qla_iocb.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/qla2xxx/qla_iocb.c +3 -0
@@ -2882,6 +2882,9 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) sp->name, res, sp->handle, fcport->d_id.b24, fcport->port_name); fcport->flags &= ~(FCF_ASYNC_SENT |FCF_ASYNC_ACTIVE ); +/* For edif, set logout on delete to ensure any residual key from FW is flushed.*/ + fcport->logout_on_delete =1 ; + fcport->chip_reset = vha->hw->base_qpair->chip_reset;if (sp->flags &SRB_WAKEUP_ON_COMP )complete (&lio->u.els_plogi.comp);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 425/779 iio: accel: bma400: Fix the scale min and max macro values
In reply to Greg Kroah-HartmanFrom: Jagath Jog J <[email protected]>
[ Upstream commit 747c7cf1592e226d40543231b26502b332d0ea2f ]
Changing the scale macro values to match the bma400 sensitivity for 1 LSB of all the available ranges.
--- drivers/iio/accel/bma400.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/iio/accel/bma400.h +21 -2
@@ -83,8 +83,27 @@#define BMA400_ACC_ODR_MIN_WHOLE_HZ 25#define BMA400_ACC_ODR_MIN_HZ 12 -#define BMA400_SCALE_MIN 38357 -#define BMA400_SCALE_MAX 306864 +/* +* BMA400_SCALE_MIN macro value represents m/s^2 for 1 LSB before +* converting to micro values for +-2g range. +* +* For +-2g - 1 LSB = 0.976562 milli g = 0.009576 m/s^2 +* For +-4g - 1 LSB = 1.953125 milli g = 0.019153 m/s^2 +* For +-16g - 1 LSB = 7.8125 milli g = 0.076614 m/s^2 +* +* The raw value which is used to select the different ranges is determined +* by the first bit set position from the scale value, so BMA400_SCALE_MIN +* should be odd. +* +* Scale values for +-2g, +-4g, +-8g and +-16g are populated into bma400_scales +* array by left shifting BMA400_SCALE_MIN. +* e.g.: +* To select +-2g = 9577 << 0 = raw value to write is 0. +* To select +-8g = 9577 << 2 = raw value to write is 2. +* To select +-16g = 9577 << 3 = raw value to write is 3. +*/ +#define BMA400_SCALE_MIN 9577 +#define BMA400_SCALE_MAX 76617#define BMA400_NUM_REGULATORS 2#define BMA400_VDD_REGULATOR 0
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 426/779 platform/chrome: cros_ec: Always expose last resume result
In reply to Greg Kroah-HartmanFrom: Stephen Boyd <[email protected]>
[ Upstream commit 74bb746407bf0d7c7d126c7731dbcd66d467619b ]
The last resume result exposing logic in cros_ec_sleep_event() incorrectly requires S0ix support, which doesn't work on ARM based systems where S0ix doesn't exist. That's because cros_ec_sleep_event() only reports the last resume result when the EC indicates the last sleep event was an S0ix resume. On ARM systems, the last sleep event is always S3 resume, but the EC can still detect sleep hang events in case some other part of the AP is blocking sleep.
Always expose the last resume result if the EC supports it so that this works on all devices regardless of S0ix support. This fixes sleep hang detection on ARM based chromebooks like Trogdor.
--- drivers/platform/chrome/cros_ec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/platform/chrome/cros_ec.c +4 -4
@@ -135,16 +135,16 @@ static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event) buf.msg.command =EC_CMD_HOST_SLEEP_EVENT ; ret =cros_ec_cmd_xfer_status (ec_dev, &buf.msg); - -/* For now, report failure to transition to S0ix with a warning. */ +/* Report failure to transition to system wide suspend with a warning. */ if (ret >=0 && ec_dev->host_sleep_v1 && - (sleep_event ==HOST_SLEEP_EVENT_S0IX_RESUME )) { + (sleep_event ==HOST_SLEEP_EVENT_S0IX_RESUME || + sleep_event ==HOST_SLEEP_EVENT_S3_RESUME )) { ec_dev->last_resume_result = buf.u.resp1.resume_response.sleep_transitions;WARN_ONCE (buf.u.resp1.resume_response.sleep_transitions &EC_HOST_RESUME_SLEEP_TIMEOUT , -"EC detected sleep transition timeout. Total slp_s0 transitions: %d" , +"EC detected sleep transition timeout. Total sleep transitions: %d" , buf.u.resp1.resume_response.sleep_transitions &EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK ); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 427/779 iio: accel: bma400: Reordering of header files
In reply to Greg Kroah-HartmanFrom: Jagath Jog J <[email protected]>
[ Upstream commit 1bd2dc6ea863690aee5c45ebf09c9194c7a42c0d ]
Reordering of header files and removing the iio/sysfs.h since custom attributes are not being used in the driver.
--- drivers/iio/accel/bma400_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/accel/bma400_core.c +2 -2
@@ -13,14 +13,14 @@#include <linux/bitops.h> #include <linux/device.h> -#include <linux/iio/iio.h> -#include <linux/iio/sysfs.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> +#include <linux/iio/iio.h> +#include "bma400.h" /*
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 428/779 clk: mediatek: reset: Fix written reset bit offset
In reply to Greg Kroah-HartmanFrom: Rex-BC Chen <[email protected]>
[ Upstream commit edabcf71d100fd433a0fc2d0c97057c446c33b2a ]
Original assert/deassert bit is BIT(0), but it's more resonable to modify them to BIT(id % 32) which is based on id.
This patch will not influence any previous driver because the reset is only used for thermal. The id (MT8183_INFRACFG_AO_THERM_SW_RST) is 0.
--- drivers/clk/mediatek/reset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/mediatek/reset.c +2 -2
@@ -25,7 +25,7 @@ static int mtk_reset_assert_set_clr(struct reset_controller_dev *rcdev, struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);unsigned int reg = data->regofs + ((id /32 ) <<4 ); -return regmap_write (data->regmap, reg,1 ); +return regmap_write (data->regmap, reg,BIT (id %32 )); } static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev,
@@ -34,7 +34,7 @@ static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev, struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);unsigned int reg = data->regofs + ((id /32 ) <<4 ) +0x4 ; -return regmap_write (data->regmap, reg,1 ); +return regmap_write (data->regmap, reg,BIT (id %32 )); } static int mtk_reset_assert(struct reset_controller_dev *rcdev,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 429/779 lib/test_hmm: avoid accessing uninitialized pages
In reply to Greg Kroah-HartmanFrom: Miaohe Lin <[email protected]>
[ Upstream commit ed913b055a74b723976f8e885a3395162a0371e6 ]
If make_device_exclusive_range() fails or returns pages marked for exclusive access less than required, remaining fields of pages will left uninitialized. So dmirror_atomic_map() will access those yet uninitialized fields of pages. To fix it, do dmirror_atomic_map() iff all pages are marked for exclusive access (we will break if mapped is less than required anyway) so we won't access those uninitialized fields of pages.
--- lib/test_hmm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
lib/test_hmm.c +8 -2
@@ -731,7 +731,7 @@ static int dmirror_exclusive(struct dmirror *dmirror,mmap_read_lock (mm);for (addr = start; addr < end; addr = next) { -unsigned long mapped; +unsigned long mapped =0 ;int i;if (end < addr + (ARRAY_SIZE (pages) <<PAGE_SHIFT ))
@@ -740,7 +740,13 @@ static int dmirror_exclusive(struct dmirror *dmirror, next = addr + (ARRAY_SIZE (pages) <<PAGE_SHIFT ); ret =make_device_exclusive_range (mm, addr, next, pages,NULL ); - mapped =dmirror_atomic_map (addr, next, pages, dmirror); +/* +* Do dmirror_atomic_map() iff all pages are marked for +* exclusive access to avoid accessing uninitialized +* fields of pages. +*/ +if (ret == (next - addr) >>PAGE_SHIFT ) + mapped =dmirror_atomic_map (addr, next, pages, dmirror);for (i =0 ; i < ret; i++) {if (pages[i]) {unlock_page (pages[i]);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 430/779 memremap: remove support for external pgmap refcounts
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
[ Upstream commit b80892ca022e9eb484771a66eb68e12364695a2a ]
No driver is left using the external pgmap refcount, so remove the code to support it.
--- drivers/pci/p2pdma.c | 2 +- include/linux/memremap.h | 18 ++-------- mm/memremap.c | 59 +++++++------------------------ tools/testing/nvdimm/test/iomap.c | 43 +++++++--------------- 4 files changed, 28 insertions(+), 94 deletions(-)
drivers/pci/p2pdma.c +1 -1
@@ -219,7 +219,7 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size, error =gen_pool_add_owner (p2pdma->pool, (unsigned long )addr,pci_bus_address (pdev, bar) + offset,range_len (&pgmap->range),dev_to_node (&pdev->dev), - pgmap->ref); + &pgmap->ref);if (error) goto pages_free;
include/linux/memremap.h +3 -15
@@ -72,16 +72,6 @@ struct dev_pagemap_ops {*/ void (*page_free)(struct page *page); -/* -* Transition the refcount in struct dev_pagemap to the dead state. -*/ -void (*kill)(struct dev_pagemap *pgmap); - -/* -* Wait for refcount in struct dev_pagemap to be idle and reap it. -*/ -void (*cleanup)(struct dev_pagemap *pgmap); -/* * Used for private (un-addressable) device memory only. Must migrate * the page back to a CPU accessible page.
@@ -95,8 +85,7 @@ struct dev_pagemap_ops {* struct dev_pagemap - metadata for ZONE_DEVICE mappings * @altmap: pre-allocated/reserved memory for vmemmap allocations * @ref: reference count that pins the devm_memremap_pages() mapping -* @internal_ref: internal reference if @ref is not provided by the caller -* @done: completion for @internal_ref +* @done: completion for @ref * @type: memory type: see MEMORY_* in memory_hotplug.h * @flags: PGMAP_* flags to specify defailed behavior * @ops: method table
@@ -109,8 +98,7 @@ struct dev_pagemap_ops {*/ struct dev_pagemap {struct vmem_altmap altmap; -struct percpu_ref *ref; -struct percpu_ref internal_ref; +struct percpu_ref ref;struct completion done;enum memory_type type;unsigned int flags;
@@ -191,7 +179,7 @@ static inline unsigned long memremap_compat_align(void)static inline void put_dev_pagemap (struct dev_pagemap *pgmap) {if (pgmap) -percpu_ref_put (pgmap->ref); +percpu_ref_put (&pgmap->ref); }#endif /* _LINUX_MEMREMAP_H_ */
mm/memremap.c +12 -47
98 lines not on this page · raw message
tools/testing/nvdimm/test/iomap.c +12 -31
59 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 431/779 mm/memremap: fix memunmap_pages() race with get_dev_pagemap()
In reply to Greg Kroah-HartmanFrom: Miaohe Lin <[email protected]>
[ Upstream commit 1e57ffb6e3fd9583268c6462c4e3853575b21701 ]
Think about the below scene:
CPU1 CPU2
memunmap_pages
percpu_ref_exit
__percpu_ref_exit
free_percpu(percpu_count);
/* percpu_count is freed here! */
get_dev_pagemap
xa_load(&pgmap_array, PHYS_PFN(phys))
/* pgmap still in the pgmap_array */
percpu_ref_tryget_live(&pgmap->ref)
if __ref_is_percpu
/* __PERCPU_REF_ATOMIC_DEAD not set yet */
this_cpu_inc(*percpu_count)
/* access freed percpu_count here! */
ref->percpu_count_ptr = __PERCPU_REF_ATOMIC_DEAD;
/* too late... */ pageunmap_range
To fix the issue, do percpu_ref_exit() after pgmap_array is emptied. So we won't do percpu_ref_tryget_live() against a being freed percpu_ref.
--- mm/memremap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/memremap.c +1 -1
@@ -148,10 +148,10 @@ void memunmap_pages(struct dev_pagemap *pgmap)for_each_device_pfn (pfn, pgmap, i)put_page (pfn_to_page (pfn));wait_for_completion (&pgmap->done); -percpu_ref_exit (&pgmap->ref);for (i =0 ; i < pgmap->nr_range; i++)pageunmap_range (pgmap, i); +percpu_ref_exit (&pgmap->ref);WARN_ONCE (pgmap->altmap.alloc,"failed to free all reserved pages\n" );devmap_managed_enable_put (pgmap);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 432/779 KVM: Dont set Accessed/Dirty bits for ZERO_PAGE
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit a1040b0d42acf69bb4f6dbdc54c2dcd78eea1de5 ]
Don't set Accessed/Dirty bits for a struct page with PG_reserved set, i.e. don't set A/D bits for the ZERO_PAGE. The ZERO_PAGE (or pages depending on the architecture) should obviously never be written, and similarly there's no point in marking it accessed as the page will never be swapped out or reclaimed. The comment in page-flags.h is quite clear that PG_reserved pages should be managed only by their owner, and strictly following that mandate also simplifies KVM's logic.
Message-Id: <[email protected]>
--- virt/kvm/kvm_main.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
virt/kvm/kvm_main.c +14 -2
@@ -2762,16 +2762,28 @@ void kvm_release_pfn_dirty(kvm_pfn_t pfn) }EXPORT_SYMBOL_GPL (kvm_release_pfn_dirty); +static bool kvm_is_ad_tracked_pfn (kvm_pfn_t pfn) +{ +if (!pfn_valid (pfn)) +return false; + +/* +* Per page-flags.h, pages tagged PG_reserved "should in general not be +* touched (e.g. set dirty) except by its owner". +*/ +return !PageReserved (pfn_to_page (pfn)); +} +void kvm_set_pfn_dirty (kvm_pfn_t pfn) { -if (!kvm_is_reserved_pfn (pfn) && !kvm_is_zone_device_pfn (pfn)) +if (kvm_is_ad_tracked_pfn (pfn))SetPageDirty (pfn_to_page (pfn)); }EXPORT_SYMBOL_GPL (kvm_set_pfn_dirty);void kvm_set_pfn_accessed (kvm_pfn_t pfn) { -if (!kvm_is_reserved_pfn (pfn) && !kvm_is_zone_device_pfn (pfn)) +if (kvm_is_ad_tracked_pfn (pfn))mark_page_accessed (pfn_to_page (pfn)); }EXPORT_SYMBOL_GPL (kvm_set_pfn_accessed);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 433/779 mwifiex: Ignore BTCOEX events from the 88W8897 firmware
In reply to Greg Kroah-HartmanFrom: Jonas Dreßler <[email protected]>
[ Upstream commit 84d94e16efa268e4f2887d858cd67ee37b870f25 ]
The firmware of the 88W8897 PCIe+USB card sends those events very unreliably, sometimes bluetooth together with 2.4ghz-wifi is used and no COEX event comes in, and sometimes bluetooth is disabled but the coexistance mode doesn't get disabled.
This means we sometimes end up capping the rx/tx window size while bluetooth is not enabled anymore, artifically limiting wifi speeds even though bluetooth is not being used.
Since we can't fix the firmware, let's just ignore those events on the 88W8897 device. From some Wireshark capture sessions it seems that the Windows driver also doesn't change the rx/tx window sizes when bluetooth gets enabled or disabled, so this is fairly consistent with the Windows driver.
--- drivers/net/wireless/marvell/mwifiex/main.h | 2 ++ drivers/net/wireless/marvell/mwifiex/pcie.c | 3 +++ drivers/net/wireless/marvell/mwifiex/sta_event.c | 3 +++ 3 files changed, 8 insertions(+)
drivers/net/wireless/marvell/mwifiex/main.h +2 -0
@@ -1054,6 +1054,8 @@ struct mwifiex_adapter {void *devdump_data;int devdump_len;struct timer_list devdump_timer; + +bool ignore_btcoex_events; };void mwifiex_process_tx_queue (struct mwifiex_adapter *adapter);
drivers/net/wireless/marvell/mwifiex/pcie.c +3 -0
@@ -3152,6 +3152,9 @@ static int mwifiex_init_pcie(struct mwifiex_adapter *adapter)if (ret) goto err_alloc_buffers; +if (pdev->device ==PCIE_DEVICE_ID_MARVELL_88W8897 ) + adapter->ignore_btcoex_events = true; +return 0 ; err_alloc_buffers:
drivers/net/wireless/marvell/mwifiex/sta_event.c +3 -0
@@ -1062,6 +1062,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)break ;case EVENT_BT_COEX_WLAN_PARA_CHANGE :dev_dbg (adapter->dev,"EVENT: BT coex wlan param update\n" ); +if (adapter->ignore_btcoex_events) +break ; +mwifiex_bt_coex_wlan_param_update_event (priv, adapter->event_skb);break ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 434/779 mwifiex: fix sleep in atomic context bugs caused by dev_coredumpv
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit a52ed4866d2b90dd5e4ae9dabd453f3ed8fa3cbc ]
There are sleep in atomic context bugs when uploading device dump data in mwifiex. The root cause is that dev_coredumpv could not be used in atomic contexts, because it calls dev_set_name which include operations that may sleep. The call tree shows execution paths that could lead to bugs:
(Interrupt context)fw_dump_timer_fn
mwifiex_upload_device_dump
dev_coredumpv(..., GFP_KERNEL)
dev_coredumpm()
kzalloc(sizeof(*devcd), gfp); //may sleep dev_set_name
kobject_set_name_vargs
kvasprintf_const(GFP_KERNEL, ...); //may sleep kstrdup(s, GFP_KERNEL); //may sleep
The corresponding fail log is shown below:
[ 135.275938] usb 1-1: == mwifiex dump information to /sys/class/devcoredump start [ 135.281029] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:265 ... [ 135.293613] Call Trace: [ 135.293613] <IRQ> [ 135.293613] dump_stack_lvl+0x57/0x7d [ 135.293613] __might_resched.cold+0x138/0x173 [ 135.293613] ? dev_coredumpm+0xca/0x2e0 [ 135.293613] kmem_cache_alloc_trace+0x189/0x1f0 [ 135.293613] ? devcd_match_failing+0x30/0x30 [ 135.293613] dev_coredumpm+0xca/0x2e0 [ 135.293613] ? devcd_freev+0x10/0x10 [ 135.293613] dev_coredumpv+0x1c/0x20 [ 135.293613] ? devcd_match_failing+0x30/0x30 [ 135.293613] mwifiex_upload_device_dump+0x65/0xb0 [ 135.293613] ? mwifiex_dnld_fw+0x1b0/0x1b0 [ 135.293613] call_timer_fn+0x122/0x3d0 [ 135.293613] ? msleep_interruptible+0xb0/0xb0 [ 135.293613] ? lock_downgrade+0x3c0/0x3c0 [ 135.293613] ? __next_timer_interrupt+0x13c/0x160 [ 135.293613] ? lockdep_hardirqs_on_prepare+0xe/0x220 [ 135.293613] ? mwifiex_dnld_fw+0x1b0/0x1b0 [ 135.293613] __run_timers.part.0+0x3f8/0x540 [ 135.293613] ? call_timer_fn+0x3d0/0x3d0 [ 135.293613] ? arch_restore_msi_irqs+0x10/0x10 [ 135.293613] ? lapic_next_event+0x31/0x40 [ 135.293613] run_timer_softirq+0x4f/0xb0 [ 135.293613] __do_softirq+0x1c2/0x651 ... [ 135.293613] RIP: 0010:default_idle+0xb/0x10 [ 135.293613] RSP: 0018:ffff888006317e68 EFLAGS: 00000246 [ 135.293613] RAX: ffffffff82ad8d10 RBX: ffff888006301cc0 RCX: ffffffff82ac90e1 [ 135.293613] RDX: ffffed100d9ff1b4 RSI: ffffffff831ad140 RDI: ffffffff82ad8f20 [ 135.293613] RBP: 0000000000000003 R08: 0000000000000000 R09: ffff88806cff8d9b [ 135.293613] R10: ffffed100d9ff1b3 R11: 0000000000000001 R12: ffffffff84593410 [ 135.293613] R13: 0000000000000000 R14: 0000000000000000 R15: 1ffff11000c62fd2 ... [ 135.389205] usb 1-1: == mwifiex dump information to /sys/class/devcoredump end
This patch uses delayed work to replace timer and moves the operations that may sleep into a delayed work in order to mitigate bugs, it was tested on Marvell 88W8801 chip whose port is usb and the firmware is usb8801_uapsta.bin. The following is the result after using delayed work to replace timer.
[ 134.936453] usb 1-1: == mwifiex dump information to /sys/class/devcoredump start [ 135.043344] usb 1-1: == mwifiex dump information to /sys/class/devcoredump end
As we can see, there is no bug now.
--- drivers/net/wireless/marvell/mwifiex/init.c | 9 +++++---- drivers/net/wireless/marvell/mwifiex/main.h | 3 ++- drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-)
drivers/net/wireless/marvell/mwifiex/init.c +5 -4
@@ -63,9 +63,10 @@ static void wakeup_timer_fn(struct timer_list *t) adapter->if_ops.card_reset (adapter); } -static void fw_dump_timer_fn (struct timer_list *t) +static void fw_dump_work (struct work_struct *work) { -struct mwifiex_adapter *adapter =from_timer (adapter, t, devdump_timer); +struct mwifiex_adapter *adapter = + container_of(work, struct mwifiex_adapter, devdump_work.work);mwifiex_upload_device_dump (adapter); }
@@ -321,7 +322,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->active_scan_triggered = false;timer_setup (&adapter->wakeup_timer, wakeup_timer_fn,0 ); adapter->devdump_len =0 ; -timer_setup (&adapter->devdump_timer, fw_dump_timer_fn,0 ); +INIT_DELAYED_WORK (&adapter->devdump_work, fw_dump_work); }/*
@@ -400,7 +401,7 @@ static void mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) {del_timer (&adapter->wakeup_timer); -del_timer_sync (&adapter->devdump_timer); +cancel_delayed_work_sync (&adapter->devdump_work);mwifiex_cancel_all_pending_cmd (adapter);wake_up_interruptible (&adapter->cmd_wait_q.wait);wake_up_interruptible (&adapter->hs_activate_wait_q);
drivers/net/wireless/marvell/mwifiex/main.h +2 -1
@@ -49,6 +49,7 @@#include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/of_irq.h> +#include <linux/workqueue.h> #include "decl.h" #include "ioctl.h"
@@ -1053,7 +1054,7 @@ struct mwifiex_adapter {/* Device dump data/length */ void *devdump_data;int devdump_len; -struct timer_list devdump_timer; +struct delayed_work devdump_work;bool ignore_btcoex_events; };
drivers/net/wireless/marvell/mwifiex/sta_event.c +3 -3
@@ -623,8 +623,8 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv,* transmission event get lost, in this cornel case, * user would still get partial of the dump. */ -mod_timer (&adapter->devdump_timer, - jiffies +msecs_to_jiffies (MWIFIEX_TIMER_10S )); +schedule_delayed_work (&adapter->devdump_work, +msecs_to_jiffies (MWIFIEX_TIMER_10S )); }/* Overflow check */
@@ -643,7 +643,7 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv,return ; upload_dump: -del_timer_sync (&adapter->devdump_timer); +cancel_delayed_work_sync (&adapter->devdump_work);mwifiex_upload_device_dump (adapter); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 435/779 scsi: iscsi: Allow iscsi_if_stop_conn() to be called from kernel
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit 3328333b47f4163504267440ec0a36087a407a5f ]
iscsi_if_stop_conn() is only called from the userspace interface but in a subsequent commit we will want to call it from the kernel interface to allow drivers like qedi to remove sessions from inside the kernel during shutdown. This removes the iscsi_uevent code from iscsi_if_stop_conn() so we can call it in a new helper.
--- drivers/scsi/scsi_transport_iscsi.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
drivers/scsi/scsi_transport_iscsi.c +7 -10
@@ -2283,16 +2283,8 @@ static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn, } } -static int iscsi_if_stop_conn (struct iscsi_transport *transport, -struct iscsi_uevent *ev) +static int iscsi_if_stop_conn (struct iscsi_cls_conn *conn,int flag) { -int flag = ev->u.stop_conn.flag; -struct iscsi_cls_conn *conn; - - conn =iscsi_conn_lookup (ev->u.stop_conn.sid, ev->u.stop_conn.cid); -if (!conn) -return -EINVAL ; -ISCSI_DBG_TRANS_CONN (conn,"iscsi if conn stop.\n" );/* * If this is a termination we have to call stop_conn with that flag
@@ -3739,7 +3731,12 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,case ISCSI_UEVENT_DESTROY_CONN :return iscsi_if_destroy_conn (transport, ev);case ISCSI_UEVENT_STOP_CONN : -return iscsi_if_stop_conn (transport, ev); + conn =iscsi_conn_lookup (ev->u.stop_conn.sid, + ev->u.stop_conn.cid); +if (!conn) +return -EINVAL ; + +return iscsi_if_stop_conn (conn, ev->u.stop_conn.flag); }/*
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 436/779 scsi: iscsi: Add helper to remove a session from the kernel
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit bb42856bfd54fda1cbc7c470fcf5db1596938f4f ]
During qedi shutdown we need to stop the iSCSI layer from sending new nops as pings and from responding to target ones and make sure there is no running connection cleanups. Commit d1f2ce77638d ("scsi: qedi: Fix host removal with running sessions") converted the driver to use the libicsi helper to drive session removal, so the above issues could be handled. The problem is that during system shutdown iscsid will not be running so when we try to remove the root session we will hang waiting for userspace to reply.
Add a helper that will drive the destruction of sessions like these during system shutdown.
--- drivers/scsi/scsi_transport_iscsi.c | 49 +++++++++++++++++++++++++++++ include/scsi/scsi_transport_iscsi.h | 1 + 2 files changed, 50 insertions(+)
drivers/scsi/scsi_transport_iscsi.c +49 -0
@@ -2360,6 +2360,55 @@ static void iscsi_cleanup_conn_work_fn(struct work_struct *work)ISCSI_DBG_TRANS_CONN (conn,"cleanup done.\n" ); } +static int iscsi_iter_force_destroy_conn_fn (struct device *dev,void *data) +{ +struct iscsi_transport *transport; +struct iscsi_cls_conn *conn; + +if (!iscsi_is_conn_dev (dev)) +return 0 ; + + conn =iscsi_dev_to_conn (dev); + transport = conn->transport; + +if (READ_ONCE (conn->state) !=ISCSI_CONN_DOWN ) +iscsi_if_stop_conn (conn,STOP_CONN_TERM ); + + transport->destroy_conn (conn); +return 0 ; +} + +/** +* iscsi_force_destroy_session - destroy a session from the kernel +* @session: session to destroy +* +* Force the destruction of a session from the kernel. This should only be +* used when userspace is no longer running during system shutdown. +*/ +void iscsi_force_destroy_session (struct iscsi_cls_session *session) +{ +struct iscsi_transport *transport = session->transport; +unsigned long flags; + +WARN_ON_ONCE (system_state ==SYSTEM_RUNNING ); + +spin_lock_irqsave (&sesslock, flags); +if (list_empty (&session->sess_list)) { +spin_unlock_irqrestore (&sesslock, flags); +/* +* Conn/ep is already freed. Session is being torn down via +* async path. For shutdown we don't care about it so return. +*/ +return ; + } +spin_unlock_irqrestore (&sesslock, flags); + +device_for_each_child (&session->dev,NULL , + iscsi_iter_force_destroy_conn_fn); + transport->destroy_session (session); +} +EXPORT_SYMBOL_GPL (iscsi_force_destroy_session); +void iscsi_free_session (struct iscsi_cls_session *session) {ISCSI_DBG_TRANS_SESSION (session,"Freeing session\n" );
include/scsi/scsi_transport_iscsi.h +1 -0
@@ -441,6 +441,7 @@ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,struct iscsi_transport *t, int dd_size, unsigned int target_id); +extern void iscsi_force_destroy_session (struct iscsi_cls_session *session);extern void iscsi_remove_session (struct iscsi_cls_session *session);extern void iscsi_free_session (struct iscsi_cls_session *session); extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 437/779 scsi: iscsi: Fix session removal on shutdown
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit 31500e902759322ba3c64b60dabae2704e738df8 ]
When the system is shutting down, iscsid is not running so we will not get a response to the ISCSI_ERR_INVALID_HOST error event. The system shutdown will then hang waiting on userspace to remove the session.
This has libiscsi force the destruction of the session from the kernel when iscsi_host_remove() is called from a driver's shutdown callout.
This fixes a regression added in qedi boot with commit d1f2ce77638d ("scsi:
qedi: Fix host removal with running sessions") which made qedi use the common session removal function that waits on userspace instead of rolling its own kernel based removal.
--- drivers/infiniband/ulp/iser/iscsi_iser.c | 4 ++-- drivers/scsi/be2iscsi/be_main.c | 2 +- drivers/scsi/bnx2i/bnx2i_iscsi.c | 2 +- drivers/scsi/cxgbi/libcxgbi.c | 2 +- drivers/scsi/iscsi_tcp.c | 4 ++-- drivers/scsi/libiscsi.c | 9 +++++++-- drivers/scsi/qedi/qedi_main.c | 9 ++++++--- include/scsi/libiscsi.h | 2 +- 8 files changed, 21 insertions(+), 13 deletions(-)
drivers/infiniband/ulp/iser/iscsi_iser.c +2 -2
@@ -584,7 +584,7 @@ iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)struct Scsi_Host *shost =iscsi_session_to_shost (cls_session);iscsi_session_teardown (cls_session); -iscsi_host_remove (shost); +iscsi_host_remove (shost, false);iscsi_host_free (shost); }
@@ -702,7 +702,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,return cls_session; remove_host: -iscsi_host_remove (shost); +iscsi_host_remove (shost, false); free_host:iscsi_host_free (shost);return NULL ;
drivers/scsi/be2iscsi/be_main.c +1 -1
@@ -5741,7 +5741,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)cancel_work_sync (&phba->sess_work);beiscsi_iface_destroy_default (phba); -iscsi_host_remove (phba->shost); +iscsi_host_remove (phba->shost, false);beiscsi_disable_port (phba,1 );/* after cancelling boot_work */
drivers/scsi/bnx2i/bnx2i_iscsi.c +1 -1
@@ -909,7 +909,7 @@ void bnx2i_free_hba(struct bnx2i_hba *hba) {struct Scsi_Host *shost = hba->shost; -iscsi_host_remove (shost); +iscsi_host_remove (shost, false);INIT_LIST_HEAD (&hba->ep_ofld_list);INIT_LIST_HEAD (&hba->ep_active_list);INIT_LIST_HEAD (&hba->ep_destroy_list);
drivers/scsi/cxgbi/libcxgbi.c +1 -1
@@ -328,7 +328,7 @@ void cxgbi_hbas_remove(struct cxgbi_device *cdev) chba = cdev->hbas[i];if (chba) { cdev->hbas[i] =NULL ; -iscsi_host_remove (chba->shost); +iscsi_host_remove (chba->shost, false);pci_dev_put (cdev->pdev);iscsi_host_free (chba->shost); }
drivers/scsi/iscsi_tcp.c +2 -2
@@ -898,7 +898,7 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, remove_session:iscsi_session_teardown (cls_session); remove_host: -iscsi_host_remove (shost); +iscsi_host_remove (shost, false); free_host:iscsi_host_free (shost);return NULL ;
@@ -915,7 +915,7 @@ static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)iscsi_tcp_r2tpool_free (cls_session->dd_data);iscsi_session_teardown (cls_session); -iscsi_host_remove (shost); +iscsi_host_remove (shost, false);iscsi_host_free (shost); }
drivers/scsi/libiscsi.c +7 -2
@@ -2830,11 +2830,12 @@ static void iscsi_notify_host_removed(struct iscsi_cls_session *cls_session)/** * iscsi_host_remove - remove host and sessions * @shost: scsi host +* @is_shutdown: true if called from a driver shutdown callout * * If there are any sessions left, this will initiate the removal and wait * for the completion. */ -void iscsi_host_remove (struct Scsi_Host *shost) +void iscsi_host_remove (struct Scsi_Host *shost,bool is_shutdown) {struct iscsi_host *ihost =shost_priv (shost);unsigned long flags;
@@ -2843,7 +2844,11 @@ void iscsi_host_remove(struct Scsi_Host *shost) ihost->state =ISCSI_HOST_REMOVED ;spin_unlock_irqrestore (&ihost->lock, flags); -iscsi_host_for_each_session (shost, iscsi_notify_host_removed); +if (!is_shutdown) +iscsi_host_for_each_session (shost, iscsi_notify_host_removed); +else +iscsi_host_for_each_session (shost, iscsi_force_destroy_session); +wait_event_interruptible (ihost->session_removal_wq, ihost->num_sessions ==0 );if (signal_pending (current))
drivers/scsi/qedi/qedi_main.c +6 -3
@@ -2417,9 +2417,12 @@ static void __qedi_remove(struct pci_dev *pdev, int mode)int rval;u16 retry =10 ; -if (mode ==QEDI_MODE_NORMAL || mode ==QEDI_MODE_SHUTDOWN ) { -iscsi_host_remove (qedi->shost); +if (mode ==QEDI_MODE_NORMAL ) +iscsi_host_remove (qedi->shost, false); +else if (mode ==QEDI_MODE_SHUTDOWN ) +iscsi_host_remove (qedi->shost, true); +if (mode ==QEDI_MODE_NORMAL || mode ==QEDI_MODE_SHUTDOWN ) {if (qedi->tmf_thread) {flush_workqueue (qedi->tmf_thread);destroy_workqueue (qedi->tmf_thread);
@@ -2796,7 +2799,7 @@ static int __qedi_probe(struct pci_dev *pdev, int mode)#ifdef CONFIG_DEBUG_FS qedi_dbg_host_exit (&qedi->dbg_ctx);#endif -iscsi_host_remove (qedi->shost); +iscsi_host_remove (qedi->shost, false); stop_iscsi_func: qedi_ops->stop (qedi->cdev); stop_slowpath:
include/scsi/libiscsi.h +1 -1
@@ -400,7 +400,7 @@ extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev);extern struct Scsi_Host *iscsi_host_alloc (struct scsi_host_template *sht,int dd_data_size,bool xmit_can_sleep); -extern void iscsi_host_remove (struct Scsi_Host *shost); +extern void iscsi_host_remove (struct Scsi_Host *shost,bool is_shutdown);extern void iscsi_host_free (struct Scsi_Host *shost);extern int iscsi_target_alloc (struct scsi_target *starget); extern int iscsi_host_get_max_scsi_cmds(struct Scsi_Host *shost,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 438/779 dmaengine: dw-edma: Fix eDMA Rd/Wr-channels and DMA-direction semantics
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit c1e33979171da63cf47e56243ccb8ba82363c7d3 ]
In accordance with [1, 2] the DW eDMA controller has been created to be part of the DW PCIe Root Port and DW PCIe End-point controllers and to offload the transferring of large blocks of data between application and remote PCIe domains leaving the system CPU free for other tasks. In the first case (eDMA being part of DW PCIe Root Port) the eDMA controller is always accessible via the CPU DBI interface and never over the PCIe wire.
The latter case is more complex. Depending on the DW PCIe End-Point IP-core synthesize parameters it's possible to have the eDMA registers accessible not only from the application CPU side, but also via mapping the eDMA CSRs over a dedicated endpoint BAR. So based on the specifics denoted above the eDMA driver is supposed to support two types of the DMA controller setups:
1) eDMA embedded into the DW PCIe Root Port/End-point and accessible over the local CPU from the application side.
2) eDMA embedded into the DW PCIe End-point and accessible via the PCIe wire with MWr/MRd TLPs generated by the CPU PCIe host controller.
Since the CPU memory resides different sides in these cases the semantics of the MEM_TO_DEV and DEV_TO_MEM operations is flipped with respect to the Tx and Rx DMA channels. So MEM_TO_DEV/DEV_TO_MEM corresponds to the Tx/Rx channels in setup 1) and to the Rx/Tx channels in case of setup 2).
The DW eDMA driver has supported the case 2) since e63d79d1ffcd ("dmaengine: Add Synopsys eDMA IP core driver") in the framework of the drivers/dma/dw-edma/dw-edma-pcie.c driver.
The case 1) support was added later by bd96f1b2f43a ("dmaengine: dw-edma:
support local dma device transfer semantics"). Afterwards the driver was supposed to cover the both possible eDMA setups, but the latter commit turned out to be not fully correct.
The problem was that the commit together with the new functionality support also changed the channel direction semantics so the eDMA Read-channel (corresponding to the DMA_DEV_TO_MEM direction for case 1) now uses the sgl/cyclic base addresses as the Source addresses of the DMA transfers and dma_slave_config.dst_addr as the Destination address of the DMA transfers.
Similarly the eDMA Write-channel (corresponding to the DMA_MEM_TO_DEV direction for case 1) now uses dma_slave_config.src_addr as a source address of the DMA transfers and sgl/cyclic base address as the Destination address of the DMA transfers. This contradicts the logic of the DMA-interface, which implies that DEV side is supposed to belong to the PCIe device memory and MEM - to the CPU/Application memory. Indeed it seems irrational to have the SG-list defined in the PCIe bus space, while expecting a contiguous buffer allocated in the CPU memory. Moreover the passed SG-list and cyclic DMA buffers are supposed to be mapped in a way so to be seen by the DW eDMA Application (CPU) interface.
So in order to have the correct DW eDMA interface we need to invert the eDMA Rd/Wr-channels and DMA-slave directions semantics by selecting the src/dst addresses based on the DMA transfer direction instead of using the channel direction capability.
[1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
v.5.40a, March 2019, p.1092
[2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Endpoint,
v.5.40a, March 2019, p.1189--- drivers/dma/dw-edma/dw-edma-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dma/dw-edma/dw-edma-core.c +1 -1
@@ -424,7 +424,7 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) chunk->ll_region.sz += burst->sz; desc->alloc_sz += burst->sz; -if (chan->dir ==EDMA_DIR_WRITE ) { +if (dir ==DMA_DEV_TO_MEM ) { burst->sar = src_addr;if (xfer->type ==EDMA_XFER_CYCLIC ) { burst->dar = xfer->xfer.cyclic.paddr;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 439/779 mtd: dataflash: Add SPI ID table
In reply to Greg Kroah-HartmanFrom: Mark Brown <[email protected]>
[ Upstream commit ac4f83482afbfd927d0fe118151b747cf175e724 ]
Currently autoloading for SPI devices does not use the DT ID table, it uses SPI modalises. Supporting OF modalises is going to be difficult if not impractical, an attempt was made but has been reverted, so ensure that module autoloading works for this driver by adding an id_table listing the SPI IDs for everything.
--- drivers/mtd/devices/mtd_dataflash.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/mtd/devices/mtd_dataflash.c +8 -0
@@ -112,6 +112,13 @@ static const struct of_device_id dataflash_dt_ids[] = {MODULE_DEVICE_TABLE (of, dataflash_dt_ids);#endif +static const struct spi_device_id dataflash_spi_ids[] = { + { .name ="at45" , }, + { .name ="dataflash" , }, + {/* sentinel */ } +}; +MODULE_DEVICE_TABLE (spi, dataflash_spi_ids); +/* ......................................................................... */ /*
@@ -938,6 +945,7 @@ static struct spi_driver dataflash_driver = { .probe = dataflash_probe, .remove = dataflash_remove, + .id_table = dataflash_spi_ids,/* FIXME: investigate suspend and resume... */ };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 440/779 clk: qcom: camcc-sm8250: Fix halt on boot by reducing drivers init level
In reply to Greg Kroah-HartmanFrom: Vladimir Zapolskiy <[email protected]>
[ Upstream commit c4f40351901a10cd662ac2c081396d8fb04f584d ]
Access to I/O of SM8250 camera clock controller IP depends on enabled GCC_CAMERA_AHB_CLK clock supplied by global clock controller, the latter one is inited on subsys level, so, to satisfy the dependency, it would make sense to deprive the init level of camcc-sm8250 driver.
If both drivers are compiled as built-in, there is a change that a board won't boot up due to a race, which happens on the same init level.
--- drivers/clk/qcom/camcc-sm8250.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
drivers/clk/qcom/camcc-sm8250.c +1 -11
@@ -2440,17 +2440,7 @@ static struct platform_driver cam_cc_sm8250_driver = { }, }; -static int __init cam_cc_sm8250_init (void ) -{ -return platform_driver_register (&cam_cc_sm8250_driver); -} -subsys_initcall (cam_cc_sm8250_init); - -static void __exit cam_cc_sm8250_exit(void) -{ -platform_driver_unregister (&cam_cc_sm8250_driver); -} -module_exit (cam_cc_sm8250_exit); +module_platform_driver (cam_cc_sm8250_driver);MODULE_DESCRIPTION ("QTI CAMCC SM8250 Driver" );MODULE_LICENSE ("GPL v2" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 441/779 misc: rtsx: Fix an error handling path in rtsx_pci_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 44fd1917314e9d4f53dd95dd65df1c152f503d3a ]
If an error occurs after a successful idr_alloc() call, the corresponding resource must be released with idr_remove() as already done in the .remove function.
Update the error handling path to add the missing idr_remove() call.
--- drivers/misc/cardreader/rtsx_pcr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/misc/cardreader/rtsx_pcr.c +5 -1
@@ -1581,7 +1581,7 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, pcr->remap_addr =ioremap (base, len);if (!pcr->remap_addr) { ret = -ENOMEM ; - goto free_handle; + goto free_idr; } pcr->rtsx_resv_buf = dma_alloc_coherent(&(pcidev->dev),
@@ -1651,6 +1651,10 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr); unmap:iounmap (pcr->remap_addr); +free_idr: +spin_lock (&rtsx_pci_lock); +idr_remove (&rtsx_pci_idr, pcr->id); +spin_unlock (&rtsx_pci_lock); free_handle:kfree (handle); free_pcr:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 442/779 driver core: fix potential deadlock in __driver_attach
In reply to Greg Kroah-HartmanFrom: Zhang Wensheng <[email protected]>
[ Upstream commit 70fe758352cafdee72a7b13bf9db065f9613ced8 ]
In __driver_attach function, There are also AA deadlock problem, like the commit b232b02bf3c2 ("driver core: fix deadlock in __device_attach").
stack like commit b232b02bf3c2 ("driver core: fix deadlock in __device_attach").
list below:
In __driver_attach function, The lock holding logic is as follows:
...
__driver_attach
if (driver_allows_async_probing(drv))
device_lock(dev) // get lock dev
async_schedule_dev(__driver_attach_async_helper, dev); // func
async_schedule_node
async_schedule_node_domain(func)
entry = kzalloc(sizeof(struct async_entry), GFP_ATOMIC); /* when fail or work limit, sync to execute func, but
__driver_attach_async_helper will get lock dev as will, which will lead to A-A deadlock. */
if (!entry || atomic_read(&entry_count) > MAX_WORK) {
func;
else
queue_work_node(node, system_unbound_wq, &entry->work)
device_unlock(dev)
As above show, when it is allowed to do async probes, because of out of memory or work limit, async work is not be allowed, to do sync execute instead. it will lead to A-A deadlock because of __driver_attach_async_helper getting lock dev.
Reproduce:
and it can be reproduce by make the condition
(if (!entry || atomic_read(&entry_count) > MAX_WORK)) untenable, like below:
[ 370.785650] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 370.787154] task:swapper/0 state:D stack: 0 pid: 1 ppid: 0 flags:0x00004000 [ 370.788865] Call Trace: [ 370.789374] <TASK> [ 370.789841] __schedule+0x482/0x1050 [ 370.790613] schedule+0x92/0x1a0 [ 370.791290] schedule_preempt_disabled+0x2c/0x50 [ 370.792256] __mutex_lock.isra.0+0x757/0xec0 [ 370.793158] __mutex_lock_slowpath+0x1f/0x30 [ 370.794079] mutex_lock+0x50/0x60 [ 370.794795] __device_driver_lock+0x2f/0x70 [ 370.795677] ? driver_probe_device+0xd0/0xd0 [ 370.796576] __driver_attach_async_helper+0x1d/0xd0 [ 370.797318] ? driver_probe_device+0xd0/0xd0 [ 370.797957] async_schedule_node_domain+0xa5/0xc0 [ 370.798652] async_schedule_node+0x19/0x30 [ 370.799243] __driver_attach+0x246/0x290 [ 370.799828] ? driver_allows_async_probing+0xa0/0xa0 [ 370.800548] bus_for_each_dev+0x9d/0x130 [ 370.801132] driver_attach+0x22/0x30 [ 370.801666] bus_add_driver+0x290/0x340 [ 370.802246] driver_register+0x88/0x140 [ 370.802817] ? virtio_scsi_init+0x116/0x116 [ 370.803425] scsi_register_driver+0x1a/0x30 [ 370.804057] init_sd+0x184/0x226 [ 370.804533] do_one_initcall+0x71/0x3a0 [ 370.805107] kernel_init_freeable+0x39a/0x43a [ 370.805759] ? rest_init+0x150/0x150 [ 370.806283] kernel_init+0x26/0x230 [ 370.806799] ret_from_fork+0x1f/0x30
To fix the deadlock, move the async_schedule_dev outside device_lock, as we can see, in async_schedule_node_domain, the parameter of queue_work_node is system_unbound_wq, so it can accept concurrent operations. which will also not change the code logic, and will not lead to deadlock.
--- drivers/base/dd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/base/dd.c +4 -1
@@ -1094,6 +1094,7 @@ static void __driver_attach_async_helper(void *_dev, async_cookie_t cookie)static int __driver_attach (struct device *dev,void *data) {struct device_driver *drv = data; +bool async = false;int ret;/*
@@ -1132,9 +1133,11 @@ static int __driver_attach(struct device *dev, void *data)if (!dev->driver) {get_device (dev); dev->p->async_driver = drv; -async_schedule_dev (__driver_attach_async_helper, dev); + async = true; }device_unlock (dev); +if (async) +async_schedule_dev (__driver_attach_async_helper, dev);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 443/779 clk: qcom: clk-krait: unlock spin after mux completion
In reply to Greg Kroah-HartmanFrom: Ansuel Smith <[email protected]>
[ Upstream commit df83d2c9e72910416f650ade1e07cc314ff02731 ]
Unlock spinlock after the mux switch is completed to prevent any corner case of mux request while the switch still needs to be done.
--- drivers/clk/qcom/clk-krait.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/clk/qcom/clk-krait.c +6 -1
@@ -32,11 +32,16 @@ static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel) regval |= (sel & mux->mask) << (mux->shift +LPL_SHIFT ); }krait_set_l2_indirect_reg (mux->offset, regval); -spin_unlock_irqrestore (&krait_clock_reg_lock, flags);/* Wait for switch to complete. */ mb ();udelay (1 ); + +/* +* Unlock now to make sure the mux register is not +* modified while switching to the new parent. +*/ +spin_unlock_irqrestore (&krait_clock_reg_lock, flags); }static int krait_mux_set_parent (struct clk_hw *hw,u8 index)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 444/779 clk: qcom: gcc-msm8939: Add missing SYSTEM_MM_NOC_BFDCD_CLK_SRC
In reply to Greg Kroah-HartmanFrom: Bryan O'Donoghue <[email protected]>
[ Upstream commit 07e7fcf1714c5f9930ad27613fea940aedba68da ]
When adding in the indexes for this clock-controller we missed SYSTEM_MM_NOC_BFDCD_CLK_SRC.
Add it in now.
--- include/dt-bindings/clock/qcom,gcc-msm8939.h | 1 + 1 file changed, 1 insertion(+)
include/dt-bindings/clock/qcom,gcc-msm8939.h +1 -0
@@ -192,6 +192,7 @@#define GCC_VENUS0_CORE0_VCODEC0_CLK 183#define GCC_VENUS0_CORE1_VCODEC0_CLK 184#define GCC_OXILI_TIMER_CLK 185 +#define SYSTEM_MM_NOC_BFDCD_CLK_SRC 186/* Indexes for GDSCs */ #define BIMC_GDSC 0
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 445/779 clk: qcom: gcc-msm8939: Fix bimc_ddr_clk_src rcgr base address
In reply to Greg Kroah-HartmanFrom: Bryan O'Donoghue <[email protected]>
[ Upstream commit 63d42708320d6d2ca9ed505123d50ff4a542c36f ]
Reviewing qcom docs for the 8939 we can see the command rcgr is pointing to the wrong address. bimc_ddr_clk_src_rcgr is @ 0x01832024 not 0x01832004.
--- drivers/clk/qcom/gcc-msm8939.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/gcc-msm8939.c +1 -1
@@ -632,7 +632,7 @@ static struct clk_rcg2 system_noc_bfdcd_clk_src = { };static struct clk_rcg2 bimc_ddr_clk_src = { - .cmd_rcgr =0x32004 , + .cmd_rcgr =0x32024 , .hid_width =5 , .parent_map = gcc_xo_gpll0_bimc_map, .clkr.hw.init = &(struct clk_init_data ){
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 446/779 clk: qcom: gcc-msm8939: Add missing system_mm_noc_bfdcd_clk_src
In reply to Greg Kroah-HartmanFrom: Bryan O'Donoghue <[email protected]>
[ Upstream commit dd363e2f7196278e7a30f509a0e8a841cb763b14 ]
The msm8939 has an additional higher operating point for the multi-media peripherals. The higher throughput MM componets operate off of the system-mm noc not the system noc.
system_mm_noc_bfdcd_clk_src is the source clock for the higher frequency capable system noc mm.
Maximum frequency for the MM SNOC is 400 MHz.
--- drivers/clk/qcom/gcc-msm8939.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/clk/qcom/gcc-msm8939.c +13 -0
@@ -644,6 +644,18 @@ static struct clk_rcg2 bimc_ddr_clk_src = { }, }; +static struct clk_rcg2 system_mm_noc_bfdcd_clk_src = { + .cmd_rcgr =0x2600c , + .hid_width =5 , + .parent_map = gcc_xo_gpll0_gpll6a_map, + .clkr.hw.init = &(struct clk_init_data ){ + .name ="system_mm_noc_bfdcd_clk_src" , + .parent_data = gcc_xo_gpll0_gpll6a_parent_data, + .num_parents =3 , + .ops = &clk_rcg2_ops, + }, +}; +static const struct freq_tbl ftbl_gcc_camss_ahb_clk[] = {F (40000000 ,P_GPLL0 ,10 ,1 ,2 ),F (80000000 ,P_GPLL0 ,10 ,0 ,0 ),
@@ -3623,6 +3635,7 @@ static struct clk_regmap *gcc_msm8939_clocks[] = { [GPLL2_VOTE] = &gpll2_vote, [PCNOC_BFDCD_CLK_SRC] = &pcnoc_bfdcd_clk_src.clkr, [SYSTEM_NOC_BFDCD_CLK_SRC] = &system_noc_bfdcd_clk_src.clkr, + [SYSTEM_MM_NOC_BFDCD_CLK_SRC] = &system_mm_noc_bfdcd_clk_src.clkr, [CAMSS_AHB_CLK_SRC] = &camss_ahb_clk_src.clkr, [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr, [CSI0_CLK_SRC] = &csi0_clk_src.clkr,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 447/779 clk: qcom: gcc-msm8939: Point MM peripherals to system_mm_noc clock
In reply to Greg Kroah-HartmanFrom: Bryan O'Donoghue <[email protected]>
[ Upstream commit 05eed0990927aa9634682fec58660e30f7b7ae30 ]
Qcom docs indciate the following peripherals operating from System NOC MM not from System NOC clocks.
- MDP
- VFE
- JPEGe
- Venus
Switch over the relevant parent pointers.
--- drivers/clk/qcom/gcc-msm8939.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/clk/qcom/gcc-msm8939.c +8 -8
@@ -2453,7 +2453,7 @@ static struct clk_branch gcc_camss_jpeg_axi_clk = { .hw.init = &(struct clk_init_data){ .name ="gcc_camss_jpeg_axi_clk" , .parent_data = &(const struct clk_parent_data ){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents =1 , .flags =CLK_SET_RATE_PARENT ,
@@ -2657,7 +2657,7 @@ static struct clk_branch gcc_camss_vfe_axi_clk = { .hw.init = &(struct clk_init_data){ .name ="gcc_camss_vfe_axi_clk" , .parent_data = &(const struct clk_parent_data ){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents =1 , .flags =CLK_SET_RATE_PARENT ,
@@ -2813,7 +2813,7 @@ static struct clk_branch gcc_mdss_axi_clk = { .hw.init = &(struct clk_init_data){ .name ="gcc_mdss_axi_clk" , .parent_data = &(const struct clk_parent_data ){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents =1 , .flags =CLK_SET_RATE_PARENT ,
@@ -3205,7 +3205,7 @@ static struct clk_branch gcc_mdp_tbu_clk = { .hw.init = &(struct clk_init_data){ .name ="gcc_mdp_tbu_clk" , .parent_data = &(const struct clk_parent_data ){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents =1 , .flags =CLK_SET_RATE_PARENT ,
@@ -3223,7 +3223,7 @@ static struct clk_branch gcc_venus_tbu_clk = { .hw.init = &(struct clk_init_data){ .name ="gcc_venus_tbu_clk" , .parent_data = &(const struct clk_parent_data ){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents =1 , .flags =CLK_SET_RATE_PARENT ,
@@ -3241,7 +3241,7 @@ static struct clk_branch gcc_vfe_tbu_clk = { .hw.init = &(struct clk_init_data){ .name ="gcc_vfe_tbu_clk" , .parent_data = &(const struct clk_parent_data ){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents =1 , .flags =CLK_SET_RATE_PARENT ,
@@ -3259,7 +3259,7 @@ static struct clk_branch gcc_jpeg_tbu_clk = { .hw.init = &(struct clk_init_data){ .name ="gcc_jpeg_tbu_clk" , .parent_data = &(const struct clk_parent_data ){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents =1 , .flags =CLK_SET_RATE_PARENT ,
@@ -3496,7 +3496,7 @@ static struct clk_branch gcc_venus0_axi_clk = { .hw.init = &(struct clk_init_data){ .name ="gcc_venus0_axi_clk" , .parent_data = &(const struct clk_parent_data ){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents =1 , .flags =CLK_SET_RATE_PARENT ,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 448/779 usb: host: xhci: use snprintf() in xhci_decode_trb()
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 1ce69c35b86038dd11d3a6115a04501c5b89a940 ]
Commit cbf286e8ef83 ("xhci: fix unsafe memory usage in xhci tracing") apparently missed one sprintf() call in xhci_decode_trb() -- replace it with the snprintf() call as well...
Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool.
--- drivers/usb/host/xhci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/xhci.h +1 -1
@@ -2395,7 +2395,7 @@ static inline const char *xhci_decode_trb(char *str, size_t size, field3 & TRB_CYCLE ? 'C' : 'c');break ;case TRB_STOP_RING : - sprintf(str, + snprintf(str, size, "%s: slot %d sp %d ep %d flags %c", xhci_trb_type_string(type), TRB_TO_SLOT_ID(field3),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 449/779 RDMA/rxe: Fix deadlock in rxe_do_local_ops()
In reply to Greg Kroah-HartmanFrom: Bob Pearson <[email protected]>
[ Upstream commit 7cb33d1bc1ac8e51fd88928f96674d392f8e07c4 ]
When a local operation (invalidate mr, reg mr, bind mw) is finished there will be no ack packet coming from a responder to cause the wqe to be completed. This may happen anyway if a subsequent wqe performs IO. Currently if the wqe is signalled the completer tasklet is scheduled immediately but not otherwise.
This leads to a deadlock if the next wqe has the fence bit set in send flags and the operation is not signalled. This patch removes the condition that the wqe must be signalled in order to schedule the completer tasklet which is the simplest fix for this deadlock and is fairly low cost. This is the analog for local operations of always setting the ackreq bit in all last or only request packets even if the operation is not signalled.
--- drivers/infiniband/sw/rxe/rxe_req.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/infiniband/sw/rxe/rxe_req.c +5 -3
@@ -612,9 +612,11 @@ static int rxe_do_local_ops(struct rxe_qp *qp, struct rxe_send_wqe *wqe) wqe->status =IB_WC_SUCCESS ; qp->req.wqe_index =next_index (qp->sq.queue, qp->req.wqe_index); -if ((wqe->wr.send_flags &IB_SEND_SIGNALED ) || - qp->sq_sig_type ==IB_SIGNAL_ALL_WR ) -rxe_run_task (&qp->comp.task,1 ); +/* There is no ack coming for local work requests +* which can lead to a deadlock. So go ahead and complete +* it now. +*/ +rxe_run_task (&qp->comp.task,1 );return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 450/779 clk: qcom: ipq8074: fix NSS core PLL-s
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit ca41ec1b30434636c56c5600b24a8d964d359d9c ]
Like in IPQ6018 the NSS related Alpha PLL-s require initial configuration to work.
So, obtain the regmap that is required for the Alpha PLL configuration and thus utilize the qcom_cc_really_probe() as we already have the regmap. Then utilize the Alpha PLL configs from the downstream QCA 5.4 based kernel to configure them.
This fixes the UBI32 and NSS crypto PLL-s failing to get enabled by the kernel.
--- drivers/clk/qcom/gcc-ipq8074.c | 39 +++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-)
drivers/clk/qcom/gcc-ipq8074.c +38 -1
@@ -4371,6 +4371,33 @@ static struct clk_branch gcc_pcie0_axi_s_bridge_clk = { }, }; +static const struct alpha_pll_config ubi32_pll_config = { + .l =0x4e , + .config_ctl_val =0x200d4aa8 , + .config_ctl_hi_val =0x3c2 , + .main_output_mask =BIT (0 ), + .aux_output_mask =BIT (1 ), + .pre_div_val =0x0 , + .pre_div_mask =BIT (12 ), + .post_div_val =0x0 , + .post_div_mask =GENMASK (9 ,8 ), +}; + +static const struct alpha_pll_config nss_crypto_pll_config = { + .l =0x3e , + .alpha =0x0 , + .alpha_hi =0x80 , + .config_ctl_val =0x4001055b , + .main_output_mask =BIT (0 ), + .pre_div_val =0x0 , + .pre_div_mask =GENMASK (14 ,12 ), + .post_div_val =0x1 <<8 , + .post_div_mask =GENMASK (11 ,8 ), + .vco_mask =GENMASK (21 ,20 ), + .vco_val =0x0 , + .alpha_en_mask =BIT (24 ), +}; +static struct clk_hw *gcc_ipq8074_hws[] = { &gpll0_out_main_div2.hw, &gpll6_out_main_div2.hw,
@@ -4772,7 +4799,17 @@ static const struct qcom_cc_desc gcc_ipq8074_desc = {static int gcc_ipq8074_probe (struct platform_device *pdev) { -return qcom_cc_probe (pdev, &gcc_ipq8074_desc); +struct regmap *regmap; + + regmap =qcom_cc_map (pdev, &gcc_ipq8074_desc); +if (IS_ERR (regmap)) +return PTR_ERR (regmap); + +clk_alpha_pll_configure (&ubi32_pll_main, regmap, &ubi32_pll_config); +clk_alpha_pll_configure (&nss_crypto_pll_main, regmap, + &nss_crypto_pll_config); + +return qcom_cc_really_probe (pdev, &gcc_ipq8074_desc, regmap); }static struct platform_driver gcc_ipq8074_driver = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 451/779 clk: qcom: ipq8074: SW workaround for UBI32 PLL lock
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit 3401ea2856ef84f39b75f0dc5ebcaeda81cb90ec ]
UBI32 Huayra PLL fails to lock in 5 us in some SoC silicon and thus it will cause the wait_for_pll() to timeout and thus return the error indicating that the PLL failed to lock.
This is bug in Huayra PLL HW for which SW workaround is to set bit 26 of TEST_CTL register.
This is ported from the QCA 5.4 based downstream kernel.
--- drivers/clk/qcom/gcc-ipq8074.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/clk/qcom/gcc-ipq8074.c +3 -0
@@ -4805,6 +4805,9 @@ static int gcc_ipq8074_probe(struct platform_device *pdev)if (IS_ERR (regmap))return PTR_ERR (regmap); +/* SW Workaround for UBI32 Huayra PLL */ +regmap_update_bits (regmap,0x2501c ,BIT (26 ),BIT (26 )); +clk_alpha_pll_configure (&ubi32_pll_main, regmap, &ubi32_pll_config);clk_alpha_pll_configure (&nss_crypto_pll_main, regmap, &nss_crypto_pll_config);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 452/779 clk: qcom: ipq8074: fix NSS port frequency tables
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit 0e9e61a2815b5cd34f1b495b2d72e8127ce9b794 ]
NSS port 5 and 6 frequency tables are currently broken and are causing a wide ranges of issue like 1G not working at all on port 6 or port 5 being clocked with 312 instead of 125 MHz as UNIPHY1 gets selected.
So, update the frequency tables with the ones from the downstream QCA 5.4 based kernel which has already fixed this.
--- drivers/clk/qcom/gcc-ipq8074.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/clk/qcom/gcc-ipq8074.c +8 -0
@@ -1788,8 +1788,10 @@ static struct clk_regmap_div nss_port4_tx_div_clk_src = {static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = {F (19200000 ,P_XO ,1 ,0 ,0 ),F (25000000 ,P_UNIPHY1_RX ,12.5 ,0 ,0 ), +F (25000000 ,P_UNIPHY0_RX ,5 ,0 ,0 ),F (78125000 ,P_UNIPHY1_RX ,4 ,0 ,0 ),F (125000000 ,P_UNIPHY1_RX ,2.5 ,0 ,0 ), +F (125000000 ,P_UNIPHY0_RX ,1 ,0 ,0 ),F (156250000 ,P_UNIPHY1_RX ,2 ,0 ,0 ),F (312500000 ,P_UNIPHY1_RX ,1 ,0 ,0 ), { }
@@ -1828,8 +1830,10 @@ static struct clk_regmap_div nss_port5_rx_div_clk_src = {static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = {F (19200000 ,P_XO ,1 ,0 ,0 ),F (25000000 ,P_UNIPHY1_TX ,12.5 ,0 ,0 ), +F (25000000 ,P_UNIPHY0_TX ,5 ,0 ,0 ),F (78125000 ,P_UNIPHY1_TX ,4 ,0 ,0 ),F (125000000 ,P_UNIPHY1_TX ,2.5 ,0 ,0 ), +F (125000000 ,P_UNIPHY0_TX ,1 ,0 ,0 ),F (156250000 ,P_UNIPHY1_TX ,2 ,0 ,0 ),F (312500000 ,P_UNIPHY1_TX ,1 ,0 ,0 ), { }
@@ -1867,8 +1871,10 @@ static struct clk_regmap_div nss_port5_tx_div_clk_src = {static const struct freq_tbl ftbl_nss_port6_rx_clk_src[] = {F (19200000 ,P_XO ,1 ,0 ,0 ), +F (25000000 ,P_UNIPHY2_RX ,5 ,0 ,0 ),F (25000000 ,P_UNIPHY2_RX ,12.5 ,0 ,0 ),F (78125000 ,P_UNIPHY2_RX ,4 ,0 ,0 ), +F (125000000 ,P_UNIPHY2_RX ,1 ,0 ,0 ),F (125000000 ,P_UNIPHY2_RX ,2.5 ,0 ,0 ),F (156250000 ,P_UNIPHY2_RX ,2 ,0 ,0 ),F (312500000 ,P_UNIPHY2_RX ,1 ,0 ,0 ),
@@ -1907,8 +1913,10 @@ static struct clk_regmap_div nss_port6_rx_div_clk_src = {static const struct freq_tbl ftbl_nss_port6_tx_clk_src[] = {F (19200000 ,P_XO ,1 ,0 ,0 ), +F (25000000 ,P_UNIPHY2_TX ,5 ,0 ,0 ),F (25000000 ,P_UNIPHY2_TX ,12.5 ,0 ,0 ),F (78125000 ,P_UNIPHY2_TX ,4 ,0 ,0 ), +F (125000000 ,P_UNIPHY2_TX ,1 ,0 ,0 ),F (125000000 ,P_UNIPHY2_TX ,2.5 ,0 ,0 ),F (156250000 ,P_UNIPHY2_TX ,2 ,0 ,0 ),F (312500000 ,P_UNIPHY2_TX ,1 ,0 ,0 ),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 453/779 clk: qcom: ipq8074: set BRANCH_HALT_DELAY flag for UBI clocks
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit 2bd357e698207e2e65db03007e4be65bf9d6a7b3 ]
Currently, attempting to enable the UBI clocks will cause the stuck at off warning to be printed and clk_enable will fail.
[ 14.936694] gcc_ubi1_ahb_clk status stuck at 'off'
Downstream 5.4 QCA kernel has fixed this by seting the BRANCH_HALT_DELAY flag on UBI clocks, so lets do the same.
--- drivers/clk/qcom/gcc-ipq8074.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/clk/qcom/gcc-ipq8074.c +10 -0
@@ -3354,6 +3354,7 @@ static struct clk_branch gcc_nssnoc_ubi1_ahb_clk = {static struct clk_branch gcc_ubi0_ahb_clk = { .halt_reg =0x6820c , + .halt_check =BRANCH_HALT_DELAY , .clkr = { .enable_reg =0x6820c , .enable_mask =BIT (0 ),
@@ -3371,6 +3372,7 @@ static struct clk_branch gcc_ubi0_ahb_clk = {static struct clk_branch gcc_ubi0_axi_clk = { .halt_reg =0x68200 , + .halt_check =BRANCH_HALT_DELAY , .clkr = { .enable_reg =0x68200 , .enable_mask =BIT (0 ),
@@ -3388,6 +3390,7 @@ static struct clk_branch gcc_ubi0_axi_clk = {static struct clk_branch gcc_ubi0_nc_axi_clk = { .halt_reg =0x68204 , + .halt_check =BRANCH_HALT_DELAY , .clkr = { .enable_reg =0x68204 , .enable_mask =BIT (0 ),
@@ -3405,6 +3408,7 @@ static struct clk_branch gcc_ubi0_nc_axi_clk = {static struct clk_branch gcc_ubi0_core_clk = { .halt_reg =0x68210 , + .halt_check =BRANCH_HALT_DELAY , .clkr = { .enable_reg =0x68210 , .enable_mask =BIT (0 ),
@@ -3422,6 +3426,7 @@ static struct clk_branch gcc_ubi0_core_clk = {static struct clk_branch gcc_ubi0_mpt_clk = { .halt_reg =0x68208 , + .halt_check =BRANCH_HALT_DELAY , .clkr = { .enable_reg =0x68208 , .enable_mask =BIT (0 ),
@@ -3439,6 +3444,7 @@ static struct clk_branch gcc_ubi0_mpt_clk = {static struct clk_branch gcc_ubi1_ahb_clk = { .halt_reg =0x6822c , + .halt_check =BRANCH_HALT_DELAY , .clkr = { .enable_reg =0x6822c , .enable_mask =BIT (0 ),
@@ -3456,6 +3462,7 @@ static struct clk_branch gcc_ubi1_ahb_clk = {static struct clk_branch gcc_ubi1_axi_clk = { .halt_reg =0x68220 , + .halt_check =BRANCH_HALT_DELAY , .clkr = { .enable_reg =0x68220 , .enable_mask =BIT (0 ),
@@ -3473,6 +3480,7 @@ static struct clk_branch gcc_ubi1_axi_clk = {static struct clk_branch gcc_ubi1_nc_axi_clk = { .halt_reg =0x68224 , + .halt_check =BRANCH_HALT_DELAY , .clkr = { .enable_reg =0x68224 , .enable_mask =BIT (0 ),
@@ -3490,6 +3498,7 @@ static struct clk_branch gcc_ubi1_nc_axi_clk = {static struct clk_branch gcc_ubi1_core_clk = { .halt_reg =0x68230 , + .halt_check =BRANCH_HALT_DELAY , .clkr = { .enable_reg =0x68230 , .enable_mask =BIT (0 ),
@@ -3507,6 +3516,7 @@ static struct clk_branch gcc_ubi1_core_clk = {static struct clk_branch gcc_ubi1_mpt_clk = { .halt_reg =0x68228 , + .halt_check =BRANCH_HALT_DELAY , .clkr = { .enable_reg =0x68228 , .enable_mask =BIT (0 ),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 454/779 clk: qcom: camcc-sdm845: Fix topology around titan_top power domain
In reply to Greg Kroah-HartmanFrom: Vladimir Zapolskiy <[email protected]>
[ Upstream commit 103dd2338bbff567bce7acd00fc5a09c806b38ec ]
On SDM845 two found VFE GDSC power domains shall not be operated, if titan top is turned off, thus the former power domains will be set as subdomains by a GDSC registration routine.
--- drivers/clk/qcom/camcc-sdm845.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/clk/qcom/camcc-sdm845.c +4 -0
@@ -1521,6 +1521,8 @@ static struct clk_branch cam_cc_sys_tmr_clk = { }, }; +static struct gdsc titan_top_gdsc; +static struct gdsc bps_gdsc = { .gdscr =0x6004 , .pd = {
@@ -1554,6 +1556,7 @@ static struct gdsc ife_0_gdsc = { .name = "ife_0_gdsc", }, .flags = POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, };
@@ -1563,6 +1566,7 @@ static struct gdsc ife_1_gdsc = { .name = "ife_1_gdsc", }, .flags = POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 455/779 clk: qcom: camcc-sm8250: Fix topology around titan_top power domain
In reply to Greg Kroah-HartmanFrom: Vladimir Zapolskiy <[email protected]>
[ Upstream commit f8acf01a6a4f84baf05181e24bd48def4ba23f5b ]
On SM8250 two found VFE GDSC power domains shall not be operated, if titan top is turned off, thus the former power domains will be set as subdomains by a GDSC registration routine.
--- drivers/clk/qcom/camcc-sm8250.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/clk/qcom/camcc-sm8250.c +4 -0
@@ -2205,6 +2205,8 @@ static struct clk_branch cam_cc_sleep_clk = { }, }; +static struct gdsc titan_top_gdsc; +static struct gdsc bps_gdsc = { .gdscr =0x7004 , .pd = {
@@ -2238,6 +2240,7 @@ static struct gdsc ife_0_gdsc = { .name = "ife_0_gdsc", }, .flags = POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, };
@@ -2247,6 +2250,7 @@ static struct gdsc ife_1_gdsc = { .name = "ife_1_gdsc", }, .flags = POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 456/779 clk: qcom: clk-rcg2: Fail Duty-Cycle configuration if MND divider is not enabled.
In reply to Greg Kroah-HartmanFrom: Nikita Travkin <[email protected]>
[ Upstream commit bdafb609c3bb848d710ad9cd4debd2ee9d6a4049 ]
In cases when MND is not enabled (e.g. when only Half Integer Divider is used), setting D registers makes no effect.
Fail instead of making ineffective write.
--- drivers/clk/qcom/clk-rcg2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/clk/qcom/clk-rcg2.c +6 -1
@@ -405,7 +405,7 @@ static int clk_rcg2_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)static int clk_rcg2_set_duty_cycle (struct clk_hw *hw,struct clk_duty *duty) {struct clk_rcg2 *rcg =to_clk_rcg2 (hw); -u32 notn_m, n, m, d, not2d, mask, duty_per; +u32 notn_m, n, m, d, not2d, mask, duty_per, cfg;int ret;/* Duty-cycle cannot be modified for non-MND RCGs */
@@ -416,6 +416,11 @@ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)regmap_read (rcg->clkr.regmap,RCG_N_OFFSET (rcg), ¬n_m);regmap_read (rcg->clkr.regmap,RCG_M_OFFSET (rcg), &m); +regmap_read (rcg->clkr.regmap,RCG_CFG_OFFSET (rcg), &cfg); + +/* Duty-cycle cannot be modified if MND divider is in bypass mode. */ +if (!(cfg &CFG_MODE_MASK )) +return -EINVAL ; n = (~(notn_m) + m) & mask;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 457/779 clk: qcom: clk-rcg2: Make sure to not write d=0 to the NMD register
In reply to Greg Kroah-HartmanFrom: Nikita Travkin <[email protected]>
[ Upstream commit d0696770cef35a1fd16ea2167e2198c18aa6fbfe ]
Sometimes calculation of d value may result in 0 because of the rounding after integer division. This causes the following error:
[ 113.969689] camss_gp1_clk_src: rcg didn't update its configuration. [ 113.969754] WARNING: CPU: 3 PID: 35 at drivers/clk/qcom/clk-rcg2.c:122 update_config+0xc8/0xdc
Make sure that D value is never zero.
--- drivers/clk/qcom/clk-rcg2.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/clk/qcom/clk-rcg2.c +6 -3
@@ -13,6 +13,7 @@#include <linux/rational.h> #include <linux/regmap.h> #include <linux/math64.h> +#include <linux/minmax.h> #include <linux/slab.h> #include <asm/div64.h>
@@ -429,9 +430,11 @@ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)/* Calculate 2d value */ d =DIV_ROUND_CLOSEST (n * duty_per *2 ,100 ); -/* Check bit widths of 2d. If D is too big reduce duty cycle. */ -if (d > mask) - d = mask; +/* +* Check bit widths of 2d. If D is too big reduce duty cycle. +* Also make sure it is never zero. +*/ + d =clamp_val (d,1 , mask);if ((d /2 ) > (n - m)) d = (n - m) *2 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 458/779 mm/mempolicy: fix get_nodes out of bound access
In reply to Greg Kroah-HartmanFrom: Tianyu Li <[email protected]>
[ Upstream commit 000eca5d044d1ee23b4ca311793cf3fc528da6c6 ]
When user specified more nodes than supported, get_nodes will access nmask array out of bounds.
--- mm/mempolicy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/mempolicy.c +1 -1
@@ -1389,7 +1389,7 @@ static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask, unsigned long bits = min_t(unsigned long, maxnode, BITS_PER_LONG);unsigned long t; -if (get_bitmap (&t, &nmask[maxnode /BITS_PER_LONG ], bits)) +if (get_bitmap (&t, &nmask[(maxnode -1 ) /BITS_PER_LONG ], bits))return -EFAULT ;if (maxnode - bits >=MAX_NUMNODES ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 459/779 PCI: dwc: Stop link on host_init errors and de-initialization
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit 113fa857b74c947137d845e7e635afcf6a59c43a ]
It's logically correct to undo everything that was done when an error is discovered or in the corresponding cleanup counterpart. Otherwise the host controller will be left in an undetermined state. Since the link is set up in the host_init method, deactivate it there in the cleanup-on-error block and stop the link in the antagonistic routine - dw_pcie_host_deinit(). Link deactivation is platform-specific and should be implemented in dw_pcie_ops.stop_link().
--- .../pci/controller/dwc/pcie-designware-host.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
drivers/pci/controller/dwc/pcie-designware-host.c +14 -2
@@ -414,8 +414,14 @@ int dw_pcie_host_init(struct pcie_port *pp) bridge->sysdata = pp; ret =pci_host_probe (bridge); -if (!ret) -return 0 ; +if (ret) + goto err_stop_link; + +return 0 ; + +err_stop_link: +if (pci->ops && pci->ops->stop_link) + pci->ops->stop_link (pci); err_free_msi:if (pp->has_msi_ctrl)
@@ -426,8 +432,14 @@ EXPORT_SYMBOL_GPL(dw_pcie_host_init);void dw_pcie_host_deinit (struct pcie_port *pp) { +struct dw_pcie *pci =to_dw_pcie_from_pp (pp); +pci_stop_root_bus (pp->bridge->bus);pci_remove_root_bus (pp->bridge->bus); + +if (pci->ops && pci->ops->stop_link) + pci->ops->stop_link (pci); +if (pp->has_msi_ctrl)dw_pcie_free_msi (pp); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 460/779 PCI: dwc: Add unroll iATU space support to dw_pcie_disable_atu()
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit d1cf738f2b65a5640234e1da90a68d3523fbed83 ]
dw_pcie_disable_atu() was introduced by f8aed6ec624f ("PCI: dwc:
designware: Add EP mode support") and supported only the viewport version of the iATU CSRs.
DW PCIe IP cores v4.80a and newer also support unrolled iATU/eDMA space. Callers of dw_pcie_disable_atu(), including pci_epc_ops.clear_bar(), pci_epc_ops.unmap_addr(), and dw_pcie_setup_rc(), don't work correctly when it is enabled.
Add dw_pcie_disable_atu() support for controllers with unrolled iATU CSRs enabled.
--- drivers/pci/controller/dwc/pcie-designware.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/pci/controller/dwc/pcie-designware.c +13 -3
@@ -491,7 +491,7 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,void dw_pcie_disable_atu (struct dw_pcie *pci,int index,enum dw_pcie_region_type type) { -int region; +u32 region;switch (type) {case DW_PCIE_REGION_INBOUND :
@@ -504,8 +504,18 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, int index,return ; } -dw_pcie_writel_dbi (pci,PCIE_ATU_VIEWPORT , region | index); -dw_pcie_writel_dbi (pci,PCIE_ATU_CR2 , ~(u32 )PCIE_ATU_ENABLE ); +if (pci->iatu_unroll_enabled) { +if (region ==PCIE_ATU_REGION_INBOUND ) { +dw_pcie_writel_ib_unroll (pci, index,PCIE_ATU_UNR_REGION_CTRL2 , + ~(u32 )PCIE_ATU_ENABLE ); + }else { +dw_pcie_writel_ob_unroll (pci, index,PCIE_ATU_UNR_REGION_CTRL2 , + ~(u32 )PCIE_ATU_ENABLE ); + } + }else { +dw_pcie_writel_dbi (pci,PCIE_ATU_VIEWPORT , region | index); +dw_pcie_writel_dbi (pci,PCIE_ATU_CR2 , ~(u32 )PCIE_ATU_ENABLE ); + } }int dw_pcie_wait_for_link (struct dw_pcie *pci)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 461/779 PCI: dwc: Disable outbound windows only for controllers using iATU
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit d60a2e281e9de2b2f67343b2e39417ca0f4fd54e ]
Some DWC-based controllers (e.g., pcie-al.c and pci-keystone.c, identified by the fact that they override the default dw_child_pcie_ops) use their own address translation approach instead of the DWC internal ATU (iATU). For those controllers, skip disabling the iATU outbound windows.
--- drivers/pci/controller/dwc/pcie-designware-host.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/pci/controller/dwc/pcie-designware-host.c +8 -6
@@ -536,7 +536,6 @@ static struct pci_ops dw_pcie_ops = {void dw_pcie_setup_rc (struct pcie_port *pp) { -int i;u32 val, ctrl, num_ctrls;struct dw_pcie *pci =to_dw_pcie_from_pp (pp);
@@ -588,19 +587,22 @@ void dw_pcie_setup_rc(struct pcie_port *pp)PCI_COMMAND_MASTER |PCI_COMMAND_SERR ;dw_pcie_writel_dbi (pci,PCI_COMMAND , val); -/* Ensure all outbound windows are disabled so there are multiple matches */ -for (i =0 ; i < pci->num_ob_windows; i++) -dw_pcie_disable_atu (pci, i,DW_PCIE_REGION_OUTBOUND ); -/* * If the platform provides its own child bus config accesses, it means * the platform uses its own address translation component rather than * ATU, so we should not program the ATU here. */ if (pp->bridge->child_ops == &dw_child_pcie_ops) { -int atu_idx =0 ; +int i, atu_idx =0 ;struct resource_entry *entry; +/* +* Disable all outbound windows to make sure a transaction +* can't match multiple windows. +*/ +for (i =0 ; i < pci->num_ob_windows; i++) +dw_pcie_disable_atu (pci, i,DW_PCIE_REGION_OUTBOUND ); +/* Get last memory resource entry */ resource_list_for_each_entry (entry, &pp->bridge->windows) {if (resource_type (entry->res) !=IORESOURCE_MEM )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 462/779 PCI: dwc: Set INCREASE_REGION_SIZE flag based on limit address
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit 777e7c3ab73036105e6fc4a67ed950179dbffbab ]
We program the 64-bit ATU limit address (in PCIE_ATU_LIMIT/ PCIE_ATU_UPPER_LIMIT or PCIE_ATU_UNR_LOWER_LIMIT/PCIE_ATU_UNR_UPPER_LIMIT), but in addition, the PCIE_ATU_INCREASE_REGION_SIZE bit must be set if the upper 32 bits of the limit address differ from the upper 32 bits of the base address (see [1,2]).
5b4cf0f65324 ("PCI: dwc: Add upper limit address for outbound iATU") set PCIE_ATU_INCREASE_REGION_SIZE, but only when the *size* was greater than 4GB. It did not set it when a smaller region crossed a 4GB boundary, e.g., [mem 0x0_f0000000-0x1_0fffffff].
Set PCIE_ATU_INCREASE_REGION_SIZE whenever PCIE_ATU_UPPER_LIMIT is greater than PCIE_ATU_UPPER_BASE.
[1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
v5.40a, March 2019, fig.3-36, p.175
[2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
v5.40a, March 2019, fig.3-37, p.176--- drivers/pci/controller/dwc/pcie-designware.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/pci/controller/dwc/pcie-designware.c +10 -6
@@ -287,8 +287,8 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, u8 func_no,dw_pcie_writel_ob_unroll (pci, index,PCIE_ATU_UNR_UPPER_TARGET ,upper_32_bits (pci_addr)); val = type |PCIE_ATU_FUNC_NUM (func_no); - val =upper_32_bits (size -1 ) ? - val |PCIE_ATU_INCREASE_REGION_SIZE : val; +if (upper_32_bits (limit_addr) >upper_32_bits (cpu_addr)) + val |=PCIE_ATU_INCREASE_REGION_SIZE ;if (pci->version ==0x490A ) val =dw_pcie_enable_ecrc (val);dw_pcie_writel_ob_unroll (pci, index,PCIE_ATU_UNR_REGION_CTRL1 , val);
@@ -315,6 +315,7 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no, u64 pci_addr, u64 size) {u32 retries, val; +u64 limit_addr;if (pci->ops && pci->ops->cpu_addr_fixup) cpu_addr = pci->ops->cpu_addr_fixup (pci, cpu_addr);
@@ -325,6 +326,8 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,return ; } + limit_addr = cpu_addr + size -1 ; +dw_pcie_writel_dbi (pci,PCIE_ATU_VIEWPORT ,PCIE_ATU_REGION_OUTBOUND | index); dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_BASE,
@@ -332,17 +335,18 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,dw_pcie_writel_dbi (pci,PCIE_ATU_UPPER_BASE ,upper_32_bits (cpu_addr));dw_pcie_writel_dbi (pci,PCIE_ATU_LIMIT , -lower_32_bits (cpu_addr + size -1 )); +lower_32_bits (limit_addr));if (pci->version >=0x460A )dw_pcie_writel_dbi (pci,PCIE_ATU_UPPER_LIMIT , -upper_32_bits (cpu_addr + size -1 )); +upper_32_bits (limit_addr));dw_pcie_writel_dbi (pci,PCIE_ATU_LOWER_TARGET ,lower_32_bits (pci_addr));dw_pcie_writel_dbi (pci,PCIE_ATU_UPPER_TARGET ,upper_32_bits (pci_addr)); val = type |PCIE_ATU_FUNC_NUM (func_no); - val = ((upper_32_bits (size -1 )) && (pci->version >=0x460A )) ? - val |PCIE_ATU_INCREASE_REGION_SIZE : val; +if (upper_32_bits (limit_addr) >upper_32_bits (cpu_addr) && + pci->version >=0x460A ) + val |=PCIE_ATU_INCREASE_REGION_SIZE ;if (pci->version ==0x490A ) val =dw_pcie_enable_ecrc (val);dw_pcie_writel_dbi (pci,PCIE_ATU_CR1 , val);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 463/779 PCI: dwc: Deallocate EPC memory on dw_pcie_ep_init() errors
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit 8161e9626b50892eaedbd8070ecb1586ecedb109 ]
If dw_pcie_ep_init() fails to perform any action after the EPC memory is initialized and the MSI memory region is allocated, the latter parts won't be undone thus causing a memory leak. Add a cleanup-on-error path to fix these leaks.
--- .../pci/controller/dwc/pcie-designware-ep.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/pci/controller/dwc/pcie-designware-ep.c +16 -2
@@ -777,8 +777,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) ep->msi_mem =pci_epc_mem_alloc_addr (epc, &ep->msi_mem_phys, epc->mem->window.page_size);if (!ep->msi_mem) { + ret = -ENOMEM ;dev_err (dev,"Failed to reserve memory for MSI/MSI-X\n" ); -return -ENOMEM ; + goto err_exit_epc_mem; }if (ep->ops->get_features) {
@@ -787,6 +788,19 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)return 0 ; } -return dw_pcie_ep_init_complete (ep); + ret =dw_pcie_ep_init_complete (ep); +if (ret) + goto err_free_epc_mem; + +return 0 ; + +err_free_epc_mem: +pci_epc_mem_free_addr (epc, ep->msi_mem_phys, ep->msi_mem, + epc->mem->window.page_size); + +err_exit_epc_mem: +pci_epc_mem_exit (epc); + +return ret; }EXPORT_SYMBOL_GPL (dw_pcie_ep_init);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 464/779 PCI: dwc: Always enable CDM check if "snps,enable-cdm-check" exists
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit ec7b952f453ce7eabe7e1bea584626934d44f668 ]
If the "snps,enable-cdm-check" property exists, we should enable the CDM check. But previously dw_pcie_setup() could exit before doing so if the "num-lanes" property was absent or invalid.
Move the CDM enable earlier so we do it regardless of whether "num-lanes" is present.
--- drivers/pci/controller/dwc/pcie-designware.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/pci/controller/dwc/pcie-designware.c +7 -7
@@ -739,6 +739,13 @@ void dw_pcie_setup(struct dw_pcie *pci) val |=PORT_LINK_DLL_LINK_EN ;dw_pcie_writel_dbi (pci,PCIE_PORT_LINK_CONTROL , val); +if (of_property_read_bool (np,"snps,enable-cdm-check" )) { + val =dw_pcie_readl_dbi (pci,PCIE_PL_CHK_REG_CONTROL_STATUS ); + val |=PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS | +PCIE_PL_CHK_REG_CHK_REG_START ; +dw_pcie_writel_dbi (pci,PCIE_PL_CHK_REG_CONTROL_STATUS , val); + } +of_property_read_u32 (np,"num-lanes" , &pci->num_lanes);if (!pci->num_lanes) {dev_dbg (pci->dev,"Using h/w default number of lanes\n" );
@@ -785,11 +792,4 @@ void dw_pcie_setup(struct dw_pcie *pci)break ; }dw_pcie_writel_dbi (pci,PCIE_LINK_WIDTH_SPEED_CONTROL , val); - -if (of_property_read_bool (np,"snps,enable-cdm-check" )) { - val =dw_pcie_readl_dbi (pci,PCIE_PL_CHK_REG_CONTROL_STATUS ); - val |=PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS | -PCIE_PL_CHK_REG_CHK_REG_START ; -dw_pcie_writel_dbi (pci,PCIE_PL_CHK_REG_CONTROL_STATUS , val); - } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 465/779 soundwire: bus_type: fix remove and shutdown support
In reply to Greg Kroah-HartmanFrom: Pierre-Louis Bossart <[email protected]>
[ Upstream commit df6407782964dc7e35ad84230abb38f46314b245 ]
The bus sdw_drv_remove() and sdw_drv_shutdown() helpers are used conditionally, if the driver provides these routines.
These helpers already test if the driver provides a .remove or .shutdown callback, so there's no harm in invoking the sdw_drv_remove() and sdw_drv_shutdown() unconditionally.
In addition, the current code is imbalanced with dev_pm_domain_attach() called from sdw_drv_probe(), but dev_pm_domain_detach() called from sdw_drv_remove() only if the driver provides a .remove callback.
--- drivers/soundwire/bus_type.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/soundwire/bus_type.c +2 -6
@@ -193,12 +193,8 @@ int __sdw_register_driver(struct sdw_driver *drv, struct module *owner) drv->driver.owner = owner; drv->driver.probe = sdw_drv_probe; - -if (drv->remove) - drv->driver.remove = sdw_drv_remove; - -if (drv->shutdown) - drv->driver.shutdown = sdw_drv_shutdown; + drv->driver.remove = sdw_drv_remove; + drv->driver.shutdown = sdw_drv_shutdown;return driver_register (&drv->driver); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 466/779 soundwire: revisit driver bind/unbind and callbacks
In reply to Greg Kroah-HartmanFrom: Pierre-Louis Bossart <[email protected]>
[ Upstream commit bd29c00edd0a5dac8b6e7332bb470cd50f92e893 ]
In the SoundWire probe, we store a pointer from the driver ops into the 'slave' structure. This can lead to kernel oopses when unbinding codec drivers, e.g. with the following sequence to remove machine driver and codec driver.
/sbin/modprobe -r snd_soc_sof_sdw/sbin/modprobe -r snd_soc_rt711
The full details can be found in the BugLink below, for reference the two following examples show different cases of driver ops/callbacks being invoked after the driver .remove().
kernel: BUG: kernel NULL pointer dereference, address: 0000000000000150 kernel: Workqueue: events cdns_update_slave_status_work [soundwire_cadence] kernel: RIP: 0010:mutex_lock+0x19/0x30 kernel: Call Trace: kernel: ? sdw_handle_slave_status+0x426/0xe00 [soundwire_bus 94ff184bf398570c3f8ff7efe9e32529f532e4ae] kernel: ? newidle_balance+0x26a/0x400 kernel: ? cdns_update_slave_status_work+0x1e9/0x200 [soundwire_cadence 1bcf98eebe5ba9833cd433323769ac923c9c6f82]
kernel: BUG: unable to handle page fault for address: ffffffffc07654c8 kernel: Workqueue: pm pm_runtime_work kernel: RIP: 0010:sdw_bus_prep_clk_stop+0x6f/0x160 [soundwire_bus] kernel: Call Trace: kernel: <TASK> kernel: sdw_cdns_clock_stop+0xb5/0x1b0 [soundwire_cadence 1bcf98eebe5ba9833cd433323769ac923c9c6f82] kernel: intel_suspend_runtime+0x5f/0x120 [soundwire_intel aca858f7c87048d3152a4a41bb68abb9b663a1dd] kernel: ? dpm_sysfs_remove+0x60/0x60
This was not detected earlier in Intel tests since the tests first remove the parent PCI device and shut down the bus. The sequence above is a corner case which keeps the bus operational but without a driver bound.
While trying to solve this kernel oopses, it became clear that the existing SoundWire bus does not deal well with the unbind case.
Commit 528be501b7d4a ("soundwire: sdw_slave: add probe_complete structure and new fields") added a 'probed' status variable and a 'probe_complete'
struct completion. This status is however not reset on remove and
likewise the 'probe complete' is not re-initialized, so the bind/unbind/bind test cases would fail. The timeout used before the 'update_status' callback was also a bad idea in hindsight, there
should really be no timing assumption as to if and when a driver is
bound to a device.
An initial draft was based on device_lock() and device_unlock() was tested. This proved too complicated, with deadlocks created during the suspend-resume sequences, which also use the same device_lock/unlock() as the bind/unbind sequences. On a CometLake device, a bad DSDT/BIOS caused spurious resumes and the use of device_lock() caused hangs during suspend. After multiple weeks or testing and painful reverse-engineering of deadlocks on different devices, we looked for alternatives that did not interfere with the device core.
A bus notifier was used successfully to keep track of DRIVER_BOUND and DRIVER_UNBIND events. This solved the bind-unbind-bind case in tests, but it can still be defeated with a theoretical corner case where the memory is freed by a .remove while the callback is in use. The notifier only helps make sure the driver callbacks are valid, but not that the memory allocated in probe remains valid while the callbacks are invoked.
This patch suggests the introduction of a new 'sdw_dev_lock' mutex protecting probe/remove and all driver callbacks. Since this mutex is 'local' to SoundWire only, it does not interfere with existing locks and does not create deadlocks. In addition, this patch removes the 'probe_complete' completion, instead we directly invoke the 'update_status' from the probe routine. That removes any sort of timing dependency and a much better support for the device/driver model, the driver could be bound before the bus started, or eons after the bus started and the hardware would be properly initialized in all cases.
--- drivers/soundwire/bus.c | 75 ++++++++++++++++++++--------------- drivers/soundwire/bus_type.c | 30 +++++++++++--- drivers/soundwire/slave.c | 3 +- drivers/soundwire/stream.c | 53 ++++++++++++++++--------- include/linux/soundwire/sdw.h | 6 +-- 5 files changed, 106 insertions(+), 61 deletions(-)
drivers/soundwire/bus.c +42 -33
@@ -7,6 +7,7 @@#include <linux/pm_runtime.h> #include <linux/soundwire/sdw_registers.h> #include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_type.h> #include "bus.h" #include "sysfs_local.h"
@@ -846,15 +847,21 @@ static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,enum sdw_clk_stop_mode mode, enum sdw_clk_stop_type type) { - int ret; + int ret = 0; -if (slave->ops && slave->ops->clk_stop) { - ret = slave->ops->clk_stop (slave, mode, type); -if (ret <0 ) -return ret; +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 (drv->ops && drv->ops->clk_stop) + ret = drv->ops->clk_stop (slave, mode, type); } -return 0 ; +mutex_unlock (&slave->sdw_dev_lock); + +return ret; } static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
@@ -1616,14 +1623,24 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave) }/* Update the Slave driver */ -if (slave_notify && slave->ops && - slave->ops->interrupt_callback) { - slave_intr.sdca_cascade = sdca_cascade; - slave_intr.control_port = clear; -memcpy (slave_intr.port, &port_status, -sizeof (slave_intr.port)); - - slave->ops->interrupt_callback (slave, &slave_intr); +if (slave_notify) { +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 (drv->ops && drv->ops->interrupt_callback) { + slave_intr.sdca_cascade = sdca_cascade; + slave_intr.control_port = clear; +memcpy (slave_intr.port, &port_status, +sizeof (slave_intr.port)); + + drv->ops->interrupt_callback (slave, &slave_intr); + } + } + +mutex_unlock (&slave->sdw_dev_lock); }/* Ack interrupt */
@@ -1697,29 +1714,21 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)static int sdw_update_slave_status (struct sdw_slave *slave,enum sdw_slave_status status) { -unsigned long time; +int ret =0 ; -if (!slave->probed) { -/* -* the slave status update is typically handled in an -* interrupt thread, which can race with the driver -* probe, e.g. when a module needs to be loaded. -* -* make sure the probe is complete before updating -* status. -*/ - time =wait_for_completion_timeout (&slave->probe_complete, -msecs_to_jiffies (DEFAULT_PROBE_TIMEOUT )); -if (!time) { -dev_err (&slave->dev,"Probe not complete, timed out\n" ); -return -ETIMEDOUT ; - } +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 (drv->ops && drv->ops->update_status) + ret = drv->ops->update_status (slave, status); } -if (!slave->ops || !slave->ops->update_status) -return 0 ; +mutex_unlock (&slave->sdw_dev_lock); -return slave->ops->update_status (slave, status); +return ret; }/**
drivers/soundwire/bus_type.c +25 -5
@@ -98,8 +98,6 @@ static int sdw_drv_probe(struct device *dev)if (!id)return -ENODEV ; - slave->ops = drv->ops; -/* * attach to power domain but don't turn on (last arg) */
@@ -107,19 +105,23 @@ static int sdw_drv_probe(struct device *dev)if (ret)return ret; +mutex_lock (&slave->sdw_dev_lock); + ret = drv->probe (slave, id);if (ret) { name = drv->name;if (!name) name = drv->driver.name; +mutex_unlock (&slave->sdw_dev_lock); +dev_err (dev,"Probe of %s failed: %d\n" , name, ret);dev_pm_domain_detach (dev, false);return ret; }/* device is probed so let's read the properties now */ -if (slave->ops && slave->ops->read_prop) - slave->ops->read_prop (slave); +if (drv->ops && drv->ops->read_prop) + drv->ops->read_prop (slave);/* init the sysfs as we have properties now */ ret =sdw_slave_sysfs_init (slave);
@@ -139,7 +141,19 @@ static int sdw_drv_probe(struct device *dev) slave->prop.clk_stop_timeout); slave->probed = true; -complete (&slave->probe_complete); + +/* +* if the probe happened after the bus was started, notify the codec driver +* of the current hardware status to e.g. start the initialization. +* Errors are only logged as warnings to avoid failing the probe. +*/ +if (drv->ops && drv->ops->update_status) { + ret = drv->ops->update_status (slave, slave->status); +if (ret <0 ) +dev_warn (dev,"%s: update_status failed with status %d\n" , __func__, ret); + } + +mutex_unlock (&slave->sdw_dev_lock);dev_dbg (dev,"probe complete\n" );
@@ -152,9 +166,15 @@ static int sdw_drv_remove(struct device *dev)struct sdw_driver *drv =drv_to_sdw_driver (dev->driver);int ret =0 ; +mutex_lock (&slave->sdw_dev_lock); + + slave->probed = false; +if (drv->remove) ret = drv->remove (slave); +mutex_unlock (&slave->sdw_dev_lock); +dev_pm_domain_detach (dev, false);return ret;
drivers/soundwire/slave.c +2 -1
@@ -12,6 +12,7 @@ static void sdw_slave_release(struct device *dev) {struct sdw_slave *slave =dev_to_sdw_dev (dev); +mutex_destroy (&slave->sdw_dev_lock);kfree (slave); }
@@ -58,9 +59,9 @@ int sdw_slave_add(struct sdw_bus *bus,init_completion (&slave->enumeration_complete);init_completion (&slave->initialization_complete); slave->dev_num =0 ; -init_completion (&slave->probe_complete); slave->probed = false; slave->first_interrupt_done = false; +mutex_init (&slave->sdw_dev_lock);for (i =0 ; i <SDW_MAX_PORTS ; i++)init_completion (&slave->port_ready[i]);
drivers/soundwire/stream.c +35 -18
85 lines not on this page · raw message
include/linux/soundwire/sdw.h +2 -4
@@ -646,9 +646,6 @@ struct sdw_slave_ops {* @dev_num: Current Device Number, values can be 0 or dev_num_sticky * @dev_num_sticky: one-time static Device Number assigned by Bus * @probed: boolean tracking driver state -* @probe_complete: completion utility to control potential races -* on startup between driver probe/initialization and SoundWire -* Slave state changes/implementation-defined interrupts * @enumeration_complete: completion utility to control potential races * on startup between device enumeration and read/write access to the * Slave device
@@ -663,6 +660,7 @@ struct sdw_slave_ops {* for a Slave happens for the first time after enumeration * @is_mockup_device: status flag used to squelch errors in the command/control * protocol for SoundWire mockup devices +* @sdw_dev_lock: mutex used to protect callbacks/remove races */ struct sdw_slave {struct sdw_slave_id id;
@@ -680,12 +678,12 @@ struct sdw_slave {u16 dev_num;u16 dev_num_sticky;bool probed; -struct completion probe_complete;struct completion enumeration_complete;struct completion initialization_complete;u32 unattach_request;bool first_interrupt_done;bool is_mockup_device; +struct mutex sdw_dev_lock;/* protect callbacks/remove races */ };#define dev_to_sdw_dev (_dev) container_of(_dev, struct sdw_slave, dev)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 467/779 KVM: arm64: Dont return from void function
In reply to Greg Kroah-HartmanFrom: Quentin Perret <[email protected]>
[ Upstream commit 1c3ace2b8b3995d3213c5e2d2aca01a0577a3b0f ]
Although harmless, the return statement in kvm_unexpected_el2_exception is rather confusing as the function itself has a void return type. The C standard is also pretty clear that "A return statement with an expression shall not appear in a function whose return type is void". Given that this return statement does not seem to add any actual value, let's not pointlessly violate the standard.
Build-tested with GCC 10 and CLANG 13 for good measure, the disassembled code is identical with or without the return statement.
--- arch/arm64/kvm/hyp/nvhe/switch.c | 2 +- arch/arm64/kvm/hyp/vhe/switch.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kvm/hyp/nvhe/switch.c +1 -1
@@ -279,5 +279,5 @@ void __noreturn hyp_panic(void) asmlinkage void kvm_unexpected_el2_exception(void) { -return __kvm_unexpected_el2_exception (); +__kvm_unexpected_el2_exception (); }
arch/arm64/kvm/hyp/vhe/switch.c +1 -1
@@ -220,5 +220,5 @@ void __noreturn hyp_panic(void) asmlinkage void kvm_unexpected_el2_exception(void) { -return __kvm_unexpected_el2_exception (); +__kvm_unexpected_el2_exception (); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 468/779 dmaengine: sf-pdma: Add multithread support for a DMA channel
In reply to Greg Kroah-HartmanFrom: Viacheslav Mitrofanov <[email protected]>
[ Upstream commit b2cc5c465c2cb8ab697c3fd6583c614e3f6cfbcc ]
When we get a DMA channel and try to use it in multiple threads it will cause oops and hanging the system.
% echo 64 > /sys/module/dmatest/parameters/threads_per_chan % echo 10000 > /sys/module/dmatest/parameters/iterations % echo 1 > /sys/module/dmatest/parameters/run
[ 89.480664] Unable to handle kernel NULL pointer dereference at virtual
address 00000000000000a0
[ 89.488725] Oops [#1]
[ 89.494708] CPU: 2 PID: 1008 Comm: dma0chan0-copy0 Not tainted
5.17.0-rc5
[ 89.509385] epc : vchan_find_desc+0x32/0x46
[ 89.513553] ra : sf_pdma_tx_status+0xca/0xd6This happens because of data race. Each thread rewrite channels's descriptor as soon as device_prep_dma_memcpy() is called. It leads to the situation when the driver thinks that it uses right descriptor that actually is freed or substituted for other one.
With current fixes a descriptor changes its value only when it has been used. A new descriptor is acquired from vc->desc_issued queue that is already filled with descriptors that are ready to be sent. Threads have no direct access to DMA channel descriptor. Now it is just possible to queue a descriptor for further processing.
--- drivers/dma/sf-pdma/sf-pdma.c | 44 ++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 14 deletions(-)
drivers/dma/sf-pdma/sf-pdma.c +30 -14
@@ -52,16 +52,6 @@ static inline struct sf_pdma_desc *to_sf_pdma_desc(struct virt_dma_desc *vd)static struct sf_pdma_desc *sf_pdma_alloc_desc (struct sf_pdma_chan *chan) {struct sf_pdma_desc *desc; -unsigned long flags; - -spin_lock_irqsave (&chan->lock, flags); - -if (chan->desc && !chan->desc->in_use) { -spin_unlock_irqrestore (&chan->lock, flags); -return chan->desc; - } - -spin_unlock_irqrestore (&chan->lock, flags); desc =kzalloc (sizeof (*desc),GFP_NOWAIT );if (!desc)
@@ -111,7 +101,6 @@ sf_pdma_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dest, dma_addr_t src, desc->async_tx =vchan_tx_prep (&chan->vchan, &desc->vdesc, flags);spin_lock_irqsave (&chan->vchan.lock, iflags); - chan->desc = desc;sf_pdma_fill_desc (desc, dest, src, len);spin_unlock_irqrestore (&chan->vchan.lock, iflags);
@@ -170,11 +159,17 @@ static size_t sf_pdma_desc_residue(struct sf_pdma_chan *chan,unsigned long flags;u64 residue =0 ;struct sf_pdma_desc *desc; -struct dma_async_tx_descriptor *tx; +struct dma_async_tx_descriptor *tx =NULL ;spin_lock_irqsave (&chan->vchan.lock, flags); - tx = &chan->desc->vdesc.tx; +list_for_each_entry (vd, &chan->vchan.desc_submitted, node) +if (vd->tx.cookie == cookie) + tx = &vd->tx; + +if (!tx) + goto out; +if (cookie == tx->chan->completed_cookie) goto out;
@@ -241,6 +236,19 @@ static void sf_pdma_enable_request(struct sf_pdma_chan *chan)writel (v, regs->ctrl); } +static struct sf_pdma_desc *sf_pdma_get_first_pending_desc (struct sf_pdma_chan *chan) +{ +struct virt_dma_chan *vchan = &chan->vchan; +struct virt_dma_desc *vdesc; + +if (list_empty (&vchan->desc_issued)) +return NULL ; + + vdesc = list_first_entry(&vchan->desc_issued, struct virt_dma_desc, node); + + return container_of(vdesc, struct sf_pdma_desc, vdesc); +} +static void sf_pdma_xfer_desc (struct sf_pdma_chan *chan) {struct sf_pdma_desc *desc = chan->desc;
@@ -268,8 +276,11 @@ static void sf_pdma_issue_pending(struct dma_chan *dchan)spin_lock_irqsave (&chan->vchan.lock, flags); -if (vchan_issue_pending (&chan->vchan) && chan->desc) +if (!chan->desc &&vchan_issue_pending (&chan->vchan)) { +/* vchan_issue_pending has made a check that desc in not NULL */ + chan->desc =sf_pdma_get_first_pending_desc (chan);sf_pdma_xfer_desc (chan); + }spin_unlock_irqrestore (&chan->vchan.lock, flags); }
@@ -298,6 +309,11 @@ static void sf_pdma_donebh_tasklet(struct tasklet_struct *t)spin_lock_irqsave (&chan->vchan.lock, flags);list_del (&chan->desc->vdesc.node);vchan_cookie_complete (&chan->desc->vdesc); + + chan->desc =sf_pdma_get_first_pending_desc (chan); +if (chan->desc) +sf_pdma_xfer_desc (chan); +spin_unlock_irqrestore (&chan->vchan.lock, flags); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 469/779 PCI: endpoint: Dont stop controller when unbinding endpoint function
In reply to Greg Kroah-HartmanFrom: Shunsuke Mie <[email protected]>
[ Upstream commit 1bc2b7bfba6e2f64edf5e246f3af2967261f6c3d ]
Unbinding an endpoint function from the endpoint controller shouldn't stop the controller. This is especially a problem for multi-function endpoints where other endpoints may still be active.
Don't stop the controller when unbinding one of its endpoints. Normally the controller is stopped via configfs.
--- drivers/pci/endpoint/functions/pci-epf-test.c | 1 - 1 file changed, 1 deletion(-)
drivers/pci/endpoint/functions/pci-epf-test.c +0 -1
@@ -627,7 +627,6 @@ static void pci_epf_test_unbind(struct pci_epf *epf)cancel_delayed_work (&epf_test->cmd_handler);pci_epf_test_clean_dma_chan (epf_test); -pci_epc_stop (epc);for (bar =0 ; bar <PCI_STD_NUM_BARS ; bar++) { epf_bar = &epf->bar[bar];
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 470/779 scsi: qla2xxx: Check correct variable in qla24xx_async_gffid()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 7c33e477bd883f79cccec418980cb8f7f2d50347 ]
There is a copy and paste bug here. It should check ".rsp" instead of ".req". The error message is copy and pasted as well so update that too.
--- drivers/scsi/qla2xxx/qla_gs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/qla2xxx/qla_gs.c +2 -2
@@ -3385,9 +3385,9 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool wait) sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, &sp->u.iocb_cmd.u.ctarg.rsp_dma, GFP_KERNEL); -if (!sp->u.iocb_cmd.u.ctarg.req) { +if (!sp->u.iocb_cmd.u.ctarg.rsp) {ql_log (ql_log_warn, vha,0xd041 , -"%s: Failed to allocate ct_sns request.\n" , +"%s: Failed to allocate ct_sns response.\n" , __func__); goto done_free_sp; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 471/779 intel_th: Fix a resource leak in an error handling path
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 086c28ab7c5699256aced0049aae9c42f1410313 ]
If an error occurs after calling 'pci_alloc_irq_vectors()', 'pci_free_irq_vectors()' must be called as already done in the remove function.
--- drivers/hwtracing/intel_th/pci.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/hwtracing/intel_th/pci.c +8 -2
@@ -100,8 +100,10 @@ static int intel_th_pci_probe(struct pci_dev *pdev, } th =intel_th_alloc (&pdev->dev, drvdata, resource, r); -if (IS_ERR (th)) -return PTR_ERR (th); +if (IS_ERR (th)) { + err =PTR_ERR (th); + goto err_free_irq; + } th->activate = intel_th_pci_activate; th->deactivate = intel_th_pci_deactivate;
@@ -109,6 +111,10 @@ static int intel_th_pci_probe(struct pci_dev *pdev,pci_set_master (pdev);return 0 ; + +err_free_irq: +pci_free_irq_vectors (pdev); +return err; }static void intel_th_pci_remove (struct pci_dev *pdev)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 472/779 intel_th: msu-sink: Potential dereference of null pointer
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 82f76a4a720791d889de775b5f7541d601efc8bd ]
The return value of dma_alloc_coherent() needs to be checked. To avoid use of null pointer in sg_set_buf() in case of the failure of alloc.
--- drivers/hwtracing/intel_th/msu-sink.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/hwtracing/intel_th/msu-sink.c +3 -0
@@ -71,6 +71,9 @@ static int msu_sink_alloc_window(void *data, struct sg_table **sgt, size_t size) block =dma_alloc_coherent (priv->dev->parent->parent,PAGE_SIZE , &sg_dma_address (sg_ptr),GFP_KERNEL ); +if (!block) +return -ENOMEM ; +sg_set_buf (sg_ptr, block,PAGE_SIZE ); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 473/779 intel_th: msu: Fix vmalloced buffers
In reply to Greg Kroah-HartmanFrom: Alexander Shishkin <[email protected]>
[ Upstream commit ac12ad3ccf6d386e64a9d6a890595a2509d24edd ]
After commit f5ff79fddf0e ("dma-mapping: remove CONFIG_DMA_REMAP") there's a chance of DMA buffer getting allocated via vmalloc(), which messes up the mmapping code:
Quoted 5 lines
RIP: msc_mmap_fault [intel_th_msu] Call Trace: <TASK> __do_fault do_fault
...
Fix this by accounting for vmalloc possibility.
--- drivers/hwtracing/intel_th/msu.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/hwtracing/intel_th/msu.c +12 -2
@@ -1069,6 +1069,16 @@ msc_buffer_set_uc(struct msc *msc) {}static inline void msc_buffer_set_wb (struct msc *msc) {}#endif /* CONFIG_X86 */ +static struct page *msc_sg_page (struct scatterlist *sg) +{ +void *addr =sg_virt (sg); + +if (is_vmalloc_addr (addr)) +return vmalloc_to_page (addr); + +return sg_page (sg); +} +/** * msc_buffer_win_alloc() - alloc a window for a multiblock mode * @msc: MSC device
@@ -1139,7 +1149,7 @@ static void __msc_buffer_win_free(struct msc *msc, struct msc_window *win)int i;for_each_sg (win->sgt->sgl, sg, win->nr_segs, i) { -struct page *page =sg_page (sg); +struct page *page =msc_sg_page (sg); page->mapping =NULL ; dma_free_coherent(msc_dev(win->msc)->parent->parent, PAGE_SIZE,
@@ -1403,7 +1413,7 @@ static struct page *msc_buffer_get_page(struct msc *msc, unsigned long pgoff) pgoff -= win->pgoff;for_each_sg (win->sgt->sgl, sg, win->nr_segs, blk) { -struct page *page =sg_page (sg); +struct page *page =msc_sg_page (sg);size_t pgsz =PFN_DOWN (sg->length);if (pgoff < pgsz)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 474/779 binder: fix redefinition of seq_file attributes
In reply to Greg Kroah-HartmanFrom: Carlos Llamas <[email protected]>
[ Upstream commit b7e241bbff24f9e106bf616408fd58bcedc44bae ]
The patchset in [1] exported some definitions to binder_internal.h in order to make the debugfs entries such as 'stats' and 'transaction_log' available in a binderfs instance. However, the DEFINE_SHOW_ATTRIBUTE macro expands into a static function/variable pair, which in turn get redefined each time a source file includes this internal header.
This problem was made evident after a report from the kernel test robot <[email protected]> where several W=1 build warnings are seen in downstream kernels. See the following example:
include/../drivers/android/binder_internal.h:111:23: warning: 'binder_stats_fops' defined but not used [-Wunused-const-variable=]
111 | DEFINE_SHOW_ATTRIBUTE(binder_stats);
| ^~~~~~~~~~~~
include/linux/seq_file.h:174:37: note: in definition of macro 'DEFINE_SHOW_ATTRIBUTE'
174 | static const struct file_operations __name ## _fops = { \
| ^~~~~~This patch fixes the above issues by moving back the definitions into binder.c and instead creates an array of the debugfs entries which is more convenient to share with binderfs and iterate through.
[1] https://lore.kernel.org/all/[email protected]/
--- drivers/android/binder.c | 114 +++++++++++++++++++++--------- drivers/android/binder_internal.h | 46 +++--------- drivers/android/binderfs.c | 47 +++--------- 3 files changed, 100 insertions(+), 107 deletions(-)
drivers/android/binder.c +79 -35
@@ -170,8 +170,32 @@ static inline void binder_stats_created(enum binder_stat_types type)atomic_inc (&binder_stats.obj_created[type]); } -struct binder_transaction_log binder_transaction_log; -struct binder_transaction_log binder_transaction_log_failed; +struct binder_transaction_log_entry { +int debug_id; +int debug_id_done; +int call_type; +int from_proc; +int from_thread; +int target_handle; +int to_proc; +int to_thread; +int to_node; +int data_size; +int offsets_size; +int return_error_line; +uint32_t return_error; +uint32_t return_error_param; +char context_name[BINDERFS_MAX_NAME +1 ]; +}; + +struct binder_transaction_log { +atomic_t cur; +bool full; +struct binder_transaction_log_entry entry[32 ]; +}; + +static struct binder_transaction_log binder_transaction_log; +static struct binder_transaction_log binder_transaction_log_failed;static struct binder_transaction_log_entry *binder_transaction_log_add (struct binder_transaction_log *log)
@@ -5801,8 +5825,7 @@ static void print_binder_proc_stats(struct seq_file *m,print_binder_stats (m," " , &proc->stats); } - -int binder_state_show (struct seq_file *m,void *unused) +static int state_show (struct seq_file *m,void *unused) {struct binder_proc *proc;struct binder_node *node;
@@ -5841,7 +5864,7 @@ int binder_state_show(struct seq_file *m, void *unused)return 0 ; } -int binder_stats_show (struct seq_file *m,void *unused) +static int stats_show (struct seq_file *m,void *unused) {struct binder_proc *proc;
@@ -5857,7 +5880,7 @@ int binder_stats_show(struct seq_file *m, void *unused)return 0 ; } -int binder_transactions_show (struct seq_file *m,void *unused) +static int transactions_show (struct seq_file *m,void *unused) {struct binder_proc *proc;
@@ -5913,7 +5936,7 @@ static void print_binder_transaction_log_entry(struct seq_file *m, "\n" : " (incomplete)\n"); } -int binder_transaction_log_show (struct seq_file *m,void *unused) +static int transaction_log_show (struct seq_file *m,void *unused) {struct binder_transaction_log *log = m->private;unsigned int log_cur =atomic_read (&log->cur);
@@ -5945,6 +5968,45 @@ const struct file_operations binder_fops = { .release = binder_release, }; +DEFINE_SHOW_ATTRIBUTE (state); +DEFINE_SHOW_ATTRIBUTE (stats); +DEFINE_SHOW_ATTRIBUTE (transactions); +DEFINE_SHOW_ATTRIBUTE (transaction_log); + +const struct binder_debugfs_entry binder_debugfs_entries[] = { + { + .name ="state" , + .mode =0444 , + .fops = &state_fops, + .data =NULL , + }, + { + .name ="stats" , + .mode =0444 , + .fops = &stats_fops, + .data =NULL , + }, + { + .name ="transactions" , + .mode =0444 , + .fops = &transactions_fops, + .data =NULL , + }, + { + .name ="transaction_log" , + .mode =0444 , + .fops = &transaction_log_fops, + .data = &binder_transaction_log, + }, + { + .name ="failed_transaction_log" , + .mode =0444 , + .fops = &transaction_log_fops, + .data = &binder_transaction_log_failed, + }, + {}/* terminator */ +}; +static int __init init_binder_device (const char *name) {int ret;
@@ -5990,36 +6052,18 @@ static int __init binder_init(void)atomic_set (&binder_transaction_log_failed.cur, ~0U ); binder_debugfs_dir_entry_root =debugfs_create_dir ("binder" ,NULL ); -if (binder_debugfs_dir_entry_root) +if (binder_debugfs_dir_entry_root) { +const struct binder_debugfs_entry *db_entry; + +binder_for_each_debugfs_entry (db_entry) +debugfs_create_file (db_entry->name, + db_entry->mode, + binder_debugfs_dir_entry_root, + db_entry->data, + db_entry->fops); + binder_debugfs_dir_entry_proc =debugfs_create_dir ("proc" , binder_debugfs_dir_entry_root); - -if (binder_debugfs_dir_entry_root) { -debugfs_create_file ("state" , -0444 , - binder_debugfs_dir_entry_root, -NULL , - &binder_state_fops); -debugfs_create_file ("stats" , -0444 , - binder_debugfs_dir_entry_root, -NULL , - &binder_stats_fops); -debugfs_create_file ("transactions" , -0444 , - binder_debugfs_dir_entry_root, -NULL , - &binder_transactions_fops); -debugfs_create_file ("transaction_log" , -0444 , - binder_debugfs_dir_entry_root, - &binder_transaction_log, - &binder_transaction_log_fops); -debugfs_create_file ("failed_transaction_log" , -0444 , - binder_debugfs_dir_entry_root, - &binder_transaction_log_failed, - &binder_transaction_log_fops); } if (!IS_ENABLED(CONFIG_ANDROID_BINDERFS) &&
drivers/android/binder_internal.h +11 -35
58 lines not on this page · raw message
drivers/android/binderfs.c +10 -37
59 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 475/779 staging: rtl8192u: Fix sleep in atomic context bug in dm_fsync_timer_callback
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 6a0c054930d554ad8f8044ef1fc856d9da391c81 ]
There are sleep in atomic context bugs when dm_fsync_timer_callback is executing. The root cause is that the memory allocation functions with GFP_KERNEL or GFP_NOIO parameters are called in dm_fsync_timer_callback which is a timer handler. The call paths that could trigger bugs are shown below:
(interrupt context)dm_fsync_timer_callback
write_nic_byte
kzalloc(sizeof(data), GFP_KERNEL); //may sleep usb_control_msg
kmalloc(.., GFP_NOIO); //may sleep
write_nic_dword
kzalloc(sizeof(data), GFP_KERNEL); //may sleep usb_control_msg
kmalloc(.., GFP_NOIO); //may sleep
This patch uses delayed work to replace timer and moves the operations that may sleep into the delayed work in order to mitigate bugs.
--- drivers/staging/rtl8192u/r8192U.h | 2 +- drivers/staging/rtl8192u/r8192U_dm.c | 38 +++++++++++++--------------- drivers/staging/rtl8192u/r8192U_dm.h | 2 +- 3 files changed, 20 insertions(+), 22 deletions(-)
drivers/staging/rtl8192u/r8192U.h +1 -1
@@ -1013,7 +1013,7 @@ typedef struct r8192_priv {bool bis_any_nonbepkts;bool bcurrent_turbo_EDCA;bool bis_cur_rdlstate; -struct timer_list fsync_timer; +struct delayed_work fsync_work;bool bfsync_processing;/* 500ms Fsync timer is active or not */ u32 rate_record;u32 rateCountDiffRecord;
drivers/staging/rtl8192u/r8192U_dm.c +18 -20
@@ -2578,19 +2578,20 @@ static void dm_init_fsync(struct net_device *dev) priv->ieee80211->fsync_seconddiff_ratethreshold =200 ; priv->ieee80211->fsync_state = Default_Fsync; priv->framesyncMonitor =1 ;/* current default 0xc38 monitor on */ -timer_setup (&priv->fsync_timer, dm_fsync_timer_callback,0 ); +INIT_DELAYED_WORK (&priv->fsync_work, dm_fsync_work_callback); }static void dm_deInit_fsync (struct net_device *dev) {struct r8192_priv *priv =ieee80211_priv (dev); -del_timer_sync (&priv->fsync_timer); +cancel_delayed_work_sync (&priv->fsync_work); } -void dm_fsync_timer_callback (struct timer_list *t) +void dm_fsync_work_callback (struct work_struct *work) { -struct r8192_priv *priv =from_timer (priv, t, fsync_timer); +struct r8192_priv *priv = + container_of(work, struct r8192_priv, fsync_work.work);struct net_device *dev = priv->ieee80211->dev;u32 rate_index, rate_count =0 , rate_count_diff =0 ;bool bSwitchFromCountDiff = false;
@@ -2657,17 +2658,16 @@ void dm_fsync_timer_callback(struct timer_list *t) } }if (bDoubleTimeInterval) { -if (timer_pending (&priv->fsync_timer)) -del_timer_sync (&priv->fsync_timer); - priv->fsync_timer.expires = jiffies + -msecs_to_jiffies (priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval); -add_timer (&priv->fsync_timer); +cancel_delayed_work_sync (&priv->fsync_work); +schedule_delayed_work (&priv->fsync_work, +msecs_to_jiffies (priv + ->ieee80211->fsync_time_interval * + priv->ieee80211->fsync_multiple_timeinterval)); }else { -if (timer_pending (&priv->fsync_timer)) -del_timer_sync (&priv->fsync_timer); - priv->fsync_timer.expires = jiffies + -msecs_to_jiffies (priv->ieee80211->fsync_time_interval); -add_timer (&priv->fsync_timer); +cancel_delayed_work_sync (&priv->fsync_work); +schedule_delayed_work (&priv->fsync_work, +msecs_to_jiffies (priv + ->ieee80211->fsync_time_interval)); } }else {/* Let Register return to default value; */
@@ -2695,7 +2695,7 @@ static void dm_EndSWFsync(struct net_device *dev)struct r8192_priv *priv =ieee80211_priv (dev);RT_TRACE (COMP_HALDM ,"%s\n" , __func__); -del_timer_sync (&(priv->fsync_timer)); +cancel_delayed_work_sync (&priv->fsync_work);/* Let Register return to default value; */ if (priv->bswitch_fsync) {
@@ -2736,11 +2736,9 @@ static void dm_StartSWFsync(struct net_device *dev)if (priv->ieee80211->fsync_rate_bitmap & rateBitmap) priv->rate_record += priv->stats.received_rate_histogram[1 ][rateIndex]; } -if (timer_pending (&priv->fsync_timer)) -del_timer_sync (&priv->fsync_timer); - priv->fsync_timer.expires = jiffies + -msecs_to_jiffies (priv->ieee80211->fsync_time_interval); -add_timer (&priv->fsync_timer); +cancel_delayed_work_sync (&priv->fsync_work); +schedule_delayed_work (&priv->fsync_work, +msecs_to_jiffies (priv->ieee80211->fsync_time_interval));write_nic_dword (dev, rOFDM0_RxDetector2,0x465c12cd ); }
drivers/staging/rtl8192u/r8192U_dm.h +1 -1
@@ -166,7 +166,7 @@ void dm_force_tx_fw_info(struct net_device *dev,void dm_init_edca_turbo (struct net_device *dev);void dm_rf_operation_test_callback (unsigned long data);void dm_rf_pathcheck_workitemcallback (struct work_struct *work); -void dm_fsync_timer_callback (struct timer_list *t); +void dm_fsync_work_callback (struct work_struct *work);void dm_cck_txpower_adjust (struct net_device *dev,bool binch14);void dm_shadow_init (struct net_device *dev);void dm_initialize_txpower_tracking (struct net_device *dev);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 476/779 mmc: sdhci-of-esdhc: Fix refcount leak in esdhc_signal_voltage_switch
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit b5899a3e2f783a27b268e38d37f9b24c71bddf45 ]
of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak. of_node_put() checks null pointer.
--- drivers/mmc/host/sdhci-of-esdhc.c | 1 + 1 file changed, 1 insertion(+)
drivers/mmc/host/sdhci-of-esdhc.c +1 -0
@@ -904,6 +904,7 @@ static int esdhc_signal_voltage_switch(struct mmc_host *mmc, scfg_node =of_find_matching_node (NULL , scfg_device_ids);if (scfg_node) scfg_base =of_iomap (scfg_node,0 ); +of_node_put (scfg_node);if (scfg_base) { sdhciovselcr =SDHCIOVSELCR_TGLEN |SDHCIOVSELCR_VSELVAL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 477/779 mmc: mxcmmc: Silence a clang warning
In reply to Greg Kroah-HartmanFrom: Fabio Estevam <[email protected]>
[ Upstream commit 7dc65e3c0ef4b746a583b7c58f99873fddf5ccfa ]
Change the of_device_get_match_data() cast to (uintptr_t) to silence the following clang warning:
drivers/mmc/host/mxcmmc.c:1028:18: warning: cast to smaller integer type 'enum mxcmci_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
--- drivers/mmc/host/mxcmmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/mxcmmc.c +1 -1
@@ -1025,7 +1025,7 @@ static int mxcmci_probe(struct platform_device *pdev) mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; mmc->max_seg_size = mmc->max_req_size; - host->devtype = (enum mxcmci_type )of_device_get_match_data (&pdev->dev); + host->devtype = (uintptr_t )of_device_get_match_data (&pdev->dev);/* adjust max_segs after devtype detection */ if (!is_mpc512x_mmc (host))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 478/779 mmc: renesas_sdhi: Get the reset handle early in the probe
In reply to Greg Kroah-HartmanFrom: Lad Prabhakar <[email protected]>
[ Upstream commit 0dac1e498f8130fdacfdd5289e3a7ac87ec1b9ad ]
In case of devm_reset_control_get_optional_exclusive() failure we returned directly instead of jumping to the error path to roll back initialization.
This patch moves devm_reset_control_get_optional_exclusive() early in the probe so that we have the reset handle prior to initialization of the hardware.
--- drivers/mmc/host/renesas_sdhi_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mmc/host/renesas_sdhi_core.c +4 -4
@@ -925,6 +925,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,if (IS_ERR (priv->clk_cd)) priv->clk_cd =NULL ; + priv->rstc =devm_reset_control_get_optional_exclusive (&pdev->dev,NULL ); +if (IS_ERR (priv->rstc)) +return PTR_ERR (priv->rstc); + priv->pinctrl =devm_pinctrl_get (&pdev->dev);if (!IS_ERR (priv->pinctrl)) { priv->pins_default = pinctrl_lookup_state(priv->pinctrl,
@@ -1013,10 +1017,6 @@ int renesas_sdhi_probe(struct platform_device *pdev,if (ret) goto efree; - priv->rstc =devm_reset_control_get_optional_exclusive (&pdev->dev,NULL ); -if (IS_ERR (priv->rstc)) -return PTR_ERR (priv->rstc); - ver =sd_ctrl_read16 (host,CTL_VERSION );/* GEN2_SDR104 is first known SDHI to use 32bit block count */ if (ver <SDHI_VER_GEN2_SDR104 && mmc_data->max_blk_count >U16_MAX )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 479/779 memstick/ms_block: Fix some incorrect memory allocation
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 2e531bc3e0d86362fcd8a577b3278d9ef3cc2ba0 ]
Some functions of the bitmap API take advantage of the fact that a bitmap is an array of long.
So, to make sure this assertion is correct, allocate bitmaps with bitmap_zalloc() instead of kzalloc()+hand-computed number of bytes.
While at it, also use bitmap_free() instead of kfree() to keep the semantic.
--- drivers/memstick/core/ms_block.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/memstick/core/ms_block.c +5 -5
@@ -1341,17 +1341,17 @@ static int msb_ftl_initialize(struct msb_data *msb) msb->zone_count = msb->block_count /MS_BLOCKS_IN_ZONE ; msb->logical_block_count = msb->zone_count *496 -2 ; - msb->used_blocks_bitmap =kzalloc (msb->block_count /8 ,GFP_KERNEL ); - msb->erased_blocks_bitmap =kzalloc (msb->block_count /8 ,GFP_KERNEL ); + msb->used_blocks_bitmap =bitmap_zalloc (msb->block_count,GFP_KERNEL ); + msb->erased_blocks_bitmap =bitmap_zalloc (msb->block_count,GFP_KERNEL ); msb->lba_to_pba_table =kmalloc_array (msb->logical_block_count,sizeof (u16),GFP_KERNEL );if (!msb->used_blocks_bitmap || !msb->lba_to_pba_table || !msb->erased_blocks_bitmap) { -kfree (msb->used_blocks_bitmap); +bitmap_free (msb->used_blocks_bitmap); +bitmap_free (msb->erased_blocks_bitmap);kfree (msb->lba_to_pba_table); -kfree (msb->erased_blocks_bitmap);return -ENOMEM ; }
@@ -1962,7 +1962,7 @@ static int msb_bd_open(struct block_device *bdev, fmode_t mode)static void msb_data_clear (struct msb_data *msb) {kfree (msb->boot_page); -kfree (msb->used_blocks_bitmap); +bitmap_free (msb->used_blocks_bitmap);kfree (msb->lba_to_pba_table);kfree (msb->cache); msb->card =NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 480/779 memstick/ms_block: Fix a memory leak
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 54eb7a55be6779c4d0c25eaf5056498a28595049 ]
'erased_blocks_bitmap' is never freed. As it is allocated at the same time as 'used_blocks_bitmap', it is likely that it should be freed also at the same time.
Add the corresponding bitmap_free() in msb_data_clear().
--- drivers/memstick/core/ms_block.c | 1 + 1 file changed, 1 insertion(+)
drivers/memstick/core/ms_block.c +1 -0
@@ -1963,6 +1963,7 @@ static void msb_data_clear(struct msb_data *msb) {kfree (msb->boot_page);bitmap_free (msb->used_blocks_bitmap); +bitmap_free (msb->erased_blocks_bitmap);kfree (msb->lba_to_pba_table);kfree (msb->cache); msb->card =NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 481/779 mmc: sdhci-of-at91: fix set_uhs_signaling rewriting of MC1R
In reply to Greg Kroah-HartmanFrom: Eugen Hristev <[email protected]>
[ Upstream commit 5987e6ded29d52e42fc7b06aa575c60a25eee38e ]
In set_uhs_signaling, the DDR bit is being set by fully writing the MC1R register.
This can lead to accidental erase of certain bits in this register. Avoid this by doing a read-modify-write operation.
--- drivers/mmc/host/sdhci-of-at91.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/mmc/host/sdhci-of-at91.c +7 -2
@@ -100,8 +100,13 @@ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock)static void sdhci_at91_set_uhs_signaling (struct sdhci_host *host,unsigned int timing) { -if (timing ==MMC_TIMING_MMC_DDR52 ) -sdhci_writeb (host,SDMMC_MC1R_DDR ,SDMMC_MC1R ); +u8 mc1r; + +if (timing ==MMC_TIMING_MMC_DDR52 ) { + mc1r =sdhci_readb (host,SDMMC_MC1R ); + mc1r |=SDMMC_MC1R_DDR ; +sdhci_writeb (host, mc1r,SDMMC_MC1R ); + }sdhci_set_uhs_signaling (host, timing); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 482/779 of: device: Fix missing of_node_put() in of_dma_set_restricted_buffer
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit d17e37c41b7ed38459957a5d2968ba61516fd5c2 ]
We should use of_node_put() for the reference 'node' returned by of_parse_phandle() which will increase the refcount.
--- drivers/of/device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/of/device.c +4 -1
@@ -81,8 +81,11 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)* restricted-dma-pool region is allowed. */ if (of_device_is_compatible (node,"restricted-dma-pool" ) && -of_device_is_available (node)) +of_device_is_available (node)) { +of_node_put (node);break ; + } +of_node_put (node); }/*
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 483/779 mmc: block: Add single read for 4k sector cards
In reply to Greg Kroah-HartmanFrom: Christian Loehle <[email protected]>
[ Upstream commit b3fa3e6dccc465969721b8bd2824213bd235efeb ]
Cards with 4k native sector size may only be read 4k-aligned, accommodate for this in the single read recovery and use it.
--- drivers/mmc/core/block.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
drivers/mmc/core/block.c +14 -14
@@ -175,7 +175,7 @@ static inline int mmc_blk_part_switch(struct mmc_card *card, unsigned int part_type);static void mmc_blk_rw_rq_prep (struct mmc_queue_req *mqrq,struct mmc_card *card, -int disable_multi, +int recovery_mode,struct mmc_queue *mq);static void mmc_blk_hsq_req_done (struct mmc_request *mrq);
@@ -1285,7 +1285,7 @@ static void mmc_blk_eval_resp_error(struct mmc_blk_request *brq) }static void mmc_blk_data_prep (struct mmc_queue *mq,struct mmc_queue_req *mqrq, -int disable_multi,bool *do_rel_wr_p, +int recovery_mode,bool *do_rel_wr_p,bool *do_data_tag_p) {struct mmc_blk_data *md = mq->blkdata;
@@ -1351,12 +1351,12 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, brq->data.blocks--;/* -* After a read error, we redo the request one sector +* After a read error, we redo the request one (native) sector * at a time in order to accurately determine which * sectors can be read successfully. */ -if (disable_multi) - brq->data.blocks =1 ; +if (recovery_mode) + brq->data.blocks =queue_physical_block_size (mq->queue) >>9 ;/* * Some controllers have HW issues while operating
@@ -1573,7 +1573,7 @@ static int mmc_blk_cqe_issue_rw_rq(struct mmc_queue *mq, struct request *req)static void mmc_blk_rw_rq_prep (struct mmc_queue_req *mqrq,struct mmc_card *card, -int disable_multi, +int recovery_mode,struct mmc_queue *mq) {u32 readcmd, writecmd;
@@ -1582,7 +1582,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,struct mmc_blk_data *md = mq->blkdata;bool do_rel_wr, do_data_tag; -mmc_blk_data_prep (mq, mqrq, disable_multi, &do_rel_wr, &do_data_tag); +mmc_blk_data_prep (mq, mqrq, recovery_mode, &do_rel_wr, &do_data_tag); brq->mrq.cmd = &brq->cmd;
@@ -1673,7 +1673,7 @@ static int mmc_blk_fix_state(struct mmc_card *card, struct request *req)#define MMC_READ_SINGLE_RETRIES 2 -/* Single sector read during recovery */ +/* Single (native) sector read during recovery */ static void mmc_blk_read_single (struct mmc_queue *mq,struct request *req) {struct mmc_queue_req *mqrq =req_to_mmc_queue_req (req);
@@ -1681,6 +1681,7 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)struct mmc_card *card = mq->card;struct mmc_host *host = card->host;blk_status_t error =BLK_STS_OK ; +size_t bytes_per_read =queue_physical_block_size (mq->queue); do { u32 status;
@@ -1715,13 +1716,13 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)else error =BLK_STS_OK ; - }while (blk_update_request (req, error,512 )); + }while (blk_update_request (req, error, bytes_per_read));return ; error_exit: mrq->data->bytes_xfered =0 ; -blk_update_request (req,BLK_STS_IOERR ,512 ); +blk_update_request (req,BLK_STS_IOERR , bytes_per_read);/* Let it try the remaining request again */ if (mqrq->retries >MMC_MAX_RETRIES -1 ) mqrq->retries =MMC_MAX_RETRIES -1 ;
@@ -1862,10 +1863,9 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)return ; } -/* FIXME: Missing single sector read for large sector size */ -if (!mmc_large_sector (card) &&rq_data_dir (req) ==READ && - brq->data.blocks >1 ) { -/* Read one sector at a time */ +if (rq_data_dir (req) ==READ && brq->data.blocks > +queue_physical_block_size (mq->queue) >>9 ) { +/* Read one (native) sector at a time */ mmc_blk_read_single (mq, req);return ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 484/779 KVM: s390: pv: leak the topmost page table when destroy fails
In reply to Greg Kroah-HartmanFrom: Claudio Imbrenda <[email protected]>
[ Upstream commit faa2f72cb3569256480c5540d242c84e99965160 ]
Each secure guest must have a unique ASCE (address space control element); we must avoid that new guests use the same page for their ASCE, to avoid errors.
Since the ASCE mostly consists of the address of the topmost page table (plus some flags), we must not return that memory to the pool unless the ASCE is no longer in use.
Only a successful Destroy Secure Configuration UVC will make the ASCE reusable again.
If the Destroy Configuration UVC fails, the ASCE cannot be reused for a secure guest (either for the ASCE or for other memory areas). To avoid a collision, it must not be used again. This is a permanent error and the page becomes in practice unusable, so we set it aside and leak it. On failure we already leak other memory that belongs to the ultravisor (i.e. the variable and base storage for a guest) and not leaking the topmost page table was an oversight.
This error (and thus the leakage) should not happen unless the hardware is broken or KVM has some unknown serious bug.
Message-Id: <[email protected]>
--- arch/s390/include/asm/gmap.h | 2 + arch/s390/kvm/pv.c | 9 ++-- arch/s390/mm/gmap.c | 86 ++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 3 deletions(-)
arch/s390/include/asm/gmap.h +2 -0
@@ -148,4 +148,6 @@ void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long dirty_bitmap[4], unsigned long gaddr, unsigned long vmaddr);int gmap_mark_unmergeable (void );void s390_reset_acc (struct mm_struct *mm); +void s390_unlist_old_asce (struct gmap *gmap); +int s390_replace_asce (struct gmap *gmap);#endif /* _ASM_S390_GMAP_H */
arch/s390/kvm/pv.c +6 -3
@@ -168,10 +168,13 @@ int kvm_s390_pv_deinit_vm(struct kvm *kvm, u16 *rc, u16 *rrc)atomic_set (&kvm->mm->context.is_protected,0 );KVM_UV_EVENT (kvm,3 ,"PROTVIRT DESTROY VM: rc %x rrc %x" , *rc, *rrc);WARN_ONCE (cc,"protvirt destroy vm failed rc %x rrc %x" , *rc, *rrc); -/* Inteded memory leak on "impossible" error */ -if (!cc) +/* Intended memory leak on "impossible" error */ +if (!cc) {kvm_s390_pv_dealloc_vm (kvm); -return cc ? -EIO :0 ; +return 0 ; + } +s390_replace_asce (kvm->arch.gmap); +return -EIO ; }int kvm_s390_pv_init_vm (struct kvm *kvm,u16 *rc,u16 *rrc)
arch/s390/mm/gmap.c +86 -0
89 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 485/779 PCI/portdrv: Dont disable AER reporting in get_port_device_capability()
In reply to Greg Kroah-HartmanFrom: Stefan Roese <[email protected]>
[ Upstream commit 8795e182b02dc87e343c79e73af6b8b7f9c5e635 ]
AER reporting is currently disabled in the DevCtl registers of all non Root Port PCIe devices on systems using pcie_ports_native || host->native_aer, disabling AER completely in such systems. This is because 2bd50dd800b5 ("PCI: PCIe: Disable PCIe port services during port initialization"), added a call to pci_disable_pcie_error_reporting() *after* the AER setup was completed for the PCIe device tree.
Here a longer analysis about the current status of AER enabling / disabling upon bootup provided by Bjorn:
pcie_portdrv_probe
pcie_port_device_register
get_port_device_capability
pci_disable_pcie_error_reporting
clear CERE NFERE FERE URRE # <-- disable for RP USP DSP
pcie_device_init
device_register # new AER service device
aer_probe
aer_enable_rootport # RP only
set_downstream_devices_error_reporting
set_device_error_reporting # self (RP)
if (RP || USP || DSP)
pci_enable_pcie_error_reporting
set CERE NFERE FERE URRE # <-- enable for RP
pci_walk_bus
set_device_error_reporting
if (RP || USP || DSP)
pci_enable_pcie_error_reporting
set CERE NFERE FERE URRE # <-- enable for USP DSP
In a typical Root Port -> Endpoint hierarchy, the above:
- Disables Error Reporting for the Root Port,
- Enables Error Reporting for the Root Port,
- Does NOT enable Error Reporting for the Endpoint because it is not a Root Port or Switch Port.
In a deeper Root Port -> Upstream Switch Port -> Downstream Switch Port -> Endpoint hierarchy:
- Disables Error Reporting for the Root Port,
- Enables Error Reporting for the Root Port,
- Enables Error Reporting for both Switch Ports,
- Does NOT enable Error Reporting for the Endpoint because it is not a Root Port or Switch Port,
- Disables Error Reporting for the Switch Ports when pcie_portdrv_probe() claims them. AER does not re-enable it because these are not Root Ports.
Remove this call to pci_disable_pcie_error_reporting() from get_port_device_capability(), leaving the already enabled AER configuration intact. With this change, AER is enabled in the Root Port and the PCIe switch upstream and downstream ports. Only the PCIe Endpoints don't have AER enabled yet. A follow-up patch will take care of this Endpoint enabling.
--- drivers/pci/pcie/portdrv_core.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
drivers/pci/pcie/portdrv_core.c +1 -8
@@ -222,15 +222,8 @@ static int get_port_device_capability(struct pci_dev *dev)#ifdef CONFIG_PCIEAER if (dev->aer_cap &&pci_aer_available () && - (pcie_ports_native || host->native_aer)) { + (pcie_ports_native || host->native_aer)) services |=PCIE_PORT_SERVICE_AER ; - -/* -* Disable AER on this port in case it's been enabled by the -* BIOS (the AER service driver will enable it when necessary). -*/ -pci_disable_pcie_error_reporting (dev); - }#endif /* Root Ports and Root Complex Event Collectors may generate PMEs */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 486/779 PCI: qcom: Set up rev 2.1.0 PARF_PHY before enabling clocks
In reply to Greg Kroah-HartmanFrom: Christian Marangi <[email protected]>
[ Upstream commit 38f897ae3d44900f627cad708a15db498ce2ca31 ]
We currently enable clocks BEFORE we write to PARF_PHY_CTRL reg to enable clocks and resets. This causes the driver to never set to a ready state with the error 'Phy link never came up'.
This is caused by the PHY clock getting enabled before setting the required bits in the PARF regs.
A workaround for this was set but with this new discovery we can drop the workaround and use a proper solution to the problem by just enabling the clock only AFTER the PARF_PHY_CTRL bit is set.
This correctly sets up the PCIe link and makes it usable even when a bootloader leaves the PCIe link in an undefined state.
--- drivers/pci/controller/dwc/pcie-qcom.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/pci/controller/dwc/pcie-qcom.c +4 -6
@@ -325,8 +325,6 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)reset_control_assert (res->ext_reset);reset_control_assert (res->phy_reset); -writel (1 , pcie->parf +PCIE20_PARF_PHY_CTRL ); - ret =regulator_bulk_enable (ARRAY_SIZE (res->supplies), res->supplies);if (ret <0 ) {dev_err (dev,"cannot enable regulators\n" );
@@ -369,15 +367,15 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) goto err_deassert_axi; } - ret =clk_bulk_prepare_enable (ARRAY_SIZE (res->clks), res->clks); -if (ret) - goto err_clks; -/* enable PCIe clocks and resets */ val =readl (pcie->parf +PCIE20_PARF_PHY_CTRL ); val &= ~BIT (0 );writel (val, pcie->parf +PCIE20_PARF_PHY_CTRL ); + ret =clk_bulk_prepare_enable (ARRAY_SIZE (res->clks), res->clks); +if (ret) + goto err_clks; +if (of_device_is_compatible (node,"qcom,pcie-ipq8064" ) ||of_device_is_compatible (node,"qcom,pcie-ipq8064-v2" )) { writel(PCS_DEEMPH_TX_DEEMPH_GEN1(24) |
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 487/779 scsi: smartpqi: Fix DMA direction for RAID requests
In reply to Greg Kroah-HartmanFrom: Mahesh Rajashekhara <[email protected]>
[ Upstream commit 69695aeaa6621bc49cdd7a8e5a8d1042461e496e ]
Correct a SOP READ and WRITE DMA flags for some requests.
This update corrects DMA direction issues with SCSI commands removed from the controller's internal lookup table.
Currently, SCSI READ BLOCK LIMITS (0x5) was removed from the controller lookup table and exposed a DMA direction flag issue.
SCSI READ BLOCK LIMITS was recently removed from our controller lookup table so the controller uses the respective IU flag field to set the DMA data direction. Since the DMA direction is incorrect the FW never completes the request causing a hang.
Some SCSI commands which use SCSI READ BLOCK LIMITS
* sg_map
* mt -f /dev/stX status
After updating controller firmware, users may notice their tape units failing. This patch resolves the issue.
Also, the AIO path DMA direction is correct.
The DMA direction flag is a day-one bug with no reported BZ.
--- drivers/scsi/smartpqi/smartpqi_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/smartpqi/smartpqi_init.c +2 -2
@@ -5310,10 +5310,10 @@ static int pqi_raid_submit_scsi_cmd_with_io_request( }switch (scmd->sc_data_direction) { -case DMA_TO_DEVICE : +case DMA_FROM_DEVICE : request->data_direction =SOP_READ_FLAG ;break ; -case DMA_FROM_DEVICE : +case DMA_TO_DEVICE : request->data_direction =SOP_WRITE_FLAG ;break ;case DMA_NONE :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 488/779 xtensa: iss/network: provide release() callback
In reply to Greg Kroah-HartmanFrom: Max Filippov <[email protected]>
[ Upstream commit 8864fb8359682912ee99235db7db916733a1fd7b ]
Provide release() callback for the platform device embedded into struct iss_net_private and registered in the iss_net_configure so that platform_device_unregister could be called for it.
--- arch/xtensa/platforms/iss/network.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/xtensa/platforms/iss/network.c +10 -0
@@ -502,6 +502,15 @@ static const struct net_device_ops iss_netdev_ops = { .ndo_set_rx_mode = iss_net_set_multicast_list, }; +static void iss_net_pdev_release (struct device *dev) +{ +struct platform_device *pdev =to_platform_device (dev); +struct iss_net_private *lp = + container_of(pdev, struct iss_net_private, pdev); + +free_netdev (lp->dev); +} +static int iss_net_configure (int index,char *init) {struct net_device *dev;
@@ -558,6 +567,7 @@ static int iss_net_configure(int index, char *init) lp->pdev.id = index; lp->pdev.name =DRIVER_NAME ; + lp->pdev.dev.release = iss_net_pdev_release;platform_device_register (&lp->pdev);SET_NETDEV_DEV (dev, &lp->pdev.dev);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 489/779 xtensa: iss: fix handling error cases in iss_net_configure()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 628ccfc8f5f79dd548319408fcc53949fe97b258 ]
The 'pdev' and 'netdev' need to be released in error cases of iss_net_configure().
Change the return type of iss_net_configure() to void, because it's not used.
--- arch/xtensa/platforms/iss/network.c | 32 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 17 deletions(-)
arch/xtensa/platforms/iss/network.c +15 -17
@@ -511,16 +511,15 @@ static void iss_net_pdev_release(struct device *dev)free_netdev (lp->dev); } -static int iss_net_configure (int index,char *init) +static void iss_net_configure (int index,char *init) {struct net_device *dev;struct iss_net_private *lp; -int err; dev =alloc_etherdev (sizeof (*lp));if (dev ==NULL ) {pr_err ("eth_configure: failed to allocate device\n" ); -return 1 ; +return ; }/* Initialize private element. */
@@ -549,7 +548,7 @@ static int iss_net_configure(int index, char *init)if (!tuntap_probe (lp, index, init)) {pr_err ("%s: invalid arguments. Skipping device!\n" , dev->name); - goto errout; + goto err_free_netdev; }pr_info ("Netdevice %d (%pM)\n" , index, dev->dev_addr);
@@ -557,7 +556,8 @@ static int iss_net_configure(int index, char *init)/* sysfs register */ if (!driver_registered) { -platform_driver_register (&iss_net_driver); +if (platform_driver_register (&iss_net_driver)) + goto err_free_netdev; driver_registered =1 ; }
@@ -568,7 +568,8 @@ static int iss_net_configure(int index, char *init) lp->pdev.id = index; lp->pdev.name =DRIVER_NAME ; lp->pdev.dev.release = iss_net_pdev_release; -platform_device_register (&lp->pdev); +if (platform_device_register (&lp->pdev)) + goto err_free_netdev;SET_NETDEV_DEV (dev, &lp->pdev.dev); dev->netdev_ops = &iss_netdev_ops;
@@ -577,23 +578,20 @@ static int iss_net_configure(int index, char *init) dev->irq =-1 ;rtnl_lock (); - err =register_netdevice (dev); -rtnl_unlock (); - -if (err) { +if (register_netdevice (dev)) { +rtnl_unlock ();pr_err ("%s: error registering net device!\n" , dev->name); -/* XXX: should we call ->remove() here? */ -free_netdev (dev); -return 1 ; +platform_device_unregister (&lp->pdev); +return ; } +rtnl_unlock ();timer_setup (&lp->tl, iss_net_user_timer_expire,0 ); -return 0 ; +return ; -errout: -/* FIXME: unregister; free, etc.. */ -return -EIO ; +err_free_netdev: +free_netdev (dev); }/* ------------------------------------------------------------------------- */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 490/779 usb: gadget: udc: amd5536 depends on HAS_DMA
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit 8097cf2fb3b2205257f1c76f4808e3398d66b6d9 ]
USB_AMD5536UDC should depend on HAS_DMA since it selects USB_SNP_CORE, which depends on HAS_DMA and since 'select' does not follow any dependency chains.
Fixes this kconfig warning:
WARNING: unmet direct dependencies detected for USB_SNP_CORE
Depends on [n]: USB_SUPPORT [=y] && USB_GADGET [=y] && (USB_AMD5536UDC [=y] || USB_SNP_UDC_PLAT [=n]) && HAS_DMA [=n] Selected by [y]:
- USB_AMD5536UDC [=y] && USB_SUPPORT [=y] && USB_GADGET [=y] && USB_PCI [=y]
--- drivers/usb/gadget/udc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/udc/Kconfig +1 -1
@@ -311,7 +311,7 @@ source "drivers/usb/gadget/udc/bdc/Kconfig" config USB_AMD5536UDC tristate "AMD5536 UDC" - depends on USB_PCI + depends on USB_PCI && HAS_DMA select USB_SNP_CORE help The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 491/779 usb: aspeed-vhub: Fix refcount leak bug in ast_vhub_init_desc()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 220fafb4ed04187e9c17be4152da5a7f2ffbdd8c ]
We should call of_node_put() for the reference returned by of_get_child_by_name() which has increased the refcount.
--- drivers/usb/gadget/udc/aspeed-vhub/hub.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/gadget/udc/aspeed-vhub/hub.c +3 -1
@@ -1028,8 +1028,10 @@ static int ast_vhub_init_desc(struct ast_vhub *vhub)/* Initialize vhub String Descriptors. */ INIT_LIST_HEAD (&vhub->vhub_str_desc); desc_np =of_get_child_by_name (vhub_np,"vhub-strings" ); -if (desc_np) +if (desc_np) { ret =ast_vhub_of_parse_str_desc (vhub, desc_np); +of_node_put (desc_np); + }else ret =ast_vhub_str_alloc_add (vhub, &ast_vhub_strings);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 492/779 usb: dwc3: core: Deprecate GCTL.CORESOFTRESET
In reply to Greg Kroah-HartmanFrom: Thinh Nguyen <[email protected]>
[ Upstream commit afbd04e66e5d16ca3c7ea2e3c56eca25558eacf3 ]
Synopsys IP DWC_usb32 and DWC_usb31 version 1.90a and above deprecated GCTL.CORESOFTRESET. The DRD mode switching flow is updated to remove the GCTL soft reset. Add version checks to prevent using deprecated setting in mode switching flow.
--- drivers/usb/dwc3/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/dwc3/core.c +2 -1
@@ -159,7 +159,8 @@ static void __dwc3_set_mode(struct work_struct *work) }/* For DRD host or device mode only */ -if (dwc->desired_dr_role !=DWC3_GCTL_PRTCAP_OTG ) { + if ((DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC31, 190A)) && + dwc->desired_dr_role !=DWC3_GCTL_PRTCAP_OTG ) { reg =dwc3_readl (dwc->regs,DWC3_GCTL ); reg |=DWC3_GCTL_CORESOFTRESET ;dwc3_writel (dwc->regs,DWC3_GCTL , reg);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 493/779 usb: dwc3: core: Do not perform GCTL_CORE_SOFTRESET during bootup
In reply to Greg Kroah-HartmanFrom: Rohith Kollalsi <[email protected]>
[ Upstream commit 07903626d98853e605fe63e5ce149f1b7314bbea ]
According to the programming guide, it is recommended to perform a GCTL_CORE_SOFTRESET only when switching the mode from device to host or host to device. However, it is found that during bootup when __dwc3_set_mode() is called for the first time, GCTL_CORESOFTRESET is done with suspendable bit(BIT 17) of DWC3_GUSB3PIPECTL set. This some times leads to issues like controller going into bad state and controller registers reading value zero. Until GCTL_CORESOFTRESET is done and run/stop bit is set core initialization is not complete. Setting suspendable bit of DWC3_GUSB3PIPECTL and then performing GCTL_CORESOFTRESET is therefore not recommended. Avoid this by only performing the reset if current_dr_role is set, that is, when doing subsequent role switching.
--- drivers/usb/dwc3/core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/usb/dwc3/core.c +7 -3
@@ -158,9 +158,13 @@ static void __dwc3_set_mode(struct work_struct *work)break ; } -/* For DRD host or device mode only */ - if ((DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC31, 190A)) && - dwc->desired_dr_role !=DWC3_GCTL_PRTCAP_OTG ) { +/* +* When current_dr_role is not set, there's no role switching. +* Only perform GCTL.CoreSoftReset when there's DRD role switching. +*/ +if (dwc->current_dr_role && ((DWC3_IP_IS (DWC3 ) || + DWC3_VER_IS_PRIOR(DWC31, 190A)) && + dwc->desired_dr_role !=DWC3_GCTL_PRTCAP_OTG )) { reg =dwc3_readl (dwc->regs,DWC3_GCTL ); reg |=DWC3_GCTL_CORESOFTRESET ;dwc3_writel (dwc->regs,DWC3_GCTL , reg);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 494/779 usb: dwc3: qcom: fix missing optional irq warnings
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit 69bb3520db7cecbccc9e497fc568fa5465c9d43f ]
Not all platforms have all of the four currently supported wakeup interrupts so use the optional irq helpers when looking up interrupts to avoid printing error messages when an optional interrupt is not found:
dwc3-qcom a6f8800.usb: error -ENXIO: IRQ hs_phy_irq not found
--- drivers/usb/dwc3/dwc3-qcom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/dwc3/dwc3-qcom.c +2 -2
@@ -443,9 +443,9 @@ static int dwc3_qcom_get_irq(struct platform_device *pdev,int ret;if (np) - ret =platform_get_irq_byname (pdev_irq, name); + ret =platform_get_irq_byname_optional (pdev_irq, name);else - ret =platform_get_irq (pdev_irq, num); + ret =platform_get_irq_optional (pdev_irq, num);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 495/779 eeprom: idt_89hpesx: uninitialized data in idt_dbgfs_csr_write()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 71d46f1ff2212ced4852c7e77c5176382a1bdcec ]
The simple_write_to_buffer() function will return positive/success if it is able to write a single byte anywhere within the buffer. However that potentially leaves a lot of the buffer uninitialized.
In this code it's better to return 0 if the offset is non-zero. This code is not written to support partial writes. And then return -EFAULT if the buffer is not completely initialized.
--- drivers/misc/eeprom/idt_89hpesx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/misc/eeprom/idt_89hpesx.c +6 -2
@@ -909,14 +909,18 @@ static ssize_t idt_dbgfs_csr_write(struct file *filep, const char __user *ubuf,u32 csraddr, csrval;char *buf; +if (*offp) +return 0 ; +/* Copy data from User-space */ buf =kmalloc (count +1 ,GFP_KERNEL );if (!buf)return -ENOMEM ; - ret =simple_write_to_buffer (buf, count, offp, ubuf, count); -if (ret <0 ) +if (copy_from_user (buf, ubuf, count)) { + ret = -EFAULT ; goto free_buf; + } buf[count] =0 ;/* Find position of colon in the buffer */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 496/779 phy: stm32: fix error return in stm32_usbphyc_phy_init
In reply to Greg Kroah-HartmanFrom: Fabrice Gasnier <[email protected]>
[ Upstream commit 32b378a9179ae4db61cfc5d502717214e6cd1e1c ]
Error code is overridden, in case the PLL doesn't lock. So, the USB initialization can continue. This leads to a platform freeze. This can be avoided by returning proper error code to avoid USB probe freezing the platform. It also displays proper errors in log.
--- drivers/phy/st/phy-stm32-usbphyc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/phy/st/phy-stm32-usbphyc.c +3 -1
@@ -279,7 +279,9 @@ static int stm32_usbphyc_phy_init(struct phy *phy)return 0 ; pll_disable: -return stm32_usbphyc_pll_disable (usbphyc); +stm32_usbphyc_pll_disable (usbphyc); + +return ret; }static int stm32_usbphyc_phy_exit (struct phy *phy)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 497/779 interconnect: imx: fix max_node_id
In reply to Greg Kroah-HartmanFrom: Peng Fan <[email protected]>
[ Upstream commit bd734481e172b4827af09c9ab06c51d2ab7201e6 ]
max_node_id not equal to the ARRAY_SIZE of node array, need increase 1, otherwise xlate will fail for the last entry. And rename max_node_id to num_nodes to reflect the reality.
--- drivers/interconnect/imx/imx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/interconnect/imx/imx.c +4 -4
@@ -226,16 +226,16 @@ int imx_icc_register(struct platform_device *pdev,struct device *dev = &pdev->dev;struct icc_onecell_data *data;struct icc_provider *provider; -int max_node_id; +int num_nodes;int ret;/* icc_onecell_data is indexed by node_id, unlike nodes param */ - max_node_id =get_max_node_id (nodes, nodes_count); - data =devm_kzalloc (dev,struct_size (data, nodes, max_node_id), + num_nodes =get_max_node_id (nodes, nodes_count) +1 ; + data =devm_kzalloc (dev,struct_size (data, nodes, num_nodes),GFP_KERNEL );if (!data)return -ENOMEM ; - data->num_nodes = max_node_id; + data->num_nodes = num_nodes; provider =devm_kzalloc (dev,sizeof (*provider),GFP_KERNEL );if (!provider)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 498/779 um: random: Dont initialise hwrng struct with zero
In reply to Greg Kroah-HartmanFrom: Christopher Obbard <[email protected]>
[ Upstream commit 9e70cbd11b03889c92462cf52edb2bd023c798fa ]
Initialising the hwrng struct with zeros causes a
compile-time sparse warning:
$ ARCH=um make -j10 W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ... CHECK arch/um/drivers/random.c arch/um/drivers/random.c:31:31: sparse: warning: Using plain integer as NULL pointer
Fix the warning by not initialising the hwrng struct with zeros as it is initialised anyway during module init.
--- arch/um/drivers/random.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/um/drivers/random.c +1 -1
@@ -28,7 +28,7 @@* protects against a module being loaded twice at the same time. */ static int random_fd =-1 ; -static struct hwrng hwrng = {0 , }; +static struct hwrng hwrng;static DECLARE_COMPLETION (have_data);static int rng_dev_read (struct hwrng *rng,void *buf,size_t max,bool block)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 499/779 RDMA/irdma: Fix a window for use-after-free
In reply to Greg Kroah-HartmanFrom: Mustafa Ismail <[email protected]>
[ Upstream commit 8ecef7890b3aea78c8bbb501a4b5b8134367b821 ]
During a destroy CQ an interrupt may cause processing of a CQE after CQ resources are freed by irdma_cq_free_rsrc(). Fix this by moving the call to irdma_cq_free_rsrc() after the irdma_sc_cleanup_ceqes(), which is called under the cq_lock.
--- drivers/infiniband/hw/irdma/verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/irdma/verbs.c +1 -1
@@ -1759,11 +1759,11 @@ static int irdma_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)spin_unlock_irqrestore (&iwcq->lock, flags);irdma_cq_wq_destroy (iwdev->rf, cq); -irdma_cq_free_rsrc (iwdev->rf, iwcq);spin_lock_irqsave (&iwceq->ce_lock, flags);irdma_sc_cleanup_ceqes (cq, ceq);spin_unlock_irqrestore (&iwceq->ce_lock, flags); +irdma_cq_free_rsrc (iwdev->rf, iwcq);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 500/779 RDMA/irdma: Fix VLAN connection with wildcard address
In reply to Greg Kroah-HartmanFrom: Mustafa Ismail <[email protected]>
[ Upstream commit 82ab2b52654c43ba24a3f6603fec40874cc5a7e5 ]
When an application listens on a wildcard address, and there are VLAN and non-VLAN IP addresses, iWARP connection establishemnt can fail if the listen node VLAN ID does not match.
Fix this by checking the vlan_id only if not a wildcard listen node.
--- drivers/infiniband/hw/irdma/cm.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/infiniband/hw/irdma/cm.c +6 -5
@@ -1477,12 +1477,13 @@ irdma_find_listener(struct irdma_cm_core *cm_core, u32 *dst_addr, u16 dst_port, list_for_each_entry (listen_node, &cm_core->listen_list, list) {memcpy (listen_addr, listen_node->loc_addr,sizeof (listen_addr)); listen_port = listen_node->loc_port; +if (listen_port != dst_port || + !(listener_state & listen_node->listener_state)) +continue ;/* compare node pair, return node handle if a match */ -if ((!memcmp (listen_addr, dst_addr,sizeof (listen_addr)) || - !memcmp (listen_addr, ip_zero,sizeof (listen_addr))) && - listen_port == dst_port && - vlan_id == listen_node->vlan_id && - (listener_state & listen_node->listener_state)) { +if (!memcmp (listen_addr, ip_zero,sizeof (listen_addr)) || + (!memcmp (listen_addr, dst_addr,sizeof (listen_addr)) && + vlan_id == listen_node->vlan_id)) {refcount_inc (&listen_node->refcnt);spin_unlock_irqrestore (&cm_core->listen_list_lock, flags);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 501/779 RDMA/irdma: Fix setting of QP context err_rq_idx_valid field
In reply to Greg Kroah-HartmanFrom: Mustafa Ismail <[email protected]>
[ Upstream commit 3a844596ed71b7c12ac602f6f6b7b0f17e4d6a90 ]
Setting err_rq_idx_valid field in QP context when the AE source of the AEQE is not associated with an RQ causes the firmware flush to fail.
Set err_rq_idx_valid field in QP context only if it is associated with an RQ. Additionally, cleanup the redundant setting of this field in irdma_process_aeq.
--- drivers/infiniband/hw/irdma/hw.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
drivers/infiniband/hw/irdma/hw.c +4 -11
@@ -257,10 +257,6 @@ static void irdma_process_aeq(struct irdma_pci_f *rf) iwqp->last_aeq = info->ae_id;spin_unlock_irqrestore (&iwqp->lock, flags); ctx_info = &iwqp->ctx_info; -if (rdma_protocol_roce (&iwqp->iwdev->ibdev,1 )) - ctx_info->roce_info->err_rq_idx_valid = true; -else - ctx_info->iwarp_info->err_rq_idx_valid = true; }else {if (info->ae_id !=IRDMA_AE_CQ_OPERATION_ERROR )continue ;
@@ -370,16 +366,12 @@ static void irdma_process_aeq(struct irdma_pci_f *rf)case IRDMA_AE_LCE_FUNCTION_CATASTROPHIC :case IRDMA_AE_LCE_CQ_CATASTROPHIC :case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG : -if (rdma_protocol_roce (&iwdev->ibdev,1 )) - ctx_info->roce_info->err_rq_idx_valid = false; -else - ctx_info->iwarp_info->err_rq_idx_valid = false; - fallthrough;default :ibdev_err (&iwdev->ibdev,"abnormal ae_id = 0x%x bool qp=%d qp_id = %d\n" , info->ae_id, info->qp, info->qp_cq_id);if (rdma_protocol_roce (&iwdev->ibdev,1 )) { -if (!info->sq && ctx_info->roce_info->err_rq_idx_valid) { + ctx_info->roce_info->err_rq_idx_valid = info->rq; +if (info->rq) { ctx_info->roce_info->err_rq_idx = info->wqe_idx;irdma_sc_qp_setctx_roce (&iwqp->sc_qp, iwqp->host_ctx.va, ctx_info);
@@ -388,7 +380,8 @@ static void irdma_process_aeq(struct irdma_pci_f *rf)irdma_cm_disconn (iwqp);break ; } -if (!info->sq && ctx_info->iwarp_info->err_rq_idx_valid) { + ctx_info->iwarp_info->err_rq_idx_valid = info->rq; +if (info->rq) { ctx_info->iwarp_info->err_rq_idx = info->wqe_idx; ctx_info->tcp_info_valid = false; ctx_info->iwarp_info_valid = true;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 502/779 RDMA/rtrs-srv: Fix modinfo output for stringify
In reply to Greg Kroah-HartmanFrom: Jack Wang <[email protected]>
[ Upstream commit ed6e53820ee4f68ed927de17e5675ff2a07a47e2 ]
stringify works with define, not enum.
--- drivers/infiniband/ulp/rtrs/rtrs-pri.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
drivers/infiniband/ulp/rtrs/rtrs-pri.h +11 -10
@@ -23,6 +23,17 @@#define RTRS_PROTO_VER_STRING __stringify(RTRS_PROTO_VER_MAJOR) "." \ __stringify(RTRS_PROTO_VER_MINOR) +/* +* Max IB immediate data size is 2^28 (MAX_IMM_PAYL_BITS) +* and the minimum chunk size is 4096 (2^12). +* So the maximum sess_queue_depth is 65536 (2^16) in theory. +* But mempool_create, create_qp and ib_post_send fail with +* "cannot allocate memory" error if sess_queue_depth is too big. +* Therefore the pratical max value of sess_queue_depth is +* somewhere between 1 and 65534 and it depends on the system. +*/ +#define MAX_SESS_QUEUE_DEPTH 65535 +enum rtrs_imm_const {MAX_IMM_TYPE_BITS =4 ,MAX_IMM_TYPE_MASK = ((1 <<MAX_IMM_TYPE_BITS ) -1 ),
@@ -46,16 +57,6 @@ enum {MAX_PATHS_NUM =128 , -/* -* Max IB immediate data size is 2^28 (MAX_IMM_PAYL_BITS) -* and the minimum chunk size is 4096 (2^12). -* So the maximum sess_queue_depth is 65536 (2^16) in theory. -* But mempool_create, create_qp and ib_post_send fail with -* "cannot allocate memory" error if sess_queue_depth is too big. -* Therefore the pratical max value of sess_queue_depth is -* somewhere between 1 and 65534 and it depends on the system. -*/ -MAX_SESS_QUEUE_DEPTH =65535 ,MIN_CHUNK_SIZE =8192 , RTRS_HB_INTERVAL_MS = 5000,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 503/779 RDMA/rtrs: Fix warning when use poll mode on client side.
In reply to Greg Kroah-HartmanFrom: Jack Wang <[email protected]>
[ Upstream commit 4b6afe9bc955bee44c0527005c3fb0edac91ac30 ]
When testing with poll mode, it will fail and lead to warning below on client side:
$ echo "sessname=bla path=gid:fe80::2:c903:4e:d0b3@gid:fe80::2:c903:8:ca17 device_path=/dev/nullb2 nr_poll_queues=-1" | \ sudo tee /sys/devices/virtual/rnbd-client/ctl/map_device
rnbd_client L597: Mapping device /dev/nullb2 on session bla, (access_mode: rw, nr_poll_queues: 8)
WARNING: CPU: 3 PID: 9886 at drivers/infiniband/core/cq.c:447 ib_cq_pool_get+0x26f/0x2a0 [ib_core]
The problem is in case of poll queue, we need to still call ib_alloc_cq/ib_free_cq, we can't use cq_poll api for poll queue.
As both client and server use shared function from rtrs, set irq_con_num to con_num on server side, which is number of total connection of the session, this way we can differ if the rtrs_con requires pollqueue.
Following up patches will replace the duplicate code with helpers.
--- drivers/infiniband/ulp/rtrs/rtrs-srv.c | 1 + drivers/infiniband/ulp/rtrs/rtrs.c | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-)
drivers/infiniband/ulp/rtrs/rtrs-srv.c +1 -0
@@ -1766,6 +1766,7 @@ static struct rtrs_srv_sess *__alloc_sess(struct rtrs_srv *srv,strscpy (sess->s.sessname, str,sizeof (sess->s.sessname)); sess->s.con_num = con_num; + sess->s.irq_con_num = con_num; sess->s.recon_cnt = recon_cnt;uuid_copy (&sess->s.uuid, uuid);spin_lock_init (&sess->state_lock);
drivers/infiniband/ulp/rtrs/rtrs.c +14 -3
@@ -228,7 +228,12 @@ static int create_cq(struct rtrs_con *con, int cq_vector, int nr_cqe,struct rdma_cm_id *cm_id = con->cm_id;struct ib_cq *cq; - cq =ib_cq_pool_get (cm_id->device, nr_cqe, cq_vector, poll_ctx); +if (con->cid >= con->sess->irq_con_num) + cq =ib_alloc_cq (cm_id->device, con, nr_cqe, cq_vector, + poll_ctx); +else + cq =ib_cq_pool_get (cm_id->device, nr_cqe, cq_vector, poll_ctx); +if (IS_ERR (cq)) {rtrs_err (con->sess,"Creating completion queue failed, errno: %ld\n" ,PTR_ERR (cq));
@@ -283,7 +288,10 @@ int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con, err =create_qp (con, sess->dev->ib_pd, max_send_wr, max_recv_wr, max_send_sge);if (err) { -ib_cq_pool_put (con->cq, con->nr_cqe); +if (con->cid >= con->sess->irq_con_num) +ib_free_cq (con->cq); +else +ib_cq_pool_put (con->cq, con->nr_cqe); con->cq =NULL ;return err; }
@@ -300,7 +308,10 @@ void rtrs_cq_qp_destroy(struct rtrs_con *con) con->qp =NULL ; }if (con->cq) { -ib_cq_pool_put (con->cq, con->nr_cqe); +if (con->cid >= con->sess->irq_con_num) +ib_free_cq (con->cq); +else +ib_cq_pool_put (con->cq, con->nr_cqe); con->cq =NULL ; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 504/779 RDMA/rtrs: Replace duplicate check with is_pollqueue helper
In reply to Greg Kroah-HartmanFrom: Jack Wang <[email protected]>
[ Upstream commit 36332ded46b6292296bc7170fada6e238a0802cc ]
if (con->cid >= con->sess->irq_con_num) check can be replaced with a is_pollqueue helper.
--- drivers/infiniband/ulp/rtrs/rtrs.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/infiniband/ulp/rtrs/rtrs.c +8 -3
@@ -222,13 +222,18 @@ static void qp_event_handler(struct ib_event *ev, void *ctx) } } +static bool is_pollqueue (struct rtrs_con *con) +{ +return con->cid >= con->sess->irq_con_num; +} +static int create_cq (struct rtrs_con *con,int cq_vector,int nr_cqe,enum ib_poll_context poll_ctx) {struct rdma_cm_id *cm_id = con->cm_id;struct ib_cq *cq; -if (con->cid >= con->sess->irq_con_num) +if (is_pollqueue (con)) cq =ib_alloc_cq (cm_id->device, con, nr_cqe, cq_vector, poll_ctx);else
@@ -288,7 +293,7 @@ int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con, err =create_qp (con, sess->dev->ib_pd, max_send_wr, max_recv_wr, max_send_sge);if (err) { -if (con->cid >= con->sess->irq_con_num) +if (is_pollqueue (con))ib_free_cq (con->cq);else ib_cq_pool_put (con->cq, con->nr_cqe);
@@ -308,7 +313,7 @@ void rtrs_cq_qp_destroy(struct rtrs_con *con) con->qp =NULL ; }if (con->cq) { -if (con->cid >= con->sess->irq_con_num) +if (is_pollqueue (con))ib_free_cq (con->cq);else ib_cq_pool_put (con->cq, con->nr_cqe);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 505/779 RDMA/rtrs: Introduce destroy_cq helper
In reply to Greg Kroah-HartmanFrom: Md Haris Iqbal <[email protected]>
[ Upstream commit 6f5649afd3984e35c4b862a05c4511c6d18b27af ]
The same code snip used twice, to avoid duplicate, replace it with a destroy_cq helper.
--- drivers/infiniband/ulp/rtrs/rtrs.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
drivers/infiniband/ulp/rtrs/rtrs.c +13 -12
@@ -279,6 +279,17 @@ static int create_qp(struct rtrs_con *con, struct ib_pd *pd,return ret; } +static void destroy_cq (struct rtrs_con *con) +{ +if (con->cq) { +if (is_pollqueue (con)) +ib_free_cq (con->cq); +else +ib_cq_pool_put (con->cq, con->nr_cqe); + } + con->cq =NULL ; +} + int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con, u32 max_send_sge, int cq_vector, int nr_cqe, u32 max_send_wr, u32 max_recv_wr,
@@ -293,11 +304,7 @@ int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con, err =create_qp (con, sess->dev->ib_pd, max_send_wr, max_recv_wr, max_send_sge);if (err) { -if (is_pollqueue (con)) -ib_free_cq (con->cq); -else -ib_cq_pool_put (con->cq, con->nr_cqe); - con->cq =NULL ; +destroy_cq (con);return err; } con->sess = sess;
@@ -312,13 +319,7 @@ void rtrs_cq_qp_destroy(struct rtrs_con *con)rdma_destroy_qp (con->cm_id); con->qp =NULL ; } -if (con->cq) { -if (is_pollqueue (con)) -ib_free_cq (con->cq); -else -ib_cq_pool_put (con->cq, con->nr_cqe); - con->cq =NULL ; - } +destroy_cq (con); }EXPORT_SYMBOL_GPL (rtrs_cq_qp_destroy);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 506/779 RDMA/rtrs: Do not allow sessname to contain special symbols / and .
In reply to Greg Kroah-HartmanFrom: Md Haris Iqbal <[email protected]>
[ Upstream commit dea7bb3ad3e08f96815330f88a62c24d7a9dacae ]
Allowing these characters in sessname can lead to unexpected results, particularly because / is used as a separator between files in a path, and . points to the current directory.
--- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 6 ++++++ drivers/infiniband/ulp/rtrs/rtrs-srv.c | 5 +++++ 2 files changed, 11 insertions(+)
drivers/infiniband/ulp/rtrs/rtrs-clt.c +6 -0
@@ -2790,6 +2790,12 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,struct rtrs_clt *clt;int err, i; +if (strchr (sessname,'/' ) ||strchr (sessname,'.' )) { +pr_err ("sessname cannot contain / and .\n" ); + err = -EINVAL ; + goto out; + } + clt = alloc_clt(sessname, paths_num, port, pdu_sz, ops->priv, ops->link_ev, reconnect_delay_sec,
drivers/infiniband/ulp/rtrs/rtrs-srv.c +5 -0
@@ -803,6 +803,11 @@ static int process_info_req(struct rtrs_srv_con *con,return err; } +if (strchr (msg->sessname,'/' ) ||strchr (msg->sessname,'.' )) { +rtrs_err (s,"sessname cannot contain / and .\n" ); +return -EINVAL ; + } +if (exist_sessname (sess->srv->ctx, msg->sessname, &sess->srv->paths_uuid)) {rtrs_err (s,"sessname is duplicated: %s\n" , msg->sessname);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 507/779 RDMA/rtrs: Rename rtrs_sess to rtrs_path
In reply to Greg Kroah-HartmanFrom: Vaishali Thakkar <[email protected]>
[ Upstream commit d9372794717f44b6e746d8fbab66763b6d753e71 ]
rtrs_sess is in fact a path. This makes it confusing and difficult to get into the code. So let's rename the structure and related use cases of it.
Coccinelle was used to do the transformation for most of the occurrences and remaining ones were handled manually.
--- drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c | 4 +- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 66 ++++++------- drivers/infiniband/ulp/rtrs/rtrs-clt.h | 4 +- drivers/infiniband/ulp/rtrs/rtrs-pri.h | 14 +-- drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c | 6 +- drivers/infiniband/ulp/rtrs/rtrs-srv.c | 46 ++++----- drivers/infiniband/ulp/rtrs/rtrs-srv.h | 2 +- drivers/infiniband/ulp/rtrs/rtrs.c | 98 ++++++++++---------- 8 files changed, 120 insertions(+), 120 deletions(-)
drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c +2 -2
@@ -13,7 +13,7 @@void rtrs_clt_update_wc_stats (struct rtrs_clt_con *con) { -struct rtrs_clt_sess *sess =to_clt_sess (con->c.sess); +struct rtrs_clt_sess *sess =to_clt_sess (con->c.path);struct rtrs_clt_stats *stats = sess->stats;struct rtrs_clt_stats_pcpu *s;int cpu;
@@ -174,7 +174,7 @@ static inline void rtrs_clt_update_rdma_stats(struct rtrs_clt_stats *stats,void rtrs_clt_update_all_stats (struct rtrs_clt_io_req *req,int dir) {struct rtrs_clt_con *con = req->con; -struct rtrs_clt_sess *sess =to_clt_sess (con->c.sess); +struct rtrs_clt_sess *sess =to_clt_sess (con->c.path);struct rtrs_clt_stats *stats = sess->stats;unsigned int len;
drivers/infiniband/ulp/rtrs/rtrs-clt.c +33 -33
262 lines not on this page · raw message
drivers/infiniband/ulp/rtrs/rtrs-clt.h +2 -2
@@ -125,7 +125,7 @@ struct rtrs_rbuf { };struct rtrs_clt_sess { -struct rtrs_sess s; +struct rtrs_path s;struct rtrs_clt *clt;wait_queue_head_t state_wq;enum rtrs_clt_state state;
@@ -186,7 +186,7 @@ static inline struct rtrs_clt_con *to_clt_con(struct rtrs_con *c) return container_of(c, struct rtrs_clt_con, c); } -static inline struct rtrs_clt_sess *to_clt_sess (struct rtrs_sess *s) +static inline struct rtrs_clt_sess *to_clt_sess (struct rtrs_path *s) { return container_of(s, struct rtrs_clt_sess, s); }
drivers/infiniband/ulp/rtrs/rtrs-pri.h +7 -7
@@ -91,7 +91,7 @@ struct rtrs_ib_dev { };struct rtrs_con { -struct rtrs_sess *sess; +struct rtrs_path *path;struct ib_qp *qp;struct ib_cq *cq;struct rdma_cm_id *cm_id;
@@ -101,7 +101,7 @@ struct rtrs_con {atomic_t sq_wr_avail; }; -struct rtrs_sess { +struct rtrs_path {struct list_head entry;struct sockaddr_storage dst_addr;struct sockaddr_storage src_addr;
@@ -314,19 +314,19 @@ int rtrs_iu_post_rdma_write_imm(struct rtrs_con *con, struct rtrs_iu *iu,int rtrs_post_recv_empty (struct rtrs_con *con,struct ib_cqe *cqe); -int rtrs_cq_qp_create (struct rtrs_sess *sess,struct rtrs_con *con, +int rtrs_cq_qp_create (struct rtrs_path *path,struct rtrs_con *con,u32 max_send_sge,int cq_vector,int nr_cqe,u32 max_send_wr,u32 max_recv_wr,enum ib_poll_context poll_ctx);void rtrs_cq_qp_destroy (struct rtrs_con *con); -void rtrs_init_hb (struct rtrs_sess *sess,struct ib_cqe *cqe, +void rtrs_init_hb (struct rtrs_path *path,struct ib_cqe *cqe,unsigned int interval_ms,unsigned int missed_max,void (*err_handler)(struct rtrs_con *con),struct workqueue_struct *wq); -void rtrs_start_hb (struct rtrs_sess *sess); -void rtrs_stop_hb (struct rtrs_sess *sess); -void rtrs_send_hb_ack (struct rtrs_sess *sess); +void rtrs_start_hb (struct rtrs_path *path); +void rtrs_stop_hb (struct rtrs_path *path); +void rtrs_send_hb_ack (struct rtrs_path *path);void rtrs_rdma_dev_pd_init (enum ib_pd_flags pd_flags,struct rtrs_rdma_dev_pd *pool);
drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c +3 -3
@@ -37,7 +37,7 @@ static ssize_t rtrs_srv_disconnect_store(struct kobject *kobj, const char *buf, size_t count) {struct rtrs_srv_sess *sess; -struct rtrs_sess *s; +struct rtrs_path *s;char str[MAXHOSTNAMELEN ]; sess = container_of(kobj, struct rtrs_srv_sess, kobj);
@@ -230,7 +230,7 @@ static struct kobj_type ktype_stats = {static int rtrs_srv_create_stats_files (struct rtrs_srv_sess *sess) {int err; -struct rtrs_sess *s = &sess->s; +struct rtrs_path *s = &sess->s; err =kobject_init_and_add (&sess->stats->kobj_stats, &ktype_stats, &sess->kobj,"stats" );
@@ -258,7 +258,7 @@ static int rtrs_srv_create_stats_files(struct rtrs_srv_sess *sess)int rtrs_srv_create_sess_files (struct rtrs_srv_sess *sess) {struct rtrs_srv *srv = sess->srv; -struct rtrs_sess *s = &sess->s; +struct rtrs_path *s = &sess->s;char str[NAME_MAX ];int err;struct rtrs_addr path = {
drivers/infiniband/ulp/rtrs/rtrs-srv.c +23 -23
182 lines not on this page · raw message
drivers/infiniband/ulp/rtrs/rtrs-srv.h +1 -1
@@ -72,7 +72,7 @@ struct rtrs_srv_mr { };struct rtrs_srv_sess { -struct rtrs_sess s; +struct rtrs_path s;struct rtrs_srv *srv;struct work_struct close_work;enum rtrs_srv_state state;
drivers/infiniband/ulp/rtrs/rtrs.c +49 -49
230 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 508/779 RDMA/rtrs-srv: Rename rtrs_srv_sess to rtrs_srv_path
In reply to Greg Kroah-HartmanFrom: Vaishali Thakkar <[email protected]>
[ Upstream commit ae4c81644e9105d9f7f713bb0d444737bb6a0cf1 ]
rtrs_srv_sess is used for paths and not sessions on the server side. This creates confusion so let's rename it to rtrs_srv_path. Also, rename related variables and functions.
Coccinelle is used to do the transformations for most of the occurrences and remaining ones were handled manually.
--- drivers/block/rnbd/rnbd-srv.c | 12 +- drivers/infiniband/ulp/rtrs/rtrs-pri.h | 2 +- drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c | 119 ++-- drivers/infiniband/ulp/rtrs/rtrs-srv.c | 627 ++++++++++--------- drivers/infiniband/ulp/rtrs/rtrs-srv.h | 10 +- drivers/infiniband/ulp/rtrs/rtrs.h | 3 +- 6 files changed, 392 insertions(+), 381 deletions(-)
drivers/block/rnbd/rnbd-srv.c +6 -6
@@ -266,12 +266,12 @@ static void destroy_sess(struct rnbd_srv_session *srv_sess)static int create_sess (struct rtrs_srv *rtrs) {struct rnbd_srv_session *srv_sess; -char sessname[NAME_MAX ]; +char pathname[NAME_MAX ];int err; - err =rtrs_srv_get_sess_name (rtrs, sessname,sizeof (sessname)); + err =rtrs_srv_get_path_name (rtrs, pathname,sizeof (pathname));if (err) { -pr_err ("rtrs_srv_get_sess_name(%s): %d\n" , sessname, err); +pr_err ("rtrs_srv_get_path_name(%s): %d\n" , pathname, err);return err; }
@@ -284,8 +284,8 @@ static int create_sess(struct rtrs_srv *rtrs) offsetof(struct rnbd_dev_blk_io , bio), BIOSET_NEED_BVECS);if (err) { -pr_err ("Allocating srv_session for session %s failed\n" , - sessname); +pr_err ("Allocating srv_session for path %s failed\n" , + pathname);kfree (srv_sess);return err; }
@@ -298,7 +298,7 @@ static int create_sess(struct rtrs_srv *rtrs)mutex_unlock (&sess_lock); srv_sess->rtrs = rtrs; -strscpy (srv_sess->sessname, sessname,sizeof (srv_sess->sessname)); +strscpy (srv_sess->sessname, pathname,sizeof (srv_sess->sessname));rtrs_srv_set_sess_priv (rtrs, srv_sess);
drivers/infiniband/ulp/rtrs/rtrs-pri.h +1 -1
@@ -234,7 +234,7 @@ struct rtrs_msg_conn_rsp {*/ struct rtrs_msg_info_req {__le16 type; -u8 sessname[NAME_MAX ]; +u8 pathname[NAME_MAX ];u8 reserved[15 ]; };
drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c +60 -59
271 lines not on this page · raw message
drivers/infiniband/ulp/rtrs/rtrs-srv.c +318 -309
1,432 lines not on this page · raw message
drivers/infiniband/ulp/rtrs/rtrs-srv.h +5 -5
@@ -37,7 +37,7 @@ struct rtrs_srv_stats_rdma_stats {struct rtrs_srv_stats {struct kobject kobj_stats;struct rtrs_srv_stats_rdma_stats rdma_stats; -struct rtrs_srv_sess *sess; +struct rtrs_srv_path *srv_path; };struct rtrs_srv_con {
@@ -71,7 +71,7 @@ struct rtrs_srv_mr {struct rtrs_iu *iu;/* send buffer for new rkey msg */ }; -struct rtrs_srv_sess { +struct rtrs_srv_path {struct rtrs_path s;struct rtrs_srv *srv;struct work_struct close_work;
@@ -125,7 +125,7 @@ struct rtrs_srv_ib_ctx {extern struct class *rtrs_dev_class; -void close_sess (struct rtrs_srv_sess *sess); +void close_path (struct rtrs_srv_path *srv_path);static inline void rtrs_srv_update_rdma_stats (struct rtrs_srv_stats *s,size_t size,int d)
@@ -143,7 +143,7 @@ ssize_t rtrs_srv_reset_all_help(struct rtrs_srv_stats *stats, char *page, size_t len);/* functions which are implemented in rtrs-srv-sysfs.c */ -int rtrs_srv_create_sess_files (struct rtrs_srv_sess *sess); -void rtrs_srv_destroy_sess_files (struct rtrs_srv_sess *sess); +int rtrs_srv_create_path_files (struct rtrs_srv_path *srv_path); +void rtrs_srv_destroy_path_files (struct rtrs_srv_path *srv_path);#endif /* RTRS_SRV_H */
drivers/infiniband/ulp/rtrs/rtrs.h +2 -1
@@ -175,7 +175,8 @@ bool rtrs_srv_resp_rdma(struct rtrs_srv_op *id, int errno);void rtrs_srv_set_sess_priv (struct rtrs_srv *sess,void *priv); -int rtrs_srv_get_sess_name (struct rtrs_srv *sess,char *sessname,size_t len); +int rtrs_srv_get_path_name (struct rtrs_srv *sess,char *pathname, +size_t len);int rtrs_srv_get_queue_depth (struct rtrs_srv *sess);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 509/779 RDMA/rtrs-clt: Rename rtrs_clt_sess to rtrs_clt_path
In reply to Greg Kroah-HartmanFrom: Vaishali Thakkar <[email protected]>
[ Upstream commit caa84d95c78f35168847e2ab861a3a7f87033d36 ]
rtrs_clt_sess is used for paths and not sessions on the client side. This creates confusion so let's rename it to rtrs_clt_path. Also, rename related variables and functions.
Coccinelle is used to do the transformations for most of the occurrences and remaining ones were handled manually.
--- drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c | 8 +- drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c | 123 +-- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 997 ++++++++++--------- drivers/infiniband/ulp/rtrs/rtrs-clt.h | 20 +- drivers/infiniband/ulp/rtrs/rtrs-pri.h | 2 +- drivers/infiniband/ulp/rtrs/rtrs.h | 4 +- 6 files changed, 586 insertions(+), 568 deletions(-)
drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c +4 -4
@@ -13,8 +13,8 @@void rtrs_clt_update_wc_stats (struct rtrs_clt_con *con) { -struct rtrs_clt_sess *sess =to_clt_sess (con->c.path); -struct rtrs_clt_stats *stats = sess->stats; +struct rtrs_clt_path *clt_path =to_clt_path (con->c.path); +struct rtrs_clt_stats *stats = clt_path->stats;struct rtrs_clt_stats_pcpu *s;int cpu;
@@ -174,8 +174,8 @@ static inline void rtrs_clt_update_rdma_stats(struct rtrs_clt_stats *stats,void rtrs_clt_update_all_stats (struct rtrs_clt_io_req *req,int dir) {struct rtrs_clt_con *con = req->con; -struct rtrs_clt_sess *sess =to_clt_sess (con->c.path); -struct rtrs_clt_stats *stats = sess->stats; +struct rtrs_clt_path *clt_path =to_clt_path (con->c.path); +struct rtrs_clt_stats *stats = clt_path->stats;unsigned int len; len = req->usr_len + req->data_len;
drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c +62 -61
277 lines not on this page · raw message
drivers/infiniband/ulp/rtrs/rtrs-clt.c +507 -490
2,260 lines not on this page · raw message
drivers/infiniband/ulp/rtrs/rtrs-clt.h +10 -10
@@ -124,7 +124,7 @@ struct rtrs_rbuf {u32 rkey; }; -struct rtrs_clt_sess { +struct rtrs_clt_path {struct rtrs_path s;struct rtrs_clt *clt;wait_queue_head_t state_wq;
@@ -156,7 +156,7 @@ struct rtrs_clt_sess {struct rtrs_clt {struct list_head paths_list;/* rcu protected list */ size_t paths_num; -struct rtrs_clt_sess +struct rtrs_clt_path __rcu *__percpu *pcpu_path;uuid_t paths_uuid;int paths_up;
@@ -186,9 +186,9 @@ static inline struct rtrs_clt_con *to_clt_con(struct rtrs_con *c) return container_of(c, struct rtrs_clt_con, c); } -static inline struct rtrs_clt_sess *to_clt_sess (struct rtrs_path *s) +static inline struct rtrs_clt_path *to_clt_path (struct rtrs_path *s) { - return container_of(s, struct rtrs_clt_sess, s); + return container_of(s, struct rtrs_clt_path, s); }static inline int permit_size (struct rtrs_clt *clt)
@@ -201,16 +201,16 @@ static inline struct rtrs_permit *get_permit(struct rtrs_clt *clt, int idx)return (struct rtrs_permit *)(clt->permits +permit_size (clt) * idx); } -int rtrs_clt_reconnect_from_sysfs (struct rtrs_clt_sess *sess); -void rtrs_clt_close_conns (struct rtrs_clt_sess *sess,bool wait); +int rtrs_clt_reconnect_from_sysfs (struct rtrs_clt_path *path); +void rtrs_clt_close_conns (struct rtrs_clt_path *clt_path,bool wait);int rtrs_clt_create_path_from_sysfs (struct rtrs_clt *clt,struct rtrs_addr *addr); -int rtrs_clt_remove_path_from_sysfs (struct rtrs_clt_sess *sess, +int rtrs_clt_remove_path_from_sysfs (struct rtrs_clt_path *path,const struct attribute *sysfs_self);void rtrs_clt_set_max_reconnect_attempts (struct rtrs_clt *clt,int value);int rtrs_clt_get_max_reconnect_attempts (const struct rtrs_clt *clt); -void free_sess (struct rtrs_clt_sess *sess); +void free_path (struct rtrs_clt_path *clt_path);/* rtrs-clt-stats.c */
@@ -243,8 +243,8 @@ ssize_t rtrs_clt_reset_all_help(struct rtrs_clt_stats *stats,int rtrs_clt_create_sysfs_root_files (struct rtrs_clt *clt);void rtrs_clt_destroy_sysfs_root (struct rtrs_clt *clt); -int rtrs_clt_create_sess_files (struct rtrs_clt_sess *sess); -void rtrs_clt_destroy_sess_files (struct rtrs_clt_sess *sess, +int rtrs_clt_create_path_files (struct rtrs_clt_path *clt_path); +void rtrs_clt_destroy_path_files (struct rtrs_clt_path *clt_path,const struct attribute *sysfs_self);#endif /* RTRS_CLT_H */
drivers/infiniband/ulp/rtrs/rtrs-pri.h +1 -1
@@ -230,7 +230,7 @@ struct rtrs_msg_conn_rsp {/** * struct rtrs_msg_info_req * @type: @RTRS_MSG_INFO_REQ -* @sessname: Session name chosen by client +* @pathname: Path name chosen by client */ struct rtrs_msg_info_req {__le16 type;
drivers/infiniband/ulp/rtrs/rtrs.h +2 -2
@@ -53,13 +53,13 @@ struct rtrs_clt_ops { };struct rtrs_clt *rtrs_clt_open (struct rtrs_clt_ops *ops, -const char *sessname, +const char *pathname,const struct rtrs_addr *paths,size_t path_cnt,u16 port,size_t pdu_sz,u8 reconnect_delay_sec,s16 max_reconnect_attempts,u32 nr_poll_queues); -void rtrs_clt_close (struct rtrs_clt *sess); +void rtrs_clt_close (struct rtrs_clt *clt_path);enum wait_type {RTRS_PERMIT_NOWAIT =0 ,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 510/779 RDMA/rtrs-clt: Replace list_next_or_null_rr_rcu with an inline function
In reply to Greg Kroah-HartmanFrom: Md Haris Iqbal <[email protected]>
[ Upstream commit c14adff285ad1bb8eefc5d8fc202ceb1f7e3a2f1 ]
removes list_next_or_null_rr_rcu macro to fix below warnings. That macro is used only twice.
CHECK:MACRO_ARG_REUSE: Macro argument reuse 'head' - possible side-effects? CHECK:MACRO_ARG_REUSE: Macro argument reuse 'ptr' - possible side-effects? CHECK:MACRO_ARG_REUSE: Macro argument reuse 'memb' - possible side-effects?
Replaces that macro with an inline function.
--- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 35 ++++++++++++-------------- 1 file changed, 16 insertions(+), 19 deletions(-)
drivers/infiniband/ulp/rtrs/rtrs-clt.c +16 -19
@@ -747,25 +747,25 @@ struct path_it {struct rtrs_clt_path *(*next_path)(struct path_it *it); }; -/** -* list_next_or_null_rr_rcu - get next list element in round-robin fashion. +/* +* rtrs_clt_get_next_path_or_null - get clt path from the list or return NULL * @head: the head for the list. -* @ptr: the list head to take the next element from. -* @type: the type of the struct this is embedded in. -* @memb: the name of the list_head within the struct. +* @clt_path: The element to take the next clt_path from. * -* Next element returned in round-robin fashion, i.e. head will be skipped, +* Next clt path returned in round-robin fashion, i.e. head will be skipped, * but if list is observed as empty, NULL will be returned. * -* This primitive may safely run concurrently with the _rcu list-mutation +* This function may safely run concurrently with the _rcu list-mutation * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock(). */ -#define list_next_or_null_rr_rcu (head, ptr, type, memb) \ -({ \ - list_next_or_null_rcu(head, ptr, type, memb) ?: \ - list_next_or_null_rcu(head, READ_ONCE((ptr)->next), \ - type, memb); \ -}) +static inline struct rtrs_clt_path * +rtrs_clt_get_next_path_or_null (struct list_head *head,struct rtrs_clt_path *clt_path) +{ +return list_next_or_null_rcu (head, &clt_path->s.entry,typeof (*clt_path), s.entry) ?: +list_next_or_null_rcu (head, +READ_ONCE ((&clt_path->s.entry)->next), +typeof (*clt_path), s.entry); +}/** * get_next_path_rr() - Returns path in round-robin fashion.
@@ -796,10 +796,8 @@ static struct rtrs_clt_path *get_next_path_rr(struct path_it *it) path =list_first_or_null_rcu (&clt->paths_list,typeof (*path), s.entry); else - path =list_next_or_null_rr_rcu (&clt->paths_list, - &path->s.entry, -typeof (*path), - s.entry); + path =rtrs_clt_get_next_path_or_null (&clt->paths_list, path); +rcu_assign_pointer (*ppcpu_path, path);return path;
@@ -2267,8 +2265,7 @@ static void rtrs_clt_remove_path_from_arr(struct rtrs_clt_path *clt_path)* removed. If @sess is the last element, then @next is NULL. */ rcu_read_lock (); - next =list_next_or_null_rr_rcu (&clt->paths_list, &clt_path->s.entry, -typeof (*next), s.entry); + next =rtrs_clt_get_next_path_or_null (&clt->paths_list, clt_path);rcu_read_unlock ();/*
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 511/779 RDMA/qedr: Fix potential memory leak in __qedr_alloc_mr()
In reply to Greg Kroah-HartmanFrom: Jianglei Nie <[email protected]>
[ Upstream commit b3236a64ddd125a455ef5b5316c1b9051b732974 ]
__qedr_alloc_mr() allocates a memory chunk for "mr->info.pbl_table" with init_mr_info(). When rdma_alloc_tid() and rdma_register_tid() fail, "mr" is released while "mr->info.pbl_table" is not released, which will lead to a memory leak.
We should release the "mr->info.pbl_table" with qedr_free_pbl() when error occurs to fix the memory leak.
--- drivers/infiniband/hw/qedr/verbs.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/infiniband/hw/qedr/verbs.c +5 -3
@@ -3093,7 +3093,7 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd,else DP_ERR (dev,"roce alloc tid returned error %d\n" , rc); - goto err0; + goto err1; }/* Index only, 18 bit long, lkey = itid << 8 | key */
@@ -3117,7 +3117,7 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd, rc = dev->ops->rdma_register_tid (dev->rdma_ctx, &mr->hw_mr);if (rc) {DP_ERR (dev,"roce register tid returned an error %d\n" , rc); - goto err1; + goto err2; } mr->ibmr.lkey = mr->hw_mr.itid <<8 | mr->hw_mr.key;
@@ -3126,8 +3126,10 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd,DP_DEBUG (dev,QEDR_MSG_MR ,"alloc frmr: %x\n" , mr->ibmr.lkey);return mr; -err1: +err2: dev->ops->rdma_free_tid (dev->rdma_ctx, mr->hw_mr.itid); +err1: +qedr_free_pbl (dev, &mr->info.pbl_info, mr->info.pbl_table); err0:kfree (mr);return ERR_PTR (rc);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 512/779 RDMA/hns: Fix incorrect clearing of interrupt status register
In reply to Greg Kroah-HartmanFrom: Haoyue Xu <[email protected]>
[ Upstream commit ecb4db5c3590aa956b4b2c352081a5b632d1f9f9 ]
The driver will clear all the interrupts in the same area when the driver handles the interrupt of type AEQ overflow. It should only set the interrupt status bit of type AEQ overflow.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +2 -2
@@ -5854,8 +5854,8 @@ static irqreturn_t hns_roce_v2_msix_interrupt_abn(int irq, void *dev_id)dev_err (dev,"AEQ overflow!\n" ); - int_st |=1 <<HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S ; -roce_write (hr_dev,ROCEE_VF_ABN_INT_ST_REG , int_st); +roce_write (hr_dev,ROCEE_VF_ABN_INT_ST_REG , +1 <<HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S );/* Set reset level for reset_event() */ if (ops->set_default_reset_request)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 513/779 RDMA/siw: Fix duplicated reported IW_CM_EVENT_CONNECT_REPLY event
In reply to Greg Kroah-HartmanFrom: Cheng Xu <[email protected]>
[ Upstream commit 3056fc6c32e613b760422b94c7617ac9a24a4721 ]
If siw_recv_mpa_rr returns -EAGAIN, it means that the MPA reply hasn't been received completely, and should not report IW_CM_EVENT_CONNECT_REPLY in this case. This may trigger a call trace in iw_cm. A simple way to trigger this:
server: ib_send_lat
client: ib_send_lat -R <server_ip>
The call trace looks like this:
kernel BUG at drivers/infiniband/core/iwcm.c:894! invalid opcode: 0000 [#1] PREEMPT SMP NOPTI <...>
Workqueue: iw_cm_wq cm_work_handler [iw_cm] Call Trace: <TASK> cm_work_handler+0x1dd/0x370 [iw_cm] process_one_work+0x1e2/0x3b0 worker_thread+0x49/0x2e0 ? rescuer_thread+0x370/0x370 kthread+0xe5/0x110 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x1f/0x30 </TASK>
--- drivers/infiniband/sw/siw/siw_cm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/infiniband/sw/siw/siw_cm.c +4 -3
@@ -725,11 +725,11 @@ static int siw_proc_mpareply(struct siw_cep *cep)enum mpa_v2_ctrl mpa_p2p_mode =MPA_V2_RDMA_NO_RTR ; rv =siw_recv_mpa_rr (cep); -if (rv != -EAGAIN ) -siw_cancel_mpatimer (cep);if (rv) goto out_err; +siw_cancel_mpatimer (cep); + rep = &cep->mpa.hdr;if (__mpa_rr_revision (rep->params.bits) >MPA_REVISION_2 ) {
@@ -895,7 +895,8 @@ static int siw_proc_mpareply(struct siw_cep *cep) } out_err: -siw_cm_upcall (cep,IW_CM_EVENT_CONNECT_REPLY , -EINVAL ); +if (rv != -EAGAIN ) +siw_cm_upcall (cep,IW_CM_EVENT_CONNECT_REPLY , -EINVAL );return rv; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 514/779 iio: cros: Register FIFO callback after sensor is registered
In reply to Greg Kroah-HartmanFrom: Gwendal Grignou <[email protected]>
[ Upstream commit 0b4ae3f6d1210c11f9baf159009c7227eacf90f2 ]
Instead of registering callback to process sensor events right at initialization time, wait for the sensor to be register in the iio subsystem.
Events can come at probe time (in case the kernel rebooted abruptly without switching the sensor off for instance), and be sent to IIO core before the sensor is fully registered.
--- drivers/iio/accel/cros_ec_accel_legacy.c | 4 +- .../cros_ec_sensors/cros_ec_lid_angle.c | 4 +- .../common/cros_ec_sensors/cros_ec_sensors.c | 6 +- .../cros_ec_sensors/cros_ec_sensors_core.c | 58 ++++++++++++++----- drivers/iio/light/cros_ec_light_prox.c | 6 +- drivers/iio/pressure/cros_ec_baro.c | 6 +- .../linux/iio/common/cros_ec_sensors_core.h | 7 ++- 7 files changed, 60 insertions(+), 31 deletions(-)
drivers/iio/accel/cros_ec_accel_legacy.c +2 -2
@@ -215,7 +215,7 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev)return -ENOMEM ; ret =cros_ec_sensors_core_init (pdev, indio_dev, true, - cros_ec_sensors_capture,NULL ); + cros_ec_sensors_capture);if (ret)return ret;
@@ -235,7 +235,7 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev) state->sign[CROS_EC_SENSOR_Z ] =-1 ; } -return devm_iio_device_register (dev, indio_dev); +return cros_ec_sensors_core_register (dev, indio_dev,NULL ); }static struct platform_driver cros_ec_accel_platform_driver = {
drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c +2 -2
@@ -97,7 +97,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev)if (!indio_dev)return -ENOMEM ; - ret =cros_ec_sensors_core_init (pdev, indio_dev, false,NULL ,NULL ); + ret =cros_ec_sensors_core_init (pdev, indio_dev, false,NULL );if (ret)return ret;
@@ -113,7 +113,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev)if (ret)return ret; -return devm_iio_device_register (dev, indio_dev); +return cros_ec_sensors_core_register (dev, indio_dev,NULL ); }static const struct platform_device_id cros_ec_lid_angle_ids[] = {
drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c +3 -3
@@ -235,8 +235,7 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)return -ENOMEM ; ret =cros_ec_sensors_core_init (pdev, indio_dev, true, - cros_ec_sensors_capture, - cros_ec_sensors_push_data); + cros_ec_sensors_capture);if (ret)return ret;
@@ -297,7 +296,8 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)else state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd; -return devm_iio_device_register (dev, indio_dev); +return cros_ec_sensors_core_register (dev, indio_dev, + cros_ec_sensors_push_data); }static const struct platform_device_id cros_ec_sensors_ids[] = {
drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +42 -16
86 lines not on this page · raw message
drivers/iio/light/cros_ec_light_prox.c +3 -3
@@ -181,8 +181,7 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)return -ENOMEM ; ret =cros_ec_sensors_core_init (pdev, indio_dev, true, - cros_ec_sensors_capture, - cros_ec_sensors_push_data); + cros_ec_sensors_capture);if (ret)return ret;
@@ -240,7 +239,8 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev) state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd; -return devm_iio_device_register (dev, indio_dev); +return cros_ec_sensors_core_register (dev, indio_dev, + cros_ec_sensors_push_data); }static const struct platform_device_id cros_ec_light_prox_ids[] = {
drivers/iio/pressure/cros_ec_baro.c +3 -3
@@ -138,8 +138,7 @@ static int cros_ec_baro_probe(struct platform_device *pdev)return -ENOMEM ; ret =cros_ec_sensors_core_init (pdev, indio_dev, true, - cros_ec_sensors_capture, - cros_ec_sensors_push_data); + cros_ec_sensors_capture);if (ret)return ret;
@@ -186,7 +185,8 @@ static int cros_ec_baro_probe(struct platform_device *pdev) state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd; -return devm_iio_device_register (dev, indio_dev); +return cros_ec_sensors_core_register (dev, indio_dev, + cros_ec_sensors_push_data); }static const struct platform_device_id cros_ec_baro_ids[] = {
include/linux/iio/common/cros_ec_sensors_core.h +5 -2
@@ -95,8 +95,11 @@ int cros_ec_sensors_read_cmd(struct iio_dev *indio_dev, unsigned long scan_mask,struct platform_device ;int cros_ec_sensors_core_init (struct platform_device *pdev,struct iio_dev *indio_dev,bool physical_device, -cros_ec_sensors_capture_t trigger_capture, -cros_ec_sensorhub_push_data_cb_t push_data); +cros_ec_sensors_capture_t trigger_capture); + +int cros_ec_sensors_core_register (struct device *dev, +struct iio_dev *indio_dev, +cros_ec_sensorhub_push_data_cb_t push_data);irqreturn_t cros_ec_sensors_capture (int irq,void *p); int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 515/779 clk: qcom: gcc-msm8939: Fix weird field spacing in ftbl_gcc_camss_cci_clk
In reply to Greg Kroah-HartmanFrom: Bryan O'Donoghue <[email protected]>
[ Upstream commit 2bc308ebc453ba22f3f120f777b9ac48f973ee80 ]
Adding a new item to this frequency table I see the existing indentation is incorrect.
--- drivers/clk/qcom/gcc-msm8939.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/gcc-msm8939.c +1 -1
@@ -1014,7 +1014,7 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = { };static const struct freq_tbl ftbl_gcc_camss_cci_clk[] = { -F (19200000 ,P_XO ,1 ,0 ,0 ), +F (19200000 ,P_XO ,1 ,0 ,0 ), { } };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 516/779 RDMA/hfi1: fix potential memory leak in setup_base_ctxt()
In reply to Greg Kroah-HartmanFrom: Jianglei Nie <[email protected]>
[ Upstream commit aa2a1df3a2c85f855af7d54466ac10bd48645d63 ]
setup_base_ctxt() allocates a memory chunk for uctxt->groups with hfi1_alloc_ctxt_rcv_groups(). When init_user_ctxt() fails, uctxt->groups is not released, which will lead to a memory leak.
We should release the uctxt->groups with hfi1_free_ctxt_rcv_groups() when init_user_ctxt() fails.
--- drivers/infiniband/hw/hfi1/file_ops.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/infiniband/hw/hfi1/file_ops.c +3 -1
@@ -1179,8 +1179,10 @@ static int setup_base_ctxt(struct hfi1_filedata *fd, goto done; ret =init_user_ctxt (fd, uctxt); -if (ret) +if (ret) { +hfi1_free_ctxt_rcv_groups (uctxt); goto done; + }user_init (uctxt);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 517/779 gpio: gpiolib-of: Fix refcount bugs in of_mm_gpiochip_add_data()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 5d07a692f9562f9c06e62cce369e9dd108173a0f ]
We should use of_node_get() when a new reference of device_node is created. It is noted that the old reference stored in 'mm_gc->gc.of_node' should also be decreased.
This patch is based on the fact that there is a call site in function 'qe_add_gpiochips()' of src file 'drivers\soc\fsl\qe\gpio.c'. In this function, of_mm_gpiochip_add_data() is contained in an iteration of for_each_compatible_node() which will automatically increase and decrease the refcount. So we need additional of_node_get() for the reference escape in of_mm_gpiochip_add_data().
--- drivers/gpio/gpiolib-of.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpio/gpiolib-of.c +3 -1
@@ -863,7 +863,8 @@ int of_mm_gpiochip_add_data(struct device_node *np,if (mm_gc->save_regs) mm_gc->save_regs (mm_gc); - mm_gc->gc.of_node = np; +of_node_put (mm_gc->gc.of_node); + mm_gc->gc.of_node =of_node_get (np); ret =gpiochip_add_data (gc, data);if (ret)
@@ -871,6 +872,7 @@ int of_mm_gpiochip_add_data(struct device_node *np,return 0 ; err2: +of_node_put (np);iounmap (mm_gc->regs); err1:kfree (gc->label);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 518/779 HID: mcp2221: prevent a buffer overflow in mcp_smbus_write()
In reply to Greg Kroah-HartmanFrom: Harshit Mogalapalli <[email protected]>
[ Upstream commit 62ac2473553a00229e67bdf3cb023b62cf7f5a9a ]
Smatch Warning:drivers/hid/hid-mcp2221.c:388 mcp_smbus_write() error: __memcpy() '&mcp->txbuf[5]' too small (59 vs 255) drivers/hid/hid-mcp2221.c:388 mcp_smbus_write() error: __memcpy() 'buf' too small (34 vs 255)
The 'len' variable can take a value between 0-255 as it can come from data->block[0] and it is user data. So add an bound check to prevent a buffer overflow in memcpy().
--- drivers/hid/hid-mcp2221.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/hid/hid-mcp2221.c +3 -0
@@ -385,6 +385,9 @@ static int mcp_smbus_write(struct mcp2221 *mcp, u16 addr, data_len =7 ;break ;default : +if (len >I2C_SMBUS_BLOCK_MAX ) +return -EINVAL ; +memcpy (&mcp->txbuf[5 ], buf, len); data_len = len +5 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 519/779 HID: amd_sfh: Add NULL check for hid device
In reply to Greg Kroah-HartmanFrom: Basavaraj Natikar <[email protected]>
[ Upstream commit 06aa2a43c307cf4096f422dcb575e5d2913e528f ]
On removal of hid device during SFH set report may cause NULL pointer exception. Hence add NULL check for hid device before accessing.
--- drivers/hid/amd-sfh-hid/amd_sfh_hid.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/hid/amd-sfh-hid/amd_sfh_hid.c +8 -4
@@ -98,11 +98,15 @@ static int amdtp_wait_for_response(struct hid_device *hid)void amdtp_hid_wakeup (struct hid_device *hid) { -struct amdtp_hid_data *hid_data = hid->driver_data; -struct amdtp_cl_data *cli_data = hid_data->cli_data; +struct amdtp_hid_data *hid_data; +struct amdtp_cl_data *cli_data; - cli_data->request_done[cli_data->cur_hid_dev] = true; -wake_up_interruptible (&hid_data->hid_wait); +if (hid) { + hid_data = hid->driver_data; + cli_data = hid_data->cli_data; + cli_data->request_done[cli_data->cur_hid_dev] = true; +wake_up_interruptible (&hid_data->hid_wait); + } }static struct hid_ll_driver amdtp_hid_ll_driver = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 520/779 dmaengine: imx-dma: Cast of_device_get_match_data() with (uintptr_t)
In reply to Greg Kroah-HartmanFrom: Fabio Estevam <[email protected]>
[ Upstream commit c3266ee185b59e5aab3e0f982e5b7f95d31555a7 ]
Change the of_device_get_match_data() cast to (uintptr_t) to silence the following clang warning:
drivers/dma/imx-dma.c:1048:20: warning: cast to smaller integer type 'enum imx_dma_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
--- drivers/dma/imx-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dma/imx-dma.c +1 -1
@@ -1047,7 +1047,7 @@ static int __init imxdma_probe(struct platform_device *pdev)return -ENOMEM ; imxdma->dev = &pdev->dev; - imxdma->devtype = (enum imx_dma_type )of_device_get_match_data (&pdev->dev); + imxdma->devtype = (uintptr_t )of_device_get_match_data (&pdev->dev); res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); imxdma->base =devm_ioremap_resource (&pdev->dev, res);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 521/779 scripts/gdb: lx-dmesg: read records individually
In reply to Greg Kroah-HartmanFrom: John Ogness <[email protected]>
[ Upstream commit deaee2704a157dfcca77301ddaa10c62a9840952 ]
For the gdb command lx-dmesg, the entire descriptor, info, and text data regions are read into memory before printing any records. For large kernel log buffers, this not only causes a huge delay before seeing any records, but it may also lead to python errors of too much memory allocation.
Rather than reading in all these regions in advance, read them as needed and only read the regions for the particular record that is being printed.
The gdb macro "dmesg" in Documentation/admin-guide/kdump/gdbmacros.txt already prints out the kernel log buffer like this.
--- scripts/gdb/linux/dmesg.py | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-)
scripts/gdb/linux/dmesg.py +18 -17
@@ -44,19 +44,17 @@ class LxDmesg(gdb.Command): sz = prb_desc_ring_type.get_type().sizeof desc_ring = utils.read_memoryview(inf, addr, sz).tobytes() - # read in descriptor array + # read in descriptor count, size, and address off = prb_desc_ring_type.get_type()['count_bits'].bitpos // 8 desc_ring_count = 1 << utils.read_u32(desc_ring, off) desc_sz = prb_desc_type.get_type().sizeof off = prb_desc_ring_type.get_type()['descs'].bitpos // 8 - addr = utils.read_ulong(desc_ring, off) - descs = utils.read_memoryview(inf, addr, desc_sz * desc_ring_count).tobytes() + desc_addr = utils.read_ulong(desc_ring, off) - # read in info array + # read in info size and address info_sz = printk_info_type.get_type().sizeof off = prb_desc_ring_type.get_type()['infos'].bitpos // 8 - addr = utils.read_ulong(desc_ring, off) - infos = utils.read_memoryview(inf, addr, info_sz * desc_ring_count).tobytes() + info_addr = utils.read_ulong(desc_ring, off) # read in text data ring structure off = printk_ringbuffer_type.get_type()['text_data_ring'].bitpos // 8
@@ -64,12 +62,11 @@ class LxDmesg(gdb.Command): sz = prb_data_ring_type.get_type().sizeof text_data_ring = utils.read_memoryview(inf, addr, sz).tobytes() - # read in text data + # read in text data size and address off = prb_data_ring_type.get_type()['size_bits'].bitpos // 8 text_data_sz = 1 << utils.read_u32(text_data_ring, off) off = prb_data_ring_type.get_type()['data'].bitpos // 8 - addr = utils.read_ulong(text_data_ring, off) - text_data = utils.read_memoryview(inf, addr, text_data_sz).tobytes() + text_data_addr = utils.read_ulong(text_data_ring, off) counter_off = atomic_long_type.get_type()['counter'].bitpos // 8
@@ -102,17 +99,20 @@ class LxDmesg(gdb.Command): desc_off = desc_sz * ind info_off = info_sz * ind + desc = utils.read_memoryview(inf, desc_addr + desc_off, desc_sz).tobytes() + # skip non-committed record - state = 3 & (utils.read_u64(descs, desc_off + sv_off + - counter_off) >> desc_flags_shift) + state = 3 & (utils.read_u64(desc, sv_off + counter_off) >> desc_flags_shift) if state != desc_committed and state != desc_finalized: if did == head_id: break did = (did + 1) & desc_id_mask continue - begin = utils.read_ulong(descs, desc_off + begin_off) % text_data_sz - end = utils.read_ulong(descs, desc_off + next_off) % text_data_sz + begin = utils.read_ulong(desc, begin_off) % text_data_sz + end = utils.read_ulong(desc, next_off) % text_data_sz + + info = utils.read_memoryview(inf, info_addr + info_off, info_sz).tobytes() # handle data-less record if begin & 1 == 1:
@@ -125,16 +125,17 @@ class LxDmesg(gdb.Command): # skip over descriptor id text_start = begin + utils.get_long_type().sizeof - text_len = utils.read_u16(infos, info_off + len_off) + text_len = utils.read_u16(info, len_off) # handle truncated message if end - text_start < text_len: text_len = end - text_start - text = text_data[text_start:text_start + text_len].decode( - encoding='utf8', errors='replace') + text_data = utils.read_memoryview(inf, text_data_addr + text_start, + text_len).tobytes() + text = text_data[0:text_len].decode(encoding='utf8', errors='replace') - time_stamp = utils.read_u64(infos, info_off + ts_off) + time_stamp = utils.read_u64(info, ts_off) for line in text.splitlines(): msg = u"[{time:12.6f}] {line}\n".format(
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 522/779 scripts/gdb: fix lx-dmesg on 32 bits arch
In reply to Greg Kroah-HartmanFrom: Antonio Borneo <[email protected]>
[ Upstream commit e3c8d33e0d62175c31ca7ab7ab01b18f0b6318d3 ]
The type atomic_long_t can have size 4 or 8 bytes, depending on CONFIG_64BIT; it's only content, the field 'counter', is either an int or a s64 value.
Current code incorrectly uses the fixed size utils.read_u64() to read the field 'counter' inside atomic_long_t.
On 32 bits architectures reading the last element 'tail_id' of the struct prb_desc_ring:
struct prb_desc_ring {
...
atomic_long_t tail_id;
};causes the utils.read_u64() to access outside the boundary of the struct and the gdb command 'lx-dmesg' exits with error:
Python Exception <class 'IndexError'>: index out of range Error occurred in Python: index out of range
Query the really used atomic_long_t counter type size.
--- scripts/gdb/linux/dmesg.py | 9 +++------ scripts/gdb/linux/utils.py | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-)
scripts/gdb/linux/dmesg.py +3 -6
@@ -22,7 +22,6 @@ prb_desc_type = utils.CachedType("struct prb_desc") prb_desc_ring_type = utils.CachedType("struct prb_desc_ring") prb_data_ring_type = utils.CachedType("struct prb_data_ring") printk_ringbuffer_type = utils.CachedType("struct printk_ringbuffer") -atomic_long_type = utils.CachedType("atomic_long_t") class LxDmesg(gdb.Command): """Print Linux kernel log buffer."""
@@ -68,8 +67,6 @@ class LxDmesg(gdb.Command): off = prb_data_ring_type.get_type()['data'].bitpos // 8 text_data_addr = utils.read_ulong(text_data_ring, off) - counter_off = atomic_long_type.get_type()['counter'].bitpos // 8 - sv_off = prb_desc_type.get_type()['state_var'].bitpos // 8 off = prb_desc_type.get_type()['text_blk_lpos'].bitpos // 8
@@ -89,9 +86,9 @@ class LxDmesg(gdb.Command): # read in tail and head descriptor ids off = prb_desc_ring_type.get_type()['tail_id'].bitpos // 8 - tail_id = utils.read_u64(desc_ring, off + counter_off) + tail_id = utils.read_atomic_long(desc_ring, off) off = prb_desc_ring_type.get_type()['head_id'].bitpos // 8 - head_id = utils.read_u64(desc_ring, off + counter_off) + head_id = utils.read_atomic_long(desc_ring, off) did = tail_id while True:
@@ -102,7 +99,7 @@ class LxDmesg(gdb.Command): desc = utils.read_memoryview(inf, desc_addr + desc_off, desc_sz).tobytes() # skip non-committed record - state = 3 & (utils.read_u64(desc, sv_off + counter_off) >> desc_flags_shift) + state = 3 & (utils.read_atomic_long(desc, sv_off) >> desc_flags_shift) if state != desc_committed and state != desc_finalized: if did == head_id: break
scripts/gdb/linux/utils.py +12 -2
@@ -35,13 +35,12 @@ class CachedType: long_type = CachedType("long") - +atomic_long_type = CachedType("atomic_long_t") def get_long_type(): global long_type return long_type.get_type() - def offset_of(typeobj, field): element = gdb.Value(0).cast(typeobj) return int(str(element[field].address).split()[0], 16)
@@ -129,6 +128,17 @@ def read_ulong(buffer, offset): else: return read_u32(buffer, offset) +atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos +atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof + +def read_atomic_long(buffer, offset): + global atomic_long_counter_offset + global atomic_long_counter_sizeof + + if atomic_long_counter_sizeof == 8: + return read_u64(buffer, offset + atomic_long_counter_offset) + else: + return read_u32(buffer, offset + atomic_long_counter_offset) target_arch = None
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 523/779 RDMA/rxe: Fix mw bind to allow any consumer key portion
In reply to Greg Kroah-HartmanFrom: Bob Pearson <[email protected]>
[ Upstream commit 1603f89935ec86d40a7667e1250392626976ccc2 ]
The current implementation of rxe_check_bind_mw() in rxe_mw.c is incorrect since it requires the new key portion provided by the mw consumer to be different than the previous key portion. This is not required by the IBA. Remove the test.
--- drivers/infiniband/sw/rxe/rxe_mw.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/infiniband/sw/rxe/rxe_mw.c +0 -7
@@ -71,8 +71,6 @@ int rxe_dealloc_mw(struct ib_mw *ibmw)static int rxe_check_bind_mw (struct rxe_qp *qp,struct rxe_send_wqe *wqe,struct rxe_mw *mw,struct rxe_mr *mr) { -u32 key = wqe->wr.wr.mw.rkey &0xff ; -if (mw->ibmw.type ==IB_MW_TYPE_1 ) {if (unlikely (mw->state !=RXE_MW_STATE_VALID )) { pr_err_once(
@@ -110,11 +108,6 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, } } -if (unlikely (key == (mw->rkey &0xff ))) { -pr_err_once ("attempt to bind MW with same key\n" ); -return -EINVAL ; - } -/* remaining checks only apply to a nonzero MR */ if (!mr)return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 524/779 mmc: cavium-octeon: Add of_node_put() when breaking out of loop
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 19bbb49acf8d7a03cb83e05624363741a4c3ec6f ]
In octeon_mmc_probe(), we should call of_node_put() when breaking out of for_each_child_of_node() which has increased and decreased the refcount during each iteration.
--- drivers/mmc/host/cavium-octeon.c | 1 + 1 file changed, 1 insertion(+)
drivers/mmc/host/cavium-octeon.c +1 -0
@@ -277,6 +277,7 @@ static int octeon_mmc_probe(struct platform_device *pdev)if (ret) {dev_err (&pdev->dev,"Error populating slots\n" );octeon_mmc_set_shared_power (host,0 ); +of_node_put (cn); goto error; } i++;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 525/779 mmc: cavium-thunderx: Add of_node_put() when breaking out of loop
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 7ee480795e41db314f2c445c65ed854a5d6e8e32 ]
In thunder_mmc_probe(), we should call of_node_put() when breaking out of for_each_child_of_node() which has increased and decreased the refcount during each iteration.
--- drivers/mmc/host/cavium-thunderx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/mmc/host/cavium-thunderx.c +3 -1
@@ -142,8 +142,10 @@ static int thunder_mmc_probe(struct pci_dev *pdev,continue ; ret =cvm_mmc_of_slot_probe (&host->slot_pdev[i]->dev, host); -if (ret) +if (ret) { +of_node_put (child_node); goto error; + } } i++; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 526/779 HID: alps: Declare U1_UNICORN_LEGACY support
In reply to Greg Kroah-HartmanFrom: Artem Borisov <[email protected]>
[ Upstream commit 1117d182c5d72abd7eb8b7d5e7b8c3373181c3ab ]
U1_UNICORN_LEGACY id was added to the driver, but was not declared in the device id table, making it impossible to use.
--- drivers/hid/hid-alps.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/hid/hid-alps.c +2 -0
@@ -830,6 +830,8 @@ static const struct hid_device_id alps_id[] = { USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) }, { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1) }, + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, + USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY) }, { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_T4_BTNLESS) }, { }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 527/779 RDMA/rxe: For invalidate compare according to set keys in mr
In reply to Greg Kroah-HartmanFrom: Md Haris Iqbal <[email protected]>
[ Upstream commit 174e7b137042f19b5ce88beb4fc0ff4ec6b0c72a ]
The 'rkey' input can be an lkey or rkey, and in rxe the lkey or rkey have the same value, including the variant bits.
So, if mr->rkey is set, compare the invalidate key with it, otherwise compare with the mr->lkey.
Since we already did a lookup on the non-varient bits to get this far, the check's only purpose is to confirm that the wqe has the correct variant bits.
--- drivers/infiniband/sw/rxe/rxe_loc.h | 2 +- drivers/infiniband/sw/rxe/rxe_mr.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-)
drivers/infiniband/sw/rxe/rxe_loc.h +1 -1
@@ -85,7 +85,7 @@ struct rxe_mr *lookup_mr(struct rxe_pd *pd, int access, u32 key, enum rxe_mr_lookup_type type);int mr_check_range (struct rxe_mr *mr,u64 iova,size_t length);int advance_dma_data (struct rxe_dma_info *dma,unsigned int length); -int rxe_invalidate_mr (struct rxe_qp *qp,u32 rkey); +int rxe_invalidate_mr (struct rxe_qp *qp,u32 key);int rxe_reg_fast_mr (struct rxe_qp *qp,struct rxe_send_wqe *wqe);int rxe_dereg_mr (struct ib_mr *ibmr,struct ib_udata *udata);void rxe_mr_cleanup (struct rxe_pool_entry *arg);
drivers/infiniband/sw/rxe/rxe_mr.c +6 -6
@@ -522,22 +522,22 @@ struct rxe_mr *lookup_mr(struct rxe_pd *pd, int access, u32 key,return mr; } -int rxe_invalidate_mr (struct rxe_qp *qp,u32 rkey) +int rxe_invalidate_mr (struct rxe_qp *qp,u32 key) {struct rxe_dev *rxe =to_rdev (qp->ibqp.device);struct rxe_mr *mr;int ret; - mr =rxe_pool_get_index (&rxe->mr_pool, rkey >>8 ); + mr =rxe_pool_get_index (&rxe->mr_pool, key >>8 );if (!mr) { -pr_err ("%s: No MR for rkey %#x\n" , __func__, rkey); +pr_err ("%s: No MR for key %#x\n" , __func__, key); ret = -EINVAL ; goto err; } -if (rkey != mr->rkey) { -pr_err ("%s: rkey (%#x) doesn't match mr->rkey (%#x)\n" , - __func__, rkey, mr->rkey); +if (mr->rkey ? (key != mr->rkey) : (key != mr->lkey)) { +pr_err ("%s: wr key (%#x) doesn't match mr key (%#x)\n" , + __func__, key, (mr->rkey ? mr->rkey : mr->lkey)); ret = -EINVAL ; goto err_drop_ref; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 528/779 PCI: tegra194: Fix Root Port interrupt handling
In reply to Greg Kroah-HartmanFrom: Vidya Sagar <[email protected]>
[ Upstream commit 6646e99bcec627e866bc84365af37942c72b4b76 ]
As part of Root Port interrupt handling, level-0 register is read first and based on the bits set in that, corresponding level-1 registers are read for further interrupt processing. Since both these values are currently read into the same 'val' variable, checking level-0 bits the second time around is happening on the 'val' variable value of level-1 register contents instead of freshly reading the level-0 value again.
Fix by using different variables to store level-0 and level-1 registers contents.
--- drivers/pci/controller/dwc/pcie-tegra194.c | 46 +++++++++++----------- 1 file changed, 22 insertions(+), 24 deletions(-)
drivers/pci/controller/dwc/pcie-tegra194.c +22 -24
@@ -352,15 +352,14 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)struct tegra_pcie_dw *pcie = arg;struct dw_pcie *pci = &pcie->pci;struct pcie_port *pp = &pci->pp; -u32 val, tmp; +u32 val, status_l0, status_l1;u16 val_w; - val =appl_readl (pcie,APPL_INTR_STATUS_L0 ); -if (val &APPL_INTR_STATUS_L0_LINK_STATE_INT ) { - val =appl_readl (pcie,APPL_INTR_STATUS_L1_0_0 ); -if (val &APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED ) { -appl_writel (pcie, val,APPL_INTR_STATUS_L1_0_0 ); - + status_l0 =appl_readl (pcie,APPL_INTR_STATUS_L0 ); +if (status_l0 &APPL_INTR_STATUS_L0_LINK_STATE_INT ) { + status_l1 =appl_readl (pcie,APPL_INTR_STATUS_L1_0_0 ); +appl_writel (pcie, status_l1,APPL_INTR_STATUS_L1_0_0 ); +if (status_l1 &APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED ) {/* SBR & Surprise Link Down WAR */ val =appl_readl (pcie,APPL_CAR_RESET_OVRD ); val &= ~APPL_CAR_RESET_OVRD_CYA_OVERRIDE_CORE_RST_N ;
@@ -376,15 +375,15 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg) } } -if (val &APPL_INTR_STATUS_L0_INT_INT ) { - val =appl_readl (pcie,APPL_INTR_STATUS_L1_8_0 ); -if (val &APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS ) { +if (status_l0 &APPL_INTR_STATUS_L0_INT_INT ) { + status_l1 =appl_readl (pcie,APPL_INTR_STATUS_L1_8_0 ); +if (status_l1 &APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS ) {appl_writel (pcie,APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS ,APPL_INTR_STATUS_L1_8_0 );apply_bad_link_workaround (pp); } -if (val &APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS ) { +if (status_l1 &APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS ) {appl_writel (pcie,APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS ,APPL_INTR_STATUS_L1_8_0 );
@@ -396,25 +395,24 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg) } } - val =appl_readl (pcie,APPL_INTR_STATUS_L0 ); -if (val &APPL_INTR_STATUS_L0_CDM_REG_CHK_INT ) { - val =appl_readl (pcie,APPL_INTR_STATUS_L1_18 ); - tmp =dw_pcie_readl_dbi (pci,PCIE_PL_CHK_REG_CONTROL_STATUS ); -if (val &APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMPLT ) { +if (status_l0 &APPL_INTR_STATUS_L0_CDM_REG_CHK_INT ) { + status_l1 =appl_readl (pcie,APPL_INTR_STATUS_L1_18 ); + val =dw_pcie_readl_dbi (pci,PCIE_PL_CHK_REG_CONTROL_STATUS ); +if (status_l1 &APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMPLT ) {dev_info (pci->dev,"CDM check complete\n" ); - tmp |=PCIE_PL_CHK_REG_CHK_REG_COMPLETE ; + val |=PCIE_PL_CHK_REG_CHK_REG_COMPLETE ; } -if (val &APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR ) { +if (status_l1 &APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR ) {dev_err (pci->dev,"CDM comparison mismatch\n" ); - tmp |=PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR ; + val |=PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR ; } -if (val &APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR ) { +if (status_l1 &APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR ) {dev_err (pci->dev,"CDM Logic error\n" ); - tmp |=PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR ; + val |=PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR ; } -dw_pcie_writel_dbi (pci,PCIE_PL_CHK_REG_CONTROL_STATUS , tmp); - tmp =dw_pcie_readl_dbi (pci,PCIE_PL_CHK_REG_ERR_ADDR ); -dev_err (pci->dev,"CDM Error Address Offset = 0x%08X\n" , tmp); +dw_pcie_writel_dbi (pci,PCIE_PL_CHK_REG_CONTROL_STATUS , val); + val =dw_pcie_readl_dbi (pci,PCIE_PL_CHK_REG_ERR_ADDR ); +dev_err (pci->dev,"CDM Error Address Offset = 0x%08X\n" , val); }return IRQ_HANDLED ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 529/779 PCI: tegra194: Fix link up retry sequence
In reply to Greg Kroah-HartmanFrom: Vidya Sagar <[email protected]>
[ Upstream commit e05fd6ae77c3e2cc0dba283005d24b6d56d2b1fa ]
Add the missing DLF capability offset while clearing DL_FEATURE_EXCHANGE_EN bit during link up retry.
--- drivers/pci/controller/dwc/pcie-tegra194.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/dwc/pcie-tegra194.c +1 -1
@@ -978,7 +978,7 @@ static int tegra_pcie_dw_start_link(struct dw_pcie *pci) offset =dw_pcie_find_ext_capability (pci,PCI_EXT_CAP_ID_DLF ); val =dw_pcie_readl_dbi (pci, offset +PCI_DLF_CAP ); val &= ~PCI_DLF_EXCHANGE_ENABLE ; -dw_pcie_writel_dbi (pci, offset, val); +dw_pcie_writel_dbi (pci, offset +PCI_DLF_CAP , val);tegra_pcie_dw_host_init (pp);dw_pcie_setup_rc (pp);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 530/779 HID: amd_sfh: Handle condition of "no sensors"
In reply to Greg Kroah-HartmanFrom: Basavaraj Natikar <[email protected]>
[ Upstream commit 5d4d0f15657535f6a122ab26d47230b5c2b944af ]
Add a check for num_hid_devices to handle special case the situation of "no sensors".
--- drivers/hid/amd-sfh-hid/amd_sfh_client.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/hid/amd-sfh-hid/amd_sfh_client.c +2 -0
@@ -154,6 +154,8 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) dev = &privdata->pdev->dev; cl_data->num_hid_devices =amd_mp2_get_sensor_num (privdata, &cl_data->sensor_idx[0 ]); +if (cl_data->num_hid_devices ==0 ) +return -ENODEV ;INIT_DELAYED_WORK (&cl_data->work, amd_sfh_work);INIT_DELAYED_WORK (&cl_data->work_buffer, amd_sfh_work_buffer);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 531/779 USB: serial: fix tty-port initialized comments
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit 688ee1d1785c1359f9040f615dd8e6054962bce2 ]
Fix up the tty-port initialized comments which got truncated and obfuscated when replacing the old ASYNCB_INITIALIZED flag.
--- drivers/usb/serial/sierra.c | 3 ++- drivers/usb/serial/usb-serial.c | 2 +- drivers/usb/serial/usb_wwan.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-)
drivers/usb/serial/sierra.c +2 -1
@@ -737,7 +737,8 @@ static void sierra_close(struct usb_serial_port *port)/* * Need to take susp_lock to make sure port is not already being -* resumed, but no need to hold it due to initialized +* resumed, but no need to hold it due to the tty-port initialized +* flag. */ spin_lock_irq (&intfdata->susp_lock);if (--intfdata->open_ports ==0 )
drivers/usb/serial/usb-serial.c +1 -1
@@ -292,7 +292,7 @@ static int serial_open(struct tty_struct *tty, struct file *filp)* * Shut down a USB serial port. Serialized against activate by the * tport mutex and kept to matching open/close pairs -* of calls by the initialized flag. +* of calls by the tty-port initialized flag. * * Not called if tty is console. */
drivers/usb/serial/usb_wwan.c +2 -1
@@ -389,7 +389,8 @@ void usb_wwan_close(struct usb_serial_port *port)/* * Need to take susp_lock to make sure port is not already being -* resumed, but no need to hold it due to initialized +* resumed, but no need to hold it due to the tty-port initialized +* flag. */ spin_lock_irq (&intfdata->susp_lock);if (--intfdata->open_ports ==0 )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 532/779 usb: cdns3: change place of priv_ep assignment in cdns3_gadget_ep_dequeue(), cdns3_gadget_ep_enable()
In reply to Greg Kroah-HartmanFrom: Andrey Strachuk <[email protected]>
[ Upstream commit c3ffc9c4ca44bfe9562166793d133e1fb0630ea6 ]
If 'ep' is NULL, result of ep_to_cdns3_ep(ep) is invalid pointer and its dereference with priv_ep->cdns3_dev may cause panic.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/usb/cdns3/cdns3-gadget.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/usb/cdns3/cdns3-gadget.c +6 -3
@@ -2281,14 +2281,15 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,int val; priv_ep =ep_to_cdns3_ep (ep); - priv_dev = priv_ep->cdns3_dev; - comp_desc = priv_ep->endpoint.comp_desc;if (!ep || !desc || desc->bDescriptorType !=USB_DT_ENDPOINT ) {dev_dbg (priv_dev->dev,"usbss: invalid parameters\n" );return -EINVAL ; } + comp_desc = priv_ep->endpoint.comp_desc; + priv_dev = priv_ep->cdns3_dev; +if (!desc->wMaxPacketSize) {dev_err (priv_dev->dev,"usbss: missing wMaxPacketSize\n" );return -EINVAL ;
@@ -2596,7 +2597,7 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep, struct usb_request *request) {struct cdns3_endpoint *priv_ep =ep_to_cdns3_ep (ep); -struct cdns3_device *priv_dev = priv_ep->cdns3_dev; +struct cdns3_device *priv_dev;struct usb_request *req, *req_temp;struct cdns3_request *priv_req;struct cdns3_trb *link_trb;
@@ -2607,6 +2608,8 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep,if (!ep || !request || !ep->desc)return -EINVAL ; + priv_dev = priv_ep->cdns3_dev; +spin_lock_irqsave (&priv_dev->lock, flags); priv_req =to_cdns3_request (request);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 533/779 mtd: spi-nor: fix spi_nor_spimem_setup_op() call in spi_nor_erase_{sector,chip}()
In reply to Greg Kroah-HartmanFrom: Patrice Chotard <[email protected]>
[ Upstream commit f8cd9f632f4415b1e8838bdca8ab42cfb37a6584 ]
For erase operations, reg_proto must be used as indicated in struct spi_nor description in spi-nor.h.
This issue was found when DT property spi-tx-bus-width is set to 4. In this case the spi_mem_op->addr.buswidth is set to 4 for erase command which is not correct.
Tested on stm32mp157c-ev1 board with mx66l51235f spi-nor.
--- drivers/mtd/spi-nor/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/mtd/spi-nor/core.c +3 -3
@@ -177,7 +177,7 @@ static int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode,static int spi_nor_controller_ops_erase (struct spi_nor *nor,loff_t offs) { -if (spi_nor_protocol_is_dtr (nor->write_proto)) +if (spi_nor_protocol_is_dtr (nor->reg_proto))return -EOPNOTSUPP ;return nor->controller_ops->erase (nor, offs);
@@ -1195,7 +1195,7 @@ static int spi_nor_erase_chip(struct spi_nor *nor)SPI_MEM_OP_NO_DUMMY , SPI_MEM_OP_NO_DATA); -spi_nor_spimem_setup_op (nor, &op, nor->write_proto); +spi_nor_spimem_setup_op (nor, &op, nor->reg_proto); ret =spi_mem_exec_op (nor->spimem, &op); }else {
@@ -1340,7 +1340,7 @@ int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)SPI_MEM_OP_NO_DUMMY , SPI_MEM_OP_NO_DATA); -spi_nor_spimem_setup_op (nor, &op, nor->write_proto); +spi_nor_spimem_setup_op (nor, &op, nor->reg_proto);return spi_mem_exec_op (nor->spimem, &op); }else if (nor->controller_ops->erase) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 534/779 KVM: nVMX: Set UMIP bit CR4_FIXED1 MSR when emulating UMIP
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit a910b5ab6b250a88fff1866bf708642d83317466 ]
Make UMIP an "allowed-1" bit CR4_FIXED1 MSR when KVM is emulating UMIP. KVM emulates UMIP for both L1 and L2, and so should enumerate that L2 is allowed to have CR4.UMIP=1. Not setting the bit doesn't immediately break nVMX, as KVM does set/clear the bit in CR4_FIXED1 in response to a guest CPUID update, i.e. KVM will correctly (dis)allow nested VM-Entry based on whether or not UMIP is exposed to L1. That said, KVM should enumerate the bit as being allowed from time zero, e.g. userspace will see the wrong value if the MSR is read before CPUID is written.
Message-Id: <[email protected]>
--- arch/x86/kvm/vmx/nested.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/kvm/vmx/nested.c +3 -0
@@ -6736,6 +6736,9 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps)rdmsrl (MSR_IA32_VMX_CR0_FIXED1 , msrs->cr0_fixed1);rdmsrl (MSR_IA32_VMX_CR4_FIXED1 , msrs->cr4_fixed1); +if (vmx_umip_emulated ()) + msrs->cr4_fixed1 |=X86_CR4_UMIP ; + msrs->vmcs_enum =nested_vmx_calc_vmcs_enum_msr (); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 535/779 platform/olpc: Fix uninitialized data in debugfs write
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 40ec787e1adf302c11668d4cc69838f4d584187d ]
The call to:
size = simple_write_to_buffer(cmdbuf, sizeof(cmdbuf), ppos, buf, size);
will succeed if at least one byte is written to the "cmdbuf" buffer. The "*ppos" value controls which byte is written. Another problem is that this code does not check for errors so it's possible for the entire buffer to be uninitialized.
Inintialize the struct to zero to prevent reading uninitialized stack data.
Debugfs is normally only writable by root so the impact of this bug is very minimal.
--- drivers/platform/olpc/olpc-ec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/olpc/olpc-ec.c +1 -1
@@ -264,7 +264,7 @@ static ssize_t ec_dbgfs_cmd_write(struct file *file, const char __user *buf,int i, m;unsigned char ec_cmd[EC_MAX_CMD_ARGS ];unsigned int ec_cmd_int[EC_MAX_CMD_ARGS ]; -char cmdbuf[64 ]; +char cmdbuf[64 ] ="" ;int ec_cmd_bytes;mutex_lock (&ec_dbgfs_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 536/779 RDMA/srpt: Duplicate port name members
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
[ Upstream commit b03b1ae2a3125d4475452e4f19f5d3a6e910ff6e ]
Prepare for decoupling the lifetimes of struct srpt_port and struct srpt_port_id by duplicating the port name into struct srpt_port.
--- drivers/infiniband/ulp/srpt/ib_srpt.c | 9 ++++++--- drivers/infiniband/ulp/srpt/ib_srpt.h | 10 +++++++--- 2 files changed, 13 insertions(+), 6 deletions(-)
drivers/infiniband/ulp/srpt/ib_srpt.c +6 -3
@@ -566,14 +566,17 @@ static int srpt_refresh_port(struct srpt_port *sport)return ret; sport->port_guid_id.wwn.priv = sport; -srpt_format_guid (sport->port_guid_id.name, -sizeof (sport->port_guid_id.name), +srpt_format_guid (sport->guid_name,ARRAY_SIZE (sport->guid_name), &sport->gid.global.interface_id); +memcpy (sport->port_guid_id.name, sport->guid_name, +ARRAY_SIZE (sport->guid_name)); sport->port_gid_id.wwn.priv = sport; -snprintf (sport->port_gid_id.name,sizeof (sport->port_gid_id.name), +snprintf (sport->gid_name,ARRAY_SIZE (sport->gid_name),"0x%016llx%016llx" ,be64_to_cpu (sport->gid.global.subnet_prefix),be64_to_cpu (sport->gid.global.interface_id)); +memcpy (sport->port_gid_id.name, sport->gid_name, +ARRAY_SIZE (sport->gid_name));if (rdma_protocol_iwarp (sport->sdev->device, sport->port))return 0 ;
drivers/infiniband/ulp/srpt/ib_srpt.h +7 -3
@@ -376,7 +376,7 @@ struct srpt_tpg { };/** -* struct srpt_port_id - information about an RDMA port name +* struct srpt_port_id - LIO RDMA port information * @mutex: Protects @tpg_list changes. * @tpg_list: TPGs associated with the RDMA port name. * @wwn: WWN associated with the RDMA port name.
@@ -402,8 +402,10 @@ struct srpt_port_id {* @lid: cached value of the port's lid. * @gid: cached value of the port's gid. * @work: work structure for refreshing the aforementioned cached values. -* @port_guid_id: target port GUID -* @port_gid_id: target port GID +* @guid_name: port name in GUID format. +* @port_guid_id: LIO target port information for the port name in GUID format. +* @gid_name: port name in GID format. +* @port_gid_id: LIO target port information for the port name in GID format. * @port_attrib: Port attributes that can be accessed through configfs. * @refcount: Number of objects associated with this port. * @freed_channels: Completion that will be signaled once @refcount becomes 0.
@@ -419,7 +421,9 @@ struct srpt_port {u32 lid;union ib_gid gid;struct work_struct work; +char guid_name[64 ];struct srpt_port_id port_guid_id; +char gid_name[64 ];struct srpt_port_id port_gid_id;struct srpt_port_attrib port_attrib;atomic_t refcount;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 537/779 RDMA/srpt: Introduce a reference count in struct srpt_device
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
[ Upstream commit aa7dfbb41b5a60ab90e244d6f586b8cb5c791c3e ]
This will be used to keep struct srpt_device around as long as either the RDMA port exists or a LIO target port is associated with the struct srpt_device.
--- drivers/infiniband/ulp/srpt/ib_srpt.c | 17 +++++++++++++++-- drivers/infiniband/ulp/srpt/ib_srpt.h | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-)
drivers/infiniband/ulp/srpt/ib_srpt.c +15 -2
@@ -3104,6 +3104,18 @@ static int srpt_use_srq(struct srpt_device *sdev, bool use_srq)return ret; } +static void srpt_free_sdev (struct kref *refcnt) +{ +struct srpt_device *sdev =container_of (refcnt,typeof (*sdev), refcnt); + +kfree (sdev); +} + +static void srpt_sdev_put (struct srpt_device *sdev) +{ +kref_put (&sdev->refcnt, srpt_free_sdev); +} +/** * srpt_add_one - InfiniBand device addition callback function * @device: Describes a HCA.
@@ -3122,6 +3134,7 @@ static int srpt_add_one(struct ib_device *device)if (!sdev)return -ENOMEM ; +kref_init (&sdev->refcnt); sdev->device = device;mutex_init (&sdev->sdev_mutex);
@@ -3217,7 +3230,7 @@ static int srpt_add_one(struct ib_device *device)srpt_free_srq (sdev);ib_dealloc_pd (sdev->pd); free_dev: -kfree (sdev); +srpt_sdev_put (sdev);pr_info ("%s(%s) failed.\n" , __func__,dev_name (&device->dev));return ret; }
@@ -3261,7 +3274,7 @@ static void srpt_remove_one(struct ib_device *device, void *client_data)ib_dealloc_pd (sdev->pd); -kfree (sdev); +srpt_sdev_put (sdev); }static struct ib_client srpt_client = {
drivers/infiniband/ulp/srpt/ib_srpt.h +2 -0
@@ -434,6 +434,7 @@ struct srpt_port {/** * struct srpt_device - information associated by SRPT with a single HCA +* @refcnt: Reference count for this device. * @device: Backpointer to the struct ib_device managed by the IB core. * @pd: IB protection domain. * @lkey: L_Key (local key) with write access to all local memory.
@@ -449,6 +450,7 @@ struct srpt_port {* @port: Information about the ports owned by this HCA. */ struct srpt_device { +struct kref refcnt;struct ib_device *device;struct ib_pd *pd;u32 lkey;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 538/779 RDMA/srpt: Fix a use-after-free
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
[ Upstream commit b5605148e6ce36bb21020d49010b617693933128 ]
Change the LIO port members inside struct srpt_port from regular members into pointers. Allocate the LIO port data structures from inside srpt_make_tport() and free these from inside srpt_make_tport(). Keep struct srpt_device as long as either an RDMA port or a LIO target port is associated with it. This patch decouples the lifetime of struct srpt_port (controlled by the RDMA core) and struct srpt_port_id (controlled by LIO). This patch fixes the following KASAN complaint:
BUG: KASAN: use-after-free in srpt_enable_tpg+0x31/0x70 [ib_srpt] Read of size 8 at addr ffff888141cc34b8 by task check/5093 Call Trace: <TASK> show_stack+0x4e/0x53 dump_stack_lvl+0x51/0x66 print_address_description.constprop.0.cold+0xea/0x41e print_report.cold+0x90/0x205 kasan_report+0xb9/0xf0 __asan_load8+0x69/0x90 srpt_enable_tpg+0x31/0x70 [ib_srpt] target_fabric_tpg_base_enable_store+0xe2/0x140 [target_core_mod] configfs_write_iter+0x18b/0x210 new_sync_write+0x1f2/0x2f0 vfs_write+0x3e3/0x540 ksys_write+0xbb/0x140 __x64_sys_write+0x42/0x50 do_syscall_64+0x34/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 </TASK>
--- drivers/infiniband/ulp/srpt/ib_srpt.c | 130 ++++++++++++++++++-------- drivers/infiniband/ulp/srpt/ib_srpt.h | 10 +- 2 files changed, 94 insertions(+), 46 deletions(-)
drivers/infiniband/ulp/srpt/ib_srpt.c +89 -41
@@ -565,18 +565,12 @@ static int srpt_refresh_port(struct srpt_port *sport)if (ret)return ret; - sport->port_guid_id.wwn.priv = sport;srpt_format_guid (sport->guid_name,ARRAY_SIZE (sport->guid_name), &sport->gid.global.interface_id); -memcpy (sport->port_guid_id.name, sport->guid_name, -ARRAY_SIZE (sport->guid_name)); - sport->port_gid_id.wwn.priv = sport;snprintf (sport->gid_name,ARRAY_SIZE (sport->gid_name),"0x%016llx%016llx" ,be64_to_cpu (sport->gid.global.subnet_prefix),be64_to_cpu (sport->gid.global.interface_id)); -memcpy (sport->port_gid_id.name, sport->gid_name, -ARRAY_SIZE (sport->gid_name));if (rdma_protocol_iwarp (sport->sdev->device, sport->port))return 0 ;
@@ -2317,31 +2311,35 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, tag_num = ch->rq_size; tag_size =1 ;/* ib_srpt does not use se_sess->sess_cmd_map */ -mutex_lock (&sport->port_guid_id.mutex); -list_for_each_entry (stpg, &sport->port_guid_id.tpg_list, entry) { -if (!IS_ERR_OR_NULL (ch->sess)) -break ; - ch->sess =target_setup_session (&stpg->tpg, tag_num, +if (sport->guid_id) { +mutex_lock (&sport->guid_id->mutex); +list_for_each_entry (stpg, &sport->guid_id->tpg_list, entry) { +if (!IS_ERR_OR_NULL (ch->sess)) +break ; + ch->sess =target_setup_session (&stpg->tpg, tag_num, tag_size,TARGET_PROT_NORMAL , ch->sess_name, ch,NULL ); + } +mutex_unlock (&sport->guid_id->mutex); } -mutex_unlock (&sport->port_guid_id.mutex); -mutex_lock (&sport->port_gid_id.mutex); -list_for_each_entry (stpg, &sport->port_gid_id.tpg_list, entry) { -if (!IS_ERR_OR_NULL (ch->sess)) -break ; - ch->sess =target_setup_session (&stpg->tpg, tag_num, +if (sport->gid_id) { +mutex_lock (&sport->gid_id->mutex); +list_for_each_entry (stpg, &sport->gid_id->tpg_list, entry) { +if (!IS_ERR_OR_NULL (ch->sess)) +break ; + ch->sess =target_setup_session (&stpg->tpg, tag_num, tag_size,TARGET_PROT_NORMAL , i_port_id, ch,NULL ); -if (!IS_ERR_OR_NULL (ch->sess)) -break ; -/* Retry without leading "0x" */ - ch->sess =target_setup_session (&stpg->tpg, tag_num, +if (!IS_ERR_OR_NULL (ch->sess)) +break ; +/* Retry without leading "0x" */ + ch->sess =target_setup_session (&stpg->tpg, tag_num, tag_size,TARGET_PROT_NORMAL , i_port_id +2 , ch,NULL ); + } +mutex_unlock (&sport->gid_id->mutex); } -mutex_unlock (&sport->port_gid_id.mutex);if (IS_ERR_OR_NULL (ch->sess)) {WARN_ON_ONCE (ch->sess ==NULL );
@@ -2986,7 +2984,12 @@ static int srpt_release_sport(struct srpt_port *sport)return 0 ; } -static struct se_wwn *__srpt_lookup_wwn (const char *name) +struct port_and_port_id { +struct srpt_port *sport; +struct srpt_port_id **port_id; +}; + +static struct port_and_port_id __srpt_lookup_port (const char *name) {struct ib_device *dev;struct srpt_device *sdev;
@@ -3001,25 +3004,38 @@ static struct se_wwn *__srpt_lookup_wwn(const char *name)for (i =0 ; i < dev->phys_port_cnt; i++) { sport = &sdev->port[i]; -if (strcmp (sport->port_guid_id.name, name) ==0 ) -return &sport->port_guid_id.wwn; -if (strcmp (sport->port_gid_id.name, name) ==0 ) -return &sport->port_gid_id.wwn; +if (strcmp (sport->guid_name, name) ==0 ) { +kref_get (&sdev->refcnt); +return (struct port_and_port_id ){ + sport, &sport->guid_id}; + } +if (strcmp (sport->gid_name, name) ==0 ) { +kref_get (&sdev->refcnt); +return (struct port_and_port_id ){ + sport, &sport->gid_id}; + } } } -return NULL ; +return (struct port_and_port_id ){}; } -static struct se_wwn *srpt_lookup_wwn (const char *name) +/** +* srpt_lookup_port() - Look up an RDMA port by name +* @name: ASCII port name +* +* Increments the RDMA port reference count if an RDMA port pointer is returned. +* The caller must drop that reference count by calling srpt_port_put_ref(). +*/ +static struct port_and_port_id srpt_lookup_port (const char *name) { -struct se_wwn *wwn; +struct port_and_port_id papi;spin_lock (&srpt_dev_lock); - wwn =__srpt_lookup_wwn (name); + papi =__srpt_lookup_port (name);spin_unlock (&srpt_dev_lock); -return wwn; +return papi; }static void srpt_free_srq (struct srpt_device *sdev)
@@ -3198,10 +3214,6 @@ static int srpt_add_one(struct ib_device *device) sport->port_attrib.srp_sq_size =DEF_SRPT_SQ_SIZE ; sport->port_attrib.use_srq = false;INIT_WORK (&sport->work, srpt_refresh_port_work); -mutex_init (&sport->port_guid_id.mutex); -INIT_LIST_HEAD (&sport->port_guid_id.tpg_list); -mutex_init (&sport->port_gid_id.mutex); -INIT_LIST_HEAD (&sport->port_gid_id.tpg_list); ret =srpt_refresh_port (sport);if (ret) {
@@ -3302,10 +3314,10 @@ static struct srpt_port_id *srpt_wwn_to_sport_id(struct se_wwn *wwn) {struct srpt_port *sport = wwn->priv; -if (wwn == &sport->port_guid_id.wwn) -return &sport->port_guid_id; -if (wwn == &sport->port_gid_id.wwn) -return &sport->port_gid_id; +if (sport->guid_id && &sport->guid_id->wwn == wwn) +return sport->guid_id; +if (sport->gid_id && &sport->gid_id->wwn == wwn) +return sport->gid_id;WARN_ON_ONCE (true);return NULL ; }
@@ -3820,7 +3832,31 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf,struct config_group *group, const char *name) { - return srpt_lookup_wwn(name) ? : ERR_PTR(-EINVAL); + struct port_and_port_id papi = srpt_lookup_port(name); +struct srpt_port *sport = papi.sport; +struct srpt_port_id *port_id; + +if (!papi.port_id) +return ERR_PTR (-EINVAL ); +if (*papi.port_id) { +/* Attempt to create a directory that already exists. */ +WARN_ON_ONCE (true); +return &(*papi.port_id)->wwn; + } + port_id =kzalloc (sizeof (*port_id),GFP_KERNEL ); +if (!port_id) { +srpt_sdev_put (sport->sdev); +return ERR_PTR (-ENOMEM ); + } +mutex_init (&port_id->mutex); +INIT_LIST_HEAD (&port_id->tpg_list); + port_id->wwn.priv = sport; +memcpy (port_id->name, port_id == sport->guid_id ? sport->guid_name : + sport->gid_name,ARRAY_SIZE (port_id->name)); + + *papi.port_id = port_id; + +return &port_id->wwn; }/**
@@ -3829,6 +3865,18 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf,*/ static void srpt_drop_tport (struct se_wwn *wwn) { +struct srpt_port_id *port_id =container_of (wwn,typeof (*port_id), wwn); +struct srpt_port *sport = wwn->priv; + +if (sport->guid_id == port_id) + sport->guid_id =NULL ; +else if (sport->gid_id == port_id) + sport->gid_id =NULL ; +else +WARN_ON_ONCE (true); + +srpt_sdev_put (sport->sdev); +kfree (port_id); }static ssize_t srpt_wwn_version_show (struct config_item *item,char *buf)
drivers/infiniband/ulp/srpt/ib_srpt.h +5 -5
@@ -393,7 +393,7 @@ struct srpt_port_id { };/** -* struct srpt_port - information associated by SRPT with a single IB port +* struct srpt_port - SRPT RDMA port information * @sdev: backpointer to the HCA information. * @mad_agent: per-port management datagram processing information. * @enabled: Whether or not this target port is enabled.
@@ -403,9 +403,9 @@ struct srpt_port_id {* @gid: cached value of the port's gid. * @work: work structure for refreshing the aforementioned cached values. * @guid_name: port name in GUID format. -* @port_guid_id: LIO target port information for the port name in GUID format. +* @guid_id: LIO target port information for the port name in GUID format. * @gid_name: port name in GID format. -* @port_gid_id: LIO target port information for the port name in GID format. +* @gid_id: LIO target port information for the port name in GID format. * @port_attrib: Port attributes that can be accessed through configfs. * @refcount: Number of objects associated with this port. * @freed_channels: Completion that will be signaled once @refcount becomes 0.
@@ -422,9 +422,9 @@ struct srpt_port {union ib_gid gid;struct work_struct work;char guid_name[64 ]; -struct srpt_port_id port_guid_id; +struct srpt_port_id *guid_id;char gid_name[64 ]; -struct srpt_port_id port_gid_id; +struct srpt_port_id *gid_id;struct srpt_port_attrib port_attrib;atomic_t refcount;struct completion *freed_channels;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 539/779 android: binder: stop saving a pointer to the VMA
In reply to Greg Kroah-HartmanFrom: Liam R. Howlett <[email protected]>
[ Upstream commit a43cfc87caaf46710c8027a8c23b8a55f1078f19 ]
Do not record a pointer to a VMA outside of the mmap_lock for later use. This is unsafe and there are a number of failure paths *after* the recorded VMA pointer may be freed during setup. There is no callback to the driver to clear the saved pointer from generic mm code. Furthermore, the VMA pointer may become stale if any number of VMA operations end up freeing the VMA so saving it was fragile to being with.
Instead, change the binder_alloc struct to record the start address of the VMA and use vma_lookup() to get the vma when needed. Add lockdep mmap_lock checks on updates to the vma pointer to ensure the lock is held and depend on that lock for synchronization of readers and writers - which was already the case anyways, so the smp_wmb()/smp_rmb() was not necessary.
--- drivers/android/binder_alloc.c | 30 ++++++++++++------------- drivers/android/binder_alloc.h | 2 +- drivers/android/binder_alloc_selftest.c | 2 +- 3 files changed, 16 insertions(+), 18 deletions(-)
drivers/android/binder_alloc.c +14 -16
@@ -213,7 +213,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,if (mm) {mmap_read_lock (mm); - vma = alloc->vma; + vma =vma_lookup (mm, alloc->vma_addr); }if (!vma && need_mm) {
@@ -313,16 +313,15 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,static inline void binder_alloc_set_vma (struct binder_alloc *alloc,struct vm_area_struct *vma) { -if (vma) +unsigned long vm_start =0 ; + +if (vma) { + vm_start = vma->vm_start; alloc->vma_vm_mm = vma->vm_mm; -/* -* If we see alloc->vma is not NULL, buffer data structures set up -* completely. Look at smp_rmb side binder_alloc_get_vma. -* We also want to guarantee new alloc->vma_vm_mm is always visible -* if alloc->vma is set. -*/ -smp_wmb (); - alloc->vma = vma; + } + +mmap_assert_write_locked (alloc->vma_vm_mm); + alloc->vma_addr = vm_start; } static inline struct vm_area_struct *binder_alloc_get_vma(
@@ -330,11 +329,9 @@ static inline struct vm_area_struct *binder_alloc_get_vma( {struct vm_area_struct *vma =NULL ; -if (alloc->vma) { -/* Look at description in binder_alloc_set_vma */ -smp_rmb (); - vma = alloc->vma; - } +if (alloc->vma_addr) + vma =vma_lookup (alloc->vma_vm_mm, alloc->vma_addr); +return vma; }
@@ -817,7 +814,8 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc) buffers =0 ;mutex_lock (&alloc->mutex); -BUG_ON (alloc->vma); +BUG_ON (alloc->vma_addr && +vma_lookup (alloc->vma_vm_mm, alloc->vma_addr));while ((n =rb_first (&alloc->allocated_buffers))) { buffer = rb_entry(n, struct binder_buffer, rb_node);
drivers/android/binder_alloc.h +1 -1
@@ -100,7 +100,7 @@ struct binder_lru_page {*/ struct binder_alloc {struct mutex mutex; -struct vm_area_struct *vma; +unsigned long vma_addr;struct mm_struct *vma_vm_mm;void __user *buffer;struct list_head buffers;
drivers/android/binder_alloc_selftest.c +1 -1
@@ -287,7 +287,7 @@ void binder_selftest_alloc(struct binder_alloc *alloc)if (!binder_selftest_run)return ;mutex_lock (&binder_selftest_lock); -if (!binder_selftest_run || !alloc->vma) +if (!binder_selftest_run || !alloc->vma_addr) goto done;pr_info ("STARTED\n" );binder_selftest_alloc_offset (alloc, end_offset,0 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 540/779 mm/mmap.c: fix missing call to vm_unacct_memory in mmap_region
In reply to Greg Kroah-HartmanFrom: Miaohe Lin <[email protected]>
[ Upstream commit 7f82f922319ede486540e8746769865b9508d2c2 ]
Since the beginning, charged is set to 0 to avoid calling vm_unacct_memory twice because vm_unacct_memory will be called by above unmap_region. But since commit 4f74d2c8e827 ("vm: remove 'nr_accounted' calculations from the unmap_vmas() interfaces"), unmap_region doesn't call vm_unacct_memory anymore. So charged shouldn't be set to 0 now otherwise the calling to paired vm_unacct_memory will be missed and leads to imbalanced account.
--- mm/mmap.c | 1 - 1 file changed, 1 deletion(-)
mm/mmap.c +0 -1
@@ -1878,7 +1878,6 @@ unsigned long mmap_region(struct file *file, unsigned long addr,/* Undo any partial mapping done by a device driver. */ unmap_region (mm, vma, prev, vma->vm_start, vma->vm_end); - charged =0 ;if (vm_flags &VM_SHARED )mapping_unmap_writable (file->f_mapping); free_vma:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 541/779 selftests: kvm: set rax before vmcall
In reply to Greg Kroah-HartmanFrom: Andrei Vagin <[email protected]>
[ Upstream commit 281106f938d3daaea6f8b6723a8217a2a1ef6936 ]
kvm_hypercall has to place the hypercall number in rax.
Trace events show that kvm_pv_test doesn't work properly:
kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0
kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0
kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0With this change, it starts working as expected:
kvm_pv_test-54285: kvm_hypercall: nr 0x5 a0 0x0 a1 0x0 a2 0x0 a3 0x0
kvm_pv_test-54285: kvm_hypercall: nr 0xa a0 0x0 a1 0x0 a2 0x0 a3 0x0
kvm_pv_test-54285: kvm_hypercall: nr 0xb a0 0x0 a1 0x0 a2 0x0 a3 0x0Message-Id: <[email protected]>
--- tools/testing/selftests/kvm/lib/x86_64/processor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/kvm/lib/x86_64/processor.c +1 -1
@@ -1326,7 +1326,7 @@ uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2, asmvolatile ("vmcall" :"=a" (r) - :"b" (a0),"c" (a1),"d" (a2),"S" (a3)); + :"a" (nr),"b" (a0),"c" (a1),"d" (a2),"S" (a3));return r; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 542/779 of/fdt: declared return type does not match actual return type
In reply to Greg Kroah-HartmanFrom: Xu Qiang <[email protected]>
[ Upstream commit 7913145afa51bbed9eaf8e5b4ee55fa9884a71e5 ]
The commit 649cab56de8e (“of: properly check for error returned by fdt_get_name()”) changed the return value type from bool to int, but forgot to change the return value simultaneously.
populate_node was only called in unflatten_dt_nodes, and returns with values greater than or equal to 0 were discarded without further processing. Considering that return 0 usually indicates success, return 0 instead of return true.
--- drivers/of/fdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/of/fdt.c +1 -1
@@ -245,7 +245,7 @@ static int populate_node(const void *blob, } *pnp = np; -return true; +return 0 ; }static void reverse_nodes (struct device_node *parent)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 543/779 RDMA/mlx5: Add missing check for return value in get namespace flow
In reply to Greg Kroah-HartmanFrom: Maor Gottlieb <[email protected]>
[ Upstream commit c9776457bd5eaad4ce4ecb17af8d8f3cc6957c0b ]
Add missing check for return value when calling to mlx5_ib_ft_type_to_namespace, even though it can't really fail in this specific call.
--- drivers/infiniband/hw/mlx5/fs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/infiniband/hw/mlx5/fs.c +2 -4
@@ -2078,12 +2078,10 @@ static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs,if (err)return err; -if (flags) { -mlx5_ib_ft_type_to_namespace ( +if (flags) +return mlx5_ib_ft_type_to_namespace (MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX , &obj->ns_type); -return 0 ; - } } obj->ns_type =MLX5_FLOW_NAMESPACE_BYPASS ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 544/779 RDMA/rxe: Add memory barriers to kernel queues
In reply to Greg Kroah-HartmanFrom: Bob Pearson <[email protected]>
[ Upstream commit ae6e843fe08d0ea8e158815809dcc20e3a1afc22 ]
Earlier patches added memory barriers to protect user space to kernel space communications. The user space queues were previously shown to have occasional memory synchonization errors which were removed by adding smp_load_acquire, smp_store_release barriers. This patch extends that to the case where queues are used between kernel space threads.
This patch also extends the queue types to include kernel ULP queues which access the other end of the queues in kernel verbs calls like poll_cq and post_send/recv.
--- drivers/infiniband/sw/rxe/rxe_comp.c | 12 +- drivers/infiniband/sw/rxe/rxe_cq.c | 25 +-- drivers/infiniband/sw/rxe/rxe_qp.c | 12 +- drivers/infiniband/sw/rxe/rxe_queue.c | 30 ++- drivers/infiniband/sw/rxe/rxe_queue.h | 292 +++++++++++--------------- drivers/infiniband/sw/rxe/rxe_req.c | 37 ++-- drivers/infiniband/sw/rxe/rxe_resp.c | 40 +--- drivers/infiniband/sw/rxe/rxe_srq.c | 2 +- drivers/infiniband/sw/rxe/rxe_verbs.c | 53 +---- 9 files changed, 189 insertions(+), 314 deletions(-)
drivers/infiniband/sw/rxe/rxe_comp.c +3 -9
@@ -142,10 +142,7 @@ static inline enum comp_state get_wqe(struct rxe_qp *qp,/* we come here whether or not we found a response packet to see if * there are any posted WQEs */ -if (qp->is_user) - wqe =queue_head (qp->sq.queue,QUEUE_TYPE_FROM_USER ); -else - wqe =queue_head (qp->sq.queue,QUEUE_TYPE_KERNEL ); + wqe =queue_head (qp->sq.queue,QUEUE_TYPE_FROM_CLIENT ); *wqe_p = wqe;/* no WQE or requester has not started it yet */
@@ -432,10 +429,7 @@ static void do_complete(struct rxe_qp *qp, struct rxe_send_wqe *wqe)if (post)make_send_cqe (qp, wqe, &cqe); -if (qp->is_user) -advance_consumer (qp->sq.queue,QUEUE_TYPE_FROM_USER ); -else -advance_consumer (qp->sq.queue,QUEUE_TYPE_KERNEL ); +queue_advance_consumer (qp->sq.queue,QUEUE_TYPE_FROM_CLIENT );if (post)rxe_cq_post (qp->scq, &cqe,0 );
@@ -539,7 +533,7 @@ static void rxe_drain_resp_pkts(struct rxe_qp *qp, bool notify) wqe->status =IB_WC_WR_FLUSH_ERR ;do_complete (qp, wqe); }else { -advance_consumer (q, q->type); +queue_advance_consumer (q, q->type); } } }
drivers/infiniband/sw/rxe/rxe_cq.c +5 -20
@@ -25,11 +25,7 @@ int rxe_cq_chk_attr(struct rxe_dev *rxe, struct rxe_cq *cq, }if (cq) { -if (cq->is_user) - count =queue_count (cq->queue,QUEUE_TYPE_TO_USER ); -else - count =queue_count (cq->queue,QUEUE_TYPE_KERNEL ); - + count =queue_count (cq->queue,QUEUE_TYPE_TO_CLIENT );if (cqe < count) {pr_warn ("cqe(%d) < current # elements in queue (%d)" , cqe, count);
@@ -65,7 +61,7 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe,int err;enum queue_type type; - type = uresp ?QUEUE_TYPE_TO_USER :QUEUE_TYPE_KERNEL ; + type =QUEUE_TYPE_TO_CLIENT ; cq->queue =rxe_queue_init (rxe, &cqe,sizeof (struct rxe_cqe ), type);if (!cq->queue) {
@@ -117,11 +113,7 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)spin_lock_irqsave (&cq->cq_lock, flags); -if (cq->is_user) - full =queue_full (cq->queue,QUEUE_TYPE_TO_USER ); -else - full =queue_full (cq->queue,QUEUE_TYPE_KERNEL ); - + full =queue_full (cq->queue,QUEUE_TYPE_TO_CLIENT );if (unlikely (full)) {spin_unlock_irqrestore (&cq->cq_lock, flags);if (cq->ibcq.event_handler) {
@@ -134,17 +126,10 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)return -EBUSY ; } -if (cq->is_user) - addr =producer_addr (cq->queue,QUEUE_TYPE_TO_USER ); -else - addr =producer_addr (cq->queue,QUEUE_TYPE_KERNEL ); - + addr =queue_producer_addr (cq->queue,QUEUE_TYPE_TO_CLIENT );memcpy (addr, cqe,sizeof (*cqe)); -if (cq->is_user) -advance_producer (cq->queue,QUEUE_TYPE_TO_USER ); -else -advance_producer (cq->queue,QUEUE_TYPE_KERNEL ); +queue_advance_producer (cq->queue,QUEUE_TYPE_TO_CLIENT );spin_unlock_irqrestore (&cq->cq_lock, flags);
drivers/infiniband/sw/rxe/rxe_qp.c +4 -8
@@ -231,7 +231,7 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp, qp->sq.max_inline = init->cap.max_inline_data = wqe_size; wqe_size +=sizeof (struct rxe_send_wqe ); - type = uresp ?QUEUE_TYPE_FROM_USER :QUEUE_TYPE_KERNEL ; + type =QUEUE_TYPE_FROM_CLIENT ; qp->sq.queue =rxe_queue_init (rxe, &qp->sq.max_wr, wqe_size, type);if (!qp->sq.queue)
@@ -248,12 +248,8 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp,return err; } -if (qp->is_user) - qp->req.wqe_index =producer_index (qp->sq.queue, -QUEUE_TYPE_FROM_USER ); -else - qp->req.wqe_index =producer_index (qp->sq.queue, -QUEUE_TYPE_KERNEL ); + qp->req.wqe_index =queue_get_producer (qp->sq.queue, +QUEUE_TYPE_FROM_CLIENT ); qp->req.state =QP_STATE_RESET ; qp->req.opcode =-1 ;
@@ -293,7 +289,7 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp,pr_debug ("qp#%d max_wr = %d, max_sge = %d, wqe_size = %d\n" ,qp_num (qp), qp->rq.max_wr, qp->rq.max_sge, wqe_size); - type = uresp ?QUEUE_TYPE_FROM_USER :QUEUE_TYPE_KERNEL ; + type =QUEUE_TYPE_FROM_CLIENT ; qp->rq.queue =rxe_queue_init (rxe, &qp->rq.max_wr, wqe_size, type);if (!qp->rq.queue)
drivers/infiniband/sw/rxe/rxe_queue.c +23 -7
@@ -111,17 +111,33 @@ struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe, int *num_elem,static int resize_finish (struct rxe_queue *q,struct rxe_queue *new_q,unsigned int num_elem) { -if (!queue_empty (q, q->type) && (num_elem <queue_count (q, q->type))) +enum queue_type type = q->type; +u32 prod; +u32 cons; + +if (!queue_empty (q, q->type) && (num_elem <queue_count (q, type)))return -EINVAL ; -while (!queue_empty (q, q->type)) { -memcpy (producer_addr (new_q, new_q->type), -consumer_addr (q, q->type), - new_q->elem_size); -advance_producer (new_q, new_q->type); -advance_consumer (q, q->type); + prod =queue_get_producer (new_q, type); + cons =queue_get_consumer (q, type); + +while (!queue_empty (q, type)) { +memcpy (queue_addr_from_index (new_q, prod), +queue_addr_from_index (q, cons), new_q->elem_size); + prod =queue_next_index (new_q, prod); + cons =queue_next_index (q, cons); } + new_q->buf->producer_index = prod; + q->buf->consumer_index = cons; + +/* update private index copies */ +if (type ==QUEUE_TYPE_TO_CLIENT ) + new_q->index = new_q->buf->producer_index; +else + q->index = q->buf->consumer_index; + +/* exchange rxe_queue headers */ swap (*q, *new_q);return 0 ;
drivers/infiniband/sw/rxe/rxe_queue.h +119 -173
398 lines not on this page · raw message
drivers/infiniband/sw/rxe/rxe_req.c +14 -23
@@ -49,21 +49,16 @@ static void req_retry(struct rxe_qp *qp)unsigned int cons;unsigned int prod; -if (qp->is_user) { - cons =consumer_index (q,QUEUE_TYPE_FROM_USER ); - prod =producer_index (q,QUEUE_TYPE_FROM_USER ); - }else { - cons =consumer_index (q,QUEUE_TYPE_KERNEL ); - prod =producer_index (q,QUEUE_TYPE_KERNEL ); - } + cons =queue_get_consumer (q,QUEUE_TYPE_FROM_CLIENT ); + prod =queue_get_producer (q,QUEUE_TYPE_FROM_CLIENT ); qp->req.wqe_index = cons; qp->req.psn = qp->comp.psn; qp->req.opcode =-1 ;for (wqe_index = cons; wqe_index != prod; - wqe_index =next_index (q, wqe_index)) { - wqe =addr_from_index (qp->sq.queue, wqe_index); + wqe_index =queue_next_index (q, wqe_index)) { + wqe =queue_addr_from_index (qp->sq.queue, wqe_index); mask =wr_opcode_mask (wqe->wr.opcode, qp);if (wqe->state == wqe_state_posted)
@@ -121,15 +116,9 @@ static struct rxe_send_wqe *req_next_wqe(struct rxe_qp *qp)unsigned int cons;unsigned int prod; -if (qp->is_user) { - wqe =queue_head (q,QUEUE_TYPE_FROM_USER ); - cons =consumer_index (q,QUEUE_TYPE_FROM_USER ); - prod =producer_index (q,QUEUE_TYPE_FROM_USER ); - }else { - wqe =queue_head (q,QUEUE_TYPE_KERNEL ); - cons =consumer_index (q,QUEUE_TYPE_KERNEL ); - prod =producer_index (q,QUEUE_TYPE_KERNEL ); - } + wqe =queue_head (q,QUEUE_TYPE_FROM_CLIENT ); + cons =queue_get_consumer (q,QUEUE_TYPE_FROM_CLIENT ); + prod =queue_get_producer (q,QUEUE_TYPE_FROM_CLIENT );if (unlikely (qp->req.state ==QP_STATE_DRAIN )) {/* check to see if we are drained;
@@ -170,7 +159,7 @@ static struct rxe_send_wqe *req_next_wqe(struct rxe_qp *qp)if (index == prod)return NULL ; - wqe =addr_from_index (q, index); + wqe =queue_addr_from_index (q, index); if (unlikely((qp->req.state == QP_STATE_DRAIN || qp->req.state == QP_STATE_DRAINED) &&
@@ -560,7 +549,8 @@ static void update_state(struct rxe_qp *qp, struct rxe_send_wqe *wqe, qp->req.opcode = pkt->opcode;if (pkt->mask &RXE_END_MASK ) - qp->req.wqe_index =next_index (qp->sq.queue, qp->req.wqe_index); + qp->req.wqe_index =queue_next_index (qp->sq.queue, + qp->req.wqe_index); qp->need_req_skb =0 ;
@@ -610,7 +600,7 @@ static int rxe_do_local_ops(struct rxe_qp *qp, struct rxe_send_wqe *wqe) wqe->state = wqe_state_done; wqe->status =IB_WC_SUCCESS ; - qp->req.wqe_index =next_index (qp->sq.queue, qp->req.wqe_index); + qp->req.wqe_index =queue_next_index (qp->sq.queue, qp->req.wqe_index);/* There is no ack coming for local work requests * which can lead to a deadlock. So go ahead and complete
@@ -643,7 +633,8 @@ int rxe_requester(void *arg) goto exit;if (unlikely (qp->req.state ==QP_STATE_RESET )) { - qp->req.wqe_index =consumer_index (q, q->type); + qp->req.wqe_index =queue_get_consumer (q, +QUEUE_TYPE_FROM_CLIENT ); qp->req.opcode =-1 ; qp->req.need_rd_atomic =0 ; qp->req.wait_psn =0 ;
@@ -709,7 +700,7 @@ int rxe_requester(void *arg) wqe->last_psn = qp->req.psn; qp->req.psn = (qp->req.psn +1 ) &BTH_PSN_MASK ; qp->req.opcode =IB_OPCODE_UD_SEND_ONLY ; - qp->req.wqe_index =next_index (qp->sq.queue, + qp->req.wqe_index =queue_next_index (qp->sq.queue, qp->req.wqe_index); wqe->state = wqe_state_done; wqe->status =IB_WC_SUCCESS ;
drivers/infiniband/sw/rxe/rxe_resp.c +10 -30
@@ -303,10 +303,7 @@ static enum resp_states get_srq_wqe(struct rxe_qp *qp)spin_lock_bh (&srq->rq.consumer_lock); -if (qp->is_user) - wqe =queue_head (q,QUEUE_TYPE_FROM_USER ); -else - wqe =queue_head (q,QUEUE_TYPE_KERNEL ); + wqe =queue_head (q,QUEUE_TYPE_FROM_CLIENT );if (!wqe) {spin_unlock_bh (&srq->rq.consumer_lock);return RESPST_ERR_RNR ;
@@ -322,13 +319,8 @@ static enum resp_states get_srq_wqe(struct rxe_qp *qp)memcpy (&qp->resp.srq_wqe, wqe, size); qp->resp.wqe = &qp->resp.srq_wqe.wqe; -if (qp->is_user) { -advance_consumer (q,QUEUE_TYPE_FROM_USER ); - count =queue_count (q,QUEUE_TYPE_FROM_USER ); - }else { -advance_consumer (q,QUEUE_TYPE_KERNEL ); - count =queue_count (q,QUEUE_TYPE_KERNEL ); - } +queue_advance_consumer (q,QUEUE_TYPE_FROM_CLIENT ); + count =queue_count (q,QUEUE_TYPE_FROM_CLIENT );if (srq->limit && srq->ibsrq.event_handler && (count < srq->limit)) { srq->limit =0 ;
@@ -357,12 +349,8 @@ static enum resp_states check_resource(struct rxe_qp *qp, qp->resp.status =IB_WC_WR_FLUSH_ERR ;return RESPST_COMPLETE ; }else if (!srq) { -if (qp->is_user) - qp->resp.wqe =queue_head (qp->rq.queue, -QUEUE_TYPE_FROM_USER ); -else - qp->resp.wqe =queue_head (qp->rq.queue, -QUEUE_TYPE_KERNEL ); + qp->resp.wqe =queue_head (qp->rq.queue, +QUEUE_TYPE_FROM_CLIENT );if (qp->resp.wqe) { qp->resp.status =IB_WC_WR_FLUSH_ERR ;return RESPST_COMPLETE ;
@@ -389,12 +377,8 @@ static enum resp_states check_resource(struct rxe_qp *qp,if (srq)return get_srq_wqe (qp); -if (qp->is_user) - qp->resp.wqe =queue_head (qp->rq.queue, -QUEUE_TYPE_FROM_USER ); -else - qp->resp.wqe =queue_head (qp->rq.queue, -QUEUE_TYPE_KERNEL ); + qp->resp.wqe =queue_head (qp->rq.queue, +QUEUE_TYPE_FROM_CLIENT );return (qp->resp.wqe) ?RESPST_CHK_LENGTH :RESPST_ERR_RNR ; }
@@ -938,12 +922,8 @@ static enum resp_states do_complete(struct rxe_qp *qp, }/* have copy for srq and reference for !srq */ -if (!qp->srq) { -if (qp->is_user) -advance_consumer (qp->rq.queue,QUEUE_TYPE_FROM_USER ); -else -advance_consumer (qp->rq.queue,QUEUE_TYPE_KERNEL ); - } +if (!qp->srq) +queue_advance_consumer (qp->rq.queue,QUEUE_TYPE_FROM_CLIENT ); qp->resp.wqe =NULL ;
@@ -1215,7 +1195,7 @@ static void rxe_drain_req_pkts(struct rxe_qp *qp, bool notify)return ;while (!qp->srq && q &&queue_head (q, q->type)) -advance_consumer (q, q->type); +queue_advance_consumer (q, q->type); }int rxe_responder (void *arg)
drivers/infiniband/sw/rxe/rxe_srq.c +1 -1
@@ -93,7 +93,7 @@ int rxe_srq_from_init(struct rxe_dev *rxe, struct rxe_srq *srq,spin_lock_init (&srq->rq.producer_lock);spin_lock_init (&srq->rq.consumer_lock); - type = uresp ?QUEUE_TYPE_FROM_USER :QUEUE_TYPE_KERNEL ; + type =QUEUE_TYPE_FROM_CLIENT ; q =rxe_queue_init (rxe, &srq->rq.max_wr, srq_wqe_size, type);if (!q) {
drivers/infiniband/sw/rxe/rxe_verbs.c +10 -43
107 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 545/779 RDMA/rxe: Remove the is_user members of struct rxe_sq/rxe_rq/rxe_srq
In reply to Greg Kroah-HartmanFrom: Xiao Yang <[email protected]>
[ Upstream commit 1cf2ce8272802e677398fab47a73713bc6e1fd5c ]
The is_user members of struct rxe_sq/rxe_rq/rxe_srq are unsed since commit ae6e843fe08d ("RDMA/rxe: Add memory barriers to kernel queues"). In this case, it is fine to remove them directly.
--- drivers/infiniband/sw/rxe/rxe_qp.c | 2 -- drivers/infiniband/sw/rxe/rxe_srq.c | 1 - drivers/infiniband/sw/rxe/rxe_verbs.c | 3 --- drivers/infiniband/sw/rxe/rxe_verbs.h | 3 --- 4 files changed, 9 deletions(-)
drivers/infiniband/sw/rxe/rxe_qp.c +0 -2
@@ -309,8 +309,6 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp,spin_lock_init (&qp->rq.producer_lock);spin_lock_init (&qp->rq.consumer_lock); - qp->rq.is_user = qp->is_user; -skb_queue_head_init (&qp->resp_pkts); rxe_init_task(rxe, &qp->resp.task, qp,
drivers/infiniband/sw/rxe/rxe_srq.c +0 -1
@@ -86,7 +86,6 @@ int rxe_srq_from_init(struct rxe_dev *rxe, struct rxe_srq *srq, srq->srq_num = srq->pelem.index; srq->rq.max_wr = init->attr.max_wr; srq->rq.max_sge = init->attr.max_sge; - srq->rq.is_user = srq->is_user; srq_wqe_size =rcv_wqe_size (srq->rq.max_sge);
drivers/infiniband/sw/rxe/rxe_verbs.c +0 -3
@@ -270,9 +270,6 @@ static int rxe_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init,if (udata->outlen <sizeof (*uresp))return -EINVAL ; uresp = udata->outbuf; - srq->is_user = true; - }else { - srq->is_user = false; } err =rxe_srq_chk_attr (rxe,NULL , &init->attr,IB_SRQ_INIT_MASK );
drivers/infiniband/sw/rxe/rxe_verbs.h +0 -3
@@ -77,7 +77,6 @@ enum wqe_state { };struct rxe_sq { -bool is_user;int max_wr;int max_sge;int max_inline;
@@ -86,7 +85,6 @@ struct rxe_sq { };struct rxe_rq { -bool is_user;int max_wr;int max_sge;spinlock_t producer_lock;/* guard queue producer */
@@ -100,7 +98,6 @@ struct rxe_srq {struct rxe_pd *pd;struct rxe_rq rq;u32 srq_num; -bool is_user;int limit;int error;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 546/779 RDMA/rxe: Fix error unwind in rxe_create_qp()
In reply to Greg Kroah-HartmanFrom: Zhu Yanjun <[email protected]>
[ Upstream commit fd5382c5805c4bcb50fd25b7246247d3f7114733 ]
In the function rxe_create_qp(), rxe_qp_from_init() is called to initialize qp, internally things like the spin locks are not setup until rxe_qp_init_req().
If an error occures before this point then the unwind will call rxe_cleanup() and eventually to rxe_qp_do_cleanup()/rxe_cleanup_task() which will oops when trying to access the uninitialized spinlock.
Move the spinlock initializations earlier before any failures.
--- drivers/infiniband/sw/rxe/rxe_qp.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/infiniband/sw/rxe/rxe_qp.c +8 -4
@@ -195,6 +195,14 @@ static void rxe_qp_init_misc(struct rxe_dev *rxe, struct rxe_qp *qp,spin_lock_init (&qp->grp_lock);spin_lock_init (&qp->state_lock); +spin_lock_init (&qp->req.task.state_lock); +spin_lock_init (&qp->resp.task.state_lock); +spin_lock_init (&qp->comp.task.state_lock); + +spin_lock_init (&qp->sq.sq_lock); +spin_lock_init (&qp->rq.producer_lock); +spin_lock_init (&qp->rq.consumer_lock); +atomic_set (&qp->ssn,0 );atomic_set (&qp->skb_out,0 ); }
@@ -255,7 +263,6 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp, qp->req.opcode =-1 ; qp->comp.opcode =-1 ; -spin_lock_init (&qp->sq.sq_lock);skb_queue_head_init (&qp->req_pkts); rxe_init_task(rxe, &qp->req.task, qp,
@@ -306,9 +313,6 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp, } } -spin_lock_init (&qp->rq.producer_lock); -spin_lock_init (&qp->rq.consumer_lock); -skb_queue_head_init (&qp->resp_pkts); rxe_init_task(rxe, &qp->resp.task, qp,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 547/779 block/rnbd-srv: Set keep_id to true after mutex_trylock
In reply to Greg Kroah-HartmanFrom: Md Haris Iqbal <[email protected]>
[ Upstream commit 4bc14f3101364877dd59085f39e068a2a7ec9f2d ]
After setting keep_id if the mutex trylock fails, the keep_id stays set for the rest of the sess_dev lifetime.
Therefore, set keep_id to true after mutex_trylock succeeds, so that a failure of trylock does'nt touch keep_id.
--- drivers/block/rnbd/rnbd-srv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/block/rnbd/rnbd-srv.c +2 -1
@@ -333,10 +333,11 @@ void rnbd_srv_sess_dev_force_close(struct rnbd_srv_sess_dev *sess_dev, {struct rnbd_srv_session *sess = sess_dev->sess; - sess_dev->keep_id = true;/* It is already started to close by client's close message. */ if (!mutex_trylock (&sess->lock))return ; + + sess_dev->keep_id = true;/* first remove sysfs itself to avoid deadlock */ sysfs_remove_file_self (&sess_dev->kobj, &attr->attr);rnbd_srv_destroy_dev_session_sysfs (sess_dev);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 548/779 null_blk: fix ida error handling in null_add_dev()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit ee452a8d984f94fa8e894f003a52e776e4572881 ]
There needs to be some error checking if ida_simple_get() fails. Also call ida_free() if there are errors later.
--- drivers/block/null_blk/main.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
drivers/block/null_blk/main.c +11 -3
@@ -1884,8 +1884,13 @@ static int null_add_dev(struct nullb_device *dev)blk_queue_flag_clear (QUEUE_FLAG_ADD_RANDOM , nullb->q);mutex_lock (&lock); - nullb->index =ida_simple_get (&nullb_indexes,0 ,0 ,GFP_KERNEL ); - dev->index = nullb->index; + rv =ida_simple_get (&nullb_indexes,0 ,0 ,GFP_KERNEL ); +if (rv <0 ) { +mutex_unlock (&lock); + goto out_cleanup_zone; + } + nullb->index = rv; + dev->index = rv;mutex_unlock (&lock);blk_queue_logical_block_size (nullb->q, dev->blocksize);
@@ -1905,13 +1910,16 @@ static int null_add_dev(struct nullb_device *dev) rv =null_gendisk_register (nullb);if (rv) - goto out_cleanup_zone; + goto out_ida_free;mutex_lock (&lock);list_add_tail (&nullb->list, &nullb_list);mutex_unlock (&lock);return 0 ; + +out_ida_free: +ida_free (&nullb_indexes, nullb->index); out_cleanup_zone:null_free_zoned_dev (dev); out_cleanup_disk:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 549/779 nvme: use command_id instead of req->tag in trace_nvme_complete_rq()
In reply to Greg Kroah-HartmanFrom: Bean Huo <[email protected]>
[ Upstream commit 679c54f2de672b7d79d02f8c4ad483ff6dd8ce2e ]
Use command_id instead of req->tag in trace_nvme_complete_rq(), because of commit e7006de6c238 ("nvme: code command_id with a genctr for use authentication after release"), cmd->common.command_id is set to ((genctl & 0xf)< 12 | req->tag), no longer req->tag, which makes cid in trace_nvme_complete_rq and trace_nvme_setup_cmd are not the same.
--- drivers/nvme/host/trace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/host/trace.h +1 -1
@@ -98,7 +98,7 @@ TRACE_EVENT(nvme_complete_rq,TP_fast_assign ( __entry->ctrl_id = nvme_req(req)->ctrl->instance; __entry->qid =nvme_req_qid (req); - __entry->cid = req->tag; + __entry->cid =nvme_req (req)->cmd->common.command_id; __entry->result =le64_to_cpu (nvme_req (req)->result.u64); __entry->retries =nvme_req (req)->retries; __entry->flags =nvme_req (req)->flags;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 550/779 nvme: define compat_ioctl again to unbreak 32-bit userspace.
In reply to Greg Kroah-HartmanFrom: Nick Bowler <[email protected]>
[ Upstream commit a25d4261582cf00dad884c194d21084836663d3d ]
Commit 89b3d6e60550 ("nvme: simplify the compat ioctl handling") removed the initialization of compat_ioctl from the nvme block_device_operations structures.
Presumably the expectation was that 32-bit ioctls would be directed through the regular handler but this is not the case: failing to assign .compat_ioctl actually means that the compat case is disabled entirely, and any attempt to submit nvme ioctls from 32-bit userspace fails outright with -ENOTTY.
For example:
% smartctl -x /dev/nvme0n1
[...]
Read NVMe Identify Controller failed: NVME_IOCTL_ADMIN_CMD: Inappropriate ioctl for device
The blkdev_compat_ptr_ioctl helper can be used to direct compat calls through the main ioctl handler and makes things work again.
--- drivers/nvme/host/core.c | 1 + drivers/nvme/host/multipath.c | 1 + 2 files changed, 2 insertions(+)
drivers/nvme/host/core.c +1 -0
@@ -2102,6 +2102,7 @@ static int nvme_report_zones(struct gendisk *disk, sector_t sector,static const struct block_device_operations nvme_bdev_ops = { .owner =THIS_MODULE , .ioctl = nvme_ioctl, + .compat_ioctl = blkdev_compat_ptr_ioctl, .open = nvme_open, .release = nvme_release, .getgeo = nvme_getgeo,
drivers/nvme/host/multipath.c +1 -0
@@ -388,6 +388,7 @@ const struct block_device_operations nvme_ns_head_ops = { .open = nvme_ns_head_open, .release = nvme_ns_head_release, .ioctl = nvme_ns_head_ioctl, + .compat_ioctl = blkdev_compat_ptr_ioctl, .getgeo = nvme_getgeo, .report_zones = nvme_ns_head_report_zones, .pr_ops = &nvme_pr_ops,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 551/779 nvme: disable namespace access for unsupported metadata
In reply to Greg Kroah-HartmanFrom: Keith Busch <[email protected]>
[ Upstream commit d39ad2a45c0e38def3e0c95f5b90d9af4274c939 ]
The only fabrics target that supports metadata handling through the separate integrity buffer is RDMA. It is currently usable only if the size is 8B per block and formatted for protection information. If an rdma target were to export a namespace with a different format (ex:
4k+64B), the driver will not be able to submit valid read/write commands for that namespace.
Suppress setting the metadata feature in the namespace so that the gendisk capacity will be set to 0. This will prevent read/write access through the block stack, but will continue to allow ioctl passthrough commands.
--- drivers/nvme/host/core.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/nvme/host/core.c +14 -3
@@ -1744,9 +1744,20 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)*/ if (WARN_ON_ONCE (!(id->flbas &NVME_NS_FLBAS_META_EXT )))return -EINVAL ; -if (ctrl->max_integrity_segments) - ns->features |= - (NVME_NS_METADATA_SUPPORTED |NVME_NS_EXT_LBAS ); + + ns->features |=NVME_NS_EXT_LBAS ; + +/* +* The current fabrics transport drivers support namespace +* metadata formats only if nvme_ns_has_pi() returns true. +* Suppress support for all other formats so the namespace will +* have a 0 capacity and not be usable through the block stack. +* +* Note, this check will need to be modified if any drivers +* gain the ability to use other metadata formats. +*/ +if (ctrl->max_integrity_segments &&nvme_ns_has_pi (ns)) + ns->features |=NVME_NS_METADATA_SUPPORTED ; }else {/* * For PCIe controllers, we can't easily remap the separate
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 552/779 nvme: dont return an error from nvme_configure_metadata
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
[ Upstream commit 363f6368603743072e5f318c668c632bccb097a3 ]
When a fabrics controller claims to support an invalidate metadata configuration we already warn and disable metadata support. No need to also return an error during revalidation.
--- drivers/nvme/host/core.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
drivers/nvme/host/core.c +5 -8
@@ -1719,7 +1719,7 @@ static int nvme_setup_streams_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns,return 0 ; } -static int nvme_configure_metadata (struct nvme_ns *ns,struct nvme_id_ns *id) +static void nvme_configure_metadata (struct nvme_ns *ns,struct nvme_id_ns *id) {struct nvme_ctrl *ctrl = ns->ctrl;
@@ -1735,7 +1735,8 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) ns->features &= ~(NVME_NS_METADATA_SUPPORTED |NVME_NS_EXT_LBAS );if (!ns->ms || !(ctrl->ops->flags &NVME_F_METADATA_SUPPORTED )) -return 0 ; +return ; +if (ctrl->ops->flags &NVME_F_FABRICS ) {/* * The NVMe over Fabrics specification only supports metadata as
@@ -1743,7 +1744,7 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)* remap the separate metadata buffer from the block layer. */ if (WARN_ON_ONCE (!(id->flbas &NVME_NS_FLBAS_META_EXT ))) -return -EINVAL ; +return ; ns->features |=NVME_NS_EXT_LBAS ;
@@ -1770,8 +1771,6 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)else ns->features |=NVME_NS_METADATA_SUPPORTED ; } - -return 0 ; } static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
@@ -1909,9 +1908,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id) ns->lba_shift = id->lbaf[lbaf].ds;nvme_set_queue_limits (ns->ctrl, ns->queue); - ret =nvme_configure_metadata (ns, id); -if (ret) - goto out_unfreeze; +nvme_configure_metadata (ns, id);nvme_set_chunk_sectors (ns, id);nvme_update_disk_info (ns->disk, ns, id);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 553/779 nvme: catch -ENODEV from nvme_revalidate_zones again
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
[ Upstream commit e06b425bc835ead08b9fd935bf5e47eef473e7a0 ]
nvme_revalidate_zones can also return -ENODEV if e.g. zone sizes aren't constant or not a power of two. In that case we should jump to marking the gendisk hidden and only support pass through.
--- drivers/nvme/host/core.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/nvme/host/core.c +7 -6
@@ -1914,8 +1914,10 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)if (ns->head->ids.csi ==NVME_CSI_ZNS ) { ret =nvme_update_zone_info (ns, lbaf); -if (ret) - goto out_unfreeze; +if (ret) { +blk_mq_unfreeze_queue (ns->disk->queue); + goto out; + } } set_disk_ro(ns->disk, (id->nsattr & NVME_NS_ATTR_RO) ||
@@ -1926,7 +1928,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)if (blk_queue_is_zoned (ns->queue)) { ret =nvme_revalidate_zones (ns);if (ret && !nvme_first_scan (ns->disk)) -return ret; + goto out; }if (nvme_ns_head_multipath (ns->head)) {
@@ -1941,9 +1943,9 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)disk_update_readahead (ns->head->disk);blk_mq_unfreeze_queue (ns->head->disk->queue); } -return 0 ; -out_unfreeze: + ret =0 ; +out:/* * If probing fails due an unsupported feature, hide the block device, * but still allow other access.
@@ -1953,7 +1955,6 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)set_bit (NVME_NS_READY , &ns->flags); ret =0 ; } -blk_mq_unfreeze_queue (ns->disk->queue);return ret; }
Signature · 1 line
2.35.1