6.11.11-rc1 review
Subsystems (6)
Greg Kroah-Hartman
maintainerPATCH 388/817 mfd: intel_soc_pmic_bxtwc: Use IRQ domain for USB Type-C device
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit 686fb77712a4bc94b76a0c5ae74c60118b7a0d79 ]
While design wise the idea of converting the driver to use the hierarchy of the IRQ chips is correct, the implementation has (inherited) flaws. This was unveiled when platform_get_irq() had started WARN() on IRQ 0 that is supposed to be a Linux IRQ number (also known as vIRQ).
Rework the driver to respect IRQ domain when creating each MFD device separately, as the domain is not the same for all of them.
--- drivers/mfd/intel_soc_pmic_bxtwc.c | 57 +++++++++++++++++++++--------- drivers/usb/typec/tcpm/wcove.c | 4 --- 2 files changed, 40 insertions(+), 21 deletions(-)
drivers/mfd/intel_soc_pmic_bxtwc.c +40 -17
@@ -241,16 +241,6 @@ static struct mfd_cell bxt_wc_dev[] = { .num_resources = ARRAY_SIZE(thermal_resources), .resources = thermal_resources, }, - { - .name = "bxt_wcove_usbc", - .num_resources = ARRAY_SIZE(usbc_resources), - .resources = usbc_resources, - }, - { - .name = "bxt_wcove_ext_charger", - .num_resources = ARRAY_SIZE(charger_resources), - .resources = charger_resources, - }, { .name = "bxt_wcove_bcu", .num_resources = ARRAY_SIZE(bcu_resources),
@@ -272,6 +262,19 @@ static struct mfd_cell bxt_wc_dev[] = { }, }; +static struct mfd_cell bxt_wc_chgr_dev[] = { + { + .name ="bxt_wcove_usbc" , + .num_resources =ARRAY_SIZE (usbc_resources), + .resources = usbc_resources, + }, + { + .name ="bxt_wcove_ext_charger" , + .num_resources =ARRAY_SIZE (charger_resources), + .resources = charger_resources, + }, +}; +static int regmap_ipc_byte_reg_read (void *context,unsigned int reg,unsigned int *val) {
@@ -426,6 +429,26 @@ static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic, 0, chip, data); } +static int bxtwc_add_chained_devices (struct intel_soc_pmic *pmic, +const struct mfd_cell *cells,int n_devs, +struct regmap_irq_chip_data *pdata, +int pirq,int irq_flags, +const struct regmap_irq_chip *chip, +struct regmap_irq_chip_data **data) +{ +struct device *dev = pmic->dev; +struct irq_domain *domain; +int ret; + + ret =bxtwc_add_chained_irq_chip (pmic, pdata, pirq, irq_flags, chip, data); +if (ret) +return dev_err_probe (dev, ret,"Failed to add %s IRQ chip\n" , chip->name); + + domain =regmap_irq_get_domain (*data); + +return devm_mfd_add_devices (dev,PLATFORM_DEVID_NONE , cells, n_devs,NULL ,0 , domain); +} +static int bxtwc_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;
@@ -501,14 +524,14 @@ static int bxtwc_probe(struct platform_device *pdev)if (ret)return dev_err_probe (dev, ret,"Failed to add ADC IRQ chip\n" ); -/* Add chained IRQ handler for CHGR IRQs */ - ret =bxtwc_add_chained_irq_chip (pmic, pmic->irq_chip_data, -BXTWC_CHGR_LVL1_IRQ , -IRQF_ONESHOT , - &bxtwc_regmap_irq_chip_chgr, - &pmic->irq_chip_data_chgr); + ret =bxtwc_add_chained_devices (pmic, bxt_wc_chgr_dev,ARRAY_SIZE (bxt_wc_chgr_dev), + pmic->irq_chip_data, +BXTWC_CHGR_LVL1_IRQ , +IRQF_ONESHOT , + &bxtwc_regmap_irq_chip_chgr, + &pmic->irq_chip_data_chgr);if (ret) -return dev_err_probe (dev, ret,"Failed to add CHGR IRQ chip\n" ); +return ret;/* Add chained IRQ handler for CRIT IRQs */ ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
drivers/usb/typec/tcpm/wcove.c +0 -4
@@ -621,10 +621,6 @@ static int wcove_typec_probe(struct platform_device *pdev)if (irq <0 )return irq; - irq =regmap_irq_get_virq (pmic->irq_chip_data_chgr, irq); -if (irq <0 ) -return irq; - ret =guid_parse (WCOVE_DSM_UUID , &wcove->guid);if (ret)return ret;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 389/817 mfd: intel_soc_pmic_bxtwc: Use IRQ domain for TMU device
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit 9b79d59e6b2b515eb9a22bc469ef7b8f0904fc73 ]
While design wise the idea of converting the driver to use the hierarchy of the IRQ chips is correct, the implementation has (inherited) flaws. This was unveiled when platform_get_irq() had started WARN() on IRQ 0 that is supposed to be a Linux IRQ number (also known as vIRQ).
Rework the driver to respect IRQ domain when creating each MFD device separately, as the domain is not the same for all of them.
--- drivers/mfd/intel_soc_pmic_bxtwc.c | 31 ++++++++++++++------------ drivers/platform/x86/intel/bxtwc_tmu.c | 22 +++++------------- 2 files changed, 23 insertions(+), 30 deletions(-)
drivers/mfd/intel_soc_pmic_bxtwc.c +17 -14
@@ -246,12 +246,6 @@ static struct mfd_cell bxt_wc_dev[] = { .num_resources = ARRAY_SIZE(bcu_resources), .resources = bcu_resources, }, - { - .name = "bxt_wcove_tmu", - .num_resources = ARRAY_SIZE(tmu_resources), - .resources = tmu_resources, - }, - { .name = "bxt_wcove_gpio", .num_resources = ARRAY_SIZE(gpio_resources),
@@ -262,6 +256,14 @@ static struct mfd_cell bxt_wc_dev[] = { }, }; +static const struct mfd_cell bxt_wc_tmu_dev[] = { + { + .name ="bxt_wcove_tmu" , + .num_resources =ARRAY_SIZE (tmu_resources), + .resources = tmu_resources, + }, +}; +static struct mfd_cell bxt_wc_chgr_dev[] = { { .name ="bxt_wcove_usbc" ,
@@ -490,6 +492,15 @@ static int bxtwc_probe(struct platform_device *pdev)if (ret)return dev_err_probe (dev, ret,"Failed to add IRQ chip\n" ); + ret =bxtwc_add_chained_devices (pmic, bxt_wc_tmu_dev,ARRAY_SIZE (bxt_wc_tmu_dev), + pmic->irq_chip_data, +BXTWC_TMU_LVL1_IRQ , +IRQF_ONESHOT , + &bxtwc_regmap_irq_chip_tmu, + &pmic->irq_chip_data_tmu); +if (ret) +return ret; + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, BXTWC_PWRBTN_LVL1_IRQ, IRQF_ONESHOT,
@@ -498,14 +509,6 @@ static int bxtwc_probe(struct platform_device *pdev)if (ret)return dev_err_probe (dev, ret,"Failed to add PWRBTN IRQ chip\n" ); - ret =bxtwc_add_chained_irq_chip (pmic, pmic->irq_chip_data, -BXTWC_TMU_LVL1_IRQ , -IRQF_ONESHOT , - &bxtwc_regmap_irq_chip_tmu, - &pmic->irq_chip_data_tmu); -if (ret) -return dev_err_probe (dev, ret,"Failed to add TMU IRQ chip\n" ); -/* Add chained IRQ handler for BCU IRQs */ ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, BXTWC_BCU_LVL1_IRQ,
drivers/platform/x86/intel/bxtwc_tmu.c +6 -16
@@ -48,9 +48,8 @@ static irqreturn_t bxt_wcove_tmu_irq_handler(int irq, void *data)static int bxt_wcove_tmu_probe (struct platform_device *pdev) {struct intel_soc_pmic *pmic =dev_get_drvdata (pdev->dev.parent); -struct regmap_irq_chip_data *regmap_irq_chip;struct wcove_tmu *wctmu; -int ret, virq, irq; +int ret; wctmu =devm_kzalloc (&pdev->dev,sizeof (*wctmu),GFP_KERNEL );if (!wctmu)
@@ -59,27 +58,18 @@ static int bxt_wcove_tmu_probe(struct platform_device *pdev) wctmu->dev = &pdev->dev; wctmu->regmap = pmic->regmap; - irq =platform_get_irq (pdev,0 ); -if (irq <0 ) -return irq; + wctmu->irq =platform_get_irq (pdev,0 ); +if (wctmu->irq <0 ) +return wctmu->irq; - regmap_irq_chip = pmic->irq_chip_data_tmu; - virq =regmap_irq_get_virq (regmap_irq_chip, irq); -if (virq <0 ) { -dev_err (&pdev->dev, -"failed to get virtual interrupt=%d\n" , irq); -return virq; - } - - ret =devm_request_threaded_irq (&pdev->dev, virq, + ret =devm_request_threaded_irq (&pdev->dev, wctmu->irq,NULL , bxt_wcove_tmu_irq_handler,IRQF_ONESHOT ,"bxt_wcove_tmu" , wctmu);if (ret) {dev_err (&pdev->dev,"request irq failed: %d,virq: %d\n" , - ret, virq); + ret, wctmu->irq);return ret; } - wctmu->irq = virq;/* Unmask TMU second level Wake & System alarm */ regmap_update_bits(wctmu->regmap, BXTWC_MTMUIRQ_REG,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 390/817 mfd: intel_soc_pmic_bxtwc: Use IRQ domain for PMIC devices
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit 0350d783ab888cb1cb48ced36cc28b372723f1a4 ]
While design wise the idea of converting the driver to use the hierarchy of the IRQ chips is correct, the implementation has (inherited) flaws. This was unveiled when platform_get_irq() had started WARN() on IRQ 0 that is supposed to be a Linux IRQ number (also known as vIRQ).
Rework the driver to respect IRQ domain when creating each MFD device separately, as the domain is not the same for all of them.
--- drivers/mfd/intel_soc_pmic_bxtwc.c | 54 +++++++++++++++++------------- 1 file changed, 30 insertions(+), 24 deletions(-)
drivers/mfd/intel_soc_pmic_bxtwc.c +30 -24
@@ -231,21 +231,11 @@ static const struct resource tmu_resources[] = { };static struct mfd_cell bxt_wc_dev[] = { - { - .name ="bxt_wcove_gpadc" , - .num_resources =ARRAY_SIZE (adc_resources), - .resources = adc_resources, - }, { .name ="bxt_wcove_thermal" , .num_resources =ARRAY_SIZE (thermal_resources), .resources = thermal_resources, }, - { - .name ="bxt_wcove_bcu" , - .num_resources =ARRAY_SIZE (bcu_resources), - .resources = bcu_resources, - }, { .name ="bxt_wcove_gpio" , .num_resources =ARRAY_SIZE (gpio_resources),
@@ -264,6 +254,22 @@ static const struct mfd_cell bxt_wc_tmu_dev[] = { }, }; +static const struct mfd_cell bxt_wc_bcu_dev[] = { + { + .name ="bxt_wcove_bcu" , + .num_resources =ARRAY_SIZE (bcu_resources), + .resources = bcu_resources, + }, +}; + +static const struct mfd_cell bxt_wc_adc_dev[] = { + { + .name ="bxt_wcove_gpadc" , + .num_resources =ARRAY_SIZE (adc_resources), + .resources = adc_resources, + }, +}; +static struct mfd_cell bxt_wc_chgr_dev[] = { { .name ="bxt_wcove_usbc" ,
@@ -509,23 +515,23 @@ static int bxtwc_probe(struct platform_device *pdev)if (ret)return dev_err_probe (dev, ret,"Failed to add PWRBTN IRQ chip\n" ); -/* Add chained IRQ handler for BCU IRQs */ - ret =bxtwc_add_chained_irq_chip (pmic, pmic->irq_chip_data, -BXTWC_BCU_LVL1_IRQ , -IRQF_ONESHOT , - &bxtwc_regmap_irq_chip_bcu, - &pmic->irq_chip_data_bcu); + ret =bxtwc_add_chained_devices (pmic, bxt_wc_bcu_dev,ARRAY_SIZE (bxt_wc_bcu_dev), + pmic->irq_chip_data, +BXTWC_BCU_LVL1_IRQ , +IRQF_ONESHOT , + &bxtwc_regmap_irq_chip_bcu, + &pmic->irq_chip_data_bcu);if (ret) -return dev_err_probe (dev, ret,"Failed to add BUC IRQ chip\n" ); +return ret; -/* Add chained IRQ handler for ADC IRQs */ - ret =bxtwc_add_chained_irq_chip (pmic, pmic->irq_chip_data, -BXTWC_ADC_LVL1_IRQ , -IRQF_ONESHOT , - &bxtwc_regmap_irq_chip_adc, - &pmic->irq_chip_data_adc); + ret =bxtwc_add_chained_devices (pmic, bxt_wc_adc_dev,ARRAY_SIZE (bxt_wc_adc_dev), + pmic->irq_chip_data, +BXTWC_ADC_LVL1_IRQ , +IRQF_ONESHOT , + &bxtwc_regmap_irq_chip_adc, + &pmic->irq_chip_data_adc);if (ret) -return dev_err_probe (dev, ret,"Failed to add ADC IRQ chip\n" ); +return ret; ret = bxtwc_add_chained_devices(pmic, bxt_wc_chgr_dev, ARRAY_SIZE(bxt_wc_chgr_dev), pmic->irq_chip_data,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 391/817 irqdomain: Simplify simple and legacy domain creation
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matti Vaittinen <[email protected]>
[ Upstream commit 70114e7f7585ef078c2b7033ee14218f95f55e22 ]
irq_domain_create_simple() and irq_domain_create_legacy() use __irq_domain_instantiate(), but have extra handling of allocating interrupt descriptors and associating interrupts in them. Some of that is duplicated.
There are also call sites which have conditonals to invoke different interrupt domain creator functions, where one of them is usually irq_domain_create_legacy(). Alternatively they associate the interrupts for the legacy case after creating the domain.
Moving the extra logic of irq_domain_create_simple()/legacy() into __irq_domain_instantiate() allows to consolidate that.
Introduce hwirq_base and virq_base members in the irq_domain_info structure, which allows to transport the required information and add the conditional interrupt descriptor allocation and interrupt association into __irq_domain_instantiate().
This reduces irq_domain_create_legacy() and irq_domain_create_simple() to trivial wrappers which fill in the info structure and allows call sites which must support the legacy case along with more modern mechanism to select the domain type via the parameters of the info struct.
[ tglx: Massaged change log ]
Stable-dep-of: 3727c0b4ff6b ("mfd: intel_soc_pmic_bxtwc: Fix IRQ domain names duplication")
--- include/linux/irqdomain.h | 5 +++ kernel/irq/irqdomain.c | 74 ++++++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 33 deletions(-)
include/linux/irqdomain.h +5 -0
@@ -291,6 +291,9 @@ struct irq_domain_chip_generic_info;* @hwirq_max: Maximum number of interrupts supported by controller * @direct_max: Maximum value of direct maps; * Use ~0 for no limit; 0 for no direct mapping +* @hwirq_base: The first hardware interrupt number (legacy domains only) +* @virq_base: The first Linux interrupt number for legacy domains to +* immediately associate the interrupts after domain creation * @bus_token: Domain bus token * @ops: Domain operation callbacks * @host_data: Controller private data pointer
@@ -307,6 +310,8 @@ struct irq_domain_info {unsigned int size;irq_hw_number_t hwirq_max;int direct_max; +unsigned int hwirq_base; +unsigned int virq_base;enum irq_domain_bus_token bus_token;const struct irq_domain_ops *ops;void *host_data;
kernel/irq/irqdomain.c +41 -33
112 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 392/817 irqdomain: Cleanup domain name allocation
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
[ Upstream commit 1bf2c92829274e7c815d06d7b3196a967ff70917 ]
irq_domain_set_name() is truly unreadable gunk. Clean it up before adding more.
Stable-dep-of: 3727c0b4ff6b ("mfd: intel_soc_pmic_bxtwc: Fix IRQ domain names duplication")
--- kernel/irq/irqdomain.c | 106 +++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 51 deletions(-)
kernel/irq/irqdomain.c +55 -51
@@ -128,72 +128,76 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode) }EXPORT_SYMBOL_GPL (irq_domain_free_fwnode); -static int irq_domain_set_name (struct irq_domain *domain, -const struct fwnode_handle *fwnode, -enum irq_domain_bus_token bus_token) +static int alloc_name (struct irq_domain *domain,char *base,enum irq_domain_bus_token bus_token) +{ + domain->name = bus_token ?kasprintf (GFP_KERNEL ,"%s-%d" , base, bus_token) : +kasprintf (GFP_KERNEL ,"%s" , base); +if (!domain->name) +return -ENOMEM ; + + domain->flags |=IRQ_DOMAIN_NAME_ALLOCATED ; +return 0 ; +} + +static int alloc_fwnode_name (struct irq_domain *domain,const struct fwnode_handle *fwnode, +enum irq_domain_bus_token bus_token) +{ +char *name = bus_token ?kasprintf (GFP_KERNEL ,"%pfw-%d" , fwnode, bus_token) : +kasprintf (GFP_KERNEL ,"%pfw" , fwnode); + +if (!name) +return -ENOMEM ; + +/* +* fwnode paths contain '/', which debugfs is legitimately unhappy +* about. Replace them with ':', which does the trick and is not as +* offensive as '\'... +*/ + domain->name =strreplace (name,'/' ,':' ); + domain->flags |=IRQ_DOMAIN_NAME_ALLOCATED ; +return 0 ; +} + +static int alloc_unknown_name (struct irq_domain *domain,enum irq_domain_bus_token bus_token) {static atomic_t unknown_domains; -struct irqchip_fwid *fwid; +int id =atomic_inc_return (&unknown_domains); + + domain->name = bus_token ?kasprintf (GFP_KERNEL ,"unknown-%d-%d" , id, bus_token) : +kasprintf (GFP_KERNEL ,"unknown-%d" , id); +if (!domain->name) +return -ENOMEM ; + domain->flags |=IRQ_DOMAIN_NAME_ALLOCATED ; +return 0 ; +} + +static int irq_domain_set_name (struct irq_domain *domain,const struct fwnode_handle *fwnode, +enum irq_domain_bus_token bus_token) +{if (is_fwnode_irqchip (fwnode)) { - fwid = container_of(fwnode, struct irqchip_fwid, fwnode); + struct irqchip_fwid *fwid = container_of(fwnode, struct irqchip_fwid, fwnode);switch (fwid->type) {case IRQCHIP_FWNODE_NAMED :case IRQCHIP_FWNODE_NAMED_ID : - domain->name = bus_token ? -kasprintf (GFP_KERNEL ,"%s-%d" , - fwid->name, bus_token) : -kstrdup (fwid->name,GFP_KERNEL ); -if (!domain->name) -return -ENOMEM ; - domain->flags |=IRQ_DOMAIN_NAME_ALLOCATED ; -break ; +return alloc_name (domain, fwid->name, bus_token);default : domain->name = fwid->name; -if (bus_token) { - domain->name =kasprintf (GFP_KERNEL ,"%s-%d" , - fwid->name, bus_token); -if (!domain->name) -return -ENOMEM ; - domain->flags |=IRQ_DOMAIN_NAME_ALLOCATED ; - } -break ; +if (bus_token) +return alloc_name (domain, fwid->name, bus_token); } - }else if (is_of_node (fwnode) ||is_acpi_device_node (fwnode) || -is_software_node (fwnode)) { -char *name; -/* -* fwnode paths contain '/', which debugfs is legitimately -* unhappy about. Replace them with ':', which does -* the trick and is not as offensive as '\'... -*/ - name = bus_token ? -kasprintf (GFP_KERNEL ,"%pfw-%d" , fwnode, bus_token) : -kasprintf (GFP_KERNEL ,"%pfw" , fwnode); -if (!name) -return -ENOMEM ; - - domain->name =strreplace (name,'/' ,':' ); - domain->flags |=IRQ_DOMAIN_NAME_ALLOCATED ; + }else if (is_of_node (fwnode) ||is_acpi_device_node (fwnode) ||is_software_node (fwnode)) { +return alloc_fwnode_name (domain, fwnode, bus_token); } -if (!domain->name) { -if (fwnode) -pr_err ("Invalid fwnode type for irqdomain\n" ); - domain->name = bus_token ? -kasprintf (GFP_KERNEL ,"unknown-%d-%d" , -atomic_inc_return (&unknown_domains), - bus_token) : -kasprintf (GFP_KERNEL ,"unknown-%d" , -atomic_inc_return (&unknown_domains)); -if (!domain->name) -return -ENOMEM ; - domain->flags |=IRQ_DOMAIN_NAME_ALLOCATED ; - } +if (domain->name) +return 0 ; -return 0 ; +if (fwnode) +pr_err ("Invalid fwnode type for irqdomain\n" ); +return alloc_unknown_name (domain, bus_token); }static struct irq_domain *__irq_domain_create (const struct irq_domain_info *info)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 393/817 irqdomain: Allow giving name suffix for domain
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matti Vaittinen <[email protected]>
[ Upstream commit 1e7c05292531e5b6bebe409cd531ed4ec0b2ff56 ]
Devices can provide multiple interrupt lines. One reason for this is that a device has multiple subfunctions, each providing its own interrupt line. Another reason is that a device can be designed to be used (also) on a system where some of the interrupts can be routed to another processor.
A line often further acts as a demultiplex for specific interrupts and has it's respective set of interrupt (status, mask, ack, ...) registers.
Regmap supports the handling of these registers and demultiplexing interrupts, but the interrupt domain code ends up assigning the same name for the per interrupt line domains. This causes a naming collision in the debugFS code and leads to confusion, as /proc/interrupts shows two separate interrupts with the same domain name and hardware interrupt number.
Instead of adding a workaround in regmap or driver code, allow giving a name suffix for the domain name when the domain is created.
Add a name_suffix field in the irq_domain_info structure and make irq_domain_instantiate() use this suffix if it is given when a domain is created.
[ tglx: Adopt it to the cleanup patch and fixup the invalid NULL return ]
Stable-dep-of: 3727c0b4ff6b ("mfd: intel_soc_pmic_bxtwc: Fix IRQ domain names duplication")
--- include/linux/irqdomain.h | 3 +++ kernel/irq/irqdomain.c | 30 +++++++++++++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-)
include/linux/irqdomain.h +3 -0
@@ -295,6 +295,8 @@ struct irq_domain_chip_generic_info;* @virq_base: The first Linux interrupt number for legacy domains to * immediately associate the interrupts after domain creation * @bus_token: Domain bus token +* @name_suffix: Optional name suffix to avoid collisions when multiple +* domains are added using same fwnode * @ops: Domain operation callbacks * @host_data: Controller private data pointer * @dgc_info: Geneneric chip information structure pointer used to
@@ -313,6 +315,7 @@ struct irq_domain_info {unsigned int hwirq_base;unsigned int virq_base;enum irq_domain_bus_token bus_token; +const char *name_suffix;const struct irq_domain_ops *ops;void *host_data;#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
kernel/irq/irqdomain.c +23 -7
@@ -140,11 +140,14 @@ static int alloc_name(struct irq_domain *domain, char *base, enum irq_domain_bus }static int alloc_fwnode_name (struct irq_domain *domain,const struct fwnode_handle *fwnode, -enum irq_domain_bus_token bus_token) +enum irq_domain_bus_token bus_token,const char *suffix) { -char *name = bus_token ?kasprintf (GFP_KERNEL ,"%pfw-%d" , fwnode, bus_token) : -kasprintf (GFP_KERNEL ,"%pfw" , fwnode); +const char *sep = suffix ?"-" :"" ; +const char *suf = suffix ? :"" ; +char *name; + name = bus_token ?kasprintf (GFP_KERNEL ,"%pfw-%s%s%d" , fwnode, suf, sep, bus_token) : +kasprintf (GFP_KERNEL ,"%pfw-%s" , fwnode, suf);if (!name)return -ENOMEM ;
@@ -172,12 +175,25 @@ static int alloc_unknown_name(struct irq_domain *domain, enum irq_domain_bus_tokreturn 0 ; } -static int irq_domain_set_name (struct irq_domain *domain,const struct fwnode_handle *fwnode, -enum irq_domain_bus_token bus_token) +static int irq_domain_set_name (struct irq_domain *domain,const struct irq_domain_info *info) { +enum irq_domain_bus_token bus_token = info->bus_token; +const struct fwnode_handle *fwnode = info->fwnode; +if (is_fwnode_irqchip (fwnode)) { struct irqchip_fwid *fwid = container_of(fwnode, struct irqchip_fwid, fwnode); +/* +* The name_suffix is only intended to be used to avoid a name +* collision when multiple domains are created for a single +* device and the name is picked using a real device node. +* (Typical use-case is regmap-IRQ controllers for devices +* providing more than one physical IRQ.) There should be no +* need to use name_suffix with irqchip-fwnode. +*/ +if (info->name_suffix) +return -EINVAL ; +switch (fwid->type) {case IRQCHIP_FWNODE_NAMED :case IRQCHIP_FWNODE_NAMED_ID :
@@ -189,7 +205,7 @@ static int irq_domain_set_name(struct irq_domain *domain, const struct fwnode_ha } }else if (is_of_node (fwnode) ||is_acpi_device_node (fwnode) ||is_software_node (fwnode)) { -return alloc_fwnode_name (domain, fwnode, bus_token); +return alloc_fwnode_name (domain, fwnode, bus_token, info->name_suffix); }if (domain->name)
@@ -215,7 +231,7 @@ static struct irq_domain *__irq_domain_create(const struct irq_domain_info *infoif (!domain)return ERR_PTR (-ENOMEM ); - err =irq_domain_set_name (domain, info->fwnode, info->bus_token); + err =irq_domain_set_name (domain, info);if (err) {kfree (domain);return ERR_PTR (err);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 394/817 regmap: Allow setting IRQ domain name suffix
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matti Vaittinen <[email protected]>
[ Upstream commit dde286ee57704226b500cb9eb59547fec07aad3d ]
When multiple IRQ domains are created from the same device-tree node they will get the same name based on the device-tree path. This will cause a naming collision in debugFS when IRQ domain specific entries are created.
The regmap-IRQ creates per instance IRQ domains. This will lead to a domain name conflict when a device which provides more than one interrupt line uses the regmap-IRQ.
Add support for specifying an IRQ domain name suffix when creating a regmap-IRQ controller.
Stable-dep-of: 3727c0b4ff6b ("mfd: intel_soc_pmic_bxtwc: Fix IRQ domain names duplication")
--- drivers/base/regmap/regmap-irq.c | 37 ++++++++++++++++++++++---------- include/linux/regmap.h | 4 ++++ 2 files changed, 30 insertions(+), 11 deletions(-)
drivers/base/regmap/regmap-irq.c +26 -11
@@ -612,6 +612,30 @@ int regmap_irq_set_type_config_simple(unsigned int **buf, unsigned int type, }EXPORT_SYMBOL_GPL (regmap_irq_set_type_config_simple); +static int regmap_irq_create_domain (struct fwnode_handle *fwnode,int irq_base, +const struct regmap_irq_chip *chip, +struct regmap_irq_chip_data *d) +{ +struct irq_domain_info info = { + .fwnode = fwnode, + .size = chip->num_irqs, + .hwirq_max = chip->num_irqs, + .virq_base = irq_base, + .ops = ®map_domain_ops, + .host_data = d, + .name_suffix = chip->domain_suffix, + }; + + d->domain =irq_domain_instantiate (&info); +if (IS_ERR (d->domain)) { +dev_err (d->map->dev,"Failed to create IRQ domain\n" ); +return PTR_ERR (d->domain); + } + +return 0 ; +} + +/** * regmap_add_irq_chip_fwnode() - Use standard regmap IRQ controller handling *
@@ -860,18 +884,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, } } -if (irq_base) - d->domain =irq_domain_create_legacy (fwnode, chip->num_irqs, - irq_base,0 , - ®map_domain_ops, d); -else - d->domain =irq_domain_create_linear (fwnode, chip->num_irqs, - ®map_domain_ops, d); -if (!d->domain) { -dev_err (map->dev,"Failed to create IRQ domain\n" ); - ret = -ENOMEM ; + ret =regmap_irq_create_domain (fwnode, irq_base, chip, d); +if (ret) goto err_alloc; - } ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags | IRQF_ONESHOT,
include/linux/regmap.h +4 -0
@@ -1521,6 +1521,9 @@ struct regmap_irq_chip_data;* struct regmap_irq_chip - Description of a generic regmap irq_chip. * * @name: Descriptive name for IRQ controller. +* @domain_suffix: Name suffix to be appended to end of IRQ domain name. Needed +* when multiple regmap-IRQ controllers are created from same +* device. * * @main_status: Base main status register address. For chips which have * interrupts arranged in separate sub-irq blocks with own IRQ
@@ -1606,6 +1609,7 @@ struct regmap_irq_chip_data;*/ struct regmap_irq_chip {const char *name; +const char *domain_suffix;unsigned int main_status;unsigned int num_main_status_bits;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 395/817 mfd: intel_soc_pmic_bxtwc: Fix IRQ domain names duplication
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit 3727c0b4ff6ba0e61203544b4c831f7f8899753b ]
For all of the devices regmap IRQ may try to created the folder with the same name which is impossible and fails with:
debugfs: File '\_SB.IPC1.PMIC' in directory 'domains' already present!
Add domain_suffix to all of the IRQ chips driver registers to solve the issue.
Depends-on: dde286ee5770 ("regmap: Allow setting IRQ domain name suffix")
--- drivers/mfd/intel_soc_pmic_bxtwc.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/mfd/intel_soc_pmic_bxtwc.c +6 -0
@@ -149,6 +149,7 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip = {static struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = { .name ="bxtwc_irq_chip_pwrbtn" , + .domain_suffix ="PWRBTN" , .status_base =BXTWC_PWRBTNIRQ , .mask_base =BXTWC_MPWRBTNIRQ , .irqs = bxtwc_regmap_irqs_pwrbtn,
@@ -158,6 +159,7 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = {static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = { .name ="bxtwc_irq_chip_tmu" , + .domain_suffix ="TMU" , .status_base =BXTWC_TMUIRQ , .mask_base =BXTWC_MTMUIRQ , .irqs = bxtwc_regmap_irqs_tmu,
@@ -167,6 +169,7 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = {static struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = { .name ="bxtwc_irq_chip_bcu" , + .domain_suffix ="BCU" , .status_base =BXTWC_BCUIRQ , .mask_base =BXTWC_MBCUIRQ , .irqs = bxtwc_regmap_irqs_bcu,
@@ -176,6 +179,7 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = {static struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = { .name ="bxtwc_irq_chip_adc" , + .domain_suffix ="ADC" , .status_base =BXTWC_ADCIRQ , .mask_base =BXTWC_MADCIRQ , .irqs = bxtwc_regmap_irqs_adc,
@@ -185,6 +189,7 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = {static struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = { .name ="bxtwc_irq_chip_chgr" , + .domain_suffix ="CHGR" , .status_base =BXTWC_CHGR0IRQ , .mask_base =BXTWC_MCHGR0IRQ , .irqs = bxtwc_regmap_irqs_chgr,
@@ -194,6 +199,7 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = {static struct regmap_irq_chip bxtwc_regmap_irq_chip_crit = { .name ="bxtwc_irq_chip_crit" , + .domain_suffix ="CRIT" , .status_base =BXTWC_CRITIRQ , .mask_base =BXTWC_MCRITIRQ , .irqs = bxtwc_regmap_irqs_crit,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 396/817 cpufreq: loongson2: Unregister platform_driver on failure
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuan Can <[email protected]>
[ Upstream commit 5f856d71ccdf89b4bac0ff70ebb0bb582e7f7f18 ]
When cpufreq_register_driver() returns error, the cpufreq_init() returns without unregister platform_driver, fix by add missing platform_driver_unregister() when cpufreq_register_driver() failed.
--- drivers/cpufreq/loongson2_cpufreq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/cpufreq/loongson2_cpufreq.c +3 -1
@@ -148,7 +148,9 @@ static int __init cpufreq_init(void) ret =cpufreq_register_driver (&loongson2_cpufreq_driver); -if (!ret && !nowait) { +if (ret) { +platform_driver_unregister (&platform_driver); + }else if (!nowait) { saved_cpu_wait = cpu_wait; cpu_wait = loongson2_cpu_wait; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 397/817 powerpc/fadump: Refactor and prepare fadump_cma_init for late init
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ritesh Harjani (IBM) <[email protected]>
[ Upstream commit adfaec30ffaceecd565e06adae367aa944acc3c9 ]
We anyway don't use any return values from fadump_cma_init(). Since fadump_reserve_mem() from where fadump_cma_init() gets called today, already has the required checks.
This patch makes this function return type as void. Let's also handle extra cases like return if fadump_supported is false or dump_active, so that in later patches we can call fadump_cma_init() separately from setup_arch().
Stable-dep-of: 05b94cae1c47 ("powerpc/fadump: Move fadump_cma_init to setup_arch() after initmem_init()")
--- arch/powerpc/kernel/fadump.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-)
arch/powerpc/kernel/fadump.c +9 -14
@@ -78,27 +78,23 @@ static struct cma *fadump_cma;* But for some reason even if it fails we still have the memory reservation * with us and we can still continue doing fadump. */ -static int __init fadump_cma_init (void ) +static void __init fadump_cma_init (void ) {unsigned long long base, size;int rc; -if (!fw_dump.fadump_enabled) -return 0 ; - +if (!fw_dump.fadump_supported || !fw_dump.fadump_enabled || + fw_dump.dump_active) +return ;/* * Do not use CMA if user has provided fadump=nocma kernel parameter. -* Return 1 to continue with fadump old behaviour. */ -if (fw_dump.nocma) -return 1 ; +if (fw_dump.nocma || !fw_dump.boot_memory_size) +return ; base = fw_dump.reserve_dump_area_start; size = fw_dump.boot_memory_size; -if (!size) -return 0 ; - rc =cma_init_reserved_mem (base, size,0 ,"fadump_cma" , &fadump_cma);if (rc) {pr_err ("Failed to init cma area for firmware-assisted dump,%d\n" , rc);
@@ -108,7 +104,7 @@ static int __init fadump_cma_init(void)* blocked from production system usage. Hence return 1, * so that we can continue with fadump. */ -return 1 ; +return ; }/*
@@ -125,10 +121,9 @@ static int __init fadump_cma_init(void)cma_get_size (fadump_cma), (unsigned long )cma_get_base (fadump_cma) >>20 , fw_dump.reserve_dump_area_size); - return 1; }#else -static int __init fadump_cma_init (void ) {return 1 ; } +static void __init fadump_cma_init (void ) { }#endif /* CONFIG_CMA */ /*
@@ -638,7 +633,7 @@ int __init fadump_reserve_mem(void)pr_info ("Reserved %lldMB of memory at %#016llx (System RAM: %lldMB)\n" , (size >>20 ), base, (memblock_phys_mem_size () >>20 )); - ret =fadump_cma_init (); +fadump_cma_init (); }return ret;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 398/817 powerpc/fadump: Move fadump_cma_init to setup_arch() after initmem_init()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ritesh Harjani (IBM) <[email protected]>
[ Upstream commit 05b94cae1c47f94588c3e7096963c1007c4d9c1d ]
During early init CMA_MIN_ALIGNMENT_BYTES can be PAGE_SIZE, since pageblock_order is still zero and it gets initialized later during initmem_init() e.g.setup_arch() -> initmem_init() -> sparse_init() -> set_pageblock_order()
One such use case where this causes issue is -early_setup() -> early_init_devtree() -> fadump_reserve_mem() -> fadump_cma_init()
This causes CMA memory alignment check to be bypassed in cma_init_reserved_mem(). Then later cma_activate_area() can hit a VM_BUG_ON_PAGE(pfn & ((1 << order) - 1)) if the reserved memory area was not pageblock_order aligned.
Fix it by moving the fadump_cma_init() after initmem_init(), where other such cma reservations also gets called.
<stack trace>
==============
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10010 flags: 0x13ffff800000000(node=1|zone=0|lastcpupid=0x7ffff) CMA raw: 013ffff800000000 5deadbeef0000100 5deadbeef0000122 0000000000000000 raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: VM_BUG_ON_PAGE(pfn & ((1 << order) - 1)) ------------[ cut here ]------------ kernel BUG at mm/page_alloc.c:778! Call Trace: __free_one_page+0x57c/0x7b0 (unreliable) free_pcppages_bulk+0x1a8/0x2c8 free_unref_page_commit+0x3d4/0x4e4 free_unref_page+0x458/0x6d0 init_cma_reserved_pageblock+0x114/0x198 cma_init_reserved_areas+0x270/0x3e0 do_one_initcall+0x80/0x2f8 kernel_init_freeable+0x33c/0x530 kernel_init+0x34/0x26c ret_from_kernel_user_thread+0x14/0x1c
--- arch/powerpc/include/asm/fadump.h | 7 +++++++ arch/powerpc/kernel/fadump.c | 6 +----- arch/powerpc/kernel/setup-common.c | 6 ++++-- 3 files changed, 12 insertions(+), 7 deletions(-)
arch/powerpc/include/asm/fadump.h +7 -0
@@ -34,4 +34,11 @@ extern int early_init_dt_scan_fw_dump(unsigned long node, const char *uname, int depth, void *data);extern int fadump_reserve_mem (void );#endif + +#if defined(CONFIG_FA_DUMP ) && defined(CONFIG_CMA ) +void fadump_cma_init (void ); +#else +static inline void fadump_cma_init (void ) { } +#endif +#endif /* _ASM_POWERPC_FADUMP_H */
arch/powerpc/kernel/fadump.c +1 -5
@@ -78,7 +78,7 @@ static struct cma *fadump_cma;* But for some reason even if it fails we still have the memory reservation * with us and we can still continue doing fadump. */ -static void __init fadump_cma_init (void ) +void __init fadump_cma_init (void ) {unsigned long long base, size;int rc;
@@ -122,8 +122,6 @@ static void __init fadump_cma_init(void) (unsigned long )cma_get_base (fadump_cma) >>20 , fw_dump.reserve_dump_area_size); } -#else -static void __init fadump_cma_init (void ) { }#endif /* CONFIG_CMA */ /*
@@ -632,8 +630,6 @@ int __init fadump_reserve_mem(void)pr_info ("Reserved %lldMB of memory at %#016llx (System RAM: %lldMB)\n" , (size >>20 ), base, (memblock_phys_mem_size () >>20 )); - -fadump_cma_init (); }return ret;
arch/powerpc/kernel/setup-common.c +4 -2
@@ -997,9 +997,11 @@ void __init setup_arch(char **cmdline_p)initmem_init ();/* -* Reserve large chunks of memory for use by CMA for KVM and hugetlb. These must -* be called after initmem_init(), so that pageblock_order is initialised. +* Reserve large chunks of memory for use by CMA for fadump, KVM and +* hugetlb. These must be called after initmem_init(), so that +* pageblock_order is initialised. */ +fadump_cma_init ();kvm_cma_reserve ();gigantic_hugetlb_cma_reserve ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 399/817 mtd: hyperbus: rpc-if: Add missing MODULE_DEVICE_TABLE
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Biju Das <[email protected]>
[ Upstream commit 7d189579a287d5c568db623c5fc2344cce98a887 ]
The rpc-if-hyperflash driver can be compiled as a module, but lacks MODULE_DEVICE_TABLE() and will therefore not be loaded automatically. Fix this.
--- drivers/mtd/hyperbus/rpc-if.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/mtd/hyperbus/rpc-if.c +7 -0
@@ -163,9 +163,16 @@ static void rpcif_hb_remove(struct platform_device *pdev)pm_runtime_disable (hyperbus->rpc.dev); } +static const struct platform_device_id rpc_if_hyperflash_id_table[] = { + { .name ="rpc-if-hyperflash" }, + {/* sentinel */ } +}; +MODULE_DEVICE_TABLE (platform, rpc_if_hyperflash_id_table); +static struct platform_driver rpcif_platform_driver = { .probe = rpcif_hb_probe, .remove_new = rpcif_hb_remove, + .id_table = rpc_if_hyperflash_id_table, .driver = { .name ="rpc-if-hyperflash" , },
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 400/817 mtd: rawnand: atmel: Fix possible memory leak
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Raynal <[email protected]>
[ Upstream commit 6d734f1bfc336aaea91313a5632f2f197608fadd ]
The pmecc "user" structure is allocated in atmel_pmecc_create_user() and was supposed to be freed with atmel_pmecc_destroy_user(), but this other helper is never called. One solution would be to find the proper location to call the destructor, but the trend today is to switch to device managed allocations, which in this case fits pretty well.
Replace kzalloc() by devm_kzalloc() and drop the destructor entirely.
--- drivers/mtd/nand/raw/atmel/pmecc.c | 8 +------- drivers/mtd/nand/raw/atmel/pmecc.h | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-)
drivers/mtd/nand/raw/atmel/pmecc.c +1 -7
@@ -362,7 +362,7 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc, size =ALIGN (size,sizeof (s32)); size += (req->ecc.strength +1 ) *sizeof (s32) *3 ; - user =kzalloc (size,GFP_KERNEL ); + user =devm_kzalloc (pmecc->dev, size,GFP_KERNEL );if (!user)return ERR_PTR (-ENOMEM );
@@ -408,12 +408,6 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc, }EXPORT_SYMBOL_GPL (atmel_pmecc_create_user); -void atmel_pmecc_destroy_user (struct atmel_pmecc_user *user) -{ -kfree (user); -} -EXPORT_SYMBOL_GPL (atmel_pmecc_destroy_user); -static int get_strength (struct atmel_pmecc_user *user) {const int *strengths = user->pmecc->caps->strengths;
drivers/mtd/nand/raw/atmel/pmecc.h +0 -2
@@ -55,8 +55,6 @@ struct atmel_pmecc *devm_atmel_pmecc_get(struct device *dev);struct atmel_pmecc_user *atmel_pmecc_create_user (struct atmel_pmecc *pmecc,struct atmel_pmecc_user_req *req); -void atmel_pmecc_destroy_user (struct atmel_pmecc_user *user); -void atmel_pmecc_reset (struct atmel_pmecc *pmecc);int atmel_pmecc_enable (struct atmel_pmecc_user *user,int op);void atmel_pmecc_disable (struct atmel_pmecc_user *user);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 401/817 powerpc/mm/fault: Fix kfence page fault reporting
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ritesh Harjani (IBM) <[email protected]>
[ Upstream commit 06dbbb4d5f7126b6307ab807cbf04ecfc459b933 ]
copy_from_kernel_nofault() can be called when doing read of /proc/kcore. /proc/kcore can have some unmapped kfence objects which when read via copy_from_kernel_nofault() can cause page faults. Since *_nofault() functions define their own fixup table for handling fault, use that instead of asking kfence to handle such faults.
Hence we search the exception tables for the nip which generated the fault. If there is an entry then we let the fixup table handler handle the page fault by returning an error from within ___do_page_fault().
This can be easily triggered if someone tries to do dd from /proc/kcore. eg. dd if=/proc/kcore of=/dev/null bs=1M
Some example false negatives:
===============================
BUG: KFENCE: invalid read in copy_from_kernel_nofault+0x9c/0x1a0 Invalid read at 0xc0000000fdff0000: copy_from_kernel_nofault+0x9c/0x1a0 0xc00000000665f950 read_kcore_iter+0x57c/0xa04 proc_reg_read_iter+0xe4/0x16c vfs_read+0x320/0x3ec ksys_read+0x90/0x154 system_call_exception+0x120/0x310 system_call_vectored_common+0x15c/0x2ec BUG: KFENCE: use-after-free read in copy_from_kernel_nofault+0x9c/0x1a0 Use-after-free read at 0xc0000000fe050000 (in kfence-#2): copy_from_kernel_nofault+0x9c/0x1a0 0xc00000000665f950 read_kcore_iter+0x57c/0xa04 proc_reg_read_iter+0xe4/0x16c vfs_read+0x320/0x3ec ksys_read+0x90/0x154 system_call_exception+0x120/0x310 system_call_vectored_common+0x15c/0x2ec
--- arch/powerpc/mm/fault.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
arch/powerpc/mm/fault.c +8 -2
@@ -439,10 +439,16 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,/* * The kernel should never take an execute fault nor should it * take a page fault to a kernel address or a page fault to a user -* address outside of dedicated places +* address outside of dedicated places. +* +* Rather than kfence directly reporting false negatives, search whether +* the NIP belongs to the fixup table for cases where fault could come +* from functions like copy_from_kernel_nofault(). */ if (unlikely (!is_user &&bad_kernel_fault (regs, error_code, address, is_write))) { -if (kfence_handle_page_fault (address, is_write, regs)) +if (is_kfence_address ((void *)address) && + !search_exception_tables (instruction_pointer (regs)) && +kfence_handle_page_fault (address, is_write, regs))return 0 ;return SIGSEGV ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 402/817 clk: sophgo: avoid integer overflow in sg2042_pll_recalc_rate()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zichen Xie <[email protected]>
[ Upstream commit 00f8f70a0e8c6601861628be26270a0b6f4bbb34 ]
This was found by a static analyzer.
There may be a potential integer overflow issue in sg2042_pll_recalc_rate(). numerator is defined as u64 while parent_rate is defined as unsigned long and ctrl_table.fbdiv is defined as unsigned int. On 32-bit machine, the result of the calculation will be limited to "u32" without correct casting. Integer overflow may occur on high-performance systems.
--- drivers/clk/sophgo/clk-sg2042-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/sophgo/clk-sg2042-pll.c +1 -1
@@ -153,7 +153,7 @@ static unsigned long sg2042_pll_recalc_rate(unsigned int reg_value,sg2042_pll_ctrl_decode (reg_value, &ctrl_table); - numerator = parent_rate * ctrl_table.fbdiv; + numerator = (u64 )parent_rate * ctrl_table.fbdiv; denominator = ctrl_table.refdiv * ctrl_table.postdiv1 * ctrl_table.postdiv2;do_div (numerator, denominator);return numerator;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 403/817 mtd: spi-nor: spansion: Use nor->addr_nbytes in octal DTR mode in RD_ANY_REG_OP
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takahiro Kuwano <[email protected]>
[ Upstream commit b61c35e3404557779ec427c077f7a9f057bb053d ]
In octal DTR mode, RD_ANY_REG_OP needs to use 4-byte address regardless of flash's internal address mode. Use nor->addr_nbytes which is set to 4 during setup.
--- drivers/mtd/spi-nor/spansion.c | 1 + 1 file changed, 1 insertion(+)
drivers/mtd/spi-nor/spansion.c +1 -0
@@ -106,6 +106,7 @@ static int cypress_nor_sr_ready_and_clear_reg(struct spi_nor *nor, u64 addr)int ret;if (nor->reg_proto ==SNOR_PROTO_8_8_8_DTR ) { + op.addr.nbytes = nor->addr_nbytes; op.dummy.nbytes = params->rdsr_dummy; op.data.nbytes =2 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 404/817 powerpc/pseries: Fix dtl_access_lock to be a rw_semaphore
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Ellerman <[email protected]>
[ Upstream commit cadae3a45d23aa4f6485938a67cbc47aaaa25e38 ]
The dtl_access_lock needs to be a rw_sempahore, a sleeping lock, because the code calls kmalloc() while holding it, which can sleep:
# echo 1 > /proc/powerpc/vcpudispatch_stats
BUG: sleeping function called from invalid context at include/linux/sched/mm.h:337
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 199, name: sh
preempt_count: 1, expected: 0
3 locks held by sh/199:
#0: c00000000a0743f8 (sb_writers#3){.+.+}-{0:0}, at: vfs_write+0x324/0x438
#1: c0000000028c7058 (dtl_enable_mutex){+.+.}-{3:3}, at: vcpudispatch_stats_write+0xd4/0x5f4
#2: c0000000028c70b8 (dtl_access_lock){+.+.}-{2:2}, at: vcpudispatch_stats_write+0x220/0x5f4
CPU: 0 PID: 199 Comm: sh Not tainted 6.10.0-rc4 #152
Hardware name: IBM pSeries (emulated by qemu) POWER9 (raw) 0x4e1202 0xf000005 of:SLOF,HEAD hv:linux,kvm pSeries
Call Trace:
dump_stack_lvl+0x130/0x148 (unreliable)
__might_resched+0x174/0x410
kmem_cache_alloc_noprof+0x340/0x3d0
alloc_dtl_buffers+0x124/0x1ac
vcpudispatch_stats_write+0x2a8/0x5f4
proc_reg_write+0xf4/0x150
vfs_write+0xfc/0x438
ksys_write+0x88/0x148
system_call_exception+0x1c4/0x5a0
system_call_common+0xf4/0x258--- arch/powerpc/include/asm/dtl.h | 4 ++-- arch/powerpc/platforms/pseries/dtl.c | 8 ++++---- arch/powerpc/platforms/pseries/lpar.c | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-)
arch/powerpc/include/asm/dtl.h +2 -2
@@ -1,8 +1,8 @@#ifndef _ASM_POWERPC_DTL_H#define _ASM_POWERPC_DTL_H +#include <linux/rwsem.h> #include <asm/lppaca.h> -#include <linux/spinlock_types.h> /* * Layout of entries in the hypervisor's dispatch trace log buffer.
@@ -35,7 +35,7 @@ struct dtl_entry {#define DTL_LOG_ALL (DTL_LOG_CEDE | DTL_LOG_PREEMPT | DTL_LOG_FAULT)extern struct kmem_cache *dtl_cache; -extern rwlock_t dtl_access_lock; +extern struct rw_semaphore dtl_access_lock;extern void register_dtl_buffer (int cpu);extern void alloc_dtl_buffers (unsigned long *time_limit);
arch/powerpc/platforms/pseries/dtl.c +4 -4
@@ -191,7 +191,7 @@ static int dtl_enable(struct dtl *dtl)return -EBUSY ;/* ensure there are no other conflicting dtl users */ -if (!read_trylock (&dtl_access_lock)) +if (!down_read_trylock (&dtl_access_lock))return -EBUSY ; n_entries = dtl_buf_entries;
@@ -199,7 +199,7 @@ static int dtl_enable(struct dtl *dtl)if (!buf) {printk (KERN_WARNING "%s: buffer alloc failed for cpu %d\n" , __func__, dtl->cpu); -read_unlock (&dtl_access_lock); +up_read (&dtl_access_lock);return -ENOMEM ; }
@@ -217,7 +217,7 @@ static int dtl_enable(struct dtl *dtl)spin_unlock (&dtl->lock);if (rc) { -read_unlock (&dtl_access_lock); +up_read (&dtl_access_lock);kmem_cache_free (dtl_cache, buf); }
@@ -232,7 +232,7 @@ static void dtl_disable(struct dtl *dtl) dtl->buf =NULL ; dtl->buf_entries =0 ;spin_unlock (&dtl->lock); -read_unlock (&dtl_access_lock); +up_read (&dtl_access_lock); }/* file interface */
arch/powerpc/platforms/pseries/lpar.c +4 -4
@@ -169,7 +169,7 @@ struct vcpu_dispatch_data {*/ #define NR_CPUS_H NR_CPUS -DEFINE_RWLOCK (dtl_access_lock); +DECLARE_RWSEM (dtl_access_lock); static DEFINE_PER_CPU(struct vcpu_dispatch_data, vcpu_disp_data); static DEFINE_PER_CPU(u64, dtl_entry_ridx); static DEFINE_PER_CPU(struct dtl_worker, dtl_workers);
@@ -463,7 +463,7 @@ static int dtl_worker_enable(unsigned long *time_limit) {int rc =0 , state; -if (!write_trylock (&dtl_access_lock)) { +if (!down_write_trylock (&dtl_access_lock)) { rc = -EBUSY ; goto out; }
@@ -479,7 +479,7 @@ static int dtl_worker_enable(unsigned long *time_limit)pr_err ("vcpudispatch_stats: unable to setup workqueue for DTL processing\n" );free_dtl_buffers (time_limit);reset_global_dtl_mask (); -write_unlock (&dtl_access_lock); +up_write (&dtl_access_lock); rc = -EINVAL ; goto out; }
@@ -494,7 +494,7 @@ static void dtl_worker_disable(unsigned long *time_limit)cpuhp_remove_state (dtl_worker_state);free_dtl_buffers (time_limit);reset_global_dtl_mask (); -write_unlock (&dtl_access_lock); +up_write (&dtl_access_lock); } static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 405/817 cpufreq: CPPC: Fix possible null-ptr-deref for cpufreq_cpu_get_raw()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit a78e7207564258db6e373e86294a85f9d646d35a ]
cpufreq_cpu_get_raw() may return NULL if the cpu is not in policy->cpus cpu mask and it will cause null pointer dereference.
--- drivers/cpufreq/cppc_cpufreq.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/cpufreq/cppc_cpufreq.c +3 -0
@@ -423,6 +423,9 @@ static int cppc_get_cpu_power(struct device *cpu_dev,struct cppc_cpudata *cpu_data; policy =cpufreq_cpu_get_raw (cpu_dev->id); +if (!policy) +return 0 ; + cpu_data = policy->driver_data; perf_caps = &cpu_data->perf_caps; max_cap =arch_scale_cpu_capacity (cpu_dev->id);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 406/817 cpufreq: CPPC: Fix possible null-ptr-deref for cppc_get_cpu_cost()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 1a1374bb8c5926674973d849feed500bc61ad535 ]
cpufreq_cpu_get_raw() may return NULL if the cpu is not in policy->cpus cpu mask and it will cause null pointer dereference, so check NULL for cppc_get_cpu_cost().
--- drivers/cpufreq/cppc_cpufreq.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/cpufreq/cppc_cpufreq.c +3 -0
@@ -493,6 +493,9 @@ static int cppc_get_cpu_cost(struct device *cpu_dev, unsigned long KHz,int step; policy =cpufreq_cpu_get_raw (cpu_dev->id); +if (!policy) +return 0 ; + cpu_data = policy->driver_data; perf_caps = &cpu_data->perf_caps; max_cap =arch_scale_cpu_capacity (cpu_dev->id);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 407/817 iommu/amd: Remove amd_iommu_domain_update() from page table freeing
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 322d889ae7d39f8538a6deac35869aa3be1855bd ]
It is a serious bug if the domain is still mapped to any DTEs when it is freed as we immediately start freeing page table memory, so any remaining HW touch will UAF.
If it is not mapped then dev_list is empty and amd_iommu_domain_update() does nothing.
Remove it and add a WARN_ON() to catch this class of bug.
Stable-dep-of: 016991606aa0 ("iommu/amd/pgtbl_v2: Take protection domain lock before invalidating TLB")
--- drivers/iommu/amd/io_pgtable.c | 3 --- drivers/iommu/amd/iommu.c | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-)
drivers/iommu/amd/io_pgtable.c +0 -3
@@ -578,9 +578,6 @@ static void v1_free_pgtable(struct io_pgtable *iop)/* Update data structure */ amd_iommu_domain_clr_pt_root (dom); - -/* Make changes visible to IOMMUs */ -amd_iommu_domain_update (dom); }static struct io_pgtable *v1_alloc_pgtable (struct io_pgtable_cfg *cfg,void *cookie)
drivers/iommu/amd/iommu.c +2 -0
@@ -2262,6 +2262,8 @@ void protection_domain_free(struct protection_domain *domain)if (!domain)return ; +WARN_ON (!list_empty (&domain->dev_list)); +if (domain->iop.pgtbl_cfg.tlb)free_io_pgtable_ops (&domain->iop.iop.ops);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 408/817 iommu/amd: Remove the amd_iommu_domain_set_pt_root() and related
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 1ed2d21d471caf2e4351c2e8bb14143bc8062092 ]
Looks like many refactorings here have left this confused. There is only one storage of the root/mode, it is in the iop struct.
increase_address_space() calls amd_iommu_domain_set_pgtable() with values that it already stored in iop a few lines above.
amd_iommu_domain_clr_pt_root() is zero'ing memory we are about to free. It used to protect against a double free of root, but that is gone now.
Remove amd_iommu_domain_set_pgtable(), amd_iommu_domain_set_pt_root(), amd_iommu_domain_clr_pt_root() as they are all pointless.
Stable-dep-of: 016991606aa0 ("iommu/amd/pgtbl_v2: Take protection domain lock before invalidating TLB")
--- drivers/iommu/amd/amd_iommu.h | 13 ------------- drivers/iommu/amd/io_pgtable.c | 24 ------------------------ 2 files changed, 37 deletions(-)
drivers/iommu/amd/amd_iommu.h +0 -13
@@ -143,19 +143,6 @@ static inline void *iommu_phys_to_virt(unsigned long paddr)return phys_to_virt (__sme_clr (paddr)); } -static inline -void amd_iommu_domain_set_pt_root (struct protection_domain *domain,u64 root) -{ - domain->iop.root = (u64 *)(root &PAGE_MASK ); - domain->iop.mode = root &7 ;/* lowest 3 bits encode pgtable mode */ -} - -static inline -void amd_iommu_domain_clr_pt_root (struct protection_domain *domain) -{ -amd_iommu_domain_set_pt_root (domain,0 ); -} -static inline int get_pci_sbdf_id (struct pci_dev *pdev) {int seg =pci_domain_nr (pdev->bus);
drivers/iommu/amd/io_pgtable.c +0 -24
@@ -132,18 +132,6 @@ static void free_sub_pt(u64 *root, int mode, struct list_head *freelist) } } -void amd_iommu_domain_set_pgtable (struct protection_domain *domain, -u64 *root,int mode) -{ -u64 pt_root; - -/* lowest 3 bits encode pgtable mode */ - pt_root = mode &7 ; - pt_root |= (u64 )root; - -amd_iommu_domain_set_pt_root (domain, pt_root); -} -/* * This function is used to add another level to an IO page table. Adding * another level increases the size of the address space by 9 bits to a size up
@@ -177,12 +165,6 @@ static bool increase_address_space(struct protection_domain *domain,amd_iommu_update_and_flush_device_table (domain);amd_iommu_domain_flush_complete (domain); -/* -* Device Table needs to be updated and flushed before the new root can -* be published. -*/ -amd_iommu_domain_set_pgtable (domain, pte, domain->iop.mode); - pte =NULL ; ret = true;
@@ -561,23 +543,17 @@ static int iommu_v1_read_and_clear_dirty(struct io_pgtable_ops *ops,static void v1_free_pgtable (struct io_pgtable *iop) { struct amd_io_pgtable *pgtable = container_of(iop, struct amd_io_pgtable, iop); -struct protection_domain *dom;LIST_HEAD (freelist);if (pgtable->mode ==PAGE_MODE_NONE )return ; - dom = container_of(pgtable, struct protection_domain, iop); -/* Page-table is not visible to IOMMU anymore, so free it */ BUG_ON (pgtable->mode <PAGE_MODE_NONE || pgtable->mode >PAGE_MODE_6_LEVEL );free_sub_pt (pgtable->root, pgtable->mode, &freelist);iommu_put_pages_list (&freelist); - -/* Update data structure */ -amd_iommu_domain_clr_pt_root (dom); }static struct io_pgtable *v1_alloc_pgtable (struct io_pgtable_cfg *cfg,void *cookie)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 409/817 iommu/amd: Rename struct amd_io_pgtable iopt to pgtbl
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 670b57796c5dc1ca58912132cad914cf4b3c0cdd ]
There is struct protection_domain iopt and struct amd_io_pgtable iopt. Next patches are going to want to write domain.iopt.iopt.xx which is quite unnatural to read.
Give one of them a different name, amd_io_pgtable has fewer references so call it pgtbl, to match pgtbl_cfg, instead.
Stable-dep-of: 016991606aa0 ("iommu/amd/pgtbl_v2: Take protection domain lock before invalidating TLB")
--- drivers/iommu/amd/amd_iommu_types.h | 4 ++-- drivers/iommu/amd/io_pgtable.c | 12 ++++++------ drivers/iommu/amd/io_pgtable_v2.c | 14 +++++++------- drivers/iommu/amd/iommu.c | 14 +++++++------- 4 files changed, 22 insertions(+), 22 deletions(-)
drivers/iommu/amd/amd_iommu_types.h +2 -2
@@ -527,7 +527,7 @@ struct amd_irte_ops;#define AMD_IOMMU_FLAG_TRANS_PRE_ENABLED (1 << 0)#define io_pgtable_to_data (x) \ - container_of((x), struct amd_io_pgtable, iop) + container_of((x), struct amd_io_pgtable, pgtbl)#define io_pgtable_ops_to_data (x) \ io_pgtable_to_data(io_pgtable_ops_to_pgtable(x))
@@ -548,7 +548,7 @@ struct gcr3_tbl_info {struct amd_io_pgtable {struct io_pgtable_cfg pgtbl_cfg; -struct io_pgtable iop; +struct io_pgtable pgtbl;int mode;u64 *root;u64 *pgd;/* v2 pgtable pgd pointer */
drivers/iommu/amd/io_pgtable.c +6 -6
@@ -542,7 +542,7 @@ static int iommu_v1_read_and_clear_dirty(struct io_pgtable_ops *ops,*/ static void v1_free_pgtable (struct io_pgtable *iop) { - struct amd_io_pgtable *pgtable = container_of(iop, struct amd_io_pgtable, iop); + struct amd_io_pgtable *pgtable = container_of(iop, struct amd_io_pgtable, pgtbl);LIST_HEAD (freelist);if (pgtable->mode ==PAGE_MODE_NONE )
@@ -570,12 +570,12 @@ static struct io_pgtable *v1_alloc_pgtable(struct io_pgtable_cfg *cfg, void *coo cfg->oas =IOMMU_OUT_ADDR_BIT_SIZE ; cfg->tlb = &v1_flush_ops; - pgtable->iop.ops.map_pages = iommu_v1_map_pages; - pgtable->iop.ops.unmap_pages = iommu_v1_unmap_pages; - pgtable->iop.ops.iova_to_phys = iommu_v1_iova_to_phys; - pgtable->iop.ops.read_and_clear_dirty = iommu_v1_read_and_clear_dirty; + pgtable->pgtbl.ops.map_pages = iommu_v1_map_pages; + pgtable->pgtbl.ops.unmap_pages = iommu_v1_unmap_pages; + pgtable->pgtbl.ops.iova_to_phys = iommu_v1_iova_to_phys; + pgtable->pgtbl.ops.read_and_clear_dirty = iommu_v1_read_and_clear_dirty; -return &pgtable->iop; +return &pgtable->pgtbl; }struct io_pgtable_init_fns io_pgtable_amd_iommu_v1_init_fns = {
drivers/iommu/amd/io_pgtable_v2.c +7 -7
@@ -234,7 +234,7 @@ static int iommu_v2_map_pages(struct io_pgtable_ops *ops, unsigned long iova, int prot, gfp_t gfp, size_t *mapped) { struct protection_domain *pdom = io_pgtable_ops_to_domain(ops); -struct io_pgtable_cfg *cfg = &pdom->iop.iop.cfg; +struct io_pgtable_cfg *cfg = &pdom->iop.pgtbl.cfg;u64 *pte;unsigned long map_size;unsigned long mapped_size =0 ;
@@ -281,7 +281,7 @@ static unsigned long iommu_v2_unmap_pages(struct io_pgtable_ops *ops, struct iommu_iotlb_gather *gather) {struct amd_io_pgtable *pgtable =io_pgtable_ops_to_data (ops); -struct io_pgtable_cfg *cfg = &pgtable->iop.cfg; +struct io_pgtable_cfg *cfg = &pgtable->pgtbl.cfg;unsigned long unmap_size;unsigned long unmapped =0 ;size_t size = pgcount <<__ffs (pgsize);
@@ -346,7 +346,7 @@ static const struct iommu_flush_ops v2_flush_ops = {static void v2_free_pgtable (struct io_pgtable *iop) { - struct amd_io_pgtable *pgtable = container_of(iop, struct amd_io_pgtable, iop); + struct amd_io_pgtable *pgtable = container_of(iop, struct amd_io_pgtable, pgtbl);if (!pgtable || !pgtable->pgd)return ;
@@ -369,16 +369,16 @@ static struct io_pgtable *v2_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cooif (get_pgtable_level () ==PAGE_MODE_5_LEVEL ) ias =57 ; - pgtable->iop.ops.map_pages = iommu_v2_map_pages; - pgtable->iop.ops.unmap_pages = iommu_v2_unmap_pages; - pgtable->iop.ops.iova_to_phys = iommu_v2_iova_to_phys; + pgtable->pgtbl.ops.map_pages = iommu_v2_map_pages; + pgtable->pgtbl.ops.unmap_pages = iommu_v2_unmap_pages; + pgtable->pgtbl.ops.iova_to_phys = iommu_v2_iova_to_phys; cfg->pgsize_bitmap =AMD_IOMMU_PGSIZES_V2 , cfg->ias = ias, cfg->oas =IOMMU_OUT_ADDR_BIT_SIZE , cfg->tlb = &v2_flush_ops; -return &pgtable->iop; +return &pgtable->pgtbl; }struct io_pgtable_init_fns io_pgtable_amd_iommu_v2_init_fns = {
drivers/iommu/amd/iommu.c +7 -7
@@ -2265,7 +2265,7 @@ void protection_domain_free(struct protection_domain *domain)WARN_ON (!list_empty (&domain->dev_list));if (domain->iop.pgtbl_cfg.tlb) -free_io_pgtable_ops (&domain->iop.iop.ops); +free_io_pgtable_ops (&domain->iop.pgtbl.ops);if (domain->id)domain_id_free (domain->id);
@@ -2373,7 +2373,7 @@ static struct iommu_domain *do_iommu_domain_alloc(unsigned int type, domain->domain.geometry.aperture_start =0 ; domain->domain.geometry.aperture_end =dma_max_address (); domain->domain.geometry.force_aperture = true; - domain->domain.pgsize_bitmap = domain->iop.iop.cfg.pgsize_bitmap; + domain->domain.pgsize_bitmap = domain->iop.pgtbl.cfg.pgsize_bitmap;if (iommu) { domain->domain.type = type;
@@ -2494,7 +2494,7 @@ static int amd_iommu_iotlb_sync_map(struct iommu_domain *dom, unsigned long iova, size_t size) {struct protection_domain *domain =to_pdomain (dom); -struct io_pgtable_ops *ops = &domain->iop.iop.ops; +struct io_pgtable_ops *ops = &domain->iop.pgtbl.ops;if (ops->map_pages)domain_flush_np_cache (domain, iova, size);
@@ -2506,7 +2506,7 @@ static int amd_iommu_map_pages(struct iommu_domain *dom, unsigned long iova, int iommu_prot, gfp_t gfp, size_t *mapped) { struct protection_domain *domain = to_pdomain(dom); -struct io_pgtable_ops *ops = &domain->iop.iop.ops; +struct io_pgtable_ops *ops = &domain->iop.pgtbl.ops;int prot =0 ;int ret = -EINVAL ;
@@ -2553,7 +2553,7 @@ static size_t amd_iommu_unmap_pages(struct iommu_domain *dom, unsigned long iova struct iommu_iotlb_gather *gather) {struct protection_domain *domain =to_pdomain (dom); -struct io_pgtable_ops *ops = &domain->iop.iop.ops; +struct io_pgtable_ops *ops = &domain->iop.pgtbl.ops;size_t r; if ((domain->pd_mode == PD_MODE_V1) &&
@@ -2572,7 +2572,7 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, dma_addr_t iova) {struct protection_domain *domain =to_pdomain (dom); -struct io_pgtable_ops *ops = &domain->iop.iop.ops; +struct io_pgtable_ops *ops = &domain->iop.pgtbl.ops;return ops->iova_to_phys (ops, iova); }
@@ -2650,7 +2650,7 @@ static int amd_iommu_read_and_clear_dirty(struct iommu_domain *domain, struct iommu_dirty_bitmap *dirty) {struct protection_domain *pdomain =to_pdomain (domain); -struct io_pgtable_ops *ops = &pdomain->iop.iop.ops; +struct io_pgtable_ops *ops = &pdomain->iop.pgtbl.ops;unsigned long lflags;if (!ops || !ops->read_and_clear_dirty)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 410/817 iommu/amd: Store the nid in io_pgtable_cfg instead of the domain
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 47f218d108950984b24af81f66356ceda380eb74 ]
We already have memory in the union here that is being wasted in AMD's case, use it to store the nid.
Putting the nid here further isolates the io_pgtable code from the struct protection_domain.
Fixup protection_domain_alloc so that the NID from the device is provided, at this point dev is never NULL for AMD so this will now allocate the first table pointer on the correct NUMA node.
Stable-dep-of: 016991606aa0 ("iommu/amd/pgtbl_v2: Take protection domain lock before invalidating TLB")
--- drivers/iommu/amd/amd_iommu.h | 2 +- drivers/iommu/amd/amd_iommu_types.h | 1 - drivers/iommu/amd/io_pgtable.c | 8 +++++--- drivers/iommu/amd/io_pgtable_v2.c | 5 ++--- drivers/iommu/amd/iommu.c | 12 +++++++----- drivers/iommu/amd/pasid.c | 2 +- include/linux/io-pgtable.h | 4 ++++ 7 files changed, 20 insertions(+), 14 deletions(-)
drivers/iommu/amd/amd_iommu.h +1 -1
@@ -45,7 +45,7 @@ extern enum io_pgtable_fmt amd_iommu_pgtable;extern int amd_iommu_gpt_level;/* Protection domain ops */ -struct protection_domain *protection_domain_alloc (unsigned int type); +struct protection_domain *protection_domain_alloc (unsigned int type,int nid);void protection_domain_free (struct protection_domain *domain);struct iommu_domain *amd_iommu_domain_alloc_sva (struct device *dev,struct mm_struct *mm);
drivers/iommu/amd/amd_iommu_types.h +0 -1
@@ -580,7 +580,6 @@ struct protection_domain {struct amd_io_pgtable iop;spinlock_t lock;/* mostly used to lock the page table*/ u16 id;/* the domain id written to the device table */ -int nid;/* Node ID */ enum protection_domain_mode pd_mode;/* Track page table type */ bool dirty_tracking;/* dirty tracking is enabled in the domain */ unsigned dev_cnt;/* devices assigned to this domain */
drivers/iommu/amd/io_pgtable.c +5 -3
@@ -141,11 +141,12 @@ static bool increase_address_space(struct protection_domain *domain, unsigned long address, gfp_t gfp) { +struct io_pgtable_cfg *cfg = &domain->iop.pgtbl.cfg;unsigned long flags;bool ret = true;u64 *pte; - pte =iommu_alloc_page_node (domain->nid, gfp); + pte =iommu_alloc_page_node (cfg->amd.nid, gfp);if (!pte)return false;
@@ -182,6 +183,7 @@ static u64 *alloc_pte(struct protection_domain *domain,gfp_t gfp, bool *updated) { + struct io_pgtable_cfg *cfg = &domain->iop.pgtbl.cfg;int level, end_lvl;u64 *pte, *page;
@@ -233,7 +235,7 @@ static u64 *alloc_pte(struct protection_domain *domain,if (!IOMMU_PTE_PRESENT (__pte) || pte_level ==PAGE_MODE_NONE ) { - page =iommu_alloc_page_node (domain->nid, gfp); + page =iommu_alloc_page_node (cfg->amd.nid, gfp);if (!page)return NULL ;
@@ -560,7 +562,7 @@ static struct io_pgtable *v1_alloc_pgtable(struct io_pgtable_cfg *cfg, void *coo {struct amd_io_pgtable *pgtable =io_pgtable_cfg_to_data (cfg); - pgtable->root =iommu_alloc_page (GFP_KERNEL ); + pgtable->root =iommu_alloc_page_node (cfg->amd.nid,GFP_KERNEL );if (!pgtable->root)return NULL ; pgtable->mode =PAGE_MODE_3_LEVEL ;
drivers/iommu/amd/io_pgtable_v2.c +2 -3
@@ -251,7 +251,7 @@ static int iommu_v2_map_pages(struct io_pgtable_ops *ops, unsigned long iova,while (mapped_size < size) { map_size =get_alloc_page_size (pgsize); - pte =v2_alloc_pte (pdom->nid, pdom->iop.pgd, + pte =v2_alloc_pte (cfg->amd.nid, pdom->iop.pgd, iova, map_size, gfp, &updated);if (!pte) { ret = -EINVAL ;
@@ -359,10 +359,9 @@ static void v2_free_pgtable(struct io_pgtable *iop)static struct io_pgtable *v2_alloc_pgtable (struct io_pgtable_cfg *cfg,void *cookie) {struct amd_io_pgtable *pgtable =io_pgtable_cfg_to_data (cfg); -struct protection_domain *pdom = (struct protection_domain *)cookie;int ias =IOMMU_IN_ADDR_BIT_SIZE ; - pgtable->pgd =iommu_alloc_page_node (pdom->nid,GFP_KERNEL ); + pgtable->pgd =iommu_alloc_page_node (cfg->amd.nid,GFP_KERNEL );if (!pgtable->pgd)return NULL ;
drivers/iommu/amd/iommu.c +7 -5
@@ -2030,6 +2030,7 @@ static int do_attach(struct iommu_dev_data *dev_data, struct protection_domain *domain) {struct amd_iommu *iommu =get_amd_iommu_from_dev_data (dev_data); +struct io_pgtable_cfg *cfg = &domain->iop.pgtbl.cfg;int ret =0 ;/* Update data structures */
@@ -2037,8 +2038,8 @@ static int do_attach(struct iommu_dev_data *dev_data,list_add (&dev_data->list, &domain->dev_list);/* Update NUMA Node ID */ -if (domain->nid ==NUMA_NO_NODE ) - domain->nid =dev_to_node (dev_data->dev); +if (cfg->amd.nid ==NUMA_NO_NODE ) + cfg->amd.nid =dev_to_node (dev_data->dev);/* Do reference counting */ domain->dev_iommu[iommu->index] +=1 ;
@@ -2273,7 +2274,7 @@ void protection_domain_free(struct protection_domain *domain)kfree (domain); } -struct protection_domain *protection_domain_alloc (unsigned int type) +struct protection_domain *protection_domain_alloc (unsigned int type,int nid) {struct io_pgtable_ops *pgtbl_ops;struct protection_domain *domain;
@@ -2290,7 +2291,7 @@ struct protection_domain *protection_domain_alloc(unsigned int type)spin_lock_init (&domain->lock);INIT_LIST_HEAD (&domain->dev_list);INIT_LIST_HEAD (&domain->dev_data_list); - domain->nid =NUMA_NO_NODE ; + domain->iop.pgtbl.cfg.amd.nid = nid;switch (type) {/* No need to allocate io pgtable ops in passthrough mode */
@@ -2366,7 +2367,8 @@ static struct iommu_domain *do_iommu_domain_alloc(unsigned int type,if (dirty_tracking && !amd_iommu_hd_support (iommu))return ERR_PTR (-EOPNOTSUPP ); - domain =protection_domain_alloc (type); + domain =protection_domain_alloc (type, + dev ?dev_to_node (dev) :NUMA_NO_NODE );if (!domain)return ERR_PTR (-ENOMEM );
drivers/iommu/amd/pasid.c +1 -1
@@ -181,7 +181,7 @@ struct iommu_domain *amd_iommu_domain_alloc_sva(struct device *dev,struct protection_domain *pdom;int ret; - pdom =protection_domain_alloc (IOMMU_DOMAIN_SVA ); + pdom =protection_domain_alloc (IOMMU_DOMAIN_SVA ,dev_to_node (dev));if (!pdom)return ERR_PTR (-ENOMEM );
include/linux/io-pgtable.h +4 -0
@@ -171,6 +171,10 @@ struct io_pgtable_cfg {u64 ttbr[4 ];u32 n_ttbrs; } apple_dart_cfg; + +struct { +int nid; + } amd; }; };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 411/817 iommu/amd: Narrow the use of struct protection_domain to invalidation
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 9ac0b3380acdece01fa1b361687e3cd988831c55 ]
The AMD io_pgtable stuff doesn't implement the tlb ops callbacks, instead it invokes the invalidation ops directly on the struct protection_domain.
Narrow the use of struct protection_domain to only those few code paths. Make everything else properly use struct amd_io_pgtable through the call chains, which is the correct modular type for an io-pgtable module.
Stable-dep-of: 016991606aa0 ("iommu/amd/pgtbl_v2: Take protection domain lock before invalidating TLB")
--- drivers/iommu/amd/io_pgtable.c | 33 +++++++++++++++++-------------- drivers/iommu/amd/io_pgtable_v2.c | 11 +++++++---- 2 files changed, 25 insertions(+), 19 deletions(-)
drivers/iommu/amd/io_pgtable.c +18 -15
@@ -137,11 +137,13 @@ static void free_sub_pt(u64 *root, int mode, struct list_head *freelist)* another level increases the size of the address space by 9 bits to a size up * to 64 bits. */ -static bool increase_address_space (struct protection_domain *domain, +static bool increase_address_space (struct amd_io_pgtable *pgtable,unsigned long address,gfp_t gfp) { -struct io_pgtable_cfg *cfg = &domain->iop.pgtbl.cfg; +struct io_pgtable_cfg *cfg = &pgtable->pgtbl.cfg; +struct protection_domain *domain = + container_of(pgtable, struct protection_domain, iop);unsigned long flags;bool ret = true;u64 *pte;
@@ -152,17 +154,17 @@ static bool increase_address_space(struct protection_domain *domain,spin_lock_irqsave (&domain->lock, flags); -if (address <=PM_LEVEL_SIZE (domain->iop.mode)) +if (address <=PM_LEVEL_SIZE (pgtable->mode)) goto out; ret = false; -if (WARN_ON_ONCE (domain->iop.mode ==PAGE_MODE_6_LEVEL )) +if (WARN_ON_ONCE (pgtable->mode ==PAGE_MODE_6_LEVEL )) goto out; - *pte =PM_LEVEL_PDE (domain->iop.mode,iommu_virt_to_phys (domain->iop.root)); + *pte =PM_LEVEL_PDE (pgtable->mode,iommu_virt_to_phys (pgtable->root)); - domain->iop.root = pte; - domain->iop.mode +=1 ; + pgtable->root = pte; + pgtable->mode +=1 ;amd_iommu_update_and_flush_device_table (domain);amd_iommu_domain_flush_complete (domain);
@@ -176,31 +178,31 @@ static bool increase_address_space(struct protection_domain *domain,return ret; } -static u64 *alloc_pte (struct protection_domain *domain, +static u64 *alloc_pte (struct amd_io_pgtable *pgtable,unsigned long address,unsigned long page_size,u64 **pte_page,gfp_t gfp,bool *updated) { -struct io_pgtable_cfg *cfg = &domain->iop.pgtbl.cfg; +struct io_pgtable_cfg *cfg = &pgtable->pgtbl.cfg;int level, end_lvl;u64 *pte, *page;BUG_ON (!is_power_of_2 (page_size)); -while (address >PM_LEVEL_SIZE (domain->iop.mode)) { +while (address >PM_LEVEL_SIZE (pgtable->mode)) {/* * Return an error if there is no memory to update the * page-table. */ -if (!increase_address_space (domain, address, gfp)) +if (!increase_address_space (pgtable, address, gfp))return NULL ; } - level = domain->iop.mode -1 ; - pte = &domain->iop.root[PM_LEVEL_INDEX (level, address)]; + level = pgtable->mode -1 ; + pte = &pgtable->root[PM_LEVEL_INDEX (level, address)]; address =PAGE_SIZE_ALIGN (address, page_size); end_lvl =PAGE_SIZE_LEVEL (page_size);
@@ -349,7 +351,7 @@ static int iommu_v1_map_pages(struct io_pgtable_ops *ops, unsigned long iova, phys_addr_t paddr, size_t pgsize, size_t pgcount, int prot, gfp_t gfp, size_t *mapped) { - struct protection_domain *dom = io_pgtable_ops_to_domain(ops); + struct amd_io_pgtable *pgtable = io_pgtable_ops_to_data(ops);LIST_HEAD (freelist);bool updated = false;u64 __pte, *pte;
@@ -366,7 +368,7 @@ static int iommu_v1_map_pages(struct io_pgtable_ops *ops, unsigned long iova,while (pgcount >0 ) { count =PAGE_SIZE_PTE_COUNT (pgsize); - pte =alloc_pte (dom, iova, pgsize,NULL , gfp, &updated); + pte =alloc_pte (pgtable, iova, pgsize,NULL , gfp, &updated); ret = -ENOMEM ;if (!pte)
@@ -403,6 +405,7 @@ static int iommu_v1_map_pages(struct io_pgtable_ops *ops, unsigned long iova, out:if (updated) { +struct protection_domain *dom =io_pgtable_ops_to_domain (ops);unsigned long flags;spin_lock_irqsave (&dom->lock, flags);
drivers/iommu/amd/io_pgtable_v2.c +7 -4
@@ -233,8 +233,8 @@ static int iommu_v2_map_pages(struct io_pgtable_ops *ops, unsigned long iova, phys_addr_t paddr, size_t pgsize, size_t pgcount, int prot, gfp_t gfp, size_t *mapped) { - struct protection_domain *pdom = io_pgtable_ops_to_domain(ops); -struct io_pgtable_cfg *cfg = &pdom->iop.pgtbl.cfg; + struct amd_io_pgtable *pgtable = io_pgtable_ops_to_data(ops); +struct io_pgtable_cfg *cfg = &pgtable->pgtbl.cfg;u64 *pte;unsigned long map_size;unsigned long mapped_size =0 ;
@@ -251,7 +251,7 @@ static int iommu_v2_map_pages(struct io_pgtable_ops *ops, unsigned long iova,while (mapped_size < size) { map_size =get_alloc_page_size (pgsize); - pte =v2_alloc_pte (cfg->amd.nid, pdom->iop.pgd, + pte =v2_alloc_pte (cfg->amd.nid, pgtable->pgd, iova, map_size, gfp, &updated);if (!pte) { ret = -EINVAL ;
@@ -266,8 +266,11 @@ static int iommu_v2_map_pages(struct io_pgtable_ops *ops, unsigned long iova, } out: -if (updated) +if (updated) { +struct protection_domain *pdom =io_pgtable_ops_to_domain (ops); +amd_iommu_domain_flush_pages (pdom, o_iova, size); + }if (mapped) *mapped += mapped_size;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 412/817 iommu/amd/pgtbl_v2: Take protection domain lock before invalidating TLB
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasant Hegde <[email protected]>
[ Upstream commit 016991606aa01c4d92e6941be636c0c897aa05c7 ]
Commit c7fc12354be0 ("iommu/amd/pgtbl_v2: Invalidate updated page ranges only") missed to take domain lock before calling amd_iommu_domain_flush_pages(). Fix this by taking protection domain lock before calling TLB invalidation function.
--- drivers/iommu/amd/io_pgtable_v2.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/iommu/amd/io_pgtable_v2.c +3 -0
@@ -268,8 +268,11 @@ static int iommu_v2_map_pages(struct io_pgtable_ops *ops, unsigned long iova, out:if (updated) {struct protection_domain *pdom =io_pgtable_ops_to_domain (ops); +unsigned long flags; +spin_lock_irqsave (&pdom->lock, flags);amd_iommu_domain_flush_pages (pdom, o_iova, size); +spin_unlock_irqrestore (&pdom->lock, flags); }if (mapped)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 413/817 RDMA/hns: Fix an AEQE overflow error caused by untimely update of eq_db_ci
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: wenglianfa <[email protected]>
[ Upstream commit 571e4ab8a45e530623ab129803f090a844dd3fe9 ]
eq_db_ci is updated only after all AEQEs are processed in the AEQ interrupt handler, which is not timely enough and may result in AEQ overflow. Two optimization methods are proposed:
1. Set an upper limit for AEQE processing.
2. Move time-consuming operations such as printings to the bottom half of the interrupt.
cmd events and flush_cqe events are still fully processed in the top half to ensure timely handling.
--- drivers/infiniband/hw/hns/hns_roce_device.h | 1 + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 75 ++++++++++++++------- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 5 ++ drivers/infiniband/hw/hns/hns_roce_qp.c | 54 +++++++++------ 4 files changed, 91 insertions(+), 44 deletions(-)
drivers/infiniband/hw/hns/hns_roce_device.h +1 -0
@@ -1289,6 +1289,7 @@ void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn);void hns_roce_cq_event (struct hns_roce_dev *hr_dev,u32 cqn,int event_type);void flush_cqe (struct hns_roce_dev *dev,struct hns_roce_qp *qp);void hns_roce_qp_event (struct hns_roce_dev *hr_dev,u32 qpn,int event_type); +void hns_roce_flush_cqe (struct hns_roce_dev *hr_dev,u32 qpn);void hns_roce_srq_event (struct hns_roce_dev *hr_dev,u32 srqn,int event_type);void hns_roce_handle_device_err (struct hns_roce_dev *hr_dev);int hns_roce_init (struct hns_roce_dev *hr_dev);
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +50 -25
138 lines not on this page · raw message
drivers/infiniband/hw/hns/hns_roce_hw_v2.h +5 -0
@@ -85,6 +85,11 @@#define HNS_ROCE_V2_TABLE_CHUNK_SIZE (1 << 18) +/* budget must be smaller than aeqe_depth to guarantee that we update +* the ci before we polled all the entries in the EQ. +*/ +#define HNS_AEQ_POLLING_BUDGET 64 +enum {HNS_ROCE_CMD_FLAG_IN =BIT (0 ),HNS_ROCE_CMD_FLAG_OUT =BIT (1 ),
drivers/infiniband/hw/hns/hns_roce_qp.c +35 -19
72 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 414/817 RDMA/hns: Fix flush cqe error when racing with destroy qp
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: wenglianfa <[email protected]>
[ Upstream commit 377a2097705b915325a67e4d44f9f2844e567809 ]
QP needs to be modified to IB_QPS_ERROR to trigger HW flush cqe. But when this process races with destroy qp, the destroy-qp process may modify the QP to IB_QPS_RESET first. In this case flush cqe will fail since it is invalid to modify qp from IB_QPS_RESET to IB_QPS_ERROR.
Add lock and bit flag to make sure pending flush cqe work is completed first and no more new works will be added.
--- drivers/infiniband/hw/hns/hns_roce_device.h | 2 ++ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 7 +++++++ drivers/infiniband/hw/hns/hns_roce_qp.c | 15 +++++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-)
drivers/infiniband/hw/hns/hns_roce_device.h +2 -0
@@ -593,6 +593,7 @@ struct hns_roce_dev;enum {HNS_ROCE_FLUSH_FLAG =0 , +HNS_ROCE_STOP_FLUSH_FLAG =1 , };struct hns_roce_work {
@@ -656,6 +657,7 @@ struct hns_roce_qp {enum hns_roce_cong_type cong_type;u8 tc_mode;u8 priority; +spinlock_t flush_lock; };struct hns_roce_ib_iboe {
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +7 -0
@@ -5598,8 +5598,15 @@ int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) {struct hns_roce_dev *hr_dev =to_hr_dev (ibqp->device);struct hns_roce_qp *hr_qp =to_hr_qp (ibqp); +unsigned long flags;int ret; +/* Make sure flush_cqe() is completed */ +spin_lock_irqsave (&hr_qp->flush_lock, flags); +set_bit (HNS_ROCE_STOP_FLUSH_FLAG , &hr_qp->flush_flag); +spin_unlock_irqrestore (&hr_qp->flush_lock, flags); +flush_work (&hr_qp->flush_work.work); + ret =hns_roce_v2_destroy_qp_common (hr_dev, hr_qp, udata);if (ret) ibdev_err(&hr_dev->ib_dev,
drivers/infiniband/hw/hns/hns_roce_qp.c +13 -2
@@ -90,11 +90,18 @@ static void flush_work_handle(struct work_struct *work)void init_flush_work (struct hns_roce_dev *hr_dev,struct hns_roce_qp *hr_qp) {struct hns_roce_work *flush_work = &hr_qp->flush_work; +unsigned long flags; + +spin_lock_irqsave (&hr_qp->flush_lock, flags); +/* Exit directly after destroy_qp() */ +if (test_bit (HNS_ROCE_STOP_FLUSH_FLAG , &hr_qp->flush_flag)) { +spin_unlock_irqrestore (&hr_qp->flush_lock, flags); +return ; + } - flush_work->hr_dev = hr_dev; -INIT_WORK (&flush_work->work, flush_work_handle);refcount_inc (&hr_qp->refcount);queue_work (hr_dev->irq_workq, &flush_work->work); +spin_unlock_irqrestore (&hr_qp->flush_lock, flags); }void flush_cqe (struct hns_roce_dev *dev,struct hns_roce_qp *qp)
@@ -1140,6 +1147,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,struct ib_udata *udata, struct hns_roce_qp *hr_qp) { + struct hns_roce_work *flush_work = &hr_qp->flush_work;struct hns_roce_ib_create_qp_resp resp = {};struct ib_device *ibdev = &hr_dev->ib_dev;struct hns_roce_ib_create_qp ucmd = {};
@@ -1148,9 +1156,12 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,mutex_init (&hr_qp->mutex);spin_lock_init (&hr_qp->sq.lock);spin_lock_init (&hr_qp->rq.lock); +spin_lock_init (&hr_qp->flush_lock); hr_qp->state =IB_QPS_RESET ; hr_qp->flush_flag =0 ; + flush_work->hr_dev = hr_dev; +INIT_WORK (&flush_work->work, flush_work_handle);if (init_attr->create_flags)return -EOPNOTSUPP ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 415/817 RDMA/hns: Modify debugfs name
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuyu Li <[email protected]>
[ Upstream commit 370a9351bf84afc5a56a3f02ba3805bbfcb53c32 ]
The sub-directory of hns_roce debugfs is named after the device's kernel name currently, but it will be inconvenient to use when the device is renamed.
Modify the name to pci name as users can always easily find the correspondence between an RDMA device and its pci name.
--- drivers/infiniband/hw/hns/hns_roce_debugfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_debugfs.c +2 -1
@@ -5,6 +5,7 @@#include <linux/debugfs.h> #include <linux/device.h> +#include <linux/pci.h> #include "hns_roce_device.h"
@@ -86,7 +87,7 @@ void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev) {struct hns_roce_dev_debugfs *dbgfs = &hr_dev->dbgfs; - dbgfs->root =debugfs_create_dir (dev_name (&hr_dev->ib_dev.dev), + dbgfs->root =debugfs_create_dir (pci_name (hr_dev->pci_dev), hns_roce_dbgfs_root);create_sw_stat_debugfs (hr_dev, dbgfs->root);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 416/817 RDMA/hns: Use dev_* printings in hem code instead of ibdev_*
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit d81fb6511abf18591befaa5f4a972ffc838690ec ]
The hem code is executed before ib_dev is registered, so use dev_* printing instead of ibdev_* to avoid log like this:
(null): set HEM address to HW failed!
--- drivers/infiniband/hw/hns/hns_roce_hem.c | 44 ++++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-)
drivers/infiniband/hw/hns/hns_roce_hem.c +22 -22
@@ -300,7 +300,7 @@ static int calc_hem_config(struct hns_roce_dev *hr_dev,struct hns_roce_hem_mhop *mhop, struct hns_roce_hem_index *index) { - struct ib_device *ibdev = &hr_dev->ib_dev; + struct device *dev = hr_dev->dev;unsigned long mhop_obj = obj;u32 l0_idx, l1_idx, l2_idx;u32 chunk_ba_num;
@@ -331,14 +331,14 @@ static int calc_hem_config(struct hns_roce_dev *hr_dev, index->buf = l0_idx;break ;default : -ibdev_err (ibdev,"table %u not support mhop.hop_num = %u!\n" , - table->type, mhop->hop_num); +dev_err (dev,"table %u not support mhop.hop_num = %u!\n" , + table->type, mhop->hop_num);return -EINVAL ; }if (unlikely (index->buf >= table->num_hem)) { -ibdev_err (ibdev,"table %u exceed hem limt idx %llu, max %lu!\n" , - table->type, index->buf, table->num_hem); +dev_err (dev,"table %u exceed hem limt idx %llu, max %lu!\n" , + table->type, index->buf, table->num_hem);return -EINVAL ; }
@@ -448,14 +448,14 @@ static int set_mhop_hem(struct hns_roce_dev *hr_dev,struct hns_roce_hem_mhop *mhop, struct hns_roce_hem_index *index) { - struct ib_device *ibdev = &hr_dev->ib_dev; + struct device *dev = hr_dev->dev;u32 step_idx;int ret =0 ;if (index->inited &HEM_INDEX_L0 ) { ret = hr_dev->hw->set_hem (hr_dev, table, obj,0 );if (ret) { -ibdev_err (ibdev,"set HEM step 0 failed!\n" ); +dev_err (dev,"set HEM step 0 failed!\n" ); goto out; } }
@@ -463,7 +463,7 @@ static int set_mhop_hem(struct hns_roce_dev *hr_dev,if (index->inited &HEM_INDEX_L1 ) { ret = hr_dev->hw->set_hem (hr_dev, table, obj,1 );if (ret) { -ibdev_err (ibdev,"set HEM step 1 failed!\n" ); +dev_err (dev,"set HEM step 1 failed!\n" ); goto out; } }
@@ -475,7 +475,7 @@ static int set_mhop_hem(struct hns_roce_dev *hr_dev, step_idx = mhop->hop_num; ret = hr_dev->hw->set_hem (hr_dev, table, obj, step_idx);if (ret) -ibdev_err (ibdev,"set HEM step last failed!\n" ); +dev_err (dev,"set HEM step last failed!\n" ); } out:return ret;
@@ -485,14 +485,14 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev, struct hns_roce_hem_table *table, unsigned long obj) { -struct ib_device *ibdev = &hr_dev->ib_dev;struct hns_roce_hem_index index = {};struct hns_roce_hem_mhop mhop = {}; +struct device *dev = hr_dev->dev;int ret; ret =calc_hem_config (hr_dev, table, obj, &mhop, &index);if (ret) { -ibdev_err (ibdev,"calc hem config failed!\n" ); +dev_err (dev,"calc hem config failed!\n" );return ret; }
@@ -504,7 +504,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev, ret =alloc_mhop_hem (hr_dev, table, &mhop, &index);if (ret) { -ibdev_err (ibdev,"alloc mhop hem failed!\n" ); +dev_err (dev,"alloc mhop hem failed!\n" ); goto out; }
@@ -512,7 +512,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,if (table->type <HEM_TYPE_MTT ) { ret =set_mhop_hem (hr_dev, table, obj, &mhop, &index);if (ret) { -ibdev_err (ibdev,"set HEM address to HW failed!\n" ); +dev_err (dev,"set HEM address to HW failed!\n" ); goto err_alloc; } }
@@ -575,7 +575,7 @@ static void clear_mhop_hem(struct hns_roce_dev *hr_dev,struct hns_roce_hem_mhop *mhop, struct hns_roce_hem_index *index) { - struct ib_device *ibdev = &hr_dev->ib_dev; + struct device *dev = hr_dev->dev;u32 hop_num = mhop->hop_num;u32 chunk_ba_num;u32 step_idx;
@@ -605,21 +605,21 @@ static void clear_mhop_hem(struct hns_roce_dev *hr_dev, ret = hr_dev->hw->clear_hem (hr_dev, table, obj, step_idx);if (ret) -ibdev_warn (ibdev,"failed to clear hop%u HEM, ret = %d.\n" , - hop_num, ret); +dev_warn (dev,"failed to clear hop%u HEM, ret = %d.\n" , + hop_num, ret);if (index->inited &HEM_INDEX_L1 ) { ret = hr_dev->hw->clear_hem (hr_dev, table, obj,1 );if (ret) -ibdev_warn (ibdev,"failed to clear HEM step 1, ret = %d.\n" , - ret); +dev_warn (dev,"failed to clear HEM step 1, ret = %d.\n" , + ret); }if (index->inited &HEM_INDEX_L0 ) { ret = hr_dev->hw->clear_hem (hr_dev, table, obj,0 );if (ret) -ibdev_warn (ibdev,"failed to clear HEM step 0, ret = %d.\n" , - ret); +dev_warn (dev,"failed to clear HEM step 0, ret = %d.\n" , + ret); } } }
@@ -629,14 +629,14 @@ static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev, unsigned long obj, int check_refcount) { -struct ib_device *ibdev = &hr_dev->ib_dev;struct hns_roce_hem_index index = {};struct hns_roce_hem_mhop mhop = {}; +struct device *dev = hr_dev->dev;int ret; ret =calc_hem_config (hr_dev, table, obj, &mhop, &index);if (ret) { -ibdev_err (ibdev,"calc hem config failed!\n" ); +dev_err (dev,"calc hem config failed!\n" );return ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 417/817 RDMA/hns: Fix cpu stuck caused by printings during reset
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: wenglianfa <[email protected]>
[ Upstream commit 323275ac2ff15b2b7b3eac391ae5d8c5a3c3a999 ]
During reset, cmd to destroy resources such as qp, cq, and mr may fail, and error logs will be printed. When a large number of resources are destroyed, there will be lots of printings, and it may lead to a cpu stuck.
Delete some unnecessary printings and replace other printing functions in these paths with the ratelimited version.
--- drivers/infiniband/hw/hns/hns_roce_cq.c | 4 +- drivers/infiniband/hw/hns/hns_roce_hem.c | 4 +- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 73 ++++++++++------------ drivers/infiniband/hw/hns/hns_roce_mr.c | 4 +- drivers/infiniband/hw/hns/hns_roce_srq.c | 4 +- 5 files changed, 41 insertions(+), 48 deletions(-)
drivers/infiniband/hw/hns/hns_roce_cq.c +2 -2
@@ -179,8 +179,8 @@ static void free_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) ret =hns_roce_destroy_hw_ctx (hr_dev,HNS_ROCE_CMD_DESTROY_CQC , hr_cq->cqn);if (ret) -dev_err (dev,"DESTROY_CQ failed (%d) for CQN %06lx\n" , ret, - hr_cq->cqn); +dev_err_ratelimited (dev,"DESTROY_CQ failed (%d) for CQN %06lx\n" , + ret, hr_cq->cqn);xa_erase_irq (&cq_table->array, hr_cq->cqn);
drivers/infiniband/hw/hns/hns_roce_hem.c +2 -2
@@ -672,8 +672,8 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev, ret = hr_dev->hw->clear_hem (hr_dev, table, obj,HEM_HOP_STEP_DIRECT );if (ret) -dev_warn (dev,"failed to clear HEM base address, ret = %d.\n" , - ret); +dev_warn_ratelimited (dev,"failed to clear HEM base address, ret = %d.\n" , + ret);hns_roce_free_hem (hr_dev, table->hem[i]); table->hem[i] =NULL ;
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +33 -40
160 lines not on this page · raw message
drivers/infiniband/hw/hns/hns_roce_mr.c +2 -2
@@ -138,8 +138,8 @@ static void hns_roce_mr_free(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mrkey_to_hw_index (mr->key) & (hr_dev->caps.num_mtpts - 1));if (ret) -ibdev_warn (ibdev,"failed to destroy mpt, ret = %d.\n" , - ret); +ibdev_warn_ratelimited (ibdev,"failed to destroy mpt, ret = %d.\n" , + ret); }free_mr_pbl (hr_dev, mr);
drivers/infiniband/hw/hns/hns_roce_srq.c +2 -2
@@ -151,8 +151,8 @@ static void free_srqc(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq) ret =hns_roce_destroy_hw_ctx (hr_dev,HNS_ROCE_CMD_DESTROY_SRQ , srq->srqn);if (ret) -dev_err (hr_dev->dev,"DESTROY_SRQ failed (%d) for SRQN %06lx\n" , - ret, srq->srqn); +dev_err_ratelimited (hr_dev->dev,"DESTROY_SRQ failed (%d) for SRQN %06lx\n" , + ret, srq->srqn);xa_erase_irq (&srq_table->xa, srq->srqn);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 418/817 RDMA/rxe: Fix the qp flush warnings in req
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Yanjun <[email protected]>
[ Upstream commit ea4c990fa9e19ffef0648e40c566b94ba5ab31be ]
When the qp is in error state, the status of WQEs in the queue should be set to error. Or else the following will appear.
[ 920.617269] WARNING: CPU: 1 PID: 21 at drivers/infiniband/sw/rxe/rxe_comp.c:756 rxe_completer+0x989/0xcc0 [rdma_rxe] [ 920.617744] Modules linked in: rnbd_client(O) rtrs_client(O) rtrs_core(O) rdma_ucm rdma_cm iw_cm ib_cm crc32_generic rdma_rxe ip6_udp_tunnel udp_tunnel ib_uverbs ib_core loop brd null_blk ipv6 [ 920.618516] CPU: 1 PID: 21 Comm: ksoftirqd/1 Tainted: G O 6.1.113-storage+ #65 [ 920.618986] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 [ 920.619396] RIP: 0010:rxe_completer+0x989/0xcc0 [rdma_rxe] [ 920.619658] Code: 0f b6 84 24 3a 02 00 00 41 89 84 24 44 04 00 00 e9 2a f7 ff ff 39 ca bb 03 00 00 00 b8 0e 00 00 00 48 0f 45 d8 e9 15 f7 ff ff <0f> 0b e9 cb f8 ff ff 41 bf f5 ff ff ff e9 08 f8 ff ff 49 8d bc 24 [ 920.620482] RSP: 0018:ffff97b7c00bbc38 EFLAGS: 00010246 [ 920.620817] RAX: 0000000000000000 RBX: 000000000000000c RCX: 0000000000000008 [ 920.621183] RDX: ffff960dc396ebc0 RSI: 0000000000005400 RDI: ffff960dc4e2fbac [ 920.621548] RBP: 0000000000000000 R08: 0000000000000001 R09: ffffffffac406450 [ 920.621884] R10: ffffffffac4060c0 R11: 0000000000000001 R12: ffff960dc4e2f800 [ 920.622254] R13: ffff960dc4e2f928 R14: ffff97b7c029c580 R15: 0000000000000000 [ 920.622609] FS: 0000000000000000(0000) GS:ffff960ef7d00000(0000) knlGS:0000000000000000 [ 920.622979] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 920.623245] CR2: 00007fa056965e90 CR3: 00000001107f1000 CR4: 00000000000006e0 [ 920.623680] Call Trace: [ 920.623815] <TASK> [ 920.623933] ? __warn+0x79/0xc0 [ 920.624116] ? rxe_completer+0x989/0xcc0 [rdma_rxe] [ 920.624356] ? report_bug+0xfb/0x150 [ 920.624594] ? handle_bug+0x3c/0x60 [ 920.624796] ? exc_invalid_op+0x14/0x70 [ 920.624976] ? asm_exc_invalid_op+0x16/0x20 [ 920.625203] ? rxe_completer+0x989/0xcc0 [rdma_rxe] [ 920.625474] ? rxe_completer+0x329/0xcc0 [rdma_rxe] [ 920.625749] rxe_do_task+0x80/0x110 [rdma_rxe] [ 920.626037] rxe_requester+0x625/0xde0 [rdma_rxe] [ 920.626310] ? rxe_cq_post+0xe2/0x180 [rdma_rxe] [ 920.626583] ? do_complete+0x18d/0x220 [rdma_rxe] [ 920.626812] ? rxe_completer+0x1a3/0xcc0 [rdma_rxe] [ 920.627050] rxe_do_task+0x80/0x110 [rdma_rxe] [ 920.627285] tasklet_action_common.constprop.0+0xa4/0x120 [ 920.627522] handle_softirqs+0xc2/0x250 [ 920.627728] ? sort_range+0x20/0x20 [ 920.627942] run_ksoftirqd+0x1f/0x30 [ 920.628158] smpboot_thread_fn+0xc7/0x1b0 [ 920.628334] kthread+0xd6/0x100 [ 920.628504] ? kthread_complete_and_exit+0x20/0x20 [ 920.628709] ret_from_fork+0x1f/0x30 [ 920.628892] </TASK>
--- drivers/infiniband/sw/rxe/rxe_req.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/infiniband/sw/rxe/rxe_req.c +4 -2
@@ -663,10 +663,12 @@ int rxe_requester(struct rxe_qp *qp)if (unlikely (qp_state (qp) ==IB_QPS_ERR )) { wqe =__req_next_wqe (qp);spin_unlock_irqrestore (&qp->state_lock, flags); -if (wqe) +if (wqe) { + wqe->status =IB_WC_WR_FLUSH_ERR ; goto err; -else + }else { goto exit; + } }if (unlikely (qp_state (qp) ==IB_QPS_RESET )) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 419/817 RDMA/bnxt_re: Check cqe flags to know imm_data vs inv_irkey
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kashyap Desai <[email protected]>
[ Upstream commit 808ca6de989c598bc5af1ae0ad971a66077efac0 ]
Invalidate rkey is cpu endian and immediate data is in big endian format. Both immediate data and invalidate the remote key returned by HW is in little endian format.
While handling the commit in fixes tag, the difference between immediate data and invalidate rkey endianness was not considered.
Without changes of this patch, Kernel ULP was failing while processing inv_rkey.
dmesg log snippet -
nvme nvme0: Bogus remote invalidation for rkey 0x2000019Fix in this patch
Do endianness conversion based on completion queue entry flag. Also, the HW completions are already converted to host endianness in bnxt_qplib_cq_process_res_rc and bnxt_qplib_cq_process_res_ud and there is no need to convert it again in bnxt_re_poll_cq. Modified the union to hold the correct data type.
--- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 7 +++++-- drivers/infiniband/hw/bnxt_re/qplib_fp.h | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-)
drivers/infiniband/hw/bnxt_re/ib_verbs.c +5 -2
@@ -3584,7 +3584,7 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp, wc->byte_len = orig_cqe->length; wc->qp = &gsi_qp->ib_qp; - wc->ex.imm_data =cpu_to_be32 (le32_to_cpu (orig_cqe->immdata)); + wc->ex.imm_data =cpu_to_be32 (orig_cqe->immdata); wc->src_qp = orig_cqe->src_qp;memcpy (wc->smac, orig_cqe->smac,ETH_ALEN );if (bnxt_re_is_vlan_pkt (orig_cqe, &vlan_id, &sl)) {
@@ -3729,7 +3729,10 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc) (unsigned long )(cqe->qp_handle), struct bnxt_re_qp, qplib_qp); wc->qp = &qp->ib_qp; - wc->ex.imm_data =cpu_to_be32 (le32_to_cpu (cqe->immdata)); +if (cqe->flags &CQ_RES_RC_FLAGS_IMM ) + wc->ex.imm_data =cpu_to_be32 (cqe->immdata); +else + wc->ex.invalidate_rkey = cqe->invrkey; wc->src_qp = cqe->src_qp;memcpy (wc->smac, cqe->smac,ETH_ALEN ); wc->port_num =1 ;
drivers/infiniband/hw/bnxt_re/qplib_fp.h +1 -1
@@ -390,7 +390,7 @@ struct bnxt_qplib_cqe {u16 cfa_meta;u64 wr_id;union { -__le32 immdata; +u32 immdata;u32 invrkey; };u64 qp_handle;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 420/817 clk: sunxi-ng: d1: Fix PLL_AUDIO0 preset
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andre Przywara <[email protected]>
[ Upstream commit e0f253a52ccee3cf3eb987e99756e20c68a1aac9 ]
To work around a limitation in our clock modelling, we try to force two bits in the AUDIO0 PLL to 0, in the CCU probe routine. However the ~ operator only applies to the first expression, and does not cover the second bit, so we end up clearing only bit 1.
Group the bit-ORing with parentheses, to make it both clearer to read and actually correct.
--- drivers/clk/sunxi-ng/ccu-sun20i-d1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/sunxi-ng/ccu-sun20i-d1.c +1 -1
@@ -1371,7 +1371,7 @@ static int sun20i_d1_ccu_probe(struct platform_device *pdev)/* Enforce m1 = 0, m0 = 0 for PLL_AUDIO0 */ val =readl (reg +SUN20I_D1_PLL_AUDIO0_REG ); - val &= ~BIT (1 ) |BIT (0 ); + val &= ~(BIT (1 ) |BIT (0 ));writel (val, reg +SUN20I_D1_PLL_AUDIO0_REG );/* Force fanout-27M factor N to 0. */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 421/817 clk: renesas: rzg2l: Fix FOUTPOSTDIV clk
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Biju Das <[email protected]>
[ Upstream commit dabf72b85f298970e86891b5218459c17b57b26a ]
While computing foutpostdiv_rate, the value of params->pl5_fracin is discarded, which results in the wrong refresh rate. Fix the formula for computing foutpostdiv_rate.
--- drivers/clk/renesas/rzg2l-cpg.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/clk/renesas/rzg2l-cpg.c +6 -5
@@ -552,7 +552,7 @@ static unsigned long rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params, unsigned long rate) { -unsigned long foutpostdiv_rate; +unsigned long foutpostdiv_rate, foutvco_rate; params->pl5_intin = rate /MEGA ; params->pl5_fracin =div_u64 (((u64 )rate %MEGA ) <<24 ,MEGA );
@@ -561,10 +561,11 @@ rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params, params->pl5_postdiv2 =1 ; params->pl5_spread =0x16 ; - foutpostdiv_rate = -EXTAL_FREQ_IN_MEGA_HZ *MEGA / params->pl5_refdiv * - ((((params->pl5_intin <<24 ) + params->pl5_fracin)) >>24 ) / - (params->pl5_postdiv1 * params->pl5_postdiv2); + foutvco_rate =div_u64 (mul_u32_u32 (EXTAL_FREQ_IN_MEGA_HZ *MEGA , + (params->pl5_intin <<24 ) + params->pl5_fracin), + params->pl5_refdiv) >>24 ; + foutpostdiv_rate =DIV_ROUND_CLOSEST_ULL (foutvco_rate, + params->pl5_postdiv1 * params->pl5_postdiv2);return foutpostdiv_rate; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 422/817 RDMA/rxe: Set queue pair cur_qp_state when being queried
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Jian <[email protected]>
[ Upstream commit 775e6d3c8fda41083b16c26d05163fd69f029a62 ]
Same with commit e375b9c92985 ("RDMA/cxgb4: Set queue pair state when
being queried"). The API for ib_query_qp requires the driver to setcur_qp_state on return, add the missing set.
--- drivers/infiniband/sw/rxe/rxe_qp.c | 1 + 1 file changed, 1 insertion(+)
drivers/infiniband/sw/rxe/rxe_qp.c +1 -0
@@ -775,6 +775,7 @@ int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask)* Yield the processor */ spin_lock_irqsave (&qp->state_lock, flags); + attr->cur_qp_state =qp_state (qp);if (qp->attr.sq_draining) {spin_unlock_irqrestore (&qp->state_lock, flags);cond_resched ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 423/817 RISC-V: KVM: Fix APLIC in_clrip and clripnum write emulation
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yong-Xuan Wang <[email protected]>
[ Upstream commit 60821fb4dd7345e5662094accf0a52845306de8c ]
In the section "4.7 Precise effects on interrupt-pending bits" of the RISC-V AIA specification defines that:
"If the source mode is Level1 or Level0 and the interrupt domain is configured in MSI delivery mode (domaincfg.DM = 1):
The pending bit is cleared whenever the rectified input value is low, when the interrupt is forwarded by MSI, or by a relevant write to an in_clrip register or to clripnum."
Update the aplic_write_pending() to match the spec.
--- arch/riscv/kvm/aia_aplic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/riscv/kvm/aia_aplic.c +2 -1
@@ -143,7 +143,7 @@ static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending)if (sm ==APLIC_SOURCECFG_SM_LEVEL_HIGH || sm ==APLIC_SOURCECFG_SM_LEVEL_LOW ) {if (!pending) - goto skip_write_pending; + goto noskip_write_pending;if ((irqd->state &APLIC_IRQ_STATE_INPUT ) && sm ==APLIC_SOURCECFG_SM_LEVEL_LOW ) goto skip_write_pending;
@@ -152,6 +152,7 @@ static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending) goto skip_write_pending; } +noskip_write_pending:if (pending) irqd->state |=APLIC_IRQ_STATE_PENDING ;else
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 424/817 riscv: kvm: Fix out-of-bounds array access
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Björn Töpel <[email protected]>
[ Upstream commit 332fa4a802b16ccb727199da685294f85f9880cb ]
In kvm_riscv_vcpu_sbi_init() the entry->ext_idx can contain an out-of-bound index. This is used as a special marker for the base extensions, that cannot be disabled. However, when traversing the extensions, that special marker is not checked prior indexing the array.
Add an out-of-bounds check to the function.
--- arch/riscv/kvm/vcpu_sbi.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
arch/riscv/kvm/vcpu_sbi.c +7 -4
@@ -486,19 +486,22 @@ void kvm_riscv_vcpu_sbi_init(struct kvm_vcpu *vcpu)struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context;const struct kvm_riscv_sbi_extension_entry *entry;const struct kvm_vcpu_sbi_extension *ext; -int i; +int idx, i;for (i =0 ; i <ARRAY_SIZE (sbi_ext); i++) { entry = &sbi_ext[i]; ext = entry->ext_ptr; + idx = entry->ext_idx; + +if (idx <0 || idx >=ARRAY_SIZE (scontext->ext_status)) +continue ;if (ext->probe && !ext->probe (vcpu)) { - scontext->ext_status[entry->ext_idx] = -KVM_RISCV_SBI_EXT_STATUS_UNAVAILABLE ; + scontext->ext_status[idx] =KVM_RISCV_SBI_EXT_STATUS_UNAVAILABLE ;continue ; } - scontext->ext_status[entry->ext_idx] = ext->default_disabled ? + scontext->ext_status[idx] = ext->default_disabled ?KVM_RISCV_SBI_EXT_STATUS_DISABLED :KVM_RISCV_SBI_EXT_STATUS_ENABLED ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 425/817 clk: imx: lpcg-scu: SW workaround for errata (e10858)
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit 5ee063fac85656bea9cfe3570af147ba1701ba18 ]
Back-to-back LPCG writes can be ignored by the LPCG register due to a HW bug. The writes need to be separated by at least 4 cycles of the gated clock. See https://www.nxp.com.cn/docs/en/errata/IMX8_1N94W.pdf
The workaround is implemented as follows:
1. For clocks running greater than or equal to 24MHz, a read followed by the write will provide sufficient delay.
2. For clocks running below 24MHz, add a delay of 4 clock cylces after the write to the LPCG register.
--- drivers/clk/imx/clk-lpcg-scu.c | 37 ++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-)
drivers/clk/imx/clk-lpcg-scu.c +29 -8
@@ -6,10 +6,12 @@#include <linux/bits.h> #include <linux/clk-provider.h> +#include <linux/delay.h> #include <linux/err.h> #include <linux/io.h> #include <linux/slab.h> #include <linux/spinlock.h> +#include <linux/units.h> #include "clk-scu.h"
@@ -41,6 +43,29 @@ struct clk_lpcg_scu {#define to_clk_lpcg_scu (_hw) container_of(_hw, struct clk_lpcg_scu, hw) +/* e10858 -LPCG clock gating register synchronization errata */ +static void lpcg_e10858_writel (unsigned long rate,void __iomem *reg,u32 val) +{ +writel (val, reg); + +if (rate >=24 *HZ_PER_MHZ || rate ==0 ) { +/* +* The time taken to access the LPCG registers from the AP core +* through the interconnect is longer than the minimum delay +* of 4 clock cycles required by the errata. +* Adding a readl will provide sufficient delay to prevent +* back-to-back writes. +*/ +readl (reg); + }else { +/* +* For clocks running below 24MHz, wait a minimum of +* 4 clock cycles. +*/ +ndelay (4 * (DIV_ROUND_UP (1000 *HZ_PER_MHZ , rate))); + } +} +static int clk_lpcg_scu_enable (struct clk_hw *hw) {struct clk_lpcg_scu *clk =to_clk_lpcg_scu (hw);
@@ -57,7 +82,8 @@ static int clk_lpcg_scu_enable(struct clk_hw *hw) val |=CLK_GATE_SCU_LPCG_HW_SEL ; reg |= val << clk->bit_idx; -writel (reg, clk->reg); + +lpcg_e10858_writel (clk_hw_get_rate (hw), clk->reg, reg);spin_unlock_irqrestore (&imx_lpcg_scu_lock, flags);
@@ -74,7 +100,7 @@ static void clk_lpcg_scu_disable(struct clk_hw *hw) reg =readl_relaxed (clk->reg); reg &= ~(CLK_GATE_SCU_LPCG_MASK << clk->bit_idx); -writel (reg, clk->reg); +lpcg_e10858_writel (clk_hw_get_rate (hw), clk->reg, reg);spin_unlock_irqrestore (&imx_lpcg_scu_lock, flags); }
@@ -145,13 +171,8 @@ static int __maybe_unused imx_clk_lpcg_scu_resume(struct device *dev) {struct clk_lpcg_scu *clk =dev_get_drvdata (dev); -/* -* FIXME: Sometimes writes don't work unless the CPU issues -* them twice -*/ - -writel (clk->state, clk->reg);writel (clk->state, clk->reg); +lpcg_e10858_writel (0 , clk->reg, clk->state);dev_dbg (dev,"restore lpcg state 0x%x\n" , clk->state);return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 426/817 clk: imx: fracn-gppll: correct PLL initialization flow
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit 557be501c38e1864b948fc6ccdf4b035d610a2ea ]
Per i.MX93 Reference Mannual 22.4 Initialization information
1. Program appropriate value of DIV[ODIV], DIV[RDIV] and DIV[MFI] as per Integer mode.
2. Wait for 5 μs.
3. Program the following field in CTRL register.
Set CTRL[POWERUP] to 1'b1 to enable PLL block.
4. Poll PLL_STATUS[PLL_LOCK] register, and wait till PLL_STATUS[PLL_LOCK] is 1'b1 and pll_lock output signal is 1'b1.
5. Set CTRL[CLKMUX_EN] to 1'b1 to enable PLL output clock.
So move the CLKMUX_EN operation after PLL locked.
--- drivers/clk/imx/clk-fracn-gppll.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/imx/clk-fracn-gppll.c +3 -3
@@ -301,13 +301,13 @@ static int clk_fracn_gppll_prepare(struct clk_hw *hw) val |=POWERUP_MASK ;writel_relaxed (val, pll->base +PLL_CTRL ); - val |=CLKMUX_EN ; -writel_relaxed (val, pll->base +PLL_CTRL ); - ret =clk_fracn_gppll_wait_lock (pll);if (ret)return ret; + val |=CLKMUX_EN ; +writel_relaxed (val, pll->base +PLL_CTRL ); + val &= ~CLKMUX_BYPASS ;writel_relaxed (val, pll->base +PLL_CTRL );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 427/817 clk: imx: fracn-gppll: fix pll power up
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit ff4279618f0aec350b0fb41b2b35841324fbd96e ]
To i.MX93 which features dual Cortex-A55 cores and DSU, when using writel_relaxed to write value to PLL registers, the value might be buffered. To make sure the value has been written into the hardware, using readl to read back the register could achieve the goal.
current PLL power up flow can be simplified as below:
1. writel_relaxed to set the PLL POWERUP bit;
2. readl_poll_timeout to check the PLL lock bit:
a). timeout = ktime_add_us(ktime_get(), timeout_us); b). readl the pll the lock reg;
c). check if the pll lock bit ready
d). check if timeout
But in some corner cases, both the write in step 1 and read in step 2 will be blocked by other bus transaction in the SoC for a long time, saying the value into real hardware is just before step b). That means the timeout counting has begins for quite sometime since step a), but value still not written into real hardware until bus released just at a point before step b).
Then there maybe chances that the pll lock bit is not ready when readl done but the timeout happens. readl_poll_timeout will err return due to timeout. To avoid such unexpected failure, read back the reg to make sure the write has been done in HW reg.
So use readl after writel_relaxed to fix the issue.
Since we are here, to avoid udelay to run before writel_relaxed, use readl before udelay.
--- drivers/clk/imx/clk-fracn-gppll.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/clk/imx/clk-fracn-gppll.c +4 -0
@@ -252,9 +252,11 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate, pll_div =FIELD_PREP (PLL_RDIV_MASK , rate->rdiv) | rate->odiv |FIELD_PREP (PLL_MFI_MASK , rate->mfi);writel_relaxed (pll_div, pll->base +PLL_DIV ); +readl (pll->base +PLL_DIV );if (pll->flags &CLK_FRACN_GPPLL_FRACN ) {writel_relaxed (rate->mfd, pll->base +PLL_DENOMINATOR );writel_relaxed (FIELD_PREP (PLL_MFN_MASK , rate->mfn), pll->base +PLL_NUMERATOR ); +readl (pll->base +PLL_NUMERATOR ); }/* Wait for 5us according to fracn mode pll doc */
@@ -263,6 +265,7 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,/* Enable Powerup */ tmp |=POWERUP_MASK ;writel_relaxed (tmp, pll->base +PLL_CTRL ); +readl (pll->base +PLL_CTRL );/* Wait Lock */ ret =clk_fracn_gppll_wait_lock (pll);
@@ -300,6 +303,7 @@ static int clk_fracn_gppll_prepare(struct clk_hw *hw) val |=POWERUP_MASK ;writel_relaxed (val, pll->base +PLL_CTRL ); +readl (pll->base +PLL_CTRL ); ret =clk_fracn_gppll_wait_lock (pll);if (ret)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 428/817 clk: imx: clk-scu: fix clk enable state save and restore
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dong Aisheng <[email protected]>
[ Upstream commit e81361f6cf9bf4a1848b0813bc4becb2250870b8 ]
The scu clk_ops only inplements prepare() and unprepare() callback. Saving the clock state during suspend by checking clk_hw_is_enabled() is not safe as it's possible that some device drivers may only disable the clocks without unprepare. Then the state retention will not work for such clocks.
Fixing it by checking clk_hw_is_prepared() which is more reasonable and safe.
--- drivers/clk/imx/clk-scu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/imx/clk-scu.c +1 -1
@@ -596,7 +596,7 @@ static int __maybe_unused imx_clk_scu_suspend(struct device *dev) clk->rate =clk_scu_recalc_rate (&clk->hw,0 ); else clk->rate = clk_hw_get_rate(&clk->hw); - clk->is_enabled =clk_hw_is_enabled (&clk->hw); + clk->is_enabled =clk_hw_is_prepared (&clk->hw);if (clk->parent) dev_dbg(dev, "save parent %s idx %u\n", clk_hw_get_name(clk->parent),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 429/817 clk: imx: imx8-acm: Fix return value check in clk_imx_acm_attach_pm_domains()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yingliang <[email protected]>
[ Upstream commit 81a206d736c19139d3863b79e7174f9e98b45499 ]
If device_link_add() fails, it returns NULL pointer not ERR_PTR(), replace IS_ERR() with NULL pointer check, and return -EINVAL.
--- drivers/clk/imx/clk-imx8-acm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/imx/clk-imx8-acm.c +2 -2
@@ -289,9 +289,9 @@ static int clk_imx_acm_attach_pm_domains(struct device *dev,DL_FLAG_STATELESS |DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); -if (IS_ERR (dev_pm->pd_dev_link[i])) { +if (!dev_pm->pd_dev_link[i]) {dev_pm_domain_detach (dev_pm->pd_dev[i], false); - ret =PTR_ERR (dev_pm->pd_dev_link[i]); + ret = -EINVAL ; goto detach_pm; } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 430/817 iommu/vt-d: Fix checks and print in dmar_fault_dump_ptes()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhenzhong Duan <[email protected]>
[ Upstream commit 6ceb93f952f6ca34823ce3650c902c31b8385b40 ]
There are some issues in dmar_fault_dump_ptes():
1. return value of phys_to_virt() is used for checking if an entry is present.
2. dump is confusing, e.g., "pasid table entry is not present", confusing by unpresent pasid table vs. unpresent pasid table entry. Current code means the former.
3. pgtable_walk() is called without checking if page table is present.
Fix 1 by checking present bit of an entry before dump a lower level entry. Fix 2 by removing "entry" string, e.g., "pasid table is not present". Fix 3 by checking page table present before walk.
Take issue 3 for example, before fix:
[ 442.240357] DMAR: pasid dir entry: 0x000000012c83e001 [ 442.246661] DMAR: pasid table entry[0]: 0x0000000000000000 [ 442.253429] DMAR: pasid table entry[1]: 0x0000000000000000 [ 442.260203] DMAR: pasid table entry[2]: 0x0000000000000000 [ 442.266969] DMAR: pasid table entry[3]: 0x0000000000000000 [ 442.273733] DMAR: pasid table entry[4]: 0x0000000000000000 [ 442.280479] DMAR: pasid table entry[5]: 0x0000000000000000 [ 442.287234] DMAR: pasid table entry[6]: 0x0000000000000000 [ 442.293989] DMAR: pasid table entry[7]: 0x0000000000000000 [ 442.300742] DMAR: PTE not present at level 2
After fix:
...
[ 357.241214] DMAR: pasid table entry[6]: 0x0000000000000000 [ 357.248022] DMAR: pasid table entry[7]: 0x0000000000000000 [ 357.254824] DMAR: scalable mode page table is not present
--- drivers/iommu/intel/iommu.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)
drivers/iommu/intel/iommu.c +20 -9
@@ -752,11 +752,11 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,pr_info ("Dump %s table entries for IOVA 0x%llx\n" , iommu->name, addr);/* root entry dump */ - rt_entry = &iommu->root_entry[bus]; -if (!rt_entry) { -pr_info ("root table entry is not present\n" ); +if (!iommu->root_entry) { +pr_info ("root table is not present\n" );return ; } + rt_entry = &iommu->root_entry[bus];if (sm_supported (iommu)) pr_info("scalable mode root entry: hi 0x%016llx, low 0x%016llx\n",
@@ -767,7 +767,7 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,/* context entry dump */ ctx_entry =iommu_context_addr (iommu, bus, devfn,0 );if (!ctx_entry) { -pr_info ("context table entry is not present\n" ); +pr_info ("context table is not present\n" );return ; }
@@ -776,17 +776,23 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,/* legacy mode does not require PASID entries */ if (!sm_supported (iommu)) { +if (!context_present (ctx_entry)) { +pr_info ("legacy mode page table is not present\n" ); +return ; + } level =agaw_to_level (ctx_entry->hi &7 ); pgtable =phys_to_virt (ctx_entry->lo &VTD_PAGE_MASK ); goto pgtable_walk; } -/* get the pointer to pasid directory entry */ - dir =phys_to_virt (ctx_entry->lo &VTD_PAGE_MASK ); -if (!dir) { -pr_info ("pasid directory entry is not present\n" ); +if (!context_present (ctx_entry)) { +pr_info ("pasid directory table is not present\n" );return ; } + +/* get the pointer to pasid directory entry */ + dir =phys_to_virt (ctx_entry->lo &VTD_PAGE_MASK ); +/* For request-without-pasid, get the pasid from context entry */ if (intel_iommu_sm && pasid ==IOMMU_PASID_INVALID ) pasid =IOMMU_NO_PASID ;
@@ -798,7 +804,7 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,/* get the pointer to the pasid table entry */ entries =get_pasid_table_from_pde (pde);if (!entries) { -pr_info ("pasid table entry is not present\n" ); +pr_info ("pasid table is not present\n" );return ; } index = pasid &PASID_PTE_MASK ;
@@ -806,6 +812,11 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,for (i =0 ; i <ARRAY_SIZE (pte->val); i++)pr_info ("pasid table entry[%d]: 0x%016llx\n" , i, pte->val[i]); +if (!pasid_pte_is_present (pte)) { +pr_info ("scalable mode page table is not present\n" ); +return ; + } +if (pasid_pte_get_pgtt (pte) ==PASID_ENTRY_PGTT_FL_ONLY ) { level = pte->val[2 ] &BIT_ULL (2 ) ?5 :4 ; pgtable =phys_to_virt (pte->val[2 ] &VTD_PAGE_MASK );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 431/817 iommu/vt-d: Fix checks and print in pgtable_walk()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhenzhong Duan <[email protected]>
[ Upstream commit f1645676f25d2c846798f0233c3a953efd62aafb ]
There are some issues in pgtable_walk():
1. Super page is dumped as non-present page
2. dma_pte_superpage() should not check against leaf page table entries
3. Pointer pte is never NULL so checking it is meaningless
4. When an entry is not present, it still makes sense to dump the entry content.
Fix 1,2 by checking dma_pte_superpage()'s returned value after level check. Fix 3 by removing pte check.
Fix 4 by checking present bit after printing.
By this chance, change to print "page table not present" instead of "PTE not present" to be clearer.
--- drivers/iommu/intel/iommu.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/iommu/intel/iommu.c +6 -5
@@ -722,14 +722,15 @@ static void pgtable_walk(struct intel_iommu *iommu, unsigned long pfn,while (1 ) { offset =pfn_level_offset (pfn, level); pte = &parent[offset]; -if (!pte || (dma_pte_superpage (pte) || !dma_pte_present (pte))) { -pr_info ("PTE not present at level %d\n" , level); -break ; - }pr_info ("pte level: %d, pte value: 0x%016llx\n" , level, pte->val); -if (level ==1 ) +if (!dma_pte_present (pte)) { +pr_info ("page table not present at level %d\n" , level -1 ); +break ; + } + +if (level ==1 ||dma_pte_superpage (pte))break ; parent =phys_to_virt (dma_pte_addr (pte));
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 432/817 checkpatch: always parse orig_commit in fixes tag
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tamir Duberstein <[email protected]>
[ Upstream commit 2f07b652384969f5d0b317e1daa5f2eb967bc73d ]
Do not require the presence of $balanced_parens to get the commit SHA; this allows a Fixes: deadbeef tag to get a correct suggestion rather than a suggestion containing a reference to HEAD.
Given this patch:
: From: Tamir Duberstein <[email protected]> : Subject: Test patch
: Date: Fri, 25 Oct 2024 19:30:51 -0400
:
: This is a test patch.
:
: Fixes: bd17e036b495
: Signed-off-by: Tamir Duberstein <[email protected]> : --- /dev/null
: +++ b/new-file
: @@ -0,0 +1 @@
: +Test.
Before:
WARNING: Please use correct Fixes: style 'Fixes: <12 chars of sha1> ("<title line>")' - ie: 'Fixes: c10a7d25e68f ("Test patch")'
After:
WARNING: Please use correct Fixes: style 'Fixes: <12 chars of sha1> ("<title line>")' - ie: 'Fixes: bd17e036b495 ("checkpatch: warn for non-standard fixes tag style")'
The prior behavior incorrectly suggested the patch's own SHA and title line rather than the referenced commit's. This fixes that.
Ironically this:
--- scripts/checkpatch.pl | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-)
scripts/checkpatch.pl +16 -21
@@ -3209,36 +3209,31 @@ sub process { # Check Fixes: styles is correct if (!$in_header_lines && - $line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) { - my $orig_commit = ""; - my $id = "0123456789ab"; - my $title = "commit title"; - my $tag_case = 1; - my $tag_space = 1; - my $id_length = 1; - my $id_case = 1; + $line =~ /^\s*(fixes:?)\s*(?:commit\s*)?([0-9a-f]{5,40})(?:\s*($balanced_parens))?/i) { + my $tag = $1; + my $orig_commit = $2; + my $title; my $title_has_quotes = 0; $fixes_tag = 1; - - if ($line =~ /(\s*fixes:?)\s+([0-9a-f]{5,})\s+($balanced_parens)/i) { - my $tag = $1; - $orig_commit = $2; - $title = $3; - - $tag_case = 0 if $tag eq "Fixes:"; - $tag_space = 0 if ($line =~ /^fixes:? [0-9a-f]{5,} ($balanced_parens)/i); - - $id_length = 0 if ($orig_commit =~ /^[0-9a-f]{12}$/i); - $id_case = 0 if ($orig_commit !~ /[A-F]/); - + if (defined $3) { # Always strip leading/trailing parens then double quotes if existing - $title = substr($title, 1, -1); + $title = substr($3, 1, -1); if ($title =~ /^".*"$/) { $title = substr($title, 1, -1); $title_has_quotes = 1; } + } else { + $title = "commit title" } + + my $tag_case = not ($tag eq "Fixes:"); + my $tag_space = not ($line =~ /^fixes:? [0-9a-f]{5,40} ($balanced_parens)/i); + + my $id_length = not ($orig_commit =~ /^[0-9a-f]{12}$/i); + my $id_case = not ($orig_commit !~ /[A-F]/); + + my $id = "0123456789ab"; my ($cid, $ctitle) = git_commit_info($orig_commit, $id, $title);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 433/817 mfd: rt5033: Fix missing regmap_del_irq_chip()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Changzhong <[email protected]>
[ Upstream commit d256d612f47529ed0b332298e2d5ea981a4dd5b8 ]
Fix missing call to regmap_del_irq_chip() in error handling path by using devm_regmap_add_irq_chip().
--- drivers/mfd/rt5033.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mfd/rt5033.c +2 -2
@@ -81,8 +81,8 @@ static int rt5033_i2c_probe(struct i2c_client *i2c) chip_rev = dev_id &RT5033_CHIP_REV_MASK ;dev_info (&i2c->dev,"Device found (rev. %d)\n" , chip_rev); - ret =regmap_add_irq_chip (rt5033->regmap, rt5033->irq, -IRQF_TRIGGER_FALLING |IRQF_ONESHOT , + ret =devm_regmap_add_irq_chip (rt5033->dev, rt5033->regmap, + rt5033->irq,IRQF_TRIGGER_FALLING |IRQF_ONESHOT ,0 , &rt5033_irq_chip, &rt5033->irq_data);if (ret) { dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 434/817 leds: max5970: Fix unreleased fwnode_handle in probe function
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <[email protected]>
[ Upstream commit 02f58f97419c828f58e30f24f54395ac9be159c0 ]
An object initialized via device_get_named_child_node() requires calls to fwnode_handle_put() when it is no longer required to avoid leaking memory.
Add the automatic cleanup facility for 'led_node' to ensure that fwnode_handle_put() is called in all execution paths.
--- drivers/leds/leds-max5970.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/leds/leds-max5970.c +3 -2
@@ -45,7 +45,7 @@ static int max5970_led_set_brightness(struct led_classdev *cdev,static int max5970_led_probe (struct platform_device *pdev) { -struct fwnode_handle *led_node, *child; +struct fwnode_handle *child;struct device *dev = &pdev->dev;struct regmap *regmap;struct max5970_led *ddata;
@@ -55,7 +55,8 @@ static int max5970_led_probe(struct platform_device *pdev)if (!regmap)return -ENODEV ; - led_node =device_get_named_child_node (dev->parent,"leds" ); + struct fwnode_handle *led_node __free(fwnode_handle) = +device_get_named_child_node (dev->parent,"leds" );if (!led_node)return -ENODEV ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 435/817 leds: ktd2692: Set missing timing properties
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raymond Hackley <[email protected]>
[ Upstream commit 95c65546f03f888481eda98b499947252e1f3b20 ]
props.timing is not set after commit b5a8c50e5c18 ("leds: ktd2692: Convert to use ExpressWire library"). Set it with ktd2692_timing.
--- drivers/leds/flash/leds-ktd2692.c | 1 + 1 file changed, 1 insertion(+)
drivers/leds/flash/leds-ktd2692.c +1 -0
@@ -293,6 +293,7 @@ static int ktd2692_probe(struct platform_device *pdev) fled_cdev = &led->fled_cdev; led_cdev = &fled_cdev->led_cdev; + led->props.timing = ktd2692_timing; ret =ktd2692_parse_dt (led, &pdev->dev, &led_cfg);if (ret)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 436/817 fs/proc/kcore.c: fix coccinelle reported ERROR instances
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mirsad Todorovac <[email protected]>
[ Upstream commit 82e33f249f1126cf3c5f39a31b850d485ac33bc3 ]
Coccinelle complains about the nested reuse of the pointer `iter' with different pointer type:
./fs/proc/kcore.c:515:26-30: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:534:23-27: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:550:40-44: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:568:27-31: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:581:28-32: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:599:27-31: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:607:38-42: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:614:26-30: ERROR: invalid reference to the index variable of the iterator on line 499
Replacing struct kcore_list *iter' with struct kcore_list *tmp' doesn't change the scope and the functionality is the same and coccinelle seems happy.
NOTE: There was an issue with using `struct kcore_list *pos' as the nested iterator.
The build did not work!
--- fs/proc/kcore.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
fs/proc/kcore.c +5 -5
@@ -493,13 +493,13 @@ static ssize_t read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter)* the previous entry, search for a matching entry. */ if (!m || start < m->addr || start >= m->addr + m->size) { -struct kcore_list *iter; +struct kcore_list *pos; m =NULL ; -list_for_each_entry (iter, &kclist_head, list) { -if (start >= iter->addr && - start < iter->addr + iter->size) { - m = iter; +list_for_each_entry (pos, &kclist_head, list) { +if (start >= pos->addr && + start < pos->addr + pos->size) { + m = pos;break ; } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 437/817 scsi: target: Fix incorrect function name in pscsi_create_type_disk()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Liu <[email protected]>
[ Upstream commit da5aeca99dd0b6c7bf6679382756ea6bda195f72 ]
In pr_err(), bdev_open_by_path() should be renamed to bdev_file_open_by_path()
--- drivers/target/target_core_pscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/target/target_core_pscsi.c +1 -1
@@ -369,7 +369,7 @@ static int pscsi_create_type_disk(struct se_device *dev, struct scsi_device *sd) bdev_file =bdev_file_open_by_path (dev->udev_path,BLK_OPEN_WRITE |BLK_OPEN_READ , pdv,NULL );if (IS_ERR (bdev_file)) { -pr_err ("pSCSI: bdev_open_by_path() failed\n" ); +pr_err ("pSCSI: bdev_file_open_by_path() failed\n" );scsi_device_put (sd);return PTR_ERR (bdev_file); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 438/817 scsi: bfa: Fix use-after-free in bfad_im_module_exit()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Bin <[email protected]>
[ Upstream commit 178b8f38932d635e90f5f0e9af1986c6f4a89271 ]
BUG: KASAN: slab-use-after-free in __lock_acquire+0x2aca/0x3a20 Read of size 8 at addr ffff8881082d80c8 by task modprobe/25303 Call Trace: <TASK> dump_stack_lvl+0x95/0xe0 print_report+0xcb/0x620 kasan_report+0xbd/0xf0 __lock_acquire+0x2aca/0x3a20 lock_acquire+0x19b/0x520 _raw_spin_lock+0x2b/0x40 attribute_container_unregister+0x30/0x160 fc_release_transport+0x19/0x90 [scsi_transport_fc] bfad_im_module_exit+0x23/0x60 [bfa] bfad_init+0xdb/0xff0 [bfa] do_one_initcall+0xdc/0x550 do_init_module+0x22d/0x6b0 load_module+0x4e96/0x5ff0 init_module_from_file+0xcd/0x130 idempotent_init_module+0x330/0x620 __x64_sys_finit_module+0xb3/0x110 do_syscall_64+0xc1/0x1d0 entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK> Allocated by task 25303: kasan_save_stack+0x24/0x50 kasan_save_track+0x14/0x30 __kasan_kmalloc+0x7f/0x90 fc_attach_transport+0x4f/0x4740 [scsi_transport_fc] bfad_im_module_init+0x17/0x80 [bfa] bfad_init+0x23/0xff0 [bfa] do_one_initcall+0xdc/0x550 do_init_module+0x22d/0x6b0 load_module+0x4e96/0x5ff0 init_module_from_file+0xcd/0x130 idempotent_init_module+0x330/0x620 __x64_sys_finit_module+0xb3/0x110 do_syscall_64+0xc1/0x1d0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 25303: kasan_save_stack+0x24/0x50 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x38/0x50 kfree+0x212/0x480 bfad_im_module_init+0x7e/0x80 [bfa] bfad_init+0x23/0xff0 [bfa] do_one_initcall+0xdc/0x550 do_init_module+0x22d/0x6b0 load_module+0x4e96/0x5ff0 init_module_from_file+0xcd/0x130 idempotent_init_module+0x330/0x620 __x64_sys_finit_module+0xb3/0x110 do_syscall_64+0xc1/0x1d0 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Above issue happens as follows:
bfad_init
error = bfad_im_module_init()
fc_release_transport(bfad_im_scsi_transport_template);
if (error)
goto ext;ext:
bfad_im_module_exit();
fc_release_transport(bfad_im_scsi_transport_template);
--> Trigger double releaseDon't call bfad_im_module_exit() if bfad_im_module_init() failed.
--- drivers/scsi/bfa/bfad.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/scsi/bfa/bfad.c +1 -2
@@ -1693,9 +1693,8 @@ bfad_init(void) error =bfad_im_module_init ();if (error) { - error = -ENOMEM ;printk (KERN_WARNING "bfad_im_module_init failure\n" ); - goto ext; +return -ENOMEM ; }if (strcmp (FCPI_NAME ," fcpim" ) ==0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 439/817 scsi: fusion: Remove unused variable rc
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zeng Heng <[email protected]>
[ Upstream commit bd65694223f7ad11c790ab63ad1af87a771192ee ]
The return value of scsi_device_reprobe() is currently ignored in _scsih_reprobe_lun(). Fixing the calling code to deal with the potential error is non-trivial, so for now just WARN_ON().
The handling of scsi_device_reprobe()'s return value refers to _scsih_reprobe_lun() and the following link:
--- drivers/message/fusion/mptsas.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/message/fusion/mptsas.c +1 -3
@@ -4231,10 +4231,8 @@ mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,static void mptsas_reprobe_lun (struct scsi_device *sdev,void *data) { -int rc; - sdev->no_uld_attach = data ?1 :0 ; - rc =scsi_device_reprobe (sdev); +WARN_ON (scsi_device_reprobe (sdev)); } static void
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 440/817 scsi: qedf: Fix a possible memory leak in qedf_alloc_and_init_sb()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhen Lei <[email protected]>
[ Upstream commit c62c30429db3eb4ced35c7fcf6f04a61ce3a01bb ]
Hook "qed_ops->common->sb_init = qed_sb_init" does not release the DMA memory sb_virt when it fails. Add dma_free_coherent() to free it. This is the same way as qedr_alloc_mem_sb() and qede_alloc_mem_sb().
--- drivers/scsi/qedf/qedf_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/qedf/qedf_main.c +1 -0
@@ -2738,6 +2738,7 @@ static int qedf_alloc_and_init_sb(struct qedf_ctx *qedf, sb_id, QED_SB_TYPE_STORAGE);if (ret) { +dma_free_coherent (&qedf->pdev->dev,sizeof (*sb_virt), sb_virt, sb_phys);QEDF_ERR (&qedf->dbg_ctx,"Status block initialization failed (0x%x) for id = %d.\n" , ret, sb_id);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 441/817 scsi: qedi: Fix a possible memory leak in qedi_alloc_and_init_sb()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhen Lei <[email protected]>
[ Upstream commit 95bbdca4999bc59a72ebab01663d421d6ce5775d ]
Hook "qedi_ops->common->sb_init = qed_sb_init" does not release the DMA memory sb_virt when it fails. Add dma_free_coherent() to free it. This is the same way as qedr_alloc_mem_sb() and qede_alloc_mem_sb().
--- drivers/scsi/qedi/qedi_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/qedi/qedi_main.c +1 -0
@@ -369,6 +369,7 @@ static int qedi_alloc_and_init_sb(struct qedi_ctx *qedi, ret = qedi_ops->common->sb_init (qedi->cdev, sb_info, sb_virt, sb_phys, sb_id,QED_SB_TYPE_STORAGE );if (ret) { +dma_free_coherent (&qedi->pdev->dev,sizeof (*sb_virt), sb_virt, sb_phys);QEDI_ERR (&qedi->dbg_ctx,"Status block initialization failed for id = %d.\n" , sb_id);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 442/817 scsi: sg: Enable runtime power management
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit 4045de893f691f75193c606aec440c365cf7a7be ]
In 2010, runtime power management support was implemented in the SCSI core. The description of patch "[SCSI] implement runtime Power Management" mentions that the sg driver is skipped but not why. This patch enables runtime power management even if an instance of the sg driver is held open. Enabling runtime PM for the sg driver is safe because all interactions of the sg driver with the SCSI device pass through the block layer (blk_execute_rq_nowait()) and the block layer already supports runtime PM.
--- drivers/scsi/sg.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
drivers/scsi/sg.c +1 -8
@@ -307,10 +307,6 @@ sg_open(struct inode *inode, struct file *filp)if (retval) goto sg_put; - retval =scsi_autopm_get_device (device); -if (retval) - goto sdp_put; -/* scsi_block_when_processing_errors() may block so bypass * check if O_NONBLOCK. Permits SCSI commands to be issued * during error recovery. Tread carefully. */
@@ -318,7 +314,7 @@ sg_open(struct inode *inode, struct file *filp) scsi_block_when_processing_errors(device))) { retval = -ENXIO ;/* we are in error recovery for this device */ - goto error_out; + goto sdp_put; }mutex_lock (&sdp->open_rel_lock);
@@ -371,8 +367,6 @@ sg_open(struct inode *inode, struct file *filp) } error_mutex_locked:mutex_unlock (&sdp->open_rel_lock); -error_out: -scsi_autopm_put_device (device); sdp_put:kref_put (&sdp->d_ref, sg_device_destroy);scsi_device_put (device);
@@ -392,7 +386,6 @@ sg_release(struct inode *inode, struct file *filp)SCSI_LOG_TIMEOUT (3 ,sg_printk (KERN_INFO , sdp,"sg_release\n" ));mutex_lock (&sdp->open_rel_lock); -scsi_autopm_put_device (sdp->device);kref_put (&sfp->f_ref, sg_remove_sfp); sdp->open_cnt--;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 443/817 x86/tdx: Introduce wrappers to read and write TD metadata
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kirill A. Shutemov <[email protected]>
[ Upstream commit 5081e8fadb809253c911b349b01d87c5b4e3fec5 ]
The TDG_VM_WR TDCALL is used to ask the TDX module to change some TD-specific VM configuration. There is currently only one user in the kernel of this TDCALL leaf. More will be added shortly.
Refactor to make way for more users of TDG_VM_WR who will need to modify other TD configuration values.
Add a wrapper for the TDG_VM_RD TDCALL that requests TD-specific metadata from the TDX module. There are currently no users for TDG_VM_RD. Mark it as __maybe_unused until the first user appears.
This is preparation for enumeration and enabling optional TD features.
Stable-dep-of: f65aa0ad79fc ("x86/tdx: Dynamically disable SEPT violations from causing #VEs")
--- arch/x86/coco/tdx/tdx.c | 32 ++++++++++++++++++++++++++----- arch/x86/include/asm/shared/tdx.h | 1 + 2 files changed, 28 insertions(+), 5 deletions(-)
arch/x86/coco/tdx/tdx.c +27 -5
@@ -78,6 +78,32 @@ static inline void tdcall(u64 fn, struct tdx_module_args *args)panic ("TDCALL %lld failed (Buggy TDX module!)\n" , fn); } +/* Read TD-scoped metadata */ +static inline u64 __maybe_unused tdg_vm_rd (u64 field,u64 *value) +{ +struct tdx_module_args args = { + .rdx = field, + }; +u64 ret; + + ret =__tdcall_ret (TDG_VM_RD , &args); + *value = args.r8; + +return ret; +} + +/* Write TD-scoped metadata */ +static inline u64 tdg_vm_wr (u64 field,u64 value,u64 mask) +{ +struct tdx_module_args args = { + .rdx = field, + .r8 = value, + .r9 = mask, + }; + +return __tdcall (TDG_VM_WR , &args); +} +/** * tdx_mcall_get_report0() - Wrapper to get TDREPORT0 (a.k.a. TDREPORT * subtype 0) using TDG.MR.REPORT TDCALL.
@@ -929,10 +955,6 @@ static void tdx_kexec_finish(void)void __init tdx_early_init (void ) { -struct tdx_module_args args = { - .rdx =TDCS_NOTIFY_ENABLES , - .r9 =-1ULL , - };u64 cc_mask;u32 eax, sig[3 ];
@@ -951,7 +973,7 @@ void __init tdx_early_init(void)cc_set_mask (cc_mask);/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */ -tdcall (TDG_VM_WR , &args); +tdg_vm_wr (TDCS_NOTIFY_ENABLES ,0 ,-1ULL );/* * All bits above GPA width are reserved and kernel treats shared bit
arch/x86/include/asm/shared/tdx.h +1 -0
@@ -16,6 +16,7 @@#define TDG_VP_VEINFO_GET 3#define TDG_MR_REPORT 4#define TDG_MEM_PAGE_ACCEPT 6 +#define TDG_VM_RD 7#define TDG_VM_WR 8/* TDCS fields. To be used by TDG.VM.WR and TDG.VM.RD module calls */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 444/817 x86/tdx: Rename tdx_parse_tdinfo() to tdx_setup()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kirill A. Shutemov <[email protected]>
[ Upstream commit b064043d9565786b385f85e6436ca5716bbd5552 ]
Rename tdx_parse_tdinfo() to tdx_setup() and move setting NOTIFY_ENABLES there.
The function will be extended to adjust TD configuration.
Stable-dep-of: f65aa0ad79fc ("x86/tdx: Dynamically disable SEPT violations from causing #VEs")
--- arch/x86/coco/tdx/tdx.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
arch/x86/coco/tdx/tdx.c +8 -5
@@ -194,7 +194,7 @@ static void __noreturn tdx_panic(const char *msg)__tdx_hypercall (&args); } -static void tdx_parse_tdinfo (u64 *cc_mask) +static void tdx_setup (u64 *cc_mask) {struct tdx_module_args args = {};unsigned int gpa_width;
@@ -219,6 +219,9 @@ static void tdx_parse_tdinfo(u64 *cc_mask) gpa_width = args.rcx &GENMASK (5 ,0 ); *cc_mask =BIT_ULL (gpa_width -1 ); +/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */ +tdg_vm_wr (TDCS_NOTIFY_ENABLES ,0 ,-1ULL ); +/* * The kernel can not handle #VE's when accessing normal kernel * memory. Ensure that no #VE will be delivered for accesses to
@@ -969,11 +972,11 @@ void __init tdx_early_init(void)setup_force_cpu_cap (X86_FEATURE_TSC_RELIABLE ); cc_vendor =CC_VENDOR_INTEL ; -tdx_parse_tdinfo (&cc_mask); -cc_set_mask (cc_mask); -/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */ -tdg_vm_wr (TDCS_NOTIFY_ENABLES ,0 ,-1ULL ); +/* Configure the TD */ +tdx_setup (&cc_mask); + +cc_set_mask (cc_mask);/* * All bits above GPA width are reserved and kernel treats shared bit
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 445/817 x86/tdx: Dynamically disable SEPT violations from causing #VEs
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kirill A. Shutemov <[email protected]>
[ Upstream commit f65aa0ad79fca4ace921da0701644f020129043d ]
Memory access #VEs are hard for Linux to handle in contexts like the entry code or NMIs. But other OSes need them for functionality. There's a static (pre-guest-boot) way for a VMM to choose one or the other. But VMMs don't always know which OS they are booting, so they choose to deliver those #VEs so the "other" OSes will work. That, unfortunately has left us in the lurch and exposed to these hard-to-handle #VEs.
The TDX module has introduced a new feature. Even if the static configuration is set to "send nasty #VEs", the kernel can dynamically request that they be disabled. Once they are disabled, access to private memory that is not in the Mapped state in the Secure-EPT (SEPT) will result in an exit to the VMM rather than injecting a #VE.
Check if the feature is available and disable SEPT #VE if possible.
If the TD is allowed to disable/enable SEPT #VEs, the ATTR_SEPT_VE_DISABLE attribute is no longer reliable. It reflects the initial state of the control for the TD, but it will not be updated if someone (e.g. bootloader) changes it before the kernel starts. Kernel must check TDCS_TD_CTLS bit to determine if SEPT #VEs are enabled or disabled.
[ dhansen: remove 'return' at end of function ]
--- arch/x86/coco/tdx/tdx.c | 74 ++++++++++++++++++++++++------- arch/x86/include/asm/shared/tdx.h | 10 ++++- 2 files changed, 67 insertions(+), 17 deletions(-)
arch/x86/coco/tdx/tdx.c +58 -16
@@ -79,7 +79,7 @@ static inline void tdcall(u64 fn, struct tdx_module_args *args) }/* Read TD-scoped metadata */ -static inline u64 __maybe_unused tdg_vm_rd (u64 field,u64 *value) +static inline u64 tdg_vm_rd (u64 field,u64 *value) {struct tdx_module_args args = { .rdx = field,
@@ -194,6 +194,60 @@ static void __noreturn tdx_panic(const char *msg)__tdx_hypercall (&args); } +/* +* The kernel cannot handle #VEs when accessing normal kernel memory. Ensure +* that no #VE will be delivered for accesses to TD-private memory. +* +* TDX 1.0 does not allow the guest to disable SEPT #VE on its own. The VMM +* controls if the guest will receive such #VE with TD attribute +* ATTR_SEPT_VE_DISABLE. +* +* Newer TDX modules allow the guest to control if it wants to receive SEPT +* violation #VEs. +* +* Check if the feature is available and disable SEPT #VE if possible. +* +* If the TD is allowed to disable/enable SEPT #VEs, the ATTR_SEPT_VE_DISABLE +* attribute is no longer reliable. It reflects the initial state of the +* control for the TD, but it will not be updated if someone (e.g. bootloader) +* changes it before the kernel starts. Kernel must check TDCS_TD_CTLS bit to +* determine if SEPT #VEs are enabled or disabled. +*/ +static void disable_sept_ve (u64 td_attr) +{ +const char *msg ="TD misconfiguration: SEPT #VE has to be disabled" ; +bool debug = td_attr &ATTR_DEBUG ; +u64 config, controls; + +/* Is this TD allowed to disable SEPT #VE */ +tdg_vm_rd (TDCS_CONFIG_FLAGS , &config); +if (!(config &TDCS_CONFIG_FLEXIBLE_PENDING_VE )) { +/* No SEPT #VE controls for the guest: check the attribute */ +if (td_attr &ATTR_SEPT_VE_DISABLE ) +return ; + +/* Relax SEPT_VE_DISABLE check for debug TD for backtraces */ +if (debug) +pr_warn ("%s\n" , msg); +else +tdx_panic (msg); +return ; + } + +/* Check if SEPT #VE has been disabled before us */ +tdg_vm_rd (TDCS_TD_CTLS , &controls); +if (controls &TD_CTLS_PENDING_VE_DISABLE ) +return ; + +/* Keep #VEs enabled for splats in debugging environments */ +if (debug) +return ; + +/* Disable SEPT #VEs */ +tdg_vm_wr (TDCS_TD_CTLS ,TD_CTLS_PENDING_VE_DISABLE , +TD_CTLS_PENDING_VE_DISABLE ); +} +static void tdx_setup (u64 *cc_mask) {struct tdx_module_args args = {};
@@ -219,24 +273,12 @@ static void tdx_setup(u64 *cc_mask) gpa_width = args.rcx &GENMASK (5 ,0 ); *cc_mask =BIT_ULL (gpa_width -1 ); + td_attr = args.rdx; +/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */ tdg_vm_wr (TDCS_NOTIFY_ENABLES ,0 ,-1ULL ); -/* -* The kernel can not handle #VE's when accessing normal kernel -* memory. Ensure that no #VE will be delivered for accesses to -* TD-private memory. Only VMM-shared memory (MMIO) will #VE. -*/ - td_attr = args.rdx; -if (!(td_attr &ATTR_SEPT_VE_DISABLE )) { -const char *msg ="TD misconfiguration: SEPT_VE_DISABLE attribute must be set." ; - -/* Relax SEPT_VE_DISABLE check for debug TD. */ -if (td_attr &ATTR_DEBUG ) -pr_warn ("%s\n" , msg); -else -tdx_panic (msg); - } +disable_sept_ve (td_attr); }/*
arch/x86/include/asm/shared/tdx.h +9 -1
@@ -19,9 +19,17 @@#define TDG_VM_RD 7#define TDG_VM_WR 8 -/* TDCS fields. To be used by TDG.VM.WR and TDG.VM.RD module calls */ +/* TDX TD-Scope Metadata. To be used by TDG.VM.WR and TDG.VM.RD */ +#define TDCS_CONFIG_FLAGS 0x1110000300000016 +#define TDCS_TD_CTLS 0x1110000300000017#define TDCS_NOTIFY_ENABLES 0x9100000000000010 +/* TDCS_CONFIG_FLAGS bits */ +#define TDCS_CONFIG_FLEXIBLE_PENDING_VE BIT_ULL(1) + +/* TDCS_TD_CTLS bits */ +#define TD_CTLS_PENDING_VE_DISABLE BIT_ULL(0) +/* TDX hypercall Leaf IDs */ #define TDVMCALL_MAP_GPA 0x10001#define TDVMCALL_GET_QUOTE 0x10002
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 446/817 powerpc/fadump: allocate memory for additional parameters early
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hari Bathini <[email protected]>
[ Upstream commit f4892c68ecc1cf45e41a78820dd2eebccc945b66 ]
Memory for passing additional parameters to fadump capture kernel is allocated during subsys_initcall level, using memblock. But as slab is already available by this time, allocation happens via the buddy allocator. This may work for radix MMU but is likely to fail in most cases for hash MMU as hash MMU needs this memory in the first memory block for it to be accessible in real mode in the capture kernel (second boot). So, allocate memory for additional parameters area as soon as MMU mode is obvious.
--- arch/powerpc/include/asm/fadump.h | 2 ++ arch/powerpc/kernel/fadump.c | 15 ++++++++++----- arch/powerpc/kernel/prom.c | 3 +++ 3 files changed, 15 insertions(+), 5 deletions(-)
arch/powerpc/include/asm/fadump.h +2 -0
@@ -19,6 +19,7 @@ extern int is_fadump_active(void);extern int should_fadump_crash (void );extern void crash_fadump (struct pt_regs *,const char *);extern void fadump_cleanup (void ); +void fadump_setup_param_area (void );extern void fadump_append_bootargs (void );#else /* CONFIG_FA_DUMP */
@@ -26,6 +27,7 @@ static inline int is_fadump_active(void) { return 0; }static inline int should_fadump_crash (void ) {return 0 ; }static inline void crash_fadump (struct pt_regs *regs,const char *str) { }static inline void fadump_cleanup (void ) { } +static inline void fadump_setup_param_area (void ) { }static inline void fadump_append_bootargs (void ) { }#endif /* !CONFIG_FA_DUMP */
arch/powerpc/kernel/fadump.c +10 -5
@@ -1577,6 +1577,12 @@ static void __init fadump_init_files(void)return ; } +if (fw_dump.param_area) { + rc =sysfs_create_file (fadump_kobj, &bootargs_append_attr.attr); +if (rc) +pr_err ("unable to create bootargs_append sysfs file (%d)\n" , rc); + } +debugfs_create_file ("fadump_region" ,0444 , arch_debugfs_dir,NULL , &fadump_region_fops);
@@ -1731,7 +1737,7 @@ static void __init fadump_process(void)* Reserve memory to store additional parameters to be passed * for fadump/capture kernel. */ -static void __init fadump_setup_param_area (void ) +void __init fadump_setup_param_area (void ) {phys_addr_t range_start, range_end;
@@ -1739,7 +1745,7 @@ static void __init fadump_setup_param_area(void)return ;/* This memory can't be used by PFW or bootloader as it is shared across kernels */ -if (radix_enabled ()) { +if (early_radix_enabled ()) {/* * Anywhere in the upper half should be good enough as all memory * is accessible in real mode.
@@ -1767,12 +1773,12 @@ static void __init fadump_setup_param_area(void)COMMAND_LINE_SIZE , range_start, range_end); -if (!fw_dump.param_area ||sysfs_create_file (fadump_kobj, &bootargs_append_attr.attr)) { +if (!fw_dump.param_area) {pr_warn ("WARNING: Could not setup area to pass additional parameters!\n" );return ; } -memset (phys_to_virt (fw_dump.param_area),0 ,COMMAND_LINE_SIZE ); +memset ((void *)fw_dump.param_area,0 ,COMMAND_LINE_SIZE ); }/*
@@ -1798,7 +1804,6 @@ int __init setup_fadump(void) }/* Initialize the kernel dump memory structure and register with f/w */ else if (fw_dump.reserve_dump_area_size) { -fadump_setup_param_area (); fw_dump.ops->fadump_init_mem_struct (&fw_dump);register_fadump (); }
arch/powerpc/kernel/prom.c +3 -0
@@ -908,6 +908,9 @@ void __init early_init_devtree(void *params)mmu_early_init_devtree (); +/* Setup param area for passing additional parameters to fadump capture kernel. */ +fadump_setup_param_area (); +#ifdef CONFIG_PPC_POWERNV /* Scan and build the list of machine check recoverable ranges */ of_scan_flat_dt (early_init_dt_scan_recoverable_ranges,NULL );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 447/817 fadump: reserve param area if below boot_mem_top
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sourabh Jain <[email protected]>
[ Upstream commit fb90dca828b6070709093934c6dec56489a2d91d ]
The param area is a memory region where the kernel places additional command-line arguments for fadump kernel. Currently, the param memory area is reserved in fadump kernel if it is above boot_mem_top. However, it should be reserved if it is below boot_mem_top because the fadump kernel already reserves memory from boot_mem_top to the end of DRAM.
Currently, there is no impact from not reserving param memory if it is below boot_mem_top, as it is not used after the early boot phase of the fadump kernel. However, if this changes in the future, it could lead to issues in the fadump kernel.
--- arch/powerpc/kernel/fadump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/fadump.c +1 -1
@@ -136,7 +136,7 @@ void __init fadump_append_bootargs(void)if (!fw_dump.dump_active || !fw_dump.param_area_supported || !fw_dump.param_area)return ; -if (fw_dump.param_area >= fw_dump.boot_mem_top) { +if (fw_dump.param_area < fw_dump.boot_mem_top) {if (memblock_reserve (fw_dump.param_area,COMMAND_LINE_SIZE )) {pr_warn ("WARNING: Can't use additional parameters area!\n" ); fw_dump.param_area =0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 448/817 RDMA/hns: Fix out-of-order issue of requester when setting FENCE
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit 5dbcb1c1900f45182b5651c89257c272f1f3ead7 ]
The FENCE indicator in hns WQE doesn't ensure that response data from a previous Read/Atomic operation has been written to the requester's memory before the subsequent Send/Write operation is processed. This may result in the subsequent Send/Write operation accessing the original data in memory instead of the expected response data.
Unlike FENCE, the SO (Strong Order) indicator blocks the subsequent operation until the previous response data is written to memory and a bresp is returned. Set the SO indicator instead of FENCE to maintain strict order.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +1 -1
@@ -575,7 +575,7 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp,if (WARN_ON (ret))return ret; -hr_reg_write (rc_sq_wqe,RC_SEND_WQE_FENCE , +hr_reg_write (rc_sq_wqe,RC_SEND_WQE_SO , (wr->send_flags &IB_SEND_FENCE ) ?1 :0 ); hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SE,
drivers/infiniband/hw/hns/hns_roce_hw_v2.h +1 -0
@@ -924,6 +924,7 @@ struct hns_roce_v2_rc_send_wqe {#define RC_SEND_WQE_OWNER RC_SEND_WQE_FIELD_LOC(7, 7)#define RC_SEND_WQE_CQE RC_SEND_WQE_FIELD_LOC(8, 8)#define RC_SEND_WQE_FENCE RC_SEND_WQE_FIELD_LOC(9, 9) +#define RC_SEND_WQE_SO RC_SEND_WQE_FIELD_LOC(10, 10)#define RC_SEND_WQE_SE RC_SEND_WQE_FIELD_LOC(11, 11)#define RC_SEND_WQE_INLINE RC_SEND_WQE_FIELD_LOC(12, 12)#define RC_SEND_WQE_WQE_INDEX RC_SEND_WQE_FIELD_LOC(30, 15)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 449/817 RDMA/hns: Fix NULL pointer derefernce in hns_roce_map_mr_sg()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit 6b526d17eed850352d880b93b9bf20b93006bd92 ]
ib_map_mr_sg() allows ULPs to specify NULL as the sg_offset argument. The driver needs to check whether it is a NULL pointer before dereferencing it.
--- drivers/infiniband/hw/hns/hns_roce_mr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/infiniband/hw/hns/hns_roce_mr.c +4 -3
@@ -435,15 +435,16 @@ static int hns_roce_set_page(struct ib_mr *ibmr, u64 addr) }int hns_roce_map_mr_sg (struct ib_mr *ibmr,struct scatterlist *sg,int sg_nents, -unsigned int *sg_offset) +unsigned int *sg_offset_p) { +unsigned int sg_offset = sg_offset_p ? *sg_offset_p :0 ;struct hns_roce_dev *hr_dev =to_hr_dev (ibmr->device);struct ib_device *ibdev = &hr_dev->ib_dev;struct hns_roce_mr *mr =to_hr_mr (ibmr);struct hns_roce_mtr *mtr = &mr->pbl_mtr;int ret, sg_num =0 ; -if (!IS_ALIGNED (*sg_offset,HNS_ROCE_FRMR_ALIGN_SIZE ) || +if (!IS_ALIGNED (sg_offset,HNS_ROCE_FRMR_ALIGN_SIZE ) || ibmr->page_size <HNS_HW_PAGE_SIZE || ibmr->page_size >HNS_HW_MAX_PAGE_SIZE )return sg_num;
@@ -454,7 +455,7 @@ int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,if (!mr->page_list)return sg_num; - sg_num =ib_sg_to_pages (ibmr, sg, sg_nents, sg_offset, hns_roce_set_page); + sg_num =ib_sg_to_pages (ibmr, sg, sg_nents, sg_offset_p, hns_roce_set_page);if (sg_num <1 ) {ibdev_err (ibdev,"failed to store sg pages %u %u, cnt = %d.\n" , mr->npages, mr->pbl_mtr.hem_cfg.buf_pg_count, sg_num);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 450/817 cpufreq: loongson3: Check for error code from devm_mutex_init() call
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit db01e46689e9a986ca6b5d2f41b57d7a81551a4f ]
Even if it's not critical, the avoidance of checking the error code from devm_mutex_init() call today diminishes the point of using devm variant of it. Tomorrow it may even leak something. Add the missed check.
--- drivers/cpufreq/loongson3_cpufreq.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/cpufreq/loongson3_cpufreq.c +5 -2
@@ -346,8 +346,11 @@ static int loongson3_cpufreq_probe(struct platform_device *pdev) {int i, ret; -for (i =0 ; i <MAX_PACKAGES ; i++) -devm_mutex_init (&pdev->dev, &cpufreq_mutex[i]); +for (i =0 ; i <MAX_PACKAGES ; i++) { + ret =devm_mutex_init (&pdev->dev, &cpufreq_mutex[i]); +if (ret) +return ret; + } ret =do_service_request (0 ,0 ,CMD_GET_VERSION ,0 ,0 );if (ret <=0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 451/817 cpufreq: CPPC: Fix wrong return value in cppc_get_cpu_cost()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit be392aa80f1e5b0b65ccc2a540b9304fefcfe3d8 ]
cppc_get_cpu_cost() return 0 if the policy is NULL. Then in em_compute_costs(), the later zero check for cost is not valid as cost is uninitialized. As Quentin pointed out, kernel energy model core check the return value of get_cost() first, so if the callback failed it should tell the core. Return -EINVAL to fix it.
--- drivers/cpufreq/cppc_cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/cppc_cpufreq.c +1 -1
@@ -494,7 +494,7 @@ static int cppc_get_cpu_cost(struct device *cpu_dev, unsigned long KHz, policy =cpufreq_cpu_get_raw (cpu_dev->id);if (!policy) -return 0 ; +return -EINVAL ; cpu_data = policy->driver_data; perf_caps = &cpu_data->perf_caps;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 452/817 cpufreq: CPPC: Fix wrong return value in cppc_get_cpu_power()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit b51eb0874d8170028434fbd259e80b78ed9b8eca ]
cppc_get_cpu_power() return 0 if the policy is NULL. Then in em_create_perf_table(), the later zero check for power is not valid as power is uninitialized. As Quentin pointed out, kernel energy model core check the return value of active_power() first, so if the callback failed it should tell the core. So return -EINVAL to fix it.
--- drivers/cpufreq/cppc_cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/cppc_cpufreq.c +1 -1
@@ -424,7 +424,7 @@ static int cppc_get_cpu_power(struct device *cpu_dev, policy =cpufreq_cpu_get_raw (cpu_dev->id);if (!policy) -return 0 ; +return -EINVAL ; cpu_data = policy->driver_data; perf_caps = &cpu_data->perf_caps;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 453/817 kasan: move checks to do_strncpy_from_user
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabyrzhan Tasbolatov <[email protected]>
[ Upstream commit ae193dd79398970ee760e0c8129ac42ef8f5c6ff ]
Patch series "kasan: migrate the last module test to kunit", v4.
copy_user_test() is the last KUnit-incompatible test with CONFIG_KASAN_MODULE_TEST requirement, which we are going to migrate to KUnit framework and delete the former test and Kconfig as well.
In this patch series:
- [1/3] move kasan_check_write() and check_object_size() to do_strncpy_from_user() to cover with KASAN checks with
multiple conditions in strncpy_from_user().
- [2/3] migrated copy_user_test() to KUnit, where we can also test strncpy_from_user() due to [1/4].
KUnits have been tested on:
- x86_64 with CONFIG_KASAN_GENERIC. Passed
- arm64 with CONFIG_KASAN_SW_TAGS. 1 fail. See [1]
- arm64 with CONFIG_KASAN_HW_TAGS. 1 fail. See [1]
[1] https://lore.kernel.org/linux-mm/CACzwLxj21h7nCcS2-KA_q7ybe+5pxH0uCDwu64q_9pPsydneWQ@mail.gmail.com/
- [3/3] delete CONFIG_KASAN_MODULE_TEST and documentation occurrences.
This patch (of 3):
Since in the commit 2865baf54077("x86: support user address masking instead of non-speculative conditional") do_strncpy_from_user() is called from multiple places, we should sanitize the kernel *dst memory and size which were done in strncpy_from_user() previously.
--- lib/strncpy_from_user.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
lib/strncpy_from_user.c +3 -2
@@ -120,6 +120,9 @@ long strncpy_from_user(char *dst, const char __user *src, long count)if (unlikely (count <=0 ))return 0 ; +kasan_check_write (dst, count); +check_object_size (dst, count, false); +if (can_do_masked_user_access ()) {long retval;
@@ -142,8 +145,6 @@ long strncpy_from_user(char *dst, const char __user *src, long count)if (max > count) max = count; -kasan_check_write (dst, count); -check_object_size (dst, count, false);if (user_read_access_begin (src, max)) { retval =do_strncpy_from_user (dst, src, count, max);user_read_access_end ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 454/817 kunit: skb: use "gfp" variable instead of hardcoding GFP_KERNEL
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit fd0a5afb5455b4561bfc6dfb0c4b2d8226f9ccfe ]
The intent here was clearly to use the gfp variable flags instead of hardcoding GFP_KERNEL. All the callers pass GFP_KERNEL as the gfp flags so this doesn't affect runtime.
--- include/kunit/skbuff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/kunit/skbuff.h +1 -1
@@ -29,7 +29,7 @@ static void kunit_action_kfree_skb(void *p)static inline struct sk_buff *kunit_zalloc_skb (struct kunit *test,int len,gfp_t gfp) { -struct sk_buff *res =alloc_skb (len,GFP_KERNEL ); +struct sk_buff *res =alloc_skb (len, gfp);if (!res ||skb_pad (res, len))return NULL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 455/817 ocfs2: fix uninitialized value in ocfs2_file_read_iter()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Antipov <[email protected]>
[ Upstream commit adc77b19f62d7e80f98400b2fca9d700d2afdd6f ]
Syzbot has reported the following KMSAN splat:
BUG: KMSAN: uninit-value in ocfs2_file_read_iter+0x9a4/0xf80 ocfs2_file_read_iter+0x9a4/0xf80 __io_read+0x8d4/0x20f0 io_read+0x3e/0xf0 io_issue_sqe+0x42b/0x22c0 io_wq_submit_work+0xaf9/0xdc0 io_worker_handle_work+0xd13/0x2110 io_wq_worker+0x447/0x1410 ret_from_fork+0x6f/0x90 ret_from_fork_asm+0x1a/0x30
Uninit was created at:
__alloc_pages_noprof+0x9a7/0xe00 alloc_pages_mpol_noprof+0x299/0x990 alloc_pages_noprof+0x1bf/0x1e0 allocate_slab+0x33a/0x1250 ___slab_alloc+0x12ef/0x35e0 kmem_cache_alloc_bulk_noprof+0x486/0x1330 __io_alloc_req_refill+0x84/0x560 io_submit_sqes+0x172f/0x2f30 __se_sys_io_uring_enter+0x406/0x41c0 __x64_sys_io_uring_enter+0x11f/0x1a0 x64_sys_call+0x2b54/0x3ba0 do_syscall_64+0xcd/0x1e0 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Since an instance of 'struct kiocb' may be passed from the block layer with 'private' field uninitialized, introduce 'ocfs2_iocb_init_rw_locked()' and use it from where 'ocfs2_dio_end_io()' might take care, i.e. in 'ocfs2_file_read_iter()' and 'ocfs2_file_write_iter()'.
--- fs/ocfs2/aops.h | 2 ++ fs/ocfs2/file.c | 4 ++++ 2 files changed, 6 insertions(+)
fs/ocfs2/aops.h +2 -0
@@ -70,6 +70,8 @@ enum ocfs2_iocb_lock_bits { OCFS2_IOCB_NUM_LOCKS }; +#define ocfs2_iocb_init_rw_locked (iocb) \ + (iocb->private = NULL)#define ocfs2_iocb_clear_rw_locked (iocb) \ clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private)#define ocfs2_iocb_rw_locked_level (iocb) \
fs/ocfs2/file.c +4 -0
@@ -2397,6 +2397,8 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, }else inode_lock (inode); +ocfs2_iocb_init_rw_locked (iocb); +/* * Concurrent O_DIRECT writes are allowed with * mount_option "coherency=buffered".
@@ -2543,6 +2545,8 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb,if (!direct_io && nowait)return -EOPNOTSUPP ; +ocfs2_iocb_init_rw_locked (iocb); +/* * buffered reads protect themselves in ->read_folio(). O_DIRECT reads * need locks to protect pending reads from racing with truncate.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 456/817 dax: delete a stale directory pmem
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harshit Mogalapalli <[email protected]>
[ Upstream commit b8e6d7ce50673c39514921ac61f7af00bbb58b87 ]
After commit: 83762cb5c7c4 ("dax: Kill DEV_DAX_PMEM_COMPAT") the pmem/ directory is not needed anymore and Makefile changes were made accordingly in this commit, but there is a Makefile and pmem.c in pmem/ which are now stale and pmem.c is empty, remove them.
--- drivers/dax/pmem/Makefile | 7 ------- drivers/dax/pmem/pmem.c | 10 ---------- 2 files changed, 17 deletions(-) delete mode 100644 drivers/dax/pmem/Makefile delete mode 100644 drivers/dax/pmem/pmem.c
drivers/dax/pmem/Makefile deleted +0 -7
@@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o -obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem_core.o - -dax_pmem-y := pmem.o -dax_pmem_core-y := core.o -dax_pmem_compat-y := compat.o
drivers/dax/pmem/pmem.c deleted +0 -10
@@ -1,10 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2016 - 2018 Intel Corporation. All rights reserved. */ -#include <linux/percpu-refcount.h> -#include <linux/memremap.h> -#include <linux/module.h> -#include <linux/pfn_t.h> -#include <linux/nd.h> -#include "../bus.h" - -
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 457/817 KVM: PPC: Book3S HV: Stop using vc->dpdes for nested KVM guests
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gautam Menghani <[email protected]>
[ Upstream commit 0d3c6b28896f9889c8864dab469e0343a0ad1c0c ]
commit 6398326b9ba1 ("KVM: PPC: Book3S HV P9: Stop using vc->dpdes") introduced an optimization to use only vcpu->doorbell_request for SMT emulation for Power9 and above guests, but the code for nested guests still relies on the old way of handling doorbells, due to which an L2 guest (see [1]) cannot be booted with XICS with SMT>1. The command to repro this issue is:
// To be run in L1
qemu-system-ppc64 \ -drive file=rhel.qcow2,format=qcow2 \ -m 20G \ -smp 8,cores=1,threads=8 \ -cpu host \ -nographic \ -machine pseries,ic-mode=xics -accel kvm
Fix the plumbing to utilize vcpu->doorbell_request instead of vcore->dpdes for nested KVM guests on P9 and above.
[1] Terminology
1. L0 : PowerNV linux running with HV privileges
2. L1 : Pseries KVM guest running on top of L0
2. L2 : Nested KVM guest running on top of L1
--- arch/powerpc/kvm/book3s_hv.c | 9 +++++++++ arch/powerpc/kvm/book3s_hv_nested.c | 14 ++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-)
arch/powerpc/kvm/book3s_hv.c +9 -0
@@ -4303,6 +4303,15 @@ static int kvmhv_vcpu_entry_p9_nested(struct kvm_vcpu *vcpu, u64 time_limit, uns } hvregs.hdec_expiry = time_limit; +/* +* hvregs has the doorbell status, so zero it here which +* enables us to receive doorbells when H_ENTER_NESTED is +* in progress for this vCPU +*/ + +if (vcpu->arch.doorbell_request) + vcpu->arch.doorbell_request =0 ; +/* * When setting DEC, we must always deal with irq_work_raise * via NMI vs setting DEC. The problem occurs right as we
arch/powerpc/kvm/book3s_hv_nested.c +10 -4
@@ -32,7 +32,7 @@ void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr)struct kvmppc_vcore *vc = vcpu->arch.vcore; hr->pcr = vc->pcr |PCR_MASK ; - hr->dpdes = vc->dpdes; + hr->dpdes = vcpu->arch.doorbell_request; hr->hfscr = vcpu->arch.hfscr; hr->tb_offset = vc->tb_offset; hr->dawr0 = vcpu->arch.dawr0;
@@ -105,7 +105,7 @@ static void save_hv_return_state(struct kvm_vcpu *vcpu, {struct kvmppc_vcore *vc = vcpu->arch.vcore; - hr->dpdes = vc->dpdes; + hr->dpdes = vcpu->arch.doorbell_request; hr->purr = vcpu->arch.purr; hr->spurr = vcpu->arch.spurr; hr->ic = vcpu->arch.ic;
@@ -143,7 +143,7 @@ static void restore_hv_regs(struct kvm_vcpu *vcpu, const struct hv_guest_state *struct kvmppc_vcore *vc = vcpu->arch.vcore; vc->pcr = hr->pcr |PCR_MASK ; - vc->dpdes = hr->dpdes; + vcpu->arch.doorbell_request = hr->dpdes; vcpu->arch.hfscr = hr->hfscr; vcpu->arch.dawr0 = hr->dawr0; vcpu->arch.dawrx0 = hr->dawrx0;
@@ -170,7 +170,13 @@ void kvmhv_restore_hv_return_state(struct kvm_vcpu *vcpu, {struct kvmppc_vcore *vc = vcpu->arch.vcore; - vc->dpdes = hr->dpdes; +/* +* This L2 vCPU might have received a doorbell while H_ENTER_NESTED was being handled. +* Make sure we preserve the doorbell if it was either: +* a) Sent after H_ENTER_NESTED was called on this vCPU (arch.doorbell_request would be 1) +* b) Doorbell was not handled and L2 exited for some other reason (hr->dpdes would be 1) +*/ + vcpu->arch.doorbell_request = vcpu->arch.doorbell_request | hr->dpdes; vcpu->arch.hfscr = hr->hfscr; vcpu->arch.purr = hr->purr; vcpu->arch.spurr = hr->spurr;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 458/817 KVM: PPC: Book3S HV: Avoid returning to nested hypervisor on pending doorbells
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gautam Menghani <[email protected]>
[ Upstream commit 26686db69917399fa30e3b3135360771e90f83ec ]
Commit 6398326b9ba1 ("KVM: PPC: Book3S HV P9: Stop using vc->dpdes") dropped the use of vcore->dpdes for msgsndp / SMT emulation. Prior to that commit, the below code at L1 level (see [1] for terminology) was responsible for setting vc->dpdes for the respective L2 vCPU:
if (!nested) {
kvmppc_core_prepare_to_enter(vcpu);
if (vcpu->arch.doorbell_request) {
vc->dpdes = 1;
smp_wmb();
vcpu->arch.doorbell_request = 0;
}L1 then sent vc->dpdes to L0 via kvmhv_save_hv_regs(), and while servicing H_ENTER_NESTED at L0, the below condition at L0 level made sure to abort and go back to L1 if vcpu->arch.doorbell_request = 1 so that L1 sets vc->dpdes as per above if condition:
} else if (vcpu->arch.pending_exceptions ||
vcpu->arch.doorbell_request ||
xive_interrupt_pending(vcpu)) {
vcpu->arch.ret = RESUME_HOST;
goto out;
}This worked fine since vcpu->arch.doorbell_request was used more like a flag and vc->dpdes was used to pass around the doorbell state. But after Commit 6398326b9ba1 ("KVM: PPC: Book3S HV P9: Stop using vc->dpdes"), vcpu->arch.doorbell_request is the only variable used to pass around doorbell state.
With the plumbing for handling doorbells for nested guests updated to use vcpu->arch.doorbell_request over vc->dpdes, the above "else if" stops doorbells from working correctly as L0 aborts execution of L2 and instead goes back to L1.
Remove vcpu->arch.doorbell_request from the above "else if" condition as it is no longer needed for L0 to correctly handle the doorbell status while running L2.
[1] Terminology
1. L0 : PowerNV linux running with HV privileges
2. L1 : Pseries KVM guest running on top of L0
2. L2 : Nested KVM guest running on top of L1
--- arch/powerpc/kvm/book3s_hv.c | 1 - 1 file changed, 1 deletion(-)
arch/powerpc/kvm/book3s_hv.c +0 -1
@@ -4915,7 +4915,6 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, lpcr &= ~LPCR_MER ; } }else if (vcpu->arch.pending_exceptions || - vcpu->arch.doorbell_request ||xive_interrupt_pending (vcpu)) { vcpu->arch.ret =RESUME_HOST ; goto out;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 459/817 powerpc/sstep: make emulate_vsx_load and emulate_vsx_store static
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Suchanek <[email protected]>
[ Upstream commit a26c4dbb3d9c1821cb0fc11cb2dbc32d5bf3463b ]
These functions are not used outside of sstep.c
--- arch/powerpc/include/asm/sstep.h | 5 ----- arch/powerpc/lib/sstep.c | 12 ++++-------- 2 files changed, 4 insertions(+), 13 deletions(-)
arch/powerpc/include/asm/sstep.h +0 -5
@@ -173,9 +173,4 @@ int emulate_step(struct pt_regs *regs, ppc_inst_t instr);*/ extern int emulate_loadstore (struct pt_regs *regs,struct instruction_op *op); -extern void emulate_vsx_load (struct instruction_op *op,union vsx_reg *reg, -const void *mem,bool cross_endian); -extern void emulate_vsx_store (struct instruction_op *op, -const union vsx_reg *reg,void *mem, -bool cross_endian);extern int emulate_dcbz (unsigned long ea,struct pt_regs *regs);
arch/powerpc/lib/sstep.c +4 -8
@@ -780,8 +780,8 @@ static nokprobe_inline int emulate_stq(struct pt_regs *regs, unsigned long ea,#endif /* __powerpc64 */ #ifdef CONFIG_VSX -void emulate_vsx_load (struct instruction_op *op,union vsx_reg *reg, -const void *mem,bool rev) +static nokprobe_inline void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, +const void *mem,bool rev) {int size, read_size;int i, j;
@@ -863,11 +863,9 @@ void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,break ; } } -EXPORT_SYMBOL_GPL (emulate_vsx_load); -NOKPROBE_SYMBOL (emulate_vsx_load); -void emulate_vsx_store (struct instruction_op *op,const union vsx_reg *reg, -void *mem,bool rev) +static nokprobe_inline void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg, +void *mem,bool rev) {int size, write_size;int i, j;
@@ -955,8 +953,6 @@ void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,break ; } } -EXPORT_SYMBOL_GPL (emulate_vsx_store); -NOKPROBE_SYMBOL (emulate_vsx_store); static nokprobe_inline int do_vsx_load(struct instruction_op *op, unsigned long ea, struct pt_regs *regs,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 460/817 RDMA/hns: Fix different dgids mapping to the same dip_idx
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Feng Fang <[email protected]>
[ Upstream commit faa62440a5772b40bb7d78bf9e29556a82ecf153 ]
DIP algorithm requires a one-to-one mapping between dgid and dip_idx. Currently a queue 'spare_idx' is used to store QPN of QPs that use DIP algorithm. For a new dgid, use a QPN from spare_idx as dip_idx. This method lacks a mechanism for deduplicating QPN, which may result in different dgids sharing the same dip_idx and break the one-to-one mapping requirement.
This patch replaces spare_idx with xarray and introduces a refcnt of a dip_idx to indicate the number of QPs that using this dip_idx.
The state machine for dip_idx management is implemented as:
* The entry at an index in xarray is empty -- This indicates that the corresponding dip_idx hasn't been created.
* The entry at an index in xarray is not empty but with 0 refcnt -- This indicates that the corresponding dip_idx has been created but not used as dip_idx yet.
* The entry at an index in xarray is not empty and with non-0 refcnt -- This indicates that the corresponding dip_idx is being used by refcnt number of DIP QPs.
--- drivers/infiniband/hw/hns/hns_roce_device.h | 11 +-- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 96 +++++++++++++++------ drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 +- drivers/infiniband/hw/hns/hns_roce_main.c | 2 - drivers/infiniband/hw/hns/hns_roce_qp.c | 8 +- 5 files changed, 75 insertions(+), 44 deletions(-)
drivers/infiniband/hw/hns/hns_roce_device.h +2 -9
@@ -489,12 +489,6 @@ struct hns_roce_bank {u32 next;/* Next ID to allocate. */ }; -struct hns_roce_idx_table { -u32 *spare_idx; -u32 head; -u32 tail; -}; -struct hns_roce_qp_table {struct hns_roce_hem_table qp_table;struct hns_roce_hem_table irrl_table;
@@ -503,7 +497,7 @@ struct hns_roce_qp_table {struct mutex scc_mutex;struct hns_roce_bank bank[HNS_ROCE_QP_BANK_NUM ];struct mutex bank_mutex; -struct hns_roce_idx_table idx_table; +struct xarray dip_xa; };struct hns_roce_cq_table {
@@ -658,6 +652,7 @@ struct hns_roce_qp {u8 tc_mode;u8 priority;spinlock_t flush_lock; +struct hns_roce_dip *dip; };struct hns_roce_ib_iboe {
@@ -984,8 +979,6 @@ struct hns_roce_dev {enum hns_roce_device_state state;struct list_head qp_list;/* list of all qps on this dev */ spinlock_t qp_list_lock;/* protect qp_list */ -struct list_head dip_list;/* list of all dest ips on this dev */ -spinlock_t dip_list_lock;/* protect dip_list */ struct list_head pgdir_list;struct mutex pgdir_mutex;
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +70 -26
154 lines not on this page · raw message
drivers/infiniband/hw/hns/hns_roce_hw_v2.h +1 -1
@@ -1348,7 +1348,7 @@ struct hns_roce_v2_priv {struct hns_roce_dip {u8 dgid[GID_LEN_V2 ];u32 dip_idx; -struct list_head node;/* all dips are on a list */ +u32 qp_cnt; };struct fmea_ram_ecc {
drivers/infiniband/hw/hns/hns_roce_main.c +0 -2
@@ -1135,8 +1135,6 @@ int hns_roce_init(struct hns_roce_dev *hr_dev)INIT_LIST_HEAD (&hr_dev->qp_list);spin_lock_init (&hr_dev->qp_list_lock); -INIT_LIST_HEAD (&hr_dev->dip_list); -spin_lock_init (&hr_dev->dip_list_lock); ret =hns_roce_register_device (hr_dev);if (ret)
drivers/infiniband/hw/hns/hns_roce_qp.c +2 -6
@@ -1573,14 +1573,10 @@ int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev)unsigned int reserved_from_bot;unsigned int i; - qp_table->idx_table.spare_idx =kcalloc (hr_dev->caps.num_qps, -sizeof (u32),GFP_KERNEL ); -if (!qp_table->idx_table.spare_idx) -return -ENOMEM ; -mutex_init (&qp_table->scc_mutex);mutex_init (&qp_table->bank_mutex);xa_init (&hr_dev->qp_table_xa); +xa_init (&qp_table->dip_xa); reserved_from_bot = hr_dev->caps.reserved_qps;
@@ -1605,7 +1601,7 @@ void hns_roce_cleanup_qp_table(struct hns_roce_dev *hr_dev)for (i =0 ; i <HNS_ROCE_QP_BANK_NUM ; i++)ida_destroy (&hr_dev->qp_table.bank[i].ida); +xa_destroy (&hr_dev->qp_table.dip_xa);mutex_destroy (&hr_dev->qp_table.bank_mutex);mutex_destroy (&hr_dev->qp_table.scc_mutex); -kfree (hr_dev->qp_table.idx_table.spare_idx); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 461/817 KVM: PPC: Book3S HV: Fix kmv -> kvm typo
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kajol Jain <[email protected]>
[ Upstream commit 590d2f9347f7974d7954400e5d937672fd844a8b ]
Fix typo in the following kvm function names from:
kmvhv_counters_tracepoint_regfunc -> kvmhv_counters_tracepoint_regfunc kmvhv_counters_tracepoint_unregfunc -> kvmhv_counters_tracepoint_unregfunc
--- arch/powerpc/include/asm/kvm_book3s_64.h | 4 ++-- arch/powerpc/kvm/book3s_hv.c | 4 ++-- arch/powerpc/kvm/trace_hv.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-)
arch/powerpc/include/asm/kvm_book3s_64.h +2 -2
@@ -684,8 +684,8 @@ int kvmhv_nestedv2_set_ptbl_entry(unsigned long lpid, u64 dw0, u64 dw1);int kvmhv_nestedv2_parse_output (struct kvm_vcpu *vcpu);int kvmhv_nestedv2_set_vpa (struct kvm_vcpu *vcpu,unsigned long vpa); -int kmvhv_counters_tracepoint_regfunc (void ); -void kmvhv_counters_tracepoint_unregfunc (void ); +int kvmhv_counters_tracepoint_regfunc (void ); +void kvmhv_counters_tracepoint_unregfunc (void );int kvmhv_get_l2_counters_status (void );void kvmhv_set_l2_counters_status (int cpu,bool status);
arch/powerpc/kvm/book3s_hv.c +2 -2
@@ -4148,7 +4148,7 @@ void kvmhv_set_l2_counters_status(int cpu, bool status)lppaca_of (cpu).l2_counters_enable =0 ; } -int kmvhv_counters_tracepoint_regfunc (void ) +int kvmhv_counters_tracepoint_regfunc (void ) {int cpu;
@@ -4158,7 +4158,7 @@ int kmvhv_counters_tracepoint_regfunc(void)return 0 ; } -void kmvhv_counters_tracepoint_unregfunc (void ) +void kvmhv_counters_tracepoint_unregfunc (void ) {int cpu;
arch/powerpc/kvm/trace_hv.h +1 -1
@@ -538,7 +538,7 @@ TRACE_EVENT_FN_COND(kvmppc_vcpu_stats,TP_printk ("VCPU %d: l1_to_l2_cs_time=%llu ns l2_to_l1_cs_time=%llu ns l2_runtime=%llu ns" , __entry->vcpu_id, __entry->l1_to_l2_cs, __entry->l2_to_l1_cs, __entry->l2_runtime), - kmvhv_counters_tracepoint_regfunc, kmvhv_counters_tracepoint_unregfunc + kvmhv_counters_tracepoint_regfunc, kvmhv_counters_tracepoint_unregfunc );#endif #endif /* _TRACE_KVM_HV_H */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 462/817 powerpc/kexec: Fix return of uninitialized variable
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Zekun <[email protected]>
[ Upstream commit 83b5a407fbb73e6965adfb4bd0a803724bf87f96 ]
of_property_read_u64() can fail and leave the variable uninitialized, which will then be used. Return error if reading the property failed.
--- arch/powerpc/kexec/file_load_64.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
arch/powerpc/kexec/file_load_64.c +7 -2
@@ -736,13 +736,18 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,if (dn) {u64 val; -of_property_read_u64 (dn,"opal-base-address" , &val); + ret =of_property_read_u64 (dn,"opal-base-address" , &val); +if (ret) + goto out; + ret =kexec_purgatory_get_set_symbol (image,"opal_base" , &val,sizeof (val), false);if (ret) goto out; -of_property_read_u64 (dn,"opal-entry-address" , &val); + ret =of_property_read_u64 (dn,"opal-entry-address" , &val); +if (ret) + goto out; ret =kexec_purgatory_get_set_symbol (image,"opal_entry" , &val,sizeof (val), false); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 463/817 fbdev: sh7760fb: Fix a possible memory leak in sh7760fb_alloc_mem()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhen Lei <[email protected]>
[ Upstream commit f89d17ae2ac42931be2a0153fecbf8533280c927 ]
When information such as info->screen_base is not ready, calling sh7760fb_free_mem() does not release memory correctly. Call dma_free_coherent() instead.
--- drivers/video/fbdev/sh7760fb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/video/fbdev/sh7760fb.c +1 -2
@@ -409,12 +409,11 @@ static int sh7760fb_alloc_mem(struct fb_info *info) vram =PAGE_SIZE ; fbmem =dma_alloc_coherent (info->device, vram, &par->fbdma,GFP_KERNEL ); -if (!fbmem)return -ENOMEM ;if ((par->fbdma &SH7760FB_DMA_MASK ) !=SH7760FB_DMA_MASK ) { -sh7760fb_free_mem (info); +dma_free_coherent (info->device, vram, fbmem, par->fbdma);dev_err (info->device,"kernel gave me memory at 0x%08lx, which is" "unusable for the LCDC\n" , (unsigned long )par->fbdma);return -ENOMEM ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 464/817 RDMA/mlx5: Move events notifier registration to be after device registration
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrisious Haddad <[email protected]>
[ Upstream commit ede132a5cf559f3ab35a4c28bac4f4a6c20334d8 ]
Move pkey change work initialization and cleanup from device resources stage to notifier stage, since this is the stage which handles this work events.
Fix a race between the device deregistration and pkey change work by moving MLX5_IB_STAGE_DEVICE_NOTIFIER to be after MLX5_IB_STAGE_IB_REG in order to ensure that the notifier is deregistered before the device during cleanup. Which ensures there are no works that are being executed after the device has already unregistered which can cause the panic below.
BUG: kernel NULL pointer dereference, address: 0000000000000000 PGD 0 P4D 0 Oops: 0000 [#1] PREEMPT SMP PTI CPU: 1 PID: 630071 Comm: kworker/1:2 Kdump: loaded Tainted: G W OE --------- --- 5.14.0-162.6.1.el9_1.x86_64 #1 Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090008 02/27/2023 Workqueue: events pkey_change_handler [mlx5_ib] RIP: 0010:setup_qp+0x38/0x1f0 [mlx5_ib] Code: ee 41 54 45 31 e4 55 89 f5 53 48 89 fb 48 83 ec 20 8b 77 08 65 48 8b 04 25 28 00 00 00 48 89 44 24 18 48 8b 07 48 8d 4c 24 16 <4c> 8b 38 49 8b 87 80 0b 00 00 4c 89 ff 48 8b 80 08 05 00 00 8b 40 RSP: 0018:ffffbcc54068be20 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff954054494128 RCX: ffffbcc54068be36 RDX: ffff954004934000 RSI: 0000000000000001 RDI: ffff954054494128 RBP: 0000000000000023 R08: ffff954001be2c20 R09: 0000000000000001 R10: ffff954001be2c20 R11: ffff9540260133c0 R12: 0000000000000000 R13: 0000000000000023 R14: 0000000000000000 R15: ffff9540ffcb0905 FS: 0000000000000000(0000) GS:ffff9540ffc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000010625c001 CR4: 00000000003706e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: mlx5_ib_gsi_pkey_change+0x20/0x40 [mlx5_ib] process_one_work+0x1e8/0x3c0 worker_thread+0x50/0x3b0 ? rescuer_thread+0x380/0x380 kthread+0x149/0x170 ? set_kthread_struct+0x50/0x50 ret_from_fork+0x22/0x30 Modules linked in: rdma_ucm(OE) rdma_cm(OE) iw_cm(OE) ib_ipoib(OE) ib_cm(OE) ib_umad(OE) mlx5_ib(OE) mlx5_fwctl(OE) fwctl(OE) ib_uverbs(OE) mlx5_core(OE) mlxdevm(OE) ib_core(OE) mlx_compat(OE) psample mlxfw(OE) tls knem(OE) netconsole nfsv3 nfs_acl nfs lockd grace fscache netfs qrtr rfkill sunrpc intel_rapl_msr intel_rapl_common rapl hv_balloon hv_utils i2c_piix4 pcspkr joydev fuse ext4 mbcache jbd2 sr_mod sd_mod cdrom t10_pi sg ata_generic pci_hyperv pci_hyperv_intf hyperv_drm drm_shmem_helper drm_kms_helper hv_storvsc syscopyarea hv_netvsc sysfillrect sysimgblt hid_hyperv fb_sys_fops scsi_transport_fc hyperv_keyboard drm ata_piix crct10dif_pclmul crc32_pclmul crc32c_intel libata ghash_clmulni_intel hv_vmbus serio_raw [last unloaded: ib_core] CR2: 0000000000000000 ---[ end trace f6f8be4eae12f7bc ]---
--- drivers/infiniband/hw/mlx5/main.c | 40 +++++++++++++--------------- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +- 2 files changed, 20 insertions(+), 22 deletions(-)
drivers/infiniband/hw/mlx5/main.c +19 -21
@@ -2968,7 +2968,6 @@ int mlx5_ib_dev_res_srq_init(struct mlx5_ib_dev *dev)static int mlx5_ib_dev_res_init (struct mlx5_ib_dev *dev) {struct mlx5_ib_resources *devr = &dev->devr; -int port;int ret;if (!MLX5_CAP_GEN (dev->mdev, xrc))
@@ -2984,10 +2983,6 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)return ret; } -for (port =0 ; port <ARRAY_SIZE (devr->ports); ++port) -INIT_WORK (&devr->ports[port].pkey_change_work, - pkey_change_handler); -mutex_init (&devr->cq_lock);mutex_init (&devr->srq_lock);
@@ -2997,16 +2992,6 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)static void mlx5_ib_dev_res_cleanup (struct mlx5_ib_dev *dev) {struct mlx5_ib_resources *devr = &dev->devr; -int port; - -/* -* Make sure no change P_Key work items are still executing. -* -* At this stage, the mlx5_ib_event should be unregistered -* and it ensures that no new works are added. -*/ -for (port =0 ; port <ARRAY_SIZE (devr->ports); ++port) -cancel_work_sync (&devr->ports[port].pkey_change_work);/* After s0/s1 init, they are not unset during the device lifetime. */ if (devr->s1) {
@@ -4279,6 +4264,13 @@ static void mlx5_ib_stage_delay_drop_cleanup(struct mlx5_ib_dev *dev)static int mlx5_ib_stage_dev_notifier_init (struct mlx5_ib_dev *dev) { +struct mlx5_ib_resources *devr = &dev->devr; +int port; + +for (port =0 ; port <ARRAY_SIZE (devr->ports); ++port) +INIT_WORK (&devr->ports[port].pkey_change_work, + pkey_change_handler); + dev->mdev_events.notifier_call = mlx5_ib_event;mlx5_notifier_register (dev->mdev, &dev->mdev_events);
@@ -4289,8 +4281,14 @@ static int mlx5_ib_stage_dev_notifier_init(struct mlx5_ib_dev *dev)static void mlx5_ib_stage_dev_notifier_cleanup (struct mlx5_ib_dev *dev) { +struct mlx5_ib_resources *devr = &dev->devr; +int port; +mlx5r_macsec_event_unregister (dev);mlx5_notifier_unregister (dev->mdev, &dev->mdev_events); + +for (port =0 ; port <ARRAY_SIZE (devr->ports); ++port) +cancel_work_sync (&devr->ports[port].pkey_change_work); } void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
@@ -4364,9 +4362,6 @@ static const struct mlx5_ib_profile pf_profile = {STAGE_CREATE (MLX5_IB_STAGE_DEVICE_RESOURCES , mlx5_ib_dev_res_init, mlx5_ib_dev_res_cleanup), -STAGE_CREATE (MLX5_IB_STAGE_DEVICE_NOTIFIER , - mlx5_ib_stage_dev_notifier_init, - mlx5_ib_stage_dev_notifier_cleanup),STAGE_CREATE (MLX5_IB_STAGE_ODP , mlx5_ib_odp_init_one, mlx5_ib_odp_cleanup_one),
@@ -4391,6 +4386,9 @@ static const struct mlx5_ib_profile pf_profile = {STAGE_CREATE (MLX5_IB_STAGE_IB_REG , mlx5_ib_stage_ib_reg_init, mlx5_ib_stage_ib_reg_cleanup), +STAGE_CREATE (MLX5_IB_STAGE_DEVICE_NOTIFIER , + mlx5_ib_stage_dev_notifier_init, + mlx5_ib_stage_dev_notifier_cleanup),STAGE_CREATE (MLX5_IB_STAGE_POST_IB_REG_UMR , mlx5_ib_stage_post_ib_reg_umr_init, NULL),
@@ -4427,9 +4425,6 @@ const struct mlx5_ib_profile raw_eth_profile = {STAGE_CREATE (MLX5_IB_STAGE_DEVICE_RESOURCES , mlx5_ib_dev_res_init, mlx5_ib_dev_res_cleanup), -STAGE_CREATE (MLX5_IB_STAGE_DEVICE_NOTIFIER , - mlx5_ib_stage_dev_notifier_init, - mlx5_ib_stage_dev_notifier_cleanup),STAGE_CREATE (MLX5_IB_STAGE_COUNTERS , mlx5_ib_counters_init, mlx5_ib_counters_cleanup),
@@ -4451,6 +4446,9 @@ const struct mlx5_ib_profile raw_eth_profile = {STAGE_CREATE (MLX5_IB_STAGE_IB_REG , mlx5_ib_stage_ib_reg_init, mlx5_ib_stage_ib_reg_cleanup), +STAGE_CREATE (MLX5_IB_STAGE_DEVICE_NOTIFIER , + mlx5_ib_stage_dev_notifier_init, + mlx5_ib_stage_dev_notifier_cleanup),STAGE_CREATE (MLX5_IB_STAGE_POST_IB_REG_UMR , mlx5_ib_stage_post_ib_reg_umr_init, NULL),
drivers/infiniband/hw/mlx5/mlx5_ib.h +1 -1
@@ -971,7 +971,6 @@ enum mlx5_ib_stages {MLX5_IB_STAGE_QP ,MLX5_IB_STAGE_SRQ ,MLX5_IB_STAGE_DEVICE_RESOURCES , -MLX5_IB_STAGE_DEVICE_NOTIFIER ,MLX5_IB_STAGE_ODP ,MLX5_IB_STAGE_COUNTERS , MLX5_IB_STAGE_CONG_DEBUGFS,
@@ -980,6 +979,7 @@ enum mlx5_ib_stages {MLX5_IB_STAGE_PRE_IB_REG_UMR ,MLX5_IB_STAGE_WHITELIST_UID ,MLX5_IB_STAGE_IB_REG , +MLX5_IB_STAGE_DEVICE_NOTIFIER ,MLX5_IB_STAGE_POST_IB_REG_UMR ,MLX5_IB_STAGE_DELAY_DROP , MLX5_IB_STAGE_RESTRACK,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 465/817 clk: clk-apple-nco: Add NULL check in applnco_probe
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Han <[email protected]>
[ Upstream commit 969c765e2b508cca9099d246c010a1e48dcfd089 ]
Add NULL check in applnco_probe, to handle kernel NULL pointer dereference error.
--- drivers/clk/clk-apple-nco.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/clk/clk-apple-nco.c +3 -0
@@ -297,6 +297,9 @@ static int applnco_probe(struct platform_device *pdev)memset (&init,0 ,sizeof (init)); init.name =devm_kasprintf (&pdev->dev,GFP_KERNEL ,"%s-%d" , np->name, i); +if (!init.name) +return -ENOMEM ; + init.ops = &applnco_ops; init.parent_data = &pdata; init.num_parents =1 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 466/817 clk: ralink: mtmips: fix clock plan for Ralink SoC RT3883
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergio Paracuellos <[email protected]>
[ Upstream commit 33239152305567b3e9bf052f71fd4baecd626341 ]
Clock plan for Ralink SoC RT3883 needs an extra 'periph' clock to properly set some peripherals that has this clock as their parent. When this driver was mainlined we could not find any active users of this SoC so we cannot perform any real tests for it. Now, one user of a Belkin f9k1109 version 1 device which uses this SoC appear and reported some issues in openWRT:
- https://github.com/openwrt/openwrt/issues/16054
The peripherals that are wrong are 'uart', 'i2c', 'i2s' and 'uartlite' which has a not defined 'periph' clock as parent. Hence, introduce it to have a properly working clock plan for this SoC.
--- drivers/clk/ralink/clk-mtmips.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/clk/ralink/clk-mtmips.c +7 -2
@@ -267,6 +267,11 @@ static struct mtmips_clk_fixed rt305x_fixed_clocks[] = { CLK_FIXED("xtal", NULL, 40000000) }; +static struct mtmips_clk_fixed rt3883_fixed_clocks[] = { +CLK_FIXED ("xtal" ,NULL ,40000000 ), +CLK_FIXED ("periph" ,"xtal" ,40000000 ) +}; +static struct mtmips_clk_fixed rt3352_fixed_clocks[] = {CLK_FIXED ("periph" ,"xtal" ,40000000 ) };
@@ -779,8 +784,8 @@ static const struct mtmips_clk_data rt3352_clk_data = {static const struct mtmips_clk_data rt3883_clk_data = { .clk_base = rt3883_clks_base, .num_clk_base =ARRAY_SIZE (rt3883_clks_base), - .clk_fixed = rt305x_fixed_clocks, - .num_clk_fixed =ARRAY_SIZE (rt305x_fixed_clocks), + .clk_fixed = rt3883_fixed_clocks, + .num_clk_fixed =ARRAY_SIZE (rt3883_fixed_clocks), .clk_factor =NULL , .num_clk_factor =0 , .clk_periph = rt5350_pherip_clks,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 467/817 clk: ralink: mtmips: fix clocks probe order in oldest ralink SoCs
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergio Paracuellos <[email protected]>
[ Upstream commit d34db686a3d74bd564bfce2ada15011c556269fc ]
Base clocks are the first in being probed and are real dependencies of the rest of fixed, factor and peripheral clocks. For old ralink SoCs RT2880, RT305x and RT3883 'xtal' must be defined first since in any other case, when fixed clocks are probed they are delayed until 'xtal' is probed so the following warning appears:
WARNING: CPU: 0 PID: 0 at drivers/clk/ralink/clk-mtmips.c:499 rt3883_bus_recalc_rate+0x98/0x138 Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 6.6.43 #0 Stack : 805e58d0 00000000 00000004 8004f950 00000000 00000004 00000000 00000000 80669c54 80830000 80700000 805ae570 80670068 00000001 80669bf8 00000000 00000000 00000000 805ae570 80669b38 00000020 804db7dc 00000000 00000000 203a6d6d 80669b78 80669e48 70617773 00000000 805ae570 00000000 00000009 00000000 00000001 00000004 00000001 00000000 00000000 83fe43b0 00000000 ... Call Trace: [<800065d0>] show_stack+0x64/0xf4 [<804bca14>] dump_stack_lvl+0x38/0x60 [<800218ac>] __warn+0x94/0xe4 [<8002195c>] warn_slowpath_fmt+0x60/0x94 [<80259ff8>] rt3883_bus_recalc_rate+0x98/0x138 [<80254530>] __clk_register+0x568/0x688 [<80254838>] of_clk_hw_register+0x18/0x2c [<8070b910>] rt2880_clk_of_clk_init_driver+0x18c/0x594 [<8070b628>] of_clk_init+0x1c0/0x23c [<806fc448>] plat_time_init+0x58/0x18c [<806fdaf0>] time_init+0x10/0x6c [<806f9bc4>] start_kernel+0x458/0x67c ---[ end trace 0000000000000000 ]---
When this driver was mainlined we could not find any active users of old ralink SoCs so we cannot perform any real tests for them. Now, one user of a Belkin f9k1109 version 1 device which uses RT3883 SoC appeared and reported some issues in openWRT:
- https://github.com/openwrt/openwrt/issues/16054
Thus, define a 'rt2880_xtal_recalc_rate()' just returning the expected frequency 40Mhz and use it along the old ralink SoCs to have a correct boot trace with no warnings and a working clock plan from the beggining.
--- drivers/clk/ralink/clk-mtmips.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
drivers/clk/ralink/clk-mtmips.c +13 -8
@@ -263,10 +263,6 @@ static int mtmips_register_pherip_clocks(struct device_node *np, .rate = _rate \ } -static struct mtmips_clk_fixed rt305x_fixed_clocks[] = { -CLK_FIXED ("xtal" ,NULL ,40000000 ) -}; -static struct mtmips_clk_fixed rt3883_fixed_clocks[] = {CLK_FIXED ("xtal" ,NULL ,40000000 ),CLK_FIXED ("periph" ,"xtal" ,40000000 )
@@ -371,6 +367,12 @@ static inline struct mtmips_clk *to_mtmips_clk(struct clk_hw *hw) return container_of(hw, struct mtmips_clk, hw); } +static unsigned long rt2880_xtal_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +return 40000000 ; +} +static unsigned long rt5350_xtal_recalc_rate (struct clk_hw *hw,unsigned long parent_rate) {
@@ -682,10 +684,12 @@ static unsigned long mt76x8_cpu_recalc_rate(struct clk_hw *hw, }static struct mtmips_clk rt2880_clks_base[] = { + {CLK_BASE ("xtal" ,NULL , rt2880_xtal_recalc_rate) }, {CLK_BASE ("cpu" ,"xtal" , rt2880_cpu_recalc_rate) } };static struct mtmips_clk rt305x_clks_base[] = { + {CLK_BASE ("xtal" ,NULL , rt2880_xtal_recalc_rate) }, {CLK_BASE ("cpu" ,"xtal" , rt305x_cpu_recalc_rate) } };
@@ -695,6 +699,7 @@ static struct mtmips_clk rt3352_clks_base[] = { };static struct mtmips_clk rt3883_clks_base[] = { + {CLK_BASE ("xtal" ,NULL , rt2880_xtal_recalc_rate) }, {CLK_BASE ("cpu" ,"xtal" , rt3883_cpu_recalc_rate) }, {CLK_BASE ("bus" ,"cpu" , rt3883_bus_recalc_rate) } };
@@ -751,8 +756,8 @@ static int mtmips_register_clocks(struct device_node *np,static const struct mtmips_clk_data rt2880_clk_data = { .clk_base = rt2880_clks_base, .num_clk_base =ARRAY_SIZE (rt2880_clks_base), - .clk_fixed = rt305x_fixed_clocks, - .num_clk_fixed =ARRAY_SIZE (rt305x_fixed_clocks), + .clk_fixed =NULL , + .num_clk_fixed =0 , .clk_factor = rt2880_factor_clocks, .num_clk_factor =ARRAY_SIZE (rt2880_factor_clocks), .clk_periph = rt2880_pherip_clks,
@@ -762,8 +767,8 @@ static const struct mtmips_clk_data rt2880_clk_data = {static const struct mtmips_clk_data rt305x_clk_data = { .clk_base = rt305x_clks_base, .num_clk_base =ARRAY_SIZE (rt305x_clks_base), - .clk_fixed = rt305x_fixed_clocks, - .num_clk_fixed =ARRAY_SIZE (rt305x_fixed_clocks), + .clk_fixed =NULL , + .num_clk_fixed =0 , .clk_factor = rt305x_factor_clocks, .num_clk_factor =ARRAY_SIZE (rt305x_factor_clocks), .clk_periph = rt305x_pherip_clks,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 468/817 clk: en7523: remove REG_PCIE*_{MEM,MEM_MASK} configuration
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit c31d1cdd7bff1d2c13d435bb9d0c76bfaa332097 ]
REG_PCIE*_MEM and REG_PCIE*_MEM_MASK regs (PBUS_CSR memory region) are not part of the scu block on the EN7581 SoC and they are used to select the PCIE ports on the PBUS, so remove this configuration from the clock driver and set these registers in the PCIE host driver instead.
This patch does not introduce any backward incompatibility since the dts for EN7581 SoC is not upstream yet.
Stable-dep-of: f98eded9e9ab ("clk: en7523: fix estimation of fixed rate for EN7581")
--- drivers/clk/clk-en7523.c | 18 ------------------ 1 file changed, 18 deletions(-)
drivers/clk/clk-en7523.c +0 -18
@@ -31,12 +31,6 @@#define REG_RESET_CONTROL_PCIE1 BIT(27)#define REG_RESET_CONTROL_PCIE2 BIT(26)/* EN7581 */ -#define REG_PCIE0_MEM 0x00 -#define REG_PCIE0_MEM_MASK 0x04 -#define REG_PCIE1_MEM 0x08 -#define REG_PCIE1_MEM_MASK 0x0c -#define REG_PCIE2_MEM 0x10 -#define REG_PCIE2_MEM_MASK 0x14#define REG_NP_SCU_PCIC 0x88#define REG_NP_SCU_SSTR 0x9c#define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13)
@@ -415,26 +409,14 @@ static void en7581_pci_disable(struct clk_hw *hw)static int en7581_clk_hw_init (struct platform_device *pdev,void __iomem *np_base) { -void __iomem *pb_base;u32 val; - pb_base =devm_platform_ioremap_resource (pdev,3 ); -if (IS_ERR (pb_base)) -return PTR_ERR (pb_base); - val =readl (np_base +REG_NP_SCU_SSTR ); val &= ~(REG_PCIE_XSI0_SEL_MASK |REG_PCIE_XSI1_SEL_MASK );writel (val, np_base +REG_NP_SCU_SSTR ); val =readl (np_base +REG_NP_SCU_PCIC );writel (val |3 , np_base +REG_NP_SCU_PCIC ); -writel (0x20000000 , pb_base +REG_PCIE0_MEM ); -writel (0xfc000000 , pb_base +REG_PCIE0_MEM_MASK ); -writel (0x24000000 , pb_base +REG_PCIE1_MEM ); -writel (0xfc000000 , pb_base +REG_PCIE1_MEM_MASK ); -writel (0x28000000 , pb_base +REG_PCIE2_MEM ); -writel (0xfc000000 , pb_base +REG_PCIE2_MEM_MASK ); -return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 469/817 clk: en7523: move clock_register in hw_init callback
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit b8bdfc666bc5f58caf46e67b615132fccbaca3d4 ]
Move en7523_register_clocks routine in hw_init callback. Introduce en7523_clk_hw_init callback for EN7523 SoC.
This is a preliminary patch to differentiate IO mapped region between EN7523 and EN7581 SoCs in order to access chip-scu IO region <0x1fa20000 0x384> on EN7581 SoC as syscon device since it contains miscellaneous registers needed by multiple devices (clock, pinctrl ..).
Stable-dep-of: f98eded9e9ab ("clk: en7523: fix estimation of fixed rate for EN7581")
--- drivers/clk/clk-en7523.c | 82 ++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 32 deletions(-)
drivers/clk/clk-en7523.c +50 -32
@@ -78,7 +78,8 @@ struct en_clk_soc_data {const u16 *idx_map;u16 idx_map_nr; } reset; -int (*hw_init)(struct platform_device *pdev,void __iomem *np_base); +int (*hw_init)(struct platform_device *pdev, +struct clk_hw_onecell_data *clk_data); };static const u32 gsw_base[] = {400000000 ,500000000 };
@@ -406,20 +407,6 @@ static void en7581_pci_disable(struct clk_hw *hw)usleep_range (1000 ,2000 ); } -static int en7581_clk_hw_init (struct platform_device *pdev, -void __iomem *np_base) -{ -u32 val; - - val =readl (np_base +REG_NP_SCU_SSTR ); - val &= ~(REG_PCIE_XSI0_SEL_MASK |REG_PCIE_XSI1_SEL_MASK ); -writel (val, np_base +REG_NP_SCU_SSTR ); - val =readl (np_base +REG_NP_SCU_PCIC ); -writel (val |3 , np_base +REG_NP_SCU_PCIC ); - -return 0 ; -} -static void en7523_register_clocks (struct device *dev,struct clk_hw_onecell_data *clk_data,void __iomem *base,void __iomem *np_base) {
@@ -449,6 +436,49 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat clk_data->num =EN7523_NUM_CLOCKS ; } +static int en7523_clk_hw_init (struct platform_device *pdev, +struct clk_hw_onecell_data *clk_data) +{ +void __iomem *base, *np_base; + + base =devm_platform_ioremap_resource (pdev,0 ); +if (IS_ERR (base)) +return PTR_ERR (base); + + np_base =devm_platform_ioremap_resource (pdev,1 ); +if (IS_ERR (np_base)) +return PTR_ERR (np_base); + +en7523_register_clocks (&pdev->dev, clk_data, base, np_base); + +return 0 ; +} + +static int en7581_clk_hw_init (struct platform_device *pdev, +struct clk_hw_onecell_data *clk_data) +{ +void __iomem *base, *np_base; +u32 val; + + base =devm_platform_ioremap_resource (pdev,0 ); +if (IS_ERR (base)) +return PTR_ERR (base); + + np_base =devm_platform_ioremap_resource (pdev,1 ); +if (IS_ERR (np_base)) +return PTR_ERR (np_base); + +en7523_register_clocks (&pdev->dev, clk_data, base, np_base); + + val =readl (np_base +REG_NP_SCU_SSTR ); + val &= ~(REG_PCIE_XSI0_SEL_MASK |REG_PCIE_XSI1_SEL_MASK ); +writel (val, np_base +REG_NP_SCU_SSTR ); + val =readl (np_base +REG_NP_SCU_PCIC ); +writel (val |3 , np_base +REG_NP_SCU_PCIC ); + +return 0 ; +} +static int en7523_reset_update (struct reset_controller_dev *rcdev,unsigned long id,bool assert) {
@@ -543,31 +573,18 @@ static int en7523_clk_probe(struct platform_device *pdev)struct device_node *node = pdev->dev.of_node;const struct en_clk_soc_data *soc_data;struct clk_hw_onecell_data *clk_data; -void __iomem *base, *np_base;int r; - base =devm_platform_ioremap_resource (pdev,0 ); -if (IS_ERR (base)) -return PTR_ERR (base); - - np_base =devm_platform_ioremap_resource (pdev,1 ); -if (IS_ERR (np_base)) -return PTR_ERR (np_base); - - soc_data =device_get_match_data (&pdev->dev); -if (soc_data->hw_init) { - r = soc_data->hw_init (pdev, np_base); -if (r) -return r; - } - clk_data =devm_kzalloc (&pdev->dev,struct_size (clk_data, hws,EN7523_NUM_CLOCKS ),GFP_KERNEL );if (!clk_data)return -ENOMEM ; -en7523_register_clocks (&pdev->dev, clk_data, base, np_base); + soc_data =device_get_match_data (&pdev->dev); + r = soc_data->hw_init (pdev, clk_data); +if (r) +return r; r =of_clk_add_hw_provider (node, of_clk_hw_onecell_get, clk_data);if (r)
@@ -590,6 +607,7 @@ static const struct en_clk_soc_data en7523_data = { .prepare = en7523_pci_prepare, .unprepare = en7523_pci_unprepare, }, + .hw_init = en7523_clk_hw_init, }; static const struct en_clk_soc_data en7581_data = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 470/817 clk: en7523: introduce chip_scu regmap
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit f72fc22038dd544fa4d39c06e8c81c09c0041ed4 ]
Introduce chip_scu regmap pointer since EN7581 SoC will access chip-scu memory area via a syscon node. Remove first memory region mapping for EN7581 SoC. This patch does not introduce any backward incompatibility since the dts for EN7581 SoC is not upstream yet.
Stable-dep-of: f98eded9e9ab ("clk: en7523: fix estimation of fixed rate for EN7581")
--- drivers/clk/clk-en7523.c | 81 ++++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 20 deletions(-)
drivers/clk/clk-en7523.c +61 -20
@@ -3,8 +3,10 @@#include <linux/delay.h> #include <linux/clk-provider.h> #include <linux/io.h> +#include <linux/mfd/syscon.h> #include <linux/platform_device.h> #include <linux/property.h> +#include <linux/regmap.h> #include <linux/reset-controller.h> #include <dt-bindings/clock/en7523-clk.h> #include <dt-bindings/reset/airoha,en7581-reset.h>
@@ -247,15 +249,11 @@ static const u16 en7581_rst_map[] = { [EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31, }; -static unsigned int en7523_get_base_rate (void __iomem *base,unsigned int i) +static u32 en7523_get_base_rate (const struct en_clk_desc *desc,u32 val) { -const struct en_clk_desc *desc = &en7523_base_clks[i]; -u32 val; -if (!desc->base_bits)return desc->base_value; - val =readl (base + desc->base_reg); val >>= desc->base_shift; val &= (1 << desc->base_bits) -1 ;
@@ -265,16 +263,11 @@ static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i)return desc->base_values[val]; } -static u32 en7523_get_div (void __iomem *base,int i) +static u32 en7523_get_div (const struct en_clk_desc *desc,u32 val) { -const struct en_clk_desc *desc = &en7523_base_clks[i]; -u32 reg, val; -if (!desc->div_bits)return 1 ; - reg = desc->div_reg ? desc->div_reg : desc->base_reg; - val =readl (base + reg); val >>= desc->div_shift; val &= (1 << desc->div_bits) -1 ;
@@ -416,9 +409,12 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_datfor (i =0 ; i <ARRAY_SIZE (en7523_base_clks); i++) {const struct en_clk_desc *desc = &en7523_base_clks[i]; +u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg; +u32 val =readl (base + desc->base_reg); - rate =en7523_get_base_rate (base, i); - rate /=en7523_get_div (base, i); + rate =en7523_get_base_rate (desc, val); + val =readl (base + reg); + rate /=en7523_get_div (desc, val); hw =clk_hw_register_fixed_rate (dev, desc->name,NULL ,0 , rate);if (IS_ERR (hw)) {
@@ -454,21 +450,66 @@ static int en7523_clk_hw_init(struct platform_device *pdev,return 0 ; } +static void en7581_register_clocks (struct device *dev,struct clk_hw_onecell_data *clk_data, +struct regmap *map,void __iomem *base) +{ +struct clk_hw *hw; +u32 rate; +int i; + +for (i =0 ; i <ARRAY_SIZE (en7523_base_clks); i++) { +const struct en_clk_desc *desc = &en7523_base_clks[i]; +u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg; +int err; + + err =regmap_read (map, desc->base_reg, &val); +if (err) { +pr_err ("Failed reading fixed clk rate %s: %d\n" , + desc->name, err); +continue ; + } + rate =en7523_get_base_rate (desc, val); + + err =regmap_read (map, reg, &val); +if (err) { +pr_err ("Failed reading fixed clk div %s: %d\n" , + desc->name, err); +continue ; + } + rate /=en7523_get_div (desc, val); + + hw =clk_hw_register_fixed_rate (dev, desc->name,NULL ,0 , rate); +if (IS_ERR (hw)) { +pr_err ("Failed to register clk %s: %ld\n" , + desc->name,PTR_ERR (hw)); +continue ; + } + + clk_data->hws[desc->id] = hw; + } + + hw =en7523_register_pcie_clk (dev, base); + clk_data->hws[EN7523_CLK_PCIE ] = hw; + + clk_data->num =EN7523_NUM_CLOCKS ; +} +static int en7581_clk_hw_init (struct platform_device *pdev,struct clk_hw_onecell_data *clk_data) { -void __iomem *base, *np_base; +void __iomem *np_base; +struct regmap *map;u32 val; - base =devm_platform_ioremap_resource (pdev,0 ); -if (IS_ERR (base)) -return PTR_ERR (base); + map =syscon_regmap_lookup_by_compatible ("airoha,en7581-chip-scu" ); +if (IS_ERR (map)) +return PTR_ERR (map); - np_base =devm_platform_ioremap_resource (pdev,1 ); + np_base =devm_platform_ioremap_resource (pdev,0 );if (IS_ERR (np_base))return PTR_ERR (np_base); -en7523_register_clocks (&pdev->dev, clk_data, base, np_base); +en7581_register_clocks (&pdev->dev, clk_data, map, np_base); val =readl (np_base +REG_NP_SCU_SSTR ); val &= ~(REG_PCIE_XSI0_SEL_MASK |REG_PCIE_XSI1_SEL_MASK );
@@ -545,7 +586,7 @@ static int en7523_reset_register(struct platform_device *pdev,if (!soc_data->reset.idx_map_nr)return 0 ; - base =devm_platform_ioremap_resource (pdev,2 ); + base =devm_platform_ioremap_resource (pdev,1 );if (IS_ERR (base))return PTR_ERR (base);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 471/817 clk: en7523: fix estimation of fixed rate for EN7581
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit f98eded9e9ab048c88ff59c5523e703a6ced5523 ]
Introduce en7581_base_clks array in order to define per-SoC fixed-rate clock parameters and fix wrong parameters for emi, npu and crypto EN7581 clocks
--- drivers/clk/clk-en7523.c | 105 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-)
drivers/clk/clk-en7523.c +103 -2
@@ -37,6 +37,7 @@#define REG_NP_SCU_SSTR 0x9c#define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13)#define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11) +#define REG_CRYPTO_CLKSRC2 0x20c#define REG_RST_CTRL2 0x00#define REG_RST_CTRL1 0x04
@@ -89,6 +90,10 @@ static const u32 emi_base[] = { 333000000, 400000000 };static const u32 bus_base[] = {500000000 ,540000000 };static const u32 slic_base[] = {100000000 ,3125000 };static const u32 npu_base[] = {333000000 ,400000000 ,500000000 }; +/* EN7581 */ +static const u32 emi7581_base[] = {540000000 ,480000000 ,400000000 ,300000000 }; +static const u32 npu7581_base[] = {800000000 ,750000000 ,720000000 ,600000000 }; +static const u32 crypto_base[] = {540000000 ,480000000 };static const struct en_clk_desc en7523_base_clks[] = { {
@@ -186,6 +191,102 @@ static const struct en_clk_desc en7523_base_clks[] = { } }; +static const struct en_clk_desc en7581_base_clks[] = { + { + .id =EN7523_CLK_GSW , + .name ="gsw" , + + .base_reg =REG_GSW_CLK_DIV_SEL , + .base_bits =1 , + .base_shift =8 , + .base_values = gsw_base, + .n_base_values =ARRAY_SIZE (gsw_base), + + .div_bits =3 , + .div_shift =0 , + .div_step =1 , + .div_offset =1 , + }, { + .id =EN7523_CLK_EMI , + .name ="emi" , + + .base_reg =REG_EMI_CLK_DIV_SEL , + .base_bits =2 , + .base_shift =8 , + .base_values = emi7581_base, + .n_base_values =ARRAY_SIZE (emi7581_base), + + .div_bits =3 , + .div_shift =0 , + .div_step =1 , + .div_offset =1 , + }, { + .id =EN7523_CLK_BUS , + .name ="bus" , + + .base_reg =REG_BUS_CLK_DIV_SEL , + .base_bits =1 , + .base_shift =8 , + .base_values = bus_base, + .n_base_values =ARRAY_SIZE (bus_base), + + .div_bits =3 , + .div_shift =0 , + .div_step =1 , + .div_offset =1 , + }, { + .id =EN7523_CLK_SLIC , + .name ="slic" , + + .base_reg =REG_SPI_CLK_FREQ_SEL , + .base_bits =1 , + .base_shift =0 , + .base_values = slic_base, + .n_base_values =ARRAY_SIZE (slic_base), + + .div_reg =REG_SPI_CLK_DIV_SEL , + .div_bits =5 , + .div_shift =24 , + .div_val0 =20 , + .div_step =2 , + }, { + .id =EN7523_CLK_SPI , + .name ="spi" , + + .base_reg =REG_SPI_CLK_DIV_SEL , + + .base_value =400000000 , + + .div_bits =5 , + .div_shift =8 , + .div_val0 =40 , + .div_step =2 , + }, { + .id =EN7523_CLK_NPU , + .name ="npu" , + + .base_reg =REG_NPU_CLK_DIV_SEL , + .base_bits =2 , + .base_shift =8 , + .base_values = npu7581_base, + .n_base_values =ARRAY_SIZE (npu7581_base), + + .div_bits =3 , + .div_shift =0 , + .div_step =1 , + .div_offset =1 , + }, { + .id =EN7523_CLK_CRYPTO , + .name ="crypto" , + + .base_reg =REG_CRYPTO_CLKSRC2 , + .base_bits =1 , + .base_shift =0 , + .base_values = crypto_base, + .n_base_values =ARRAY_SIZE (crypto_base), + } +}; +static const u16 en7581_rst_ofs[] = {REG_RST_CTRL2 ,REG_RST_CTRL1 ,
@@ -457,8 +558,8 @@ static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_datu32 rate;int i; -for (i =0 ; i <ARRAY_SIZE (en7523_base_clks); i++) { -const struct en_clk_desc *desc = &en7523_base_clks[i]; +for (i =0 ; i <ARRAY_SIZE (en7581_base_clks); i++) { +const struct en_clk_desc *desc = &en7581_base_clks[i];u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg;int err;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 472/817 dt-bindings: clock: axi-clkgen: include AXI clk
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sa <[email protected]>
[ Upstream commit 47f3f5a82a31527e027929c5cec3dd1ef5ef30f5 ]
In order to access the registers of the HW, we need to make sure that the AXI bus clock is enabled. Hence let's increase the number of clocks by one and add clock-names to differentiate between parent clocks and the bus clock.
--- .../bindings/clock/adi,axi-clkgen.yaml | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml +18 -4
@@ -26,9 +26,21 @@ properties: description: Specifies the reference clock(s) from which the output frequency is derived. This must either reference one clock if only the first clock - input is connected or two if both clock inputs are connected. - minItems: 1 - maxItems: 2 + input is connected or two if both clock inputs are connected. The last + clock is the AXI bus clock that needs to be enabled so we can access the + core registers. + minItems: 2 + maxItems: 3 + + clock-names: + oneOf: + - items: + - const: clkin1 + - const: s_axi_aclk + - items: + - const: clkin1 + - const: clkin2 + - const: s_axi_aclk '#clock-cells': const: 0
@@ -40,6 +52,7 @@ required: - compatible - reg - clocks + - clock-names - '#clock-cells' additionalProperties: false
@@ -50,5 +63,6 @@ examples: compatible = "adi,axi-clkgen-2.00.a"; #clock-cells = <0>; reg = <0xff000000 0x1000>; - clocks = <&osc 1>; + clocks = <&osc 1>, <&clkc 15>; + clock-names = "clkin1", "s_axi_aclk"; };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 473/817 clk: clk-axi-clkgen: make sure to enable the AXI bus clock
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sa <[email protected]>
[ Upstream commit c64ef7e4851d1a9abbb7f7833e4936973ac5ba79 ]
In order to access the registers of the HW, we need to make sure that the AXI bus clock is enabled. Hence let's increase the number of clocks by one.
In order to keep backward compatibility and make sure old DTs still work we check if clock-names is available or not. If it is, then we can disambiguate between really having the AXI clock or a parent clock and so we can enable the bus clock. If not, we fallback to what was done before and don't explicitly enable the AXI bus clock.
Note that if clock-names is given, the axi clock must be the last one in the phandle array (also enforced in the DT bindings) so that we can reuse as much code as possible.
--- drivers/clk/clk-axi-clkgen.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
drivers/clk/clk-axi-clkgen.c +20 -2
@@ -7,6 +7,7 @@*/ #include <linux/platform_device.h> +#include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/slab.h> #include <linux/io.h>
@@ -512,6 +513,7 @@ static int axi_clkgen_probe(struct platform_device *pdev)struct clk_init_data init;const char *parent_names[2 ];const char *clk_name; +struct clk *axi_clk;unsigned int i;int ret;
@@ -528,8 +530,24 @@ static int axi_clkgen_probe(struct platform_device *pdev)return PTR_ERR (axi_clkgen->base); init.num_parents =of_clk_get_parent_count (pdev->dev.of_node); -if (init.num_parents <1 || init.num_parents >2 ) -return -EINVAL ; + + axi_clk =devm_clk_get_enabled (&pdev->dev,"s_axi_aclk" ); +if (!IS_ERR (axi_clk)) { +if (init.num_parents <2 || init.num_parents >3 ) +return -EINVAL ; + + init.num_parents -=1 ; + }else { +/* +* Legacy... So that old DTs which do not have clock-names still +* work. In this case we don't explicitly enable the AXI bus +* clock. +*/ +if (PTR_ERR (axi_clk) != -ENOENT ) +return PTR_ERR (axi_clk); +if (init.num_parents <1 || init.num_parents >2 ) +return -EINVAL ; + }for (i =0 ; i < init.num_parents; i++) { parent_names[i] =of_clk_get_parent_name (pdev->dev.of_node, i);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 474/817 arm64: dts: qcom: sc8180x: Add a SoC-specific compatible to cpufreq-hw
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <[email protected]>
[ Upstream commit 5df30684415d5a902f23862ab5bbed2a2df7fbf1 ]
Comply with bindings guidelines and get rid of errors such as:
cpufreq@18323000: compatible: 'oneOf' conditional failed, one must be fixed:
['qcom,cpufreq-hw'] is too short
--- arch/arm64/boot/dts/qcom/sc8180x.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sc8180x.dtsi +1 -1
@@ -3730,7 +3730,7 @@ lmh@18358800 { }; cpufreq_hw: cpufreq@18323000 { - compatible = "qcom,cpufreq-hw"; + compatible = "qcom,sc8180x-cpufreq-hw", "qcom,cpufreq-hw"; reg = <0 0x18323000 0 0x1400>, <0 0x18325800 0 0x1400>; reg-names = "freq-domain0", "freq-domain1";
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 475/817 pinctrl: k210: Undef K210_PC_DEFAULT
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: zhang jiao <[email protected]>
[ Upstream commit 7e86490c5dee5c41a55f32d0dc34269e200e6909 ]
When the temporary macro K210_PC_DEFAULT is not needed anymore, use its name in the #undef statement instead of
the incorrect "DEFAULT" name.
--- drivers/pinctrl/pinctrl-k210.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/pinctrl-k210.c +1 -1
@@ -183,7 +183,7 @@ static const u32 k210_pinconf_mode_id_to_mode[] = { [K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU, }; -#undef DEFAULT +#undef K210_PC_DEFAULT/* * Pin functions configuration information.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 476/817 rtla/timerlat: Do not set params->user_workload with -U
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomas Glozar <[email protected]>
[ Upstream commit fcbc60d7dc4b125c8de130aa1512e5d20726c06e ]
Since commit fb9e90a67ee9 ("rtla/timerlat: Make user-space threads the default"), rtla-timerlat has been defaulting to params->user_workload if neither that or params->kernel_workload is set. This has unintentionally made -U, which sets only params->user_hist/top but not params->user_workload, to behave like -u unless -k is set, preventing the user from running a custom workload.
Example:
$ rtla timerlat hist -U -c 0 & [1] 7413 $ python sample/timerlat_load.py 0 Error opening timerlat fd, did you run timerlat -U? $ ps | grep timerlatu 7415 pts/4 00:00:00 timerlatu/0
Fix the issue by checking for params->user_top/hist instead of params->user_workload when setting default thread mode.
--- tools/tracing/rtla/src/timerlat_hist.c | 2 +- tools/tracing/rtla/src/timerlat_top.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
tools/tracing/rtla/src/timerlat_hist.c +1 -1
@@ -1064,7 +1064,7 @@ timerlat_hist_apply_config(struct osnoise_tool *tool, struct timerlat_hist_param* If the user did not specify a type of thread, try user-threads first. * Fall back to kernel threads otherwise. */ -if (!params->kernel_workload && !params->user_workload) { +if (!params->kernel_workload && !params->user_hist) { retval =tracefs_file_exists (NULL ,"osnoise/per_cpu/cpu0/timerlat_fd" );if (retval) {debug_msg ("User-space interface detected, setting user-threads\n" );
tools/tracing/rtla/src/timerlat_top.c +1 -1
@@ -830,7 +830,7 @@ timerlat_top_apply_config(struct osnoise_tool *top, struct timerlat_top_params ** If the user did not specify a type of thread, try user-threads first. * Fall back to kernel threads otherwise. */ -if (!params->kernel_workload && !params->user_workload) { +if (!params->kernel_workload && !params->user_top) { retval =tracefs_file_exists (NULL ,"osnoise/per_cpu/cpu0/timerlat_fd" );if (retval) {debug_msg ("User-space interface detected, setting user-threads\n" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 477/817 smb: cached directories can be more than root file handle
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Aurich <[email protected]>
[ Upstream commit 128630e1dbec8074c7707aad107299169047e68f ]
Update this log message since cached fids may represent things other than the root of a mount.
--- fs/smb/client/cached_dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/smb/client/cached_dir.c +1 -1
@@ -401,7 +401,7 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon,spin_lock (&cfids->cfid_list_lock);list_for_each_entry (cfid, &cfids->entries, entry) {if (dentry && cfid->dentry == dentry) { -cifs_dbg (FYI ,"found a cached root file handle by dentry\n" ); +cifs_dbg (FYI ,"found a cached file handle by dentry\n" );kref_get (&cfid->refcount); *ret_cfid = cfid;spin_unlock (&cfids->cfid_list_lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 478/817 mailbox: mtk-cmdq: fix wrong use of sizeof in cmdq_get_clocks()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yingliang <[email protected]>
[ Upstream commit 271ee263cc8771982809185007181ca10346fe73 ]
It should be size of the struct clk_bulk_data, not data pointer pass to devm_kcalloc().
--- drivers/mailbox/mtk-cmdq-mailbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mailbox/mtk-cmdq-mailbox.c +1 -1
@@ -584,7 +584,7 @@ static int cmdq_get_clocks(struct device *dev, struct cmdq *cmdq)struct clk_bulk_data *clks; cmdq->clocks =devm_kcalloc (dev, cmdq->pdata->gce_num, -sizeof (cmdq->clocks),GFP_KERNEL ); +sizeof (*cmdq->clocks),GFP_KERNEL );if (!cmdq->clocks)return -ENOMEM ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 479/817 mailbox: arm_mhuv2: clean up loop in get_irq_chan_comb()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 192a16a3430ca459c4e986f3d10758c4d6b1aa29 ]
Both the inner and outer loops in this code use the "i" iterator. The inner loop should really use a different iterator.
It doesn't affect things in practice because the data comes from the device tree. The "protocol" and "windows" variables are going to be zero. That means we're always going to hit the "return &chans[channel];" statement and we're not going to want to iterate through the outer loop again.
Still it's worth fixing this for future use cases.
--- drivers/mailbox/arm_mhuv2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mailbox/arm_mhuv2.c +4 -4
@@ -500,7 +500,7 @@ static const struct mhuv2_protocol_ops mhuv2_data_transfer_ops = {static struct mbox_chan *get_irq_chan_comb (struct mhuv2 *mhu,u32 __iomem *reg) {struct mbox_chan *chans = mhu->mbox.chans; -int channel =0 , i, offset =0 , windows, protocol, ch_wn; +int channel =0 , i, j, offset =0 , windows, protocol, ch_wn;u32 stat;for (i =0 ; i <MHUV2_CMB_INT_ST_REG_CNT ; i++) {
@@ -510,9 +510,9 @@ static struct mbox_chan *get_irq_chan_comb(struct mhuv2 *mhu, u32 __iomem *reg) ch_wn = i *MHUV2_STAT_BITS +__builtin_ctz (stat); -for (i =0 ; i < mhu->length; i +=2 ) { - protocol = mhu->protocols[i]; - windows = mhu->protocols[i +1 ]; +for (j =0 ; j < mhu->length; j +=2 ) { + protocol = mhu->protocols[j]; + windows = mhu->protocols[j +1 ];if (ch_wn >= offset + windows) {if (protocol ==DOORBELL )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 480/817 x86: fix off-by-one in access_ok()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Laight <[email protected]>
[ Upstream commit 573f45a9f9a47fed4c7957609689b772121b33d7 ]
When the size isn't a small constant, __access_ok() will call valid_user_address() with the address after the last byte of the user buffer.
It is valid for a buffer to end with the last valid user address so valid_user_address() must allow accesses to the base of the guard page.
[ This introduces an off-by-one in the other direction for the plain
non-sized accesses, but since we have that guard region that is a whole page, those checks "allowing" accesses to that guard region don't really matter. The access will fault anyway, whether to the guard page or if the address has been masked to all ones - Linus ]
--- arch/x86/kernel/cpu/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/common.c +2 -2
@@ -2374,12 +2374,12 @@ void __init arch_cpu_finalize_init(void)alternative_instructions ();if (IS_ENABLED (CONFIG_X86_64 )) { -unsigned long USER_PTR_MAX =TASK_SIZE_MAX -1 ; +unsigned long USER_PTR_MAX =TASK_SIZE_MAX ;/* * Enable this when LAM is gated on LASS support if (cpu_feature_enabled(X86_FEATURE_LAM)) -USER_PTR_MAX = (1ul << 63) - PAGE_SIZE - 1; +USER_PTR_MAX = (1ul << 63) - PAGE_SIZE; */ runtime_const_init (ptr,USER_PTR_MAX );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 481/817 perf cs-etm: Dont flush when packet_queue fills up
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Clark <[email protected]>
[ Upstream commit 5afd032961e8465808c4bc385c06e7676fbe1951 ]
cs_etm__flush(), like cs_etm__sample() is an operation that generates a sample and then swaps the current with the previous packet. Calling flush after processing the queues results in two swaps which corrupts the next sample. Therefore it wasn't appropriate to call flush here so remove it.
Flushing is still done on a discontinuity to explicitly clear the last branch buffer, but when the packet_queue fills up before reaching a timestamp, that's not a discontinuity and the call to cs_etm__process_traceid_queue() already generated samples and drained the buffers correctly.
This is visible by looking for a branch that has the same target as the previous branch and the following source is before the address of the last target, which is impossible as execution would have had to have gone backwards:
ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
(packet_queue fills here before a timestamp, resulting in a flush and
branch target ffff80008011cadc is duplicated.)
ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff80008011cadc update_sg_lb_stats+0x94 ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34
After removing the flush the correct branch target is used for the second sample, and ffff8000801117c4 is no longer before the previous address:
ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94 ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff8000801117a0 cpu_util+0x0 ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34
Make sure that a final branch stack is output at the end of the trace by calling cs_etm__end_block(). This is already done for both the timeless decode paths.
--- tools/perf/util/cs-etm.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
tools/perf/util/cs-etm.c +18 -7
@@ -2439,12 +2439,6 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)/* Ignore return value */ cs_etm__process_traceid_queue (etmq, tidq); - -/* -* Generate an instruction sample with the remaining -* branchstack entries. -*/ -cs_etm__flush (etmq, tidq); } }
@@ -2587,7 +2581,7 @@ static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm)while (1 ) {if (!etm->heap.heap_cnt) - goto out; +break ;/* Take the entry at the top of the min heap */ cs_queue_nr = etm->heap.heap_array[0 ].queue_nr;
@@ -2670,6 +2664,23 @@ static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm) ret =auxtrace_heap__add (&etm->heap, cs_queue_nr, cs_timestamp); } +for (i =0 ; i < etm->queues.nr_queues; i++) { +struct int_node *inode; + + etmq = etm->queues.queue_array[i].priv; +if (!etmq) +continue ; + +intlist__for_each_entry (inode, etmq->traceid_queues_list) { +int idx = (int )(intptr_t )inode->priv; + +/* Flush any remaining branch stack entries */ + tidq = etmq->traceid_queues[idx]; + ret =cs_etm__end_block (etmq, tidq); +if (ret) +return ret; + } + } out:return ret; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 482/817 gfs2: Rename GLF_VERIFY_EVICT to GLF_VERIFY_DELETE
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit 820ce8ed53ce2111aa5171f7349f289d7e9d0693 ]
Rename the GLF_VERIFY_EVICT flag to GLF_VERIFY_DELETE: that flag indicates that we want to delete an inode / verify that it has been deleted.
To match, rename gfs2_queue_verify_evict() togfs2_queue_verify_delete().
Stable-dep-of: 7c6f714d8847 ("gfs2: Fix unlinked inode cleanup")
--- fs/gfs2/glock.c | 14 +++++++------- fs/gfs2/incore.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-)
fs/gfs2/glock.c +7 -7
@@ -1013,11 +1013,11 @@ bool gfs2_queue_try_to_evict(struct gfs2_glock *gl) &gl->gl_delete, 0); } -static bool gfs2_queue_verify_evict (struct gfs2_glock *gl) +static bool gfs2_queue_verify_delete (struct gfs2_glock *gl) {struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; -if (test_and_set_bit (GLF_VERIFY_EVICT , &gl->gl_flags)) +if (test_and_set_bit (GLF_VERIFY_DELETE , &gl->gl_flags))return false;return queue_delayed_work (sdp->sd_delete_wq, &gl->gl_delete,5 *HZ );
@@ -1052,19 +1052,19 @@ static void delete_work_func(struct work_struct *work)if (gfs2_try_evict (gl)) {if (test_bit (SDF_KILL , &sdp->sd_flags)) goto out; -if (gfs2_queue_verify_evict (gl)) +if (gfs2_queue_verify_delete (gl))return ; } goto out; } -if (test_and_clear_bit (GLF_VERIFY_EVICT , &gl->gl_flags)) { +if (test_and_clear_bit (GLF_VERIFY_DELETE , &gl->gl_flags)) { inode =gfs2_lookup_by_inum (sdp, no_addr, gl->gl_no_formal_ino,GFS2_BLKST_UNLINKED );if (IS_ERR (inode)) {if (PTR_ERR (inode) == -EAGAIN && !test_bit (SDF_KILL , &sdp->sd_flags) && -gfs2_queue_verify_evict (gl)) +gfs2_queue_verify_delete (gl))return ; }else {d_prune_aliases (inode);
@@ -2116,7 +2116,7 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)void gfs2_cancel_delete_work (struct gfs2_glock *gl) {clear_bit (GLF_TRY_TO_EVICT , &gl->gl_flags); -clear_bit (GLF_VERIFY_EVICT , &gl->gl_flags); +clear_bit (GLF_VERIFY_DELETE , &gl->gl_flags);if (cancel_delayed_work (&gl->gl_delete))gfs2_glock_put (gl); }
@@ -2369,7 +2369,7 @@ static const char *gflags2str(char *buf, const struct gfs2_glock *gl) *p++ ='N' ;if (test_bit (GLF_TRY_TO_EVICT , gflags)) *p++ ='e' ; -if (test_bit (GLF_VERIFY_EVICT , gflags)) +if (test_bit (GLF_VERIFY_DELETE , gflags)) *p++ ='E' ; *p =0 ;return buf;
fs/gfs2/incore.h +1 -1
@@ -329,7 +329,7 @@ enum {GLF_BLOCKING =15 ,GLF_UNLOCKED =16 ,/* Wait for glock to be unlocked */ GLF_TRY_TO_EVICT =17 ,/* iopen glocks only */ - GLF_VERIFY_EVICT = 18, /* iopen glocks only */ + GLF_VERIFY_DELETE = 18, /* iopen glocks only */ }; struct gfs2_glock {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 483/817 gfs2: Allow immediate GLF_VERIFY_DELETE work
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit 160bc9555d8654464cbbd7bb1f6687048471d2f6 ]
Add an argument to gfs2_queue_verify_delete() that allows it to queue GLF_VERIFY_DELETE work for immediate execution. This is used in the next patch.
Stable-dep-of: 7c6f714d8847 ("gfs2: Fix unlinked inode cleanup")
--- fs/gfs2/glock.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
fs/gfs2/glock.c +6 -5
@@ -1013,14 +1013,15 @@ bool gfs2_queue_try_to_evict(struct gfs2_glock *gl) &gl->gl_delete, 0); } -static bool gfs2_queue_verify_delete (struct gfs2_glock *gl) +static bool gfs2_queue_verify_delete (struct gfs2_glock *gl,bool later) {struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; +unsigned long delay;if (test_and_set_bit (GLF_VERIFY_DELETE , &gl->gl_flags))return false; -return queue_delayed_work (sdp->sd_delete_wq, - &gl->gl_delete,5 *HZ ); + delay = later ?5 *HZ :0 ; +return queue_delayed_work (sdp->sd_delete_wq, &gl->gl_delete, delay); }static void delete_work_func (struct work_struct *work)
@@ -1052,7 +1053,7 @@ static void delete_work_func(struct work_struct *work)if (gfs2_try_evict (gl)) {if (test_bit (SDF_KILL , &sdp->sd_flags)) goto out; -if (gfs2_queue_verify_delete (gl)) +if (gfs2_queue_verify_delete (gl, true))return ; } goto out;
@@ -1064,7 +1065,7 @@ static void delete_work_func(struct work_struct *work)if (IS_ERR (inode)) {if (PTR_ERR (inode) == -EAGAIN && !test_bit (SDF_KILL , &sdp->sd_flags) && -gfs2_queue_verify_delete (gl)) +gfs2_queue_verify_delete (gl, true))return ; }else {d_prune_aliases (inode);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 484/817 gfs2: Fix unlinked inode cleanup
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit 7c6f714d88475ceae5342264858a641eafa19632 ]
Before commit f0e56edc2ec7 ("gfs2: Split the two kinds of glock "delete" work"), function delete_work_func() was used to trigger the eviction of in-memory inodes from remote as well as deleting unlinked inodes at a later point. These two kinds of work were then split into two kinds of work, and the two places in the code were deferred deletion of inodes is required accidentally ended up queuing the wrong kind of work. This caused unlinked inodes to be left behind, which could in the worst case fill up filesystems and require a filesystem check to recover.
Fix that by queuing the right kind of work in try_rgrp_unlink() and gfs2_drop_inode().
--- fs/gfs2/glock.c | 2 +- fs/gfs2/glock.h | 1 + fs/gfs2/rgrp.c | 2 +- fs/gfs2/super.c | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-)
fs/gfs2/glock.c +1 -1
@@ -1013,7 +1013,7 @@ bool gfs2_queue_try_to_evict(struct gfs2_glock *gl) &gl->gl_delete, 0); } -static bool gfs2_queue_verify_delete (struct gfs2_glock *gl,bool later) +bool gfs2_queue_verify_delete (struct gfs2_glock *gl,bool later) {struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;unsigned long delay;
fs/gfs2/glock.h +1 -0
@@ -245,6 +245,7 @@ static inline int gfs2_glock_nq_init(struct gfs2_glock *gl,void gfs2_glock_cb (struct gfs2_glock *gl,unsigned int state);void gfs2_glock_complete (struct gfs2_glock *gl,int ret);bool gfs2_queue_try_to_evict (struct gfs2_glock *gl); +bool gfs2_queue_verify_delete (struct gfs2_glock *gl,bool later);void gfs2_cancel_delete_work (struct gfs2_glock *gl);void gfs2_flush_delete_work (struct gfs2_sbd *sdp);void gfs2_gl_hash_clear (struct gfs2_sbd *sdp);
fs/gfs2/rgrp.c +1 -1
@@ -1879,7 +1879,7 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip*/ ip = gl->gl_object; -if (ip || !gfs2_queue_try_to_evict (gl)) +if (ip || !gfs2_queue_verify_delete (gl, false))gfs2_glock_put (gl);else found++;
fs/gfs2/super.c +1 -1
@@ -1045,7 +1045,7 @@ static int gfs2_drop_inode(struct inode *inode)struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;gfs2_glock_hold (gl); -if (!gfs2_queue_try_to_evict (gl)) +if (!gfs2_queue_verify_delete (gl, true))gfs2_glock_put_async (gl);return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 485/817 perf test: Add test for Intel TPEBS counting mode
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weilin Wang <[email protected]>
[ Upstream commit b2738fda24543777a623a7d1cc2a9985ab81b448 ]
Intel TPEBS sampling mode is supported through perf record. The counting mode code uses perf record to capture retire_latency value and use it in metric calculation. This test checks the counting mode code on Intel platforms.
Committer testing:
root@x1:~# perf test tpebs 123: test Intel TPEBS counting mode : Ok root@x1:~# set -o vi root@x1:~# perf test tpebs 123: test Intel TPEBS counting mode : Ok root@x1:~# perf test -v tpebs 123: test Intel TPEBS counting mode : Ok root@x1:~# perf test -vvv tpebs 123: test Intel TPEBS counting mode: --- start --- test child forked, pid 16603 Testing without --record-tpebs Testing with --record-tpebs ---- end(0) ---- 123: test Intel TPEBS counting mode : Ok root@x1:~#
Stable-dep-of: 057f8bfc6f70 ("perf stat: Uniquify event name improvements")
--- .../perf/tests/shell/test_stat_intel_tpebs.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100755 tools/perf/tests/shell/test_stat_intel_tpebs.sh
tools/perf/tests/shell/test_stat_intel_tpebs.sh new file +19 -0
@@ -0,0 +1,19 @@ +#!/bin/bash +# test Intel TPEBS counting mode +# SPDX-License-Identifier: GPL-2.0 + +set -e +grep -q GenuineIntel /proc/cpuinfo || { echo Skipping non-Intel; exit 2; } + +# Use this event for testing because it should exist in all platforms +event=cache-misses:R + +# Without this cmd option, default value or zero is returned +echo "Testing without --record-tpebs" +result=$(perf stat -e "$event" true 2>&1) +[[ "$result" =~ $event ]] || exit 1 + +# In platforms that do not support TPEBS, it should execute without error. +echo "Testing with --record-tpebs" +result=$(perf stat -e "$event" --record-tpebs -a sleep 0.01 2>&1) +[[ "$result" =~ "perf record" && "$result" =~ $event ]] || exit 1
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 486/817 perf stat: Uniquify event name improvements
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Rogers <[email protected]>
[ Upstream commit 057f8bfc6f7070577523d1e3081081bbf4229c1c ]
Without aggregation on Intel:
``` $ perf stat -e instructions,cycles ... ```
Will use "cycles" for the name of the legacy cycles event but as "instructions" has a sysfs name it will and a "[cpu]" PMU suffix. This often breaks things as the space between the event and the PMU name look like an extra column. The existing uniquify logic was also uniquifying in cases when all events are core and not with uncore events, it was not correctly handling modifiers, etc.
Change the logic so that an initial pass that can disable uniquification is run. For individual counters, disable uniquification in more cases such as for consistency with legacy events or for libpfm4 events. Don't use the "[pmu]" style suffix in uniquification, always use "pmu/.../". Change how modifiers/terms are handled in the uniquification so that they look like parse-able events.
This fixes "102: perf stat metrics (shadow stat) test:" that has been failing due to "instructions [cpu]" breaking its column/awk logic when values aren't aggregated. This started happening when instructions could match a sysfs rather than a legacy event, so the fixes tag reflects this.
--- .../perf/tests/shell/test_stat_intel_tpebs.sh | 11 +- tools/perf/util/stat-display.c | 101 ++++++++++++++---- 2 files changed, 85 insertions(+), 27 deletions(-)
tools/perf/tests/shell/test_stat_intel_tpebs.sh +7 -4
@@ -8,12 +8,15 @@ grep -q GenuineIntel /proc/cpuinfo || { echo Skipping non-Intel; exit 2; } # Use this event for testing because it should exist in all platforms event=cache-misses:R +# Hybrid platforms output like "cpu_atom/cache-misses/R", rather than as above +alt_name=/cache-misses/R + # Without this cmd option, default value or zero is returned -echo "Testing without --record-tpebs" -result=$(perf stat -e "$event" true 2>&1) -[[ "$result" =~ $event ]] || exit 1 +#echo "Testing without --record-tpebs" +#result=$(perf stat -e "$event" true 2>&1) +#[[ "$result" =~ $event || "$result" =~ $alt_name ]] || exit 1 # In platforms that do not support TPEBS, it should execute without error. echo "Testing with --record-tpebs" result=$(perf stat -e "$event" --record-tpebs -a sleep 0.01 2>&1) -[[ "$result" =~ "perf record" && "$result" =~ $event ]] || exit 1 +[[ "$result" =~ "perf record" && "$result" =~ $event || "$result" =~ $alt_name ]] || exit 1
tools/perf/util/stat-display.c +78 -23
128 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 487/817 perf mem: Fix printing PERF_MEM_LVLNUM_{L2_MHB|MSC}
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Falcon <[email protected]>
[ Upstream commit 4f23fc34cc68812c68c3a3dec15e26e87565f430 ]
With commit 8ec9497d3ef34 ("tools/include: Sync uapi/linux/perf.h with the kernel sources"), 'perf mem report' gives an incorrect memory access string.
...
0.02% 1 3644 L5 hit [.] 0x0000000000009b0e mlc [.] 0x00007fce43f59480
...
This occurs because, if no entry exists in mem_lvlnum, perf_mem__lvl_scnprintf will default to 'L%d, lvl', which in this case for PERF_MEM_LVLNUM_L2_MHB is 0x05. Add entries for PERF_MEM_LVLNUM_L2_MHB and PERF_MEM_LVLNUM_MSC to mem_lvlnum, so that the correct strings are printed.
...
0.02% 1 3644 L2 MHB hit [.] 0x0000000000009b0e mlc [.] 0x00007fce43f59480
...
--- tools/perf/util/mem-events.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
tools/perf/util/mem-events.c +7 -1
@@ -366,6 +366,12 @@ static const char * const mem_lvl[] = { };static const char *const mem_lvlnum[] = { + [PERF_MEM_LVLNUM_L1 ] ="L1" , + [PERF_MEM_LVLNUM_L2 ] ="L2" , + [PERF_MEM_LVLNUM_L3 ] ="L3" , + [PERF_MEM_LVLNUM_L4 ] ="L4" , + [PERF_MEM_LVLNUM_L2_MHB ] ="L2 MHB" , + [PERF_MEM_LVLNUM_MSC ] ="Memory-side Cache" , [PERF_MEM_LVLNUM_UNC ] ="Uncached" , [PERF_MEM_LVLNUM_CXL ] ="CXL" , [PERF_MEM_LVLNUM_IO ] ="I/O" ,
@@ -448,7 +454,7 @@ int perf_mem__lvl_scnprintf(char *out, size_t sz, const struct mem_info *mem_infif (mem_lvlnum[lvl]) l +=scnprintf (out + l, sz - l, mem_lvlnum[lvl]);else - l +=scnprintf (out + l, sz - l,"L%d" , lvl); + l +=scnprintf (out + l, sz - l,"Unknown level %d" , lvl); l +=scnprintf (out + l, sz - l," %s" , hit_miss);return l;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 488/817 PCI: Fix reset_method_store() memory leak
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Todd Kjos <[email protected]>
[ Upstream commit 2985b1844f3f3447f2d938eff1ef6762592065a5 ]
In reset_method_store(), a string is allocated via kstrndup() and assigned to the local "options". options is then used in with strsep() to find spaces:
while ((name = strsep(&options, " ")) != NULL) {If there are no remaining spaces, then options is set to NULL by strsep(), so the subsequent kfree(options) doesn't free the memory allocated via kstrndup().
Fix by using a separate tmp_options to iterate with strsep() so options is preserved.
--- drivers/pci/pci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/pci/pci.c +3 -2
@@ -5233,7 +5233,7 @@ static ssize_t reset_method_store(struct device *dev, const char *buf, size_t count) {struct pci_dev *pdev =to_pci_dev (dev); -char *options, *name; +char *options, *tmp_options, *name;int m, n;u8 reset_methods[PCI_NUM_RESET_METHODS ] = {0 };
@@ -5253,7 +5253,8 @@ static ssize_t reset_method_store(struct device *dev,return -ENOMEM ; n =0 ; -while ((name =strsep (&options," " )) !=NULL ) { + tmp_options = options; +while ((name =strsep (&tmp_options," " )) !=NULL ) {if (sysfs_streq (name,"" ))continue ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 489/817 perf stat: Close cork_fd when create_perf_stat_counter() failed
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Levi Yun <[email protected]>
[ Upstream commit e880a70f8046df0dd9089fa60dcb866a2cc69194 ]
When create_perf_stat_counter() failed, it doesn't close workload.cork_fd open in evlist__prepare_workload(). This could make too many open file error while __run_perf_stat() repeats.
Introduce evlist__cancel_workload to close workload.cork_fd and wait workload.child_pid until exit to clear child process when create_perf_stat_counter() is failed.
Stable-dep-of: 7f6ccb70e465 ("perf stat: Fix affinity memory leaks on error path")
--- tools/perf/builtin-stat.c | 50 +++++++++++++++++++++++++++------------ tools/perf/util/evlist.c | 19 +++++++++++++-- tools/perf/util/evlist.h | 1 + 3 files changed, 53 insertions(+), 17 deletions(-)
tools/perf/builtin-stat.c +35 -15
@@ -712,15 +712,19 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) }if (!cpu_map__is_dummy (evsel_list->core.user_requested_cpus)) { -if (affinity__setup (&saved_affinity) <0 ) -return -1 ; +if (affinity__setup (&saved_affinity) <0 ) { + err =-1 ; + goto err_out; + } affinity = &saved_affinity; }evlist__for_each_entry (evsel_list, counter) { counter->reset_group = false; -if (bpf_counter__load (counter, &target)) -return -1 ; +if (bpf_counter__load (counter, &target)) { + err =-1 ; + goto err_out; + }if (!(evsel__is_bperf (counter))) all_counters_use_bpf = false; }
@@ -763,7 +767,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)switch (stat_handle_error (counter)) {case COUNTER_FATAL : -return -1 ; + err =-1 ; + goto err_out;case COUNTER_RETRY : goto try_again;case COUNTER_SKIP :
@@ -804,7 +809,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)switch (stat_handle_error (counter)) {case COUNTER_FATAL : -return -1 ; + err =-1 ; + goto err_out;case COUNTER_RETRY : goto try_again_reset;case COUNTER_SKIP :
@@ -829,8 +835,10 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) stat_config.unit_width = l;if (evsel__should_store_id (counter) && -evsel__store_ids (counter, evsel_list)) -return -1 ; +evsel__store_ids (counter, evsel_list)) { + err =-1 ; + goto err_out; + } }if (evlist__apply_filters (evsel_list, &counter)) {
@@ -851,20 +859,23 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) }if (err <0 ) -return err; + goto err_out; err =perf_event__synthesize_stat_events (&stat_config,NULL , evsel_list, process_synthesized_event, is_pipe);if (err <0 ) -return err; + goto err_out; + }if (target.initial_delay) {pr_info (EVLIST_DISABLED_MSG ); }else { err =enable_counters (); -if (err) -return -1 ; +if (err) { + err =-1 ; + goto err_out; + } }/* Exec the command, if any */
@@ -874,8 +885,10 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)if (target.initial_delay >0 ) {usleep (target.initial_delay *USEC_PER_MSEC ); err =enable_counters (); -if (err) -return -1 ; +if (err) { + err =-1 ; + goto err_out; + }pr_info (EVLIST_ENABLED_MSG ); }
@@ -895,7 +908,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)if (workload_exec_errno) {const char *emsg =str_error_r (workload_exec_errno, msg,sizeof (msg));pr_err ("Workload failed: %s\n" , emsg); -return -1 ; + err =-1 ; + goto err_out; }if (WIFSIGNALED (status))
@@ -942,6 +956,12 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)evlist__close (evsel_list);return WEXITSTATUS (status); + +err_out: +if (forks) +evlist__cancel_workload (evsel_list); + +return err; }static int run_perf_stat (int argc,const char **argv,int run_idx)
tools/perf/util/evlist.c +17 -2
@@ -46,6 +46,7 @@#include <sys/mman.h> #include <sys/prctl.h> #include <sys/timerfd.h> +#include <sys/wait.h> #include <linux/bitops.h> #include <linux/hash.h>
@@ -1413,6 +1414,8 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, constint child_ready_pipe[2 ], go_pipe[2 ];char bf; + evlist->workload.cork_fd =-1 ; +if (pipe (child_ready_pipe) <0 ) {perror ("failed to create 'ready' pipe" );return -1 ;
@@ -1465,7 +1468,7 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, const* For cancelling the workload without actually running it, * the parent will just close workload.cork_fd, without writing * anything, i.e. read will return zero and we just exit() -* here. +* here (See evlist__cancel_workload()). */ if (ret !=1 ) {if (ret ==-1 )
@@ -1529,7 +1532,7 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, constint evlist__start_workload (struct evlist *evlist) { -if (evlist->workload.cork_fd >0 ) { +if (evlist->workload.cork_fd >=0 ) {char bf =0 ;int ret;/*
@@ -1540,12 +1543,24 @@ int evlist__start_workload(struct evlist *evlist)perror ("unable to write to pipe" );close (evlist->workload.cork_fd); + evlist->workload.cork_fd =-1 ;return ret; }return 0 ; } +void evlist__cancel_workload (struct evlist *evlist) +{ +int status; + +if (evlist->workload.cork_fd >=0 ) { +close (evlist->workload.cork_fd); + evlist->workload.cork_fd =-1 ; +waitpid (evlist->workload.pid, &status,WNOHANG ); + } +} +int evlist__parse_sample (struct evlist *evlist,union perf_event *event,struct perf_sample *sample) {struct evsel *evsel =evlist__event2evsel (evlist, event);
tools/perf/util/evlist.h +1 -0
@@ -184,6 +184,7 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, const char *argv[], bool pipe_output, void (*exec_error)(int signo, siginfo_t *info, void *ucontext));int evlist__start_workload (struct evlist *evlist); +void evlist__cancel_workload (struct evlist *evlist);struct option ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 490/817 perf stat: Fix affinity memory leaks on error path
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Rogers <[email protected]>
[ Upstream commit 7f6ccb70e465bd8c9cf8973aee1c01224e4bdb3c ]
Missed cleanup when an error occurs.
--- tools/perf/builtin-stat.c | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/builtin-stat.c +2 -0
@@ -823,6 +823,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) } }affinity__cleanup (affinity); + affinity =NULL ;evlist__for_each_entry (evsel_list, counter) {if (!counter->supported) {
@@ -961,6 +962,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)if (forks)evlist__cancel_workload (evsel_list); +affinity__cleanup (affinity);return err; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 491/817 perf trace: Keep exited threads for summary
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Petlan <[email protected]>
[ Upstream commit d29d92df410e2fb523f640478b18f70c1823e55e ]
Since 9ffa6c7512ca ("perf machine thread: Remove exited threads by default") perf cleans exited threads up, but as said, sometimes they are necessary to be kept. The mentioned commit does not cover all the cases, we also need the information to construct the summary table in perf-trace.
Before:
# perf trace -s true
Summary of events:
After:
# perf trace -s -- true
Summary of events:
true (383382), 64 events, 91.4%
syscall calls errors total min avg max stddev
(msec) (msec) (msec) (msec) (%)
--------------- -------- ------ -------- --------- --------- --------- ------
mmap 8 0 0.150 0.013 0.019 0.031 11.90%
mprotect 3 0 0.045 0.014 0.015 0.017 6.47%
openat 2 0 0.014 0.006 0.007 0.007 9.73%
munmap 1 0 0.009 0.009 0.009 0.009 0.00%
access 1 1 0.009 0.009 0.009 0.009 0.00%
pread64 4 0 0.006 0.001 0.001 0.002 4.53%
fstat 2 0 0.005 0.001 0.002 0.003 37.59%
arch_prctl 2 1 0.003 0.001 0.002 0.002 25.91%
read 1 0 0.003 0.003 0.003 0.003 0.00%
close 2 0 0.003 0.001 0.001 0.001 3.86%
brk 1 0 0.002 0.002 0.002 0.002 0.00%
rseq 1 0 0.001 0.001 0.001 0.001 0.00%
prlimit64 1 0 0.001 0.001 0.001 0.001 0.00%
set_robust_list 1 0 0.001 0.001 0.001 0.001 0.00%
set_tid_address 1 0 0.001 0.001 0.001 0.001 0.00%
execve 1 0 0.000 0.000 0.000 0.000 0.00%[namhyung: simplified the condition]
--- tools/perf/builtin-trace.c | 4 ++++ 1 file changed, 4 insertions(+)
tools/perf/builtin-trace.c +4 -0
@@ -5038,6 +5038,10 @@ int cmd_trace(int argc, const char **argv)if (trace.summary_only) trace.summary = trace.summary_only; +/* Keep exited threads, otherwise information might be lost for summary */ +if (trace.summary) + symbol_conf.keep_exited_threads = true; +if (output_name !=NULL ) { err =trace__open_output (&trace, output_name);if (err <0 ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 492/817 perf test attr: Add back missing topdown events
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Veronika Molnarova <[email protected]>
[ Upstream commit 6bff76af9635411214ca44ea38fc2781e78064b6 ]
With the patch 0b6c5371c03c "Add missing topdown metrics events" eight topdown metric events with numbers ranging from 0x8000 to 0x8700 were added to the test since they were added as 'perf stat' default events. Later the patch 951efb9976ce "Update no event/metric expectations" kept only 4 of those events(0x8000-0x8300).
Currently, the topdown events with numbers 0x8400 to 0x8700 are missing from the list of expected events resulting in a failure. Add back the missing topdown events.
--- tools/perf/tests/attr/test-stat-default | 90 ++++++++++---- tools/perf/tests/attr/test-stat-detailed-1 | 106 +++++++++++----- tools/perf/tests/attr/test-stat-detailed-2 | 130 ++++++++++++------- tools/perf/tests/attr/test-stat-detailed-3 | 138 ++++++++++++++------- 4 files changed, 320 insertions(+), 144 deletions(-)
tools/perf/tests/attr/test-stat-default +67 -23
@@ -88,98 +88,142 @@ enable_on_exec=0 read_format=15 optional=1 -# PERF_TYPE_RAW / topdown-fe-bound (0x8200) +# PERF_TYPE_RAW / topdown-bad-spec (0x8100) [event13:base-stat] fd=13 group_fd=11 type=4 -config=33280 +config=33024 disabled=0 enable_on_exec=0 read_format=15 optional=1 -# PERF_TYPE_RAW / topdown-be-bound (0x8300) +# PERF_TYPE_RAW / topdown-fe-bound (0x8200) [event14:base-stat] fd=14 group_fd=11 type=4 -config=33536 +config=33280 disabled=0 enable_on_exec=0 read_format=15 optional=1 -# PERF_TYPE_RAW / topdown-bad-spec (0x8100) +# PERF_TYPE_RAW / topdown-be-bound (0x8300) [event15:base-stat] fd=15 group_fd=11 type=4 -config=33024 +config=33536 disabled=0 enable_on_exec=0 read_format=15 optional=1 -# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING +# PERF_TYPE_RAW / topdown-heavy-ops (0x8400) [event16:base-stat] fd=16 +group_fd=11 type=4 -config=4109 +config=33792 +disabled=0 +enable_on_exec=0 +read_format=15 optional=1 -# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/ +# PERF_TYPE_RAW / topdown-br-mispredict (0x8500) [event17:base-stat] fd=17 +group_fd=11 type=4 -config=17039629 +config=34048 +disabled=0 +enable_on_exec=0 +read_format=15 optional=1 -# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD +# PERF_TYPE_RAW / topdown-fetch-lat (0x8600) [event18:base-stat] fd=18 +group_fd=11 type=4 -config=60 +config=34304 +disabled=0 +enable_on_exec=0 +read_format=15 optional=1 -# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY +# PERF_TYPE_RAW / topdown-mem-bound (0x8700) [event19:base-stat] fd=19 +group_fd=11 type=4 -config=2097421 +config=34560 +disabled=0 +enable_on_exec=0 +read_format=15 optional=1 -# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK +# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING [event20:base-stat] fd=20 type=4 -config=316 +config=4109 optional=1 -# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE +# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/ [event21:base-stat] fd=21 type=4 -config=412 +config=17039629 optional=1 -# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE +# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD [event22:base-stat] fd=22 type=4 -config=572 +config=60 optional=1 -# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS +# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY [event23:base-stat] fd=23 type=4 -config=706 +config=2097421 optional=1 -# PERF_TYPE_RAW / UOPS_ISSUED.ANY +# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK [event24:base-stat] fd=24 type=4 +config=316 +optional=1 + +# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE +[event25:base-stat] +fd=25 +type=4 +config=412 +optional=1 + +# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE +[event26:base-stat] +fd=26 +type=4 +config=572 +optional=1 + +# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS +[event27:base-stat] +fd=27 +type=4 +config=706 +optional=1 + +# PERF_TYPE_RAW / UOPS_ISSUED.ANY +[event28:base-stat] +fd=28 +type=4 config=270 optional=1
tools/perf/tests/attr/test-stat-detailed-1 +75 -31
206 lines not on this page · raw message
tools/perf/tests/attr/test-stat-detailed-2 +87 -43
266 lines not on this page · raw message
tools/perf/tests/attr/test-stat-detailed-3 +91 -47
286 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 493/817 f2fs: compress: fix inconsistent update of i_blocks in release_compress_blocks and reserve_compress_blocks
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qi Han <[email protected]>
[ Upstream commit 26413ce18e85de3dda2cd3d72c3c3e8ab8f4f996 ]
After release a file and subsequently reserve it, the FSCK flag is set when the file is deleted, as shown in the following backtrace:
F2FS-fs (dm-48): Inconsistent i_blocks, ino:401231, iblocks:1448, sectors:1472
fs_rec_info_write_type+0x58/0x274 f2fs_rec_info_write+0x1c/0x2c set_sbi_flag+0x74/0x98 dec_valid_block_count+0x150/0x190 f2fs_truncate_data_blocks_range+0x2d4/0x3cc f2fs_do_truncate_blocks+0x2fc/0x5f0 f2fs_truncate_blocks+0x68/0x100 f2fs_truncate+0x80/0x128 f2fs_evict_inode+0x1a4/0x794 evict+0xd4/0x280 iput+0x238/0x284 do_unlinkat+0x1ac/0x298 __arm64_sys_unlinkat+0x48/0x68 invoke_syscall+0x58/0x11c
For clusters of the following type, i_blocks are decremented by 1 and i_compr_blocks are incremented by 7 in release_compress_blocks, while updates to i_blocks and i_compr_blocks are skipped in reserve_compress_blocks.
raw node:
D D D D D D D D
after compress:
C D D D D D D D
after reserve:
C D D D D D D D
Let's update i_blocks and i_compr_blocks properly in reserve_compress_blocks.
--- fs/f2fs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/f2fs/file.c +1 -1
@@ -3798,7 +3798,7 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count, to_reserved = cluster_size - compr_blocks - reserved;/* for the case all blocks in cluster were reserved */ -if (to_reserved ==1 ) { +if (reserved && to_reserved ==1 ) { dn->ofs_in_node += cluster_size; goto next; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 494/817 f2fs: fix null-ptr-deref in f2fs_submit_page_bio()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Bin <[email protected]>
[ Upstream commit b7d0a97b28083084ebdd8e5c6bccd12e6ec18faa ]
There's issue as follows when concurrently installing the f2fs.ko module and mounting the f2fs file system:
KASAN: null-ptr-deref in range [0x0000000000000020-0x0000000000000027] RIP: 0010:__bio_alloc+0x2fb/0x6c0 [f2fs] Call Trace: <TASK> f2fs_submit_page_bio+0x126/0x8b0 [f2fs] __get_meta_page+0x1d4/0x920 [f2fs] get_checkpoint_version.constprop.0+0x2b/0x3c0 [f2fs] validate_checkpoint+0xac/0x290 [f2fs] f2fs_get_valid_checkpoint+0x207/0x950 [f2fs] f2fs_fill_super+0x1007/0x39b0 [f2fs] mount_bdev+0x183/0x250 legacy_get_tree+0xf4/0x1e0 vfs_get_tree+0x88/0x340 do_new_mount+0x283/0x5e0 path_mount+0x2b2/0x15b0 __x64_sys_mount+0x1fe/0x270 do_syscall_64+0x5f/0x170 entry_SYSCALL_64_after_hwframe+0x76/0x7e
Above issue happens as the biset of the f2fs file system is not initialized before register "f2fs_fs_type".
To address above issue just register "f2fs_fs_type" at the last in init_f2fs_fs(). Ensure that all f2fs file system resources are initialized.
--- fs/f2fs/super.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
fs/f2fs/super.c +6 -6
@@ -4972,9 +4972,6 @@ static int __init init_f2fs_fs(void) err =f2fs_init_shrinker ();if (err) goto free_sysfs; - err =register_filesystem (&f2fs_fs_type); -if (err) - goto free_shrinker;f2fs_create_root_stats (); err =f2fs_init_post_read_processing ();if (err)
@@ -4997,7 +4994,12 @@ static int __init init_f2fs_fs(void) err =f2fs_create_casefold_cache ();if (err) goto free_compress_cache; + err =register_filesystem (&f2fs_fs_type); +if (err) + goto free_casefold_cache;return 0 ; +free_casefold_cache: +f2fs_destroy_casefold_cache (); free_compress_cache:f2fs_destroy_compress_cache (); free_compress_mempool:
@@ -5012,8 +5014,6 @@ static int __init init_f2fs_fs(void)f2fs_destroy_post_read_processing (); free_root_stats:f2fs_destroy_root_stats (); -unregister_filesystem (&f2fs_fs_type); -free_shrinker:f2fs_exit_shrinker (); free_sysfs:f2fs_exit_sysfs ();
@@ -5037,6 +5037,7 @@ static int __init init_f2fs_fs(void) static void __exit exit_f2fs_fs(void) { +unregister_filesystem (&f2fs_fs_type);f2fs_destroy_casefold_cache ();f2fs_destroy_compress_cache ();f2fs_destroy_compress_mempool ();
@@ -5045,7 +5046,6 @@ static void __exit exit_f2fs_fs(void)f2fs_destroy_iostat_processing ();f2fs_destroy_post_read_processing ();f2fs_destroy_root_stats (); -unregister_filesystem (&f2fs_fs_type);f2fs_exit_shrinker ();f2fs_exit_sysfs ();f2fs_destroy_garbage_collection_cache ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 495/817 f2fs: fix to account dirty data in __get_secs_required()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 1acd73edbbfef2c3c5b43cba4006a7797eca7050 ]
It will trigger system panic w/ testcase in [1]:
------------[ cut here ]------------ kernel BUG at fs/f2fs/segment.c:2752! RIP: 0010:new_curseg+0xc81/0x2110 Call Trace: f2fs_allocate_data_block+0x1c91/0x4540 do_write_page+0x163/0xdf0 f2fs_outplace_write_data+0x1aa/0x340 f2fs_do_write_data_page+0x797/0x2280 f2fs_write_single_data_page+0x16cd/0x2190 f2fs_write_cache_pages+0x994/0x1c80 f2fs_write_data_pages+0x9cc/0xea0 do_writepages+0x194/0x7a0 filemap_fdatawrite_wbc+0x12b/0x1a0 __filemap_fdatawrite_range+0xbb/0xf0 file_write_and_wait_range+0xa1/0x110 f2fs_do_sync_file+0x26f/0x1c50 f2fs_sync_file+0x12b/0x1d0 vfs_fsync_range+0xfa/0x230 do_fsync+0x3d/0x80 __x64_sys_fsync+0x37/0x50 x64_sys_call+0x1e88/0x20d0 do_syscall_64+0x4b/0x110 entry_SYSCALL_64_after_hwframe+0x76/0x7e
The root cause is if checkpoint_disabling and lfs_mode are both on, it will trigger OPU for all overwritten data, it may cost more free segment than expected, so f2fs must account those data correctly to calculate cosumed free segments later, and return ENOSPC earlier to avoid run out of free segment during block allocation.
[1] https://lore.kernel.org/fstests/[email protected]/
--- fs/f2fs/segment.h | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-)
fs/f2fs/segment.h +25 -10
@@ -558,18 +558,21 @@ static inline int reserved_sections(struct f2fs_sb_info *sbi) }static inline bool has_curseg_enough_space (struct f2fs_sb_info *sbi, -unsigned int node_blocks,unsigned int dent_blocks) +unsigned int node_blocks,unsigned int data_blocks, +unsigned int dent_blocks) { -unsigned segno, left_blocks; +unsigned int segno, left_blocks, blocks;int i; -/* check current node sections in the worst case. */ -for (i =CURSEG_HOT_NODE ; i <=CURSEG_COLD_NODE ; i++) { +/* check current data/node sections in the worst case. */ +for (i =CURSEG_HOT_DATA ; i <NR_PERSISTENT_LOG ; i++) { segno =CURSEG_I (sbi, i)->segno; left_blocks =CAP_BLKS_PER_SEC (sbi) -get_ckpt_valid_blocks (sbi, segno, true); -if (node_blocks > left_blocks) + + blocks = i <=CURSEG_COLD_DATA ? data_blocks : node_blocks; +if (blocks > left_blocks)return false; }
@@ -583,8 +586,9 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi, }/* -* calculate needed sections for dirty node/dentry -* and call has_curseg_enough_space +* calculate needed sections for dirty node/dentry and call +* has_curseg_enough_space, please note that, it needs to account +* dirty data as well in lfs mode when checkpoint is disabled. */ static inline void __get_secs_required (struct f2fs_sb_info *sbi,unsigned int *lower_p,unsigned int *upper_p,bool *curseg_p)
@@ -593,19 +597,30 @@ static inline void __get_secs_required(struct f2fs_sb_info *sbi,get_pages (sbi,F2FS_DIRTY_DENTS ) +get_pages (sbi,F2FS_DIRTY_IMETA );unsigned int total_dent_blocks =get_pages (sbi,F2FS_DIRTY_DENTS ); +unsigned int total_data_blocks =0 ;unsigned int node_secs = total_node_blocks /CAP_BLKS_PER_SEC (sbi);unsigned int dent_secs = total_dent_blocks /CAP_BLKS_PER_SEC (sbi); +unsigned int data_secs =0 ;unsigned int node_blocks = total_node_blocks %CAP_BLKS_PER_SEC (sbi);unsigned int dent_blocks = total_dent_blocks %CAP_BLKS_PER_SEC (sbi); +unsigned int data_blocks =0 ; + +if (f2fs_lfs_mode (sbi) && +unlikely (is_sbi_flag_set (sbi,SBI_CP_DISABLED ))) { + total_data_blocks =get_pages (sbi,F2FS_DIRTY_DATA ); + data_secs = total_data_blocks /CAP_BLKS_PER_SEC (sbi); + data_blocks = total_data_blocks %CAP_BLKS_PER_SEC (sbi); + }if (lower_p) - *lower_p = node_secs + dent_secs; + *lower_p = node_secs + dent_secs + data_secs;if (upper_p) *upper_p = node_secs + dent_secs + - (node_blocks ?1 :0 ) + (dent_blocks ?1 :0 ); + (node_blocks ?1 :0 ) + (dent_blocks ?1 :0 ) + + (data_blocks ?1 :0 );if (curseg_p) *curseg_p =has_curseg_enough_space (sbi, - node_blocks, dent_blocks); + node_blocks, data_blocks, dent_blocks); } static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 496/817 perf dso: Fix symtab_type for kmod compression
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Veronika Molnarova <[email protected]>
[ Upstream commit 05a62936e6b14c005db3b0c9c7d8b93d825dd9ca ]
During the rework of the dso structure in patch ee756ef7491eafd an increment was forgotten for the symtab_type in case the data for the kernel module are compressed. This affects the probing of the kernel modules, which fails if the data are not already cached.
Increment the value of the symtab_type to its compressed variant so the data could be recovered successfully.
--- tools/perf/util/machine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/machine.c +1 -1
@@ -1342,7 +1342,7 @@ static int maps__set_module_path(struct maps *maps, const char *path, struct kmo* we need to update the symtab_type if needed. */ if (m->comp &&is_kmod_dso (dso)) { -dso__set_symtab_type (dso,dso__symtab_type (dso)); +dso__set_symtab_type (dso,dso__symtab_type (dso)+1 );dso__set_comp (dso, m->comp); }map__put (map);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 497/817 perf probe: Fix libdw memory leak
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Rogers <[email protected]>
[ Upstream commit 4585038b8e186252141ef86e9f0d8e97f11dce8d ]
Add missing dwarf_cfi_end to free memory associated with probe_finder cfi_eh which is allocated and owned via a call to dwarf_getcfi_elf. Confusingly cfi_dbg shouldn't be freed as its memory is owned by the passed in debuginfo struct. Add comments to highlight this.
This addresses leak sanitizer issues seen in:tools/perf/tests/shell/test_uprobe_from_different_cu.sh
--- tools/perf/util/probe-finder.c | 4 ++++ tools/perf/util/probe-finder.h | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-)
tools/perf/util/probe-finder.c +4 -0
@@ -1379,6 +1379,10 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,if (ret >=0 && tf.pf.skip_empty_arg) ret =fill_empty_trace_arg (pev, tf.tevs, tf.ntevs); +#if _ELFUTILS_PREREQ (0 ,142 ) +dwarf_cfi_end (tf.pf.cfi_eh); +#endif +if (ret <0 || tf.ntevs ==0 ) {for (i =0 ; i < tf.ntevs; i++)clear_probe_trace_event (&tf.tevs[i]);
tools/perf/util/probe-finder.h +2 -2
@@ -64,9 +64,9 @@ struct probe_finder {/* For variable searching */ #if _ELFUTILS_PREREQ (0 ,142 ) -/* Call Frame Information from .eh_frame */ +/* Call Frame Information from .eh_frame. Owned by this struct. */ Dwarf_CFI *cfi_eh; -/* Call Frame Information from .debug_frame */ +/* Call Frame Information from .debug_frame. Not owned. */ Dwarf_CFI *cfi_dbg;#endif Dwarf_Op *fb_ops;/* Frame base attribute */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 498/817 perf probe: Correct demangled symbols in C++ program
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leo Yan <[email protected]>
[ Upstream commit 314909f13cc12d47c468602c37dace512d225eeb ]
An issue can be observed when probe C++ demangled symbol with steps:
# nm test_cpp_mangle | grep print_data
0000000000000c94 t _GLOBAL__sub_I__Z10print_datai
0000000000000afc T _Z10print_datai
0000000000000b38 T _Z10print_dataR5Point # perf probe -x /home/niayan01/test_cpp_mangle -F --demangle
...
print_data(Point&)
print_data(int)
... # perf --debug verbose=3 probe -x test_cpp_mangle --add "test=print_data(int)"
probe-definition(0): test=print_data(int)
symbol:print_data(int) file:(null) line:0 offset:0 return:0 lazy:(null)
0 arguments
Open Debuginfo file: /home/niayan01/test_cpp_mangle
Try to find probe point from debuginfo.
Symbol print_data(int) address found : afc
Matched function: print_data [2ccf]
Probe point found: print_data+0
Found 1 probe_trace_events.
Opening /sys/kernel/tracing//uprobe_events write=1
Opening /sys/kernel/tracing//README write=0
Writing event: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_mangle:0xb38
...When tried to probe symbol "print_data(int)", the log shows:
Symbol print_data(int) address found : afc
The found address is 0xafc - which is right with verifying the output result from nm. Afterwards when write event, the command uses offset 0xb38 in the last log, which is a wrong address.
The dwarf_diename() gets a common function name, in above case, it returns string "print_data". As a result, the tool parses the offset based on the common name. This leads to probe at the wrong symbol "print_data(Point&)".
To fix the issue, use the die_get_linkage_name() function to retrieve the distinct linkage name - this is the mangled name for the C++ case. Based on this unique name, the tool can get a correct offset for probing. Based on DWARF doc, it is possible the linkage name is missed in the DIE, it rolls back to use dwarf_diename().
After:
# perf --debug verbose=3 probe -x test_cpp_mangle --add "test=print_data(int)"
probe-definition(0): test=print_data(int)
symbol:print_data(int) file:(null) line:0 offset:0 return:0 lazy:(null)
0 arguments
Open Debuginfo file: /home/niayan01/test_cpp_mangle
Try to find probe point from debuginfo.
Symbol print_data(int) address found : afc
Matched function: print_data [2d06]
Probe point found: print_data+0
Found 1 probe_trace_events.
Opening /sys/kernel/tracing//uprobe_events write=1
Opening /sys/kernel/tracing//README write=0
Writing event: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_mangle:0xafc
Added new event:
probe_test_cpp_mangle:test (on print_data(int) in /home/niayan01/test_cpp_mangle)You can now use it in all perf tools, such as:
perf record -e probe_test_cpp_mangle:test -aR sleep 1
# perf --debug verbose=3 probe -x test_cpp_mangle --add "test2=print_data(Point&)"
probe-definition(0): test2=print_data(Point&)
symbol:print_data(Point&) file:(null) line:0 offset:0 return:0 lazy:(null)
0 arguments
Open Debuginfo file: /home/niayan01/test_cpp_mangle
Try to find probe point from debuginfo.
Symbol print_data(Point&) address found : b38
Matched function: print_data [2ccf]
Probe point found: print_data+0
Found 1 probe_trace_events.
Opening /sys/kernel/tracing//uprobe_events write=1
Parsing probe_events: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_mangle:0x0000000000000afc
Group:probe_test_cpp_mangle Event:test probe:p
Opening /sys/kernel/tracing//README write=0
Writing event: p:probe_test_cpp_mangle/test2 /home/niayan01/test_cpp_mangle:0xb38
Added new event:
probe_test_cpp_mangle:test2 (on print_data(Point&) in /home/niayan01/test_cpp_mangle)You can now use it in all perf tools, such as:
perf record -e probe_test_cpp_mangle:test2 -aR sleep 1
--- tools/perf/util/probe-finder.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
tools/perf/util/probe-finder.c +15 -2
@@ -1587,8 +1587,21 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr,/* Find a corresponding function (name, baseline and baseaddr) */ if (die_find_realfunc (&cudie, (Dwarf_Addr )addr, &spdie)) { -/* Get function entry information */ - func = basefunc =dwarf_diename (&spdie); +/* +* Get function entry information. +* +* As described in the document DWARF Debugging Information +* Format Version 5, section 2.22 Linkage Names, "mangled names, +* are used in various ways, ... to distinguish multiple +* entities that have the same name". +* +* Firstly try to get distinct linkage name, if fail then +* rollback to get associated name in DIE. +*/ + func = basefunc =die_get_linkage_name (&spdie); +if (!func) + func = basefunc =dwarf_diename (&spdie); +if (!func ||die_entrypc (&spdie, &baseaddr) !=0 ||dwarf_decl_line (&spdie, &baseline) !=0 ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 499/817 rust: kernel: fix THIS_MODULE header path in ThisModule doc comment
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yutaro Ohno <[email protected]>
[ Upstream commit 8b55dc8610acf816a66373be53ca6e3bbe2d313a ]
The doc comment for ThisModule incorrectly states the C header file for THIS_MODULE as include/linux/export.h, while the correct path is include/linux/init.h. This is because THIS_MODULE was moved in commit 5b20755b7780 ("init: move THIS_MODULE from <linux/export.h> to <linux/init.h>").
Update the doc comment for ThisModule to reflect the correct header file path for THIS_MODULE.
--- rust/kernel/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/lib.rs +1 -1
@@ -80,7 +80,7 @@ pub trait Module: Sized + Sync + Send {/// Equivalent to `THIS_MODULE` in the C API. /// -/// C header: [`include/linux/export.h`](srctree/include/linux/export.h) +/// C header: [`include/linux/init.h`](srctree/include/linux/init.h) pub struct ThisModule (*mut bindings::module );// SAFETY: `THIS_MODULE` may be used from all threads within a module.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 500/817 rust: macros: fix documentation of the paste! macro
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Bonzini <[email protected]>
[ Upstream commit 15541c9263ce34ff95a06bc68f45d9bc5c990bcd ]
One of the example in this section uses a curious mix of the constant and function declaration syntaxes; fix it.
--- rust/macros/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
rust/macros/lib.rs +1 -1
@@ -355,7 +355,7 @@ pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {/// macro_rules! pub_no_prefix { /// ($prefix:ident, $($newname:ident),+) => { /// kernel::macros::paste! { -/// $(pub(crate) const fn [<$newname:lower:span>]: u32 = [<$prefix $newname:span>];)+ +/// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+ /// } /// }; /// }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 501/817 PCI: cpqphp: Use PCI_POSSIBLE_ERROR() to check config reads
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: weiyufeng <[email protected]>
[ Upstream commit 87d5403378cccc557af9e02a8a2c8587ad8b7e9a ]
Use PCI_POSSIBLE_ERROR() to check the response we get when we read data from hardware. This unifies PCI error response checking and makes error checks consistent and easier to find.
Stable-dep-of: e2226dbc4a49 ("PCI: cpqphp: Fix PCIBIOS_* return value confusion")
--- drivers/pci/hotplug/cpqphp_pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/hotplug/cpqphp_pci.c +2 -2
@@ -138,7 +138,7 @@ static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 oif (pci_bus_read_config_dword (bus, devfn,PCI_VENDOR_ID , &vendID) ==-1 )return -1 ; -if (vendID ==0xffffffff ) +if (PCI_POSSIBLE_ERROR (vendID))return -1 ;return pci_bus_read_config_dword (bus, devfn, offset, value); }
@@ -253,7 +253,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num *dev_num = tdevice; ctrl->pci_bus->number = tbus;pci_bus_read_config_dword (ctrl->pci_bus, *dev_num,PCI_VENDOR_ID , &work); -if (!nobridge || (work ==0xffffffff )) +if (!nobridge ||PCI_POSSIBLE_ERROR (work))return 0 ;dbg ("bus_num %d devfn %d\n" , *bus_num, *dev_num);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 502/817 PCI: cpqphp: Fix PCIBIOS_* return value confusion
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
[ Upstream commit e2226dbc4a4919d9c8bd9293299b532090bdf020 ]
Code in and related to PCI_RefinedAccessConfig() has three types of return type confusion:
- PCI_RefinedAccessConfig() tests pci_bus_read_config_dword() return value against -1.
- PCI_RefinedAccessConfig() returns both -1 and PCIBIOS_* return codes.
- Callers of PCI_RefinedAccessConfig() only test for -1.
Make PCI_RefinedAccessConfig() return PCIBIOS_* codes consistently and adapt callers accordingly.
--- drivers/pci/hotplug/cpqphp_pci.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/pci/hotplug/cpqphp_pci.c +10 -5
@@ -135,11 +135,13 @@ int cpqhp_unconfigure_device(struct pci_func *func)static int PCI_RefinedAccessConfig (struct pci_bus *bus,unsigned int devfn,u8 offset,u32 *value) {u32 vendID =0 ; +int ret; -if (pci_bus_read_config_dword (bus, devfn,PCI_VENDOR_ID , &vendID) ==-1 ) -return -1 ; + ret =pci_bus_read_config_dword (bus, devfn,PCI_VENDOR_ID , &vendID); +if (ret !=PCIBIOS_SUCCESSFUL ) +return PCIBIOS_DEVICE_NOT_FOUND ;if (PCI_POSSIBLE_ERROR (vendID)) -return -1 ; +return PCIBIOS_DEVICE_NOT_FOUND ;return pci_bus_read_config_dword (bus, devfn, offset, value); }
@@ -202,13 +204,15 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_ {u16 tdevice;u32 work; +int ret;u8 tbus; ctrl->pci_bus->number = bus_num;for (tdevice =0 ; tdevice <0xFF ; tdevice++) {/* Scan for access first */ -if (PCI_RefinedAccessConfig (ctrl->pci_bus, tdevice,0x08 , &work) ==-1 ) + ret =PCI_RefinedAccessConfig (ctrl->pci_bus, tdevice,0x08 , &work); +if (ret)continue ;dbg ("Looking for nonbridge bus_num %d dev_num %d\n" , bus_num, tdevice);/* Yep we got one. Not a bridge ? */
@@ -220,7 +224,8 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_ }for (tdevice =0 ; tdevice <0xFF ; tdevice++) {/* Scan for access first */ -if (PCI_RefinedAccessConfig (ctrl->pci_bus, tdevice,0x08 , &work) ==-1 ) + ret =PCI_RefinedAccessConfig (ctrl->pci_bus, tdevice,0x08 , &work); +if (ret)continue ;dbg ("Looking for bridge bus_num %d dev_num %d\n" , bus_num, tdevice);/* Yep we got one. bridge ? */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 503/817 rust: block: fix formatting of `kernel::block::mq::request` module
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Zardi <[email protected]>
[ Upstream commit 28e848386b92645f93b9f2fdba5882c3ca7fb3e2 ]
Fix several issues with rustdoc formatting for the kernel::block::mq::Request module, in particular:
- An ordered list not rendering correctly, fixed by using numbers prefixes instead of letters.
- Code snippets formatted as regular text, fixed by wrapping the code with back-ticks.
- References to types missing intra-doc links, fixed by wrapping the types with [square brackets].
[ Added an extra intra-doc link. Took the chance to add some periods
for consistency. Reworded slightly. - Miguel ]
--- rust/kernel/block/mq/request.rs | 67 +++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 29 deletions(-)
rust/kernel/block/mq/request.rs +38 -29
@@ -16,50 +16,55 @@ sync::atomic::{AtomicU64, Ordering}, }; -/// A wrapper around a blk-mq `struct request`. This represents an IO request. +/// A wrapper around a blk-mq [`struct request`]. This represents an IO request. /// /// # Implementation details /// /// There are four states for a request that the Rust bindings care about: /// -/// A) Request is owned by block layer (refcount 0) -/// B) Request is owned by driver but with zero `ARef`s in existence -/// (refcount 1) -/// C) Request is owned by driver with exactly one `ARef` in existence -/// (refcount 2) -/// D) Request is owned by driver with more than one `ARef` in existence -/// (refcount > 2) +/// 1. Request is owned by block layer (refcount 0). +/// 2. Request is owned by driver but with zero [`ARef`]s in existence +/// (refcount 1). +/// 3. Request is owned by driver with exactly one [`ARef`] in existence +/// (refcount 2). +/// 4. Request is owned by driver with more than one [`ARef`] in existence +/// (refcount > 2). /// /// -/// We need to track A and B to ensure we fail tag to request conversions for +/// We need to track 1 and 2 to ensure we fail tag to request conversions for /// requests that are not owned by the driver. /// -/// We need to track C and D to ensure that it is safe to end the request and hand +/// We need to track 3 and 4 to ensure that it is safe to end the request and hand /// back ownership to the block layer. /// /// The states are tracked through the private `refcount` field of /// `RequestDataWrapper`. This structure lives in the private data area of the C -/// `struct request`. +/// [`struct request`]. /// /// # Invariants /// -/// * `self.0` is a valid `struct request` created by the C portion of the kernel. +/// * `self.0` is a valid [`struct request`] created by the C portion of the +/// kernel. /// * The private data area associated with this request must be an initialized /// and valid `RequestDataWrapper<T>`. /// * `self` is reference counted by atomic modification of -/// self.wrapper_ref().refcount(). +/// `self.wrapper_ref().refcount()`. +/// +/// [`struct request`]: srctree/include/linux/blk-mq.h /// #[repr(transparent)] pub struct Request <T :Operations >(Opaque <bindings::request >,PhantomData <T >);impl <T :Operations >Request <T > { -/// Create an `ARef<Request>` from a `struct request` pointer. +/// Create an [`ARef<Request>`] from a [`struct request`] pointer. /// /// # Safety /// /// * The caller must own a refcount on `ptr` that is transferred to the -/// returned `ARef`. -/// * The type invariants for `Request` must hold for the pointee of `ptr`. +/// returned [`ARef`]. +/// * The type invariants for [`Request`] must hold for the pointee of `ptr`. +/// +/// [`struct request`]: srctree/include/linux/blk-mq.h pub (crate )unsafe fn aref_from_raw (ptr: *mut bindings::request ) ->ARef <Self > {// INVARIANT: By the safety requirements of this function, invariants are upheld. // SAFETY: By the safety requirement of this function, we own a
@@ -84,12 +89,14 @@ pub(crate) unsafe fn start_unchecked(this: &ARef<Self>) { }/// Try to take exclusive ownership of `this` by dropping the refcount to 0. -/// This fails if `this` is not the only `ARef` pointing to the underlying -/// `Request`. +/// This fails if `this` is not the only [`ARef`] pointing to the underlying +/// [`Request`]. /// -/// If the operation is successful, `Ok` is returned with a pointer to the -/// C `struct request`. If the operation fails, `this` is returned in the -/// `Err` variant. +/// If the operation is successful, [`Ok`] is returned with a pointer to the +/// C [`struct request`]. If the operation fails, `this` is returned in the +/// [`Err`] variant. +/// +/// [`struct request`]: srctree/include/linux/blk-mq.h fn try_set_end(this: ARef<Self>) -> Result<*mut bindings::request, ARef<Self>> { // We can race with `TagSet::tag_to_rq` if let Err(_old) = this.wrapper_ref().refcount().compare_exchange(
@@ -109,7 +116,7 @@ fn try_set_end(this: ARef<Self>) -> Result<*mut bindings::request, ARef<Self>> {/// Notify the block layer that the request has been completed without errors. /// -/// This function will return `Err` if `this` is not the only `ARef` +/// This function will return [`Err`] if `this` is not the only [`ARef`] /// referencing the request. pub fn end_ok (this:ARef <Self >) ->Result <(),ARef <Self >> {let request_ptr =Self ::try_set_end (this)?;
@@ -123,13 +130,13 @@ pub fn end_ok(this: ARef<Self>) -> Result<(), ARef<Self>> {Ok (()) } -/// Return a pointer to the `RequestDataWrapper` stored in the private area +/// Return a pointer to the [`RequestDataWrapper`] stored in the private area /// of the request structure. /// /// # Safety /// /// - `this` must point to a valid allocation of size at least size of -/// `Self` plus size of `RequestDataWrapper`. +/// [`Self`] plus size of [`RequestDataWrapper`]. pub (crate )unsafe fn wrapper_ptr (this: *mut Self ) ->NonNull <RequestDataWrapper > {let request_ptr = this.cast ::<bindings::request >();// SAFETY: By safety requirements for this function, `this` is a
@@ -141,7 +148,7 @@ pub(crate) unsafe fn wrapper_ptr(this: *mut Self) -> NonNull<RequestDataWrapper>unsafe {NonNull ::new_unchecked (wrapper_ptr) } } -/// Return a reference to the `RequestDataWrapper` stored in the private +/// Return a reference to the [`RequestDataWrapper`] stored in the private /// area of the request structure. pub (crate )fn wrapper_ref (&self) -> &RequestDataWrapper {// SAFETY: By type invariant, `self.0` is a valid allocation. Further,
@@ -152,13 +159,15 @@ pub(crate) fn wrapper_ref(&self) -> &RequestDataWrapper { } } -/// A wrapper around data stored in the private area of the C `struct request`. +/// A wrapper around data stored in the private area of the C [`struct request`]. +/// +/// [`struct request`]: srctree/include/linux/blk-mq.h pub (crate )struct RequestDataWrapper {/// The Rust request refcount has the following states: /// /// - 0: The request is owned by C block layer. -/// - 1: The request is owned by Rust abstractions but there are no ARef references to it. -/// - 2+: There are `ARef` references to the request. +/// - 1: The request is owned by Rust abstractions but there are no [`ARef`] references to it. +/// - 2+: There are [`ARef`] references to the request. refcount:AtomicU64 , }
@@ -204,7 +213,7 @@ fn atomic_relaxed_op_return(target: &AtomicU64, op: impl Fn(u64) -> u64) -> u64 }/// Store the result of `op(target.load)` in `target` if `target.load() != -/// pred`, returning true if the target was updated. +/// pred`, returning [`true`] if the target was updated. fn atomic_relaxed_op_unless (target: &AtomicU64 , op:impl Fn (u64 ) ->u64 , pred:u64 ) ->bool { target .fetch_update (Ordering ::Relaxed ,Ordering ::Relaxed , |x| {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 504/817 perf disasm: Use disasm_line__free() to properly free disasm_line
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Huafei <[email protected]>
[ Upstream commit b4e0e9a1e30059f4523c9b6a1f8045ad89b5db8a ]
The structure disasm_line contains members that require dynamically allocated memory and need to be freed correctly using disasm_line__free().
This patch fixes the incorrect release insymbol__disassemble_capstone().
--- tools/perf/util/disasm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/disasm.c +1 -1
@@ -1391,7 +1391,7 @@ static int symbol__disassemble_capstone(char *filename, struct symbol *sym,*/ list_for_each_entry_safe (dl, tmp, ¬es->src->source, al.node) {list_del (&dl->al.node); -free (dl); +disasm_line__free (dl); } } count =-1 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 505/817 virtiofs: use pages instead of pointer for kernel direct IO
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hou Tao <[email protected]>
[ Upstream commit 41748675c0bf252b3c5f600a95830f0936d366c1 ]
When trying to insert a 10MB kernel module kept in a virtio-fs with cache disabled, the following warning was reported:
------------[ cut here ]------------ WARNING: CPU: 1 PID: 404 at mm/page_alloc.c:4551 ...... Modules linked in: CPU: 1 PID: 404 Comm: insmod Not tainted 6.9.0-rc5+ #123 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) ...... RIP: 0010:__alloc_pages+0x2bf/0x380 ...... Call Trace: <TASK> ? __warn+0x8e/0x150 ? __alloc_pages+0x2bf/0x380 __kmalloc_large_node+0x86/0x160 __kmalloc+0x33c/0x480 virtio_fs_enqueue_req+0x240/0x6d0 virtio_fs_wake_pending_and_unlock+0x7f/0x190 queue_request_and_unlock+0x55/0x60 fuse_simple_request+0x152/0x2b0 fuse_direct_io+0x5d2/0x8c0 fuse_file_read_iter+0x121/0x160 __kernel_read+0x151/0x2d0 kernel_read+0x45/0x50 kernel_read_file+0x1a9/0x2a0 init_module_from_file+0x6a/0xe0 idempotent_init_module+0x175/0x230 __x64_sys_finit_module+0x5d/0xb0 x64_sys_call+0x1c3/0x9e0 do_syscall_64+0x3d/0xc0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 ...... </TASK> ---[ end trace 0000000000000000 ]---
The warning is triggered as follows:
1) syscall finit_module() handles the module insertion and it invokes kernel_read_file() to read the content of the module first.
2) kernel_read_file() allocates a 10MB buffer by using vmalloc() and passes it to kernel_read(). kernel_read() constructs a kvec iter by using iov_iter_kvec() and passes it to fuse_file_read_iter().
3) virtio-fs disables the cache, so fuse_file_read_iter() invokes fuse_direct_io(). As for now, the maximal read size for kvec iter is only limited by fc->max_read. For virtio-fs, max_read is UINT_MAX, so fuse_direct_io() doesn't split the 10MB buffer. It saves the address and the size of the 10MB-sized buffer in out_args[0] of a fuse request and passes the fuse request to virtio_fs_wake_pending_and_unlock().
4) virtio_fs_wake_pending_and_unlock() uses virtio_fs_enqueue_req() to queue the request. Because virtiofs need DMA-able address, so virtio_fs_enqueue_req() uses kmalloc() to allocate a bounce buffer for all fuse args, copies these args into the bounce buffer and passed the physical address of the bounce buffer to virtiofsd. The total length of these fuse args for the passed fuse request is about 10MB, so copy_args_to_argbuf() invokes kmalloc() with a 10MB size parameter and it triggers the warning in __alloc_pages():
if (WARN_ON_ONCE_GFP(order > MAX_PAGE_ORDER, gfp)) return NULL;
5) virtio_fs_enqueue_req() will retry the memory allocation in a kworker, but it won't help, because kmalloc() will always return NULL due to the abnormal size and finit_module() will hang forever.
A feasible solution is to limit the value of max_read for virtio-fs, so the length passed to kmalloc() will be limited. However it will affect the maximal read size for normal read. And for virtio-fs write initiated from kernel, it has the similar problem but now there is no way to limit fc->max_write in kernel.
So instead of limiting both the values of max_read and max_write in kernel, introducing use_pages_for_kvec_io in fuse_conn and setting it as true in virtiofs. When use_pages_for_kvec_io is enabled, fuse will use pages instead of pointer to pass the KVEC_IO data.
After switching to pages for KVEC_IO data, these pages will be used for DMA through virtio-fs. If these pages are backed by vmalloc(), {flush|invalidate}_kernel_vmap_range() are necessary to flush or invalidate the cache before the DMA operation. So add two new fields in fuse_args_pages to record the base address of vmalloc area and the condition indicating whether invalidation is needed. Perform the flush in fuse_get_user_pages() for write operations and the invalidation in fuse_release_user_pages() for read operations.
It may seem necessary to introduce another field in fuse_conn to indicate that these KVEC_IO pages are used for DMA, However, considering that virtio-fs is currently the only user of use_pages_for_kvec_io, just reuse use_pages_for_kvec_io to indicate that these pages will be used for DMA.
--- fs/fuse/file.c | 62 +++++++++++++++++++++++++++++++-------------- fs/fuse/fuse_i.h | 6 +++++ fs/fuse/virtio_fs.c | 1 + 3 files changed, 50 insertions(+), 19 deletions(-)
fs/fuse/file.c +43 -19
@@ -645,7 +645,7 @@ void fuse_read_args_fill(struct fuse_io_args *ia, struct file *file, loff_t pos, args->out_args[0 ].size = count; } -static void fuse_release_user_pages (struct fuse_args_pages *ap, +static void fuse_release_user_pages (struct fuse_args_pages *ap,ssize_t nres,bool should_dirty) {unsigned int i;
@@ -656,6 +656,9 @@ static void fuse_release_user_pages(struct fuse_args_pages *ap,if (ap->args.is_pinned)unpin_user_page (ap->pages[i]); } + +if (nres >0 && ap->args.invalidate_vmap) +invalidate_kernel_vmap_range (ap->args.vmap_base, nres); }static void fuse_io_release (struct kref *kref)
@@ -754,25 +757,29 @@ static void fuse_aio_complete_req(struct fuse_mount *fm, struct fuse_args *args,struct fuse_io_args *ia =container_of (args,typeof (*ia), ap.args);struct fuse_io_priv *io = ia->io;ssize_t pos =-1 ; - -fuse_release_user_pages (&ia->ap, io->should_dirty); +size_t nres;if (err) {/* Nothing */ }else if (io->write) {if (ia->write.out.size > ia->write.in.size) { err = -EIO ; - }else if (ia->write.in.size != ia->write.out.size) { - pos = ia->write.in.offset - io->offset + - ia->write.out.size; + }else { + nres = ia->write.out.size; +if (ia->write.in.size != ia->write.out.size) + pos = ia->write.in.offset - io->offset + + ia->write.out.size; } }else {u32 outsize = args->out_args[0 ].size; + nres = outsize;if (ia->read.in.size != outsize) pos = ia->read.in.offset - io->offset + outsize; } +fuse_release_user_pages (&ia->ap, err ?: nres, io->should_dirty); +fuse_aio_complete (io, err, pos);fuse_io_free (ia); }
@@ -1467,24 +1474,37 @@ static inline size_t fuse_get_frag_size(const struct iov_iter *ii,static int fuse_get_user_pages (struct fuse_args_pages *ap,struct iov_iter *ii,size_t *nbytesp,int write, -unsigned int max_pages) +unsigned int max_pages, +bool use_pages_for_kvec_io) { +bool flush_or_invalidate = false;size_t nbytes =0 ;/* # bytes already packed in req */ ssize_t ret =0 ; -/* Special case for kernel I/O: can copy directly into the buffer */ +/* Special case for kernel I/O: can copy directly into the buffer. +* However if the implementation of fuse_conn requires pages instead of +* pointer (e.g., virtio-fs), use iov_iter_extract_pages() instead. +*/ if (iov_iter_is_kvec (ii)) { -unsigned long user_addr =fuse_get_user_addr (ii); -size_t frag_size =fuse_get_frag_size (ii, *nbytesp); +void *user_addr = (void *)fuse_get_user_addr (ii); -if (write) - ap->args.in_args[1 ].value = (void *) user_addr; -else - ap->args.out_args[0 ].value = (void *) user_addr; +if (!use_pages_for_kvec_io) { +size_t frag_size =fuse_get_frag_size (ii, *nbytesp); -iov_iter_advance (ii, frag_size); - *nbytesp = frag_size; -return 0 ; +if (write) + ap->args.in_args[1 ].value = user_addr; +else + ap->args.out_args[0 ].value = user_addr; + +iov_iter_advance (ii, frag_size); + *nbytesp = frag_size; +return 0 ; + } + +if (is_vmalloc_addr (user_addr)) { + ap->args.vmap_base = user_addr; + flush_or_invalidate = true; + } }while (nbytes < *nbytesp && ap->num_pages < max_pages) {
@@ -1513,6 +1533,10 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii, (PAGE_SIZE - ret) & (PAGE_SIZE -1 ); } +if (write && flush_or_invalidate) +flush_kernel_vmap_range (ap->args.vmap_base, nbytes); + + ap->args.invalidate_vmap = !write && flush_or_invalidate; ap->args.is_pinned =iov_iter_extract_will_pin (ii); ap->args.user_pages = true;if (write)
@@ -1581,7 +1605,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,size_t nbytes =min (count, nmax); err =fuse_get_user_pages (&ia->ap, iter, &nbytes, write, - max_pages); + max_pages, fc->use_pages_for_kvec_io);if (err && !nbytes)break ;
@@ -1595,7 +1619,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, }if (!io->async || nres <0 ) { -fuse_release_user_pages (&ia->ap, io->should_dirty); +fuse_release_user_pages (&ia->ap, nres, io->should_dirty);fuse_io_free (ia); } ia =NULL ;
fs/fuse/fuse_i.h +6 -0
@@ -309,9 +309,12 @@ struct fuse_args { bool may_block:1; bool is_ext:1; bool is_pinned:1; + bool invalidate_vmap:1;struct fuse_in_arg in_args[3 ];struct fuse_arg out_args[2 ];void (*end)(struct fuse_mount *fm,struct fuse_args *args,int error); +/* Used for kvec iter backed by vmalloc address */ +void *vmap_base; };struct fuse_args_pages {
@@ -860,6 +863,9 @@ struct fuse_conn {/** Passthrough support for read/write IO */ unsigned int passthrough:1; +/* Use pages instead of pointer for kernel I/O */ + unsigned int use_pages_for_kvec_io:1; +/** Maximum stack depth for passthrough backing files */ int max_stack_depth;
fs/fuse/virtio_fs.c +1 -0
@@ -1568,6 +1568,7 @@ static int virtio_fs_get_tree(struct fs_context *fsc) fc->delete_stale = true; fc->auto_submounts = true; fc->sync_fs = true; + fc->use_pages_for_kvec_io = true;/* Tell FUSE to split requests that exceed the virtqueue's size */ fc->max_pages_limit = min_t(unsigned int, fc->max_pages_limit,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 506/817 perf ftrace latency: Fix unit on histogram first entry when using --use-nsec
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
[ Upstream commit 064d569e20e82c065b1dec9d20c29c7087bb1a00 ]
The use_nsec arg wasn't being taken into account when printing the first histogram entry, fix it:
root@number:~# perf ftrace latency --use-nsec -T switch_mm_irqs_off -a sleep 2
# DURATION | COUNT | GRAPH |
0 - 1 us | 0 | |
1 - 2 ns | 0 | |
2 - 4 ns | 0 | |
4 - 8 ns | 0 | |
8 - 16 ns | 0 | |
16 - 32 ns | 0 | |
32 - 64 ns | 125 | |
64 - 128 ns | 335 | |
128 - 256 ns | 2155 | #### |
256 - 512 ns | 9996 | ################### |
512 - 1024 ns | 4958 | ######### |
1 - 2 us | 4636 | ######### |
2 - 4 us | 1053 | ## |
4 - 8 us | 15 | |
8 - 16 us | 1 | |
16 - 32 us | 0 | |
32 - 64 us | 0 | |
64 - 128 us | 0 | |
128 - 256 us | 0 | |
256 - 512 us | 0 | |
512 - 1024 us | 0 | |
1 - ... ms | 0 | |
root@number:~#After:
root@number:~# perf ftrace latency --use-nsec -T switch_mm_irqs_off -a sleep 2
# DURATION | COUNT | GRAPH |
0 - 1 ns | 0 | |
1 - 2 ns | 0 | |
2 - 4 ns | 0 | |
4 - 8 ns | 0 | |
8 - 16 ns | 0 | |
16 - 32 ns | 0 | |
32 - 64 ns | 19 | |
64 - 128 ns | 94 | |
128 - 256 ns | 2191 | #### |
256 - 512 ns | 9719 | #################### |
512 - 1024 ns | 5330 | ########### |
1 - 2 us | 4104 | ######## |
2 - 4 us | 807 | # |
4 - 8 us | 9 | |
8 - 16 us | 0 | |
16 - 32 us | 0 | |
32 - 64 us | 0 | |
64 - 128 us | 0 | |
128 - 256 us | 0 | |
256 - 512 us | 0 | |
512 - 1024 us | 0 | |
1 - ... ms | 0 | |
root@number:~#--- tools/perf/builtin-ftrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-ftrace.c +1 -1
@@ -771,7 +771,7 @@ static void display_histogram(int buckets[], bool use_nsec) bar_len = buckets[0 ] * bar_total / total;printf (" %4d - %-4d %s | %10d | %.*s%*s |\n" , -0 ,1 ,"us" , buckets[0 ], bar_len, bar, bar_total - bar_len,"" ); +0 ,1 , use_nsec ?"ns" :"us" , buckets[0 ], bar_len, bar, bar_total - bar_len,"" );for (i =1 ; i <NUM_BUCKET -1 ; i++) {int start = (1 << (i -1 ));
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 507/817 i3c: master: Remove i3c_dev_disable_ibi_locked(olddev) on device hotjoin
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
[ Upstream commit 36faa04ce3d9c962b4b29d285ad07ca29e2988e4 ]
When a new device hotjoins, a new dynamic address is assigned. i3c_master_add_i3c_dev_locked() identifies that the device was previously attached to the bus and locates the olddev.
i3c_master_add_i3c_dev_locked()
{
...
olddev = i3c_master_search_i3c_dev_duplicate(newdev);
...
if (olddev) {
...
i3c_dev_disable_ibi_locked(olddev);
^^^^^^
The olddev should not receive any commands on the i3c bus as it
does not exist and has been assigned a new address. This will
result in NACK or timeout. So remove it.
}
i3c_dev_free_ibi_locked(olddev);
^^^^^^^^
This function internally calls i3c_dev_disable_ibi_locked() function
causing to send DISEC command with old Address.
The olddev should not receive any commands on the i3c bus as it
does not exist and has been assigned a new address. This will
result in NACK or timeout. So, update the olddev->ibi->enabled
flag to false to avoid DISEC with OldAddr.
}Include part of Ravindra Yashvant Shinde's work:
https://lore.kernel.org/linux-i3c/[email protected]/T/#u
--- drivers/i3c/master.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/i3c/master.c +9 -4
@@ -2039,11 +2039,16 @@ int i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master, ibireq.max_payload_len = olddev->ibi->max_payload_len; ibireq.num_slots = olddev->ibi->num_slots; -if (olddev->ibi->enabled) { +if (olddev->ibi->enabled) enable_ibi = true; -i3c_dev_disable_ibi_locked (olddev); - } - +/* +* The olddev should not receive any commands on the +* i3c bus as it does not exist and has been assigned +* a new address. This will result in NACK or timeout. +* So, update the olddev->ibi->enabled flag to false +* to avoid DISEC with OldAddr. +*/ + olddev->ibi->enabled = false;i3c_dev_free_ibi_locked (olddev); }mutex_unlock (&olddev->ibi_lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 508/817 f2fs: fix the wrong f2fs_bug_on condition in f2fs_do_replace_block
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: LongPing Wei <[email protected]>
[ Upstream commit c3af1f13476ec23fd99c98d060a89be28c1e8871 ]
This f2fs_bug_on was introduced by commit 2c1905042c8c ("f2fs: check segment type in __f2fs_replace_block") when there were only 6 curseg types. After commit d0b9e42ab615 ("f2fs: introduce inmem curseg") was introduced, the condition should be changed to checking curseg->seg_type.
--- fs/f2fs/segment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/f2fs/segment.c +1 -1
@@ -3974,8 +3974,8 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, } } -f2fs_bug_on (sbi, !IS_DATASEG (type)); curseg =CURSEG_I (sbi, type); +f2fs_bug_on (sbi, !IS_DATASEG (curseg->seg_type));mutex_lock (&curseg->curseg_mutex);down_write (&sit_i->sentry_lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 509/817 f2fs: check curseg->inited before write_sum_page in change_curseg
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongpeng Yang <[email protected]>
[ Upstream commit 43563069e1c1df417d2eed6eca8a22fc6b04691d ]
In the __f2fs_init_atgc_curseg->get_atssr_segment calling, curseg->segno is NULL_SEGNO, indicating that there is no summary block that needs to be written.
--- fs/f2fs/segment.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/f2fs/segment.c +2 -1
@@ -2926,7 +2926,8 @@ static int change_curseg(struct f2fs_sb_info *sbi, int type)struct f2fs_summary_block *sum_node;struct page *sum_page; -write_sum_page (sbi, curseg->sum_blk,GET_SUM_BLOCK (sbi, curseg->segno)); +if (curseg->inited) +write_sum_page (sbi, curseg->sum_blk,GET_SUM_BLOCK (sbi, curseg->segno));__set_test_and_inuse (sbi, new_segno);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 510/817 f2fs: Fix not used variable index
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zeng Heng <[email protected]>
[ Upstream commit 0c3a38a4b442893f8baca72e44a2a27d52d6cc75 ]
Fix the following compilation warning:fs/f2fs/data.c:2391:10: warning: variable ‘index’ set but not used [-Wunused-but-set-variable]
2391 | pgoff_t index;
Only define and set the variable index when the CONFIG_F2FS_FS_COMPRESSION is enabled.
--- fs/f2fs/data.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/f2fs/data.c +2 -2
@@ -2354,10 +2354,10 @@ static int f2fs_mpage_readpages(struct i .nr_cpages = 0, };pgoff_t nc_cluster_idx =NULL_CLUSTER ; +pgoff_t index;#endif unsigned nr_pages = rac ?readahead_count (rac) :1 ;unsigned max_nr_pages = nr_pages; -pgoff_t index;int ret =0 ; map.m_pblk =0 ;
@@ -2375,9 +2375,9 @@ static int f2fs_mpage_readpages(struct iprefetchw (&folio->flags); } +#ifdef CONFIG_F2FS_FS_COMPRESSION index =folio_index (folio); -#ifdef CONFIG_F2FS_FS_COMPRESSION if (!f2fs_compressed_file (inode)) goto read_single_page;
Greg Kroah-Hartman
maintainerPATCH 511/817 f2fs: fix to avoid potential deadlock in f2fs_record_stop_reason()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit f10a890308a7cd8794e21f646f09827c6cb4bf5d ]
syzbot reports deadlock issue of f2fs as below:
======================================================
WARNING: possible circular locking dependency detected 6.12.0-rc3-syzkaller-00087-gc964ced77262 #0 Not tainted
------------------------------------------------------
kswapd0/79 is trying to acquire lock:ffff888011824088 (&sbi->sb_lock){++++}-{3:3}, at: f2fs_down_write fs/f2fs/f2fs.h:2199 [inline] ffff888011824088 (&sbi->sb_lock){++++}-{3:3}, at: f2fs_record_stop_reason+0x52/0x1d0 fs/f2fs/super.c:4068
but task is already holding lock:ffff88804bd92610 (sb_internal#2){.+.+}-{0:0}, at: f2fs_evict_inode+0x662/0x15c0 fs/f2fs/inode.c:842
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (sb_internal#2){.+.+}-{0:0}:
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5825
percpu_down_read include/linux/percpu-rwsem.h:51 [inline]
__sb_start_write include/linux/fs.h:1716 [inline]
sb_start_intwrite+0x4d/0x1c0 include/linux/fs.h:1899
f2fs_evict_inode+0x662/0x15c0 fs/f2fs/inode.c:842
evict+0x4e8/0x9b0 fs/inode.c:725
f2fs_evict_inode+0x1a4/0x15c0 fs/f2fs/inode.c:807
evict+0x4e8/0x9b0 fs/inode.c:725
dispose_list fs/inode.c:774 [inline]
prune_icache_sb+0x239/0x2f0 fs/inode.c:963
super_cache_scan+0x38c/0x4b0 fs/super.c:223
do_shrink_slab+0x701/0x1160 mm/shrinker.c:435
shrink_slab+0x1093/0x14d0 mm/shrinker.c:662
shrink_one+0x43b/0x850 mm/vmscan.c:4818
shrink_many mm/vmscan.c:4879 [inline]
lru_gen_shrink_node mm/vmscan.c:4957 [inline]
shrink_node+0x3799/0x3de0 mm/vmscan.c:5937
kswapd_shrink_node mm/vmscan.c:6765 [inline]
balance_pgdat mm/vmscan.c:6957 [inline]
kswapd+0x1ca3/0x3700 mm/vmscan.c:7226
kthread+0x2f0/0x390 kernel/kthread.c:389
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244-> #1 (fs_reclaim){+.+.}-{0:0}:
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5825
__fs_reclaim_acquire mm/page_alloc.c:3834 [inline]
fs_reclaim_acquire+0x88/0x130 mm/page_alloc.c:3848
might_alloc include/linux/sched/mm.h:318 [inline]
prepare_alloc_pages+0x147/0x5b0 mm/page_alloc.c:4493
__alloc_pages_noprof+0x16f/0x710 mm/page_alloc.c:4722
alloc_pages_mpol_noprof+0x3e8/0x680 mm/mempolicy.c:2265
alloc_pages_noprof mm/mempolicy.c:2345 [inline]
folio_alloc_noprof+0x128/0x180 mm/mempolicy.c:2352
filemap_alloc_folio_noprof+0xdf/0x500 mm/filemap.c:1010
do_read_cache_folio+0x2eb/0x850 mm/filemap.c:3787
read_mapping_folio include/linux/pagemap.h:1011 [inline]
f2fs_commit_super+0x3c0/0x7d0 fs/f2fs/super.c:4032
f2fs_record_stop_reason+0x13b/0x1d0 fs/f2fs/super.c:4079
f2fs_handle_critical_error+0x2ac/0x5c0 fs/f2fs/super.c:4174
f2fs_write_inode+0x35f/0x4d0 fs/f2fs/inode.c:785
write_inode fs/fs-writeback.c:1503 [inline]
__writeback_single_inode+0x711/0x10d0 fs/fs-writeback.c:1723
writeback_single_inode+0x1f3/0x660 fs/fs-writeback.c:1779
sync_inode_metadata+0xc4/0x120 fs/fs-writeback.c:2849
f2fs_release_file+0xa8/0x100 fs/f2fs/file.c:1941
__fput+0x23f/0x880 fs/file_table.c:431
task_work_run+0x24f/0x310 kernel/task_work.c:228
resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
exit_to_user_mode_loop kernel/entry/common.c:114 [inline]
exit_to_user_mode_prepare include/linux/entry-common.h:328 [inline]
__syscall_exit_to_user_mode_work kernel/entry/common.c:207 [inline]
syscall_exit_to_user_mode+0x168/0x370 kernel/entry/common.c:218
do_syscall_64+0x100/0x230 arch/x86/entry/common.c:89
entry_SYSCALL_64_after_hwframe+0x77/0x7f-> #0 (&sbi->sb_lock){++++}-{3:3}:
check_prev_add kernel/locking/lockdep.c:3161 [inline]
check_prevs_add kernel/locking/lockdep.c:3280 [inline]
validate_chain+0x18ef/0x5920 kernel/locking/lockdep.c:3904
__lock_acquire+0x1384/0x2050 kernel/locking/lockdep.c:5202
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5825
down_write+0x99/0x220 kernel/locking/rwsem.c:1577
f2fs_down_write fs/f2fs/f2fs.h:2199 [inline]
f2fs_record_stop_reason+0x52/0x1d0 fs/f2fs/super.c:4068
f2fs_handle_critical_error+0x2ac/0x5c0 fs/f2fs/super.c:4174
f2fs_evict_inode+0xa61/0x15c0 fs/f2fs/inode.c:883
evict+0x4e8/0x9b0 fs/inode.c:725
f2fs_evict_inode+0x1a4/0x15c0 fs/f2fs/inode.c:807
evict+0x4e8/0x9b0 fs/inode.c:725
dispose_list fs/inode.c:774 [inline]
prune_icache_sb+0x239/0x2f0 fs/inode.c:963
super_cache_scan+0x38c/0x4b0 fs/super.c:223
do_shrink_slab+0x701/0x1160 mm/shrinker.c:435
shrink_slab+0x1093/0x14d0 mm/shrinker.c:662
shrink_one+0x43b/0x850 mm/vmscan.c:4818
shrink_many mm/vmscan.c:4879 [inline]
lru_gen_shrink_node mm/vmscan.c:4957 [inline]
shrink_node+0x3799/0x3de0 mm/vmscan.c:5937
kswapd_shrink_node mm/vmscan.c:6765 [inline]
balance_pgdat mm/vmscan.c:6957 [inline]
kswapd+0x1ca3/0x3700 mm/vmscan.c:7226
kthread+0x2f0/0x390 kernel/kthread.c:389
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244other info that might help us debug this:
Chain exists of: &sbi->sb_lock --> fs_reclaim --> sb_internal#2 Possible unsafe locking scenario:
CPU0 CPU1
---- ----
rlock(sb_internal#2);
lock(fs_reclaim);
lock(sb_internal#2); lock(&sbi->sb_lock);
Root cause is there will be potential deadlock in between below tasks:
Thread A Kswapd
- f2fs_ioc_commit_atomic_write
- mnt_want_write_file -- down_read lock A
- balance_pgdat
- __fs_reclaim_acquire -- lock B
- shrink_node
- prune_icache_sb
- dispose_list
- f2fs_evict_inode
- sb_start_intwrite -- down_read lock A
- f2fs_do_sync_file
- f2fs_write_inode
- f2fs_handle_critical_error
- f2fs_record_stop_reason
- f2fs_commit_super
- read_mapping_folio
- filemap_alloc_folio_noprof
- fs_reclaim_acquire -- lock B
Both threads try to acquire read lock of lock A, then its upcoming write lock grabber will trigger deadlock.
Let's always create an asynchronous task in f2fs_handle_critical_error() rather than calling f2fs_record_stop_reason() synchronously to avoid this potential deadlock issue.
--- fs/f2fs/checkpoint.c | 2 +- fs/f2fs/f2fs.h | 3 +-- fs/f2fs/super.c | 13 +++++++------ 3 files changed, 9 insertions(+), 9 deletions(-)
fs/f2fs/checkpoint.c +1 -1
@@ -32,7 +32,7 @@ void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,f2fs_build_fault_attr (sbi,0 ,0 );if (!end_io)f2fs_flush_merged_writes (sbi); -f2fs_handle_critical_error (sbi, reason, end_io); +f2fs_handle_critical_error (sbi, reason); }/*
fs/f2fs/f2fs.h +1 -2
@@ -3635,8 +3635,7 @@ int f2fs_quota_sync(struct super_block *sb, int type);loff_t max_file_blocks (struct inode *inode);void f2fs_quota_off_umount (struct super_block *sb);void f2fs_save_errors (struct f2fs_sb_info *sbi,unsigned char flag); -void f2fs_handle_critical_error (struct f2fs_sb_info *sbi,unsigned char reason, -bool irq_context); +void f2fs_handle_critical_error (struct f2fs_sb_info *sbi,unsigned char reason);void f2fs_handle_error (struct f2fs_sb_info *sbi,unsigned char error);void f2fs_handle_error_async (struct f2fs_sb_info *sbi,unsigned char error);int f2fs_commit_super (struct f2fs_sb_info *sbi,bool recover);
fs/f2fs/super.c +7 -6
@@ -4136,8 +4136,7 @@ static bool system_going_down(void) || system_state == SYSTEM_RESTART; } -void f2fs_handle_critical_error (struct f2fs_sb_info *sbi,unsigned char reason, -bool irq_context) +void f2fs_handle_critical_error (struct f2fs_sb_info *sbi,unsigned char reason) {struct super_block *sb = sbi->sb;bool shutdown = reason ==STOP_CP_REASON_SHUTDOWN ;
@@ -4149,10 +4148,12 @@ void f2fs_handle_critical_error(struct f2fs_sb_info *sbi, unsigned char reason,if (!f2fs_hw_is_readonly (sbi)) {save_stop_reason (sbi, reason); -if (irq_context && !shutdown) -schedule_work (&sbi->s_error_work); -else -f2fs_record_stop_reason (sbi); +/* +* always create an asynchronous task to record stop_reason +* in order to avoid potential deadlock when running into +* f2fs_record_stop_reason() synchronously. +*/ +schedule_work (&sbi->s_error_work); }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 512/817 f2fs: fix to avoid use GC_AT when setting gc_mode as GC_URGENT_LOW or GC_URGENT_MID
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiguo Niu <[email protected]>
[ Upstream commit 296b8cb34e65fa93382cf919be5a056f719c9a26 ]
If gc_mode is set to GC_URGENT_LOW or GC_URGENT_MID, cost benefit GC approach should be used, but if ATGC is enabled at the same time, Age-threshold approach will be selected, which can only do amount of GC and it is much less than the numbers of CB approach.
some traces:
f2fs_gc-254:48-396 [007] ..... 2311600.684028: f2fs_gc_begin: dev = (254,48), gc_type = Background GC, no_background_GC = 0, nr_free_secs = 0, nodes = 1053, dents = 2, imeta = 18, free_sec:44898, free_seg:44898, rsv_seg:239, prefree_seg:0 f2fs_gc-254:48-396 [007] ..... 2311600.684527: f2fs_get_victim: dev = (254,48), type = No TYPE, policy = (Background GC, LFS-mode, Age-threshold), victim = 10, cost = 4294364975, ofs_unit = 1, pre_victim_secno = -1, prefree = 0, free = 44898 f2fs_gc-254:48-396 [007] ..... 2311600.714835: f2fs_gc_end: dev = (254,48), ret = 0, seg_freed = 0, sec_freed = 0, nodes = 1562, dents = 2, imeta = 18, free_sec:44898, free_seg:44898, rsv_seg:239, prefree_seg:0 f2fs_gc-254:48-396 [007] ..... 2311600.714843: f2fs_background_gc: dev = (254,48), wait_ms = 50, prefree = 0, free = 44898 f2fs_gc-254:48-396 [007] ..... 2311600.771785: f2fs_gc_begin: dev = (254,48), gc_type = Background GC, no_background_GC = 0, nr_free_secs = 0, nodes = 1562, dents = 2, imeta = 18, free_sec:44898, free_seg:44898, rsv_seg:239, prefree_seg: f2fs_gc-254:48-396 [007] ..... 2311600.772275: f2fs_gc_end: dev = (254,48), ret = -61, seg_freed = 0, sec_freed = 0, nodes = 1562, dents = 2, imeta = 18, free_sec:44898, free_seg:44898, rsv_seg:239, prefree_seg:0
--- Documentation/ABI/testing/sysfs-fs-f2fs | 7 +++++-- fs/f2fs/gc.c | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-)
Documentation/ABI/testing/sysfs-fs-f2fs +5 -2
@@ -311,10 +311,13 @@ Description: Do background GC aggressively when set. Set to 0 by default. GC approach and turns SSR mode on. gc urgent low(2): lowers the bar of checking I/O idling in order to process outstanding discard commands and GC a - little bit aggressively. uses cost benefit GC approach. + little bit aggressively. always uses cost benefit GC approach, + and will override age-threshold GC approach if ATGC is enabled + at the same time. gc urgent mid(3): does GC forcibly in a period of given gc_urgent_sleep_time and executes a mid level of I/O idling check. - uses cost benefit GC approach. + always uses cost benefit GC approach, and will override + age-threshold GC approach if ATGC is enabled at the same time. What: /sys/fs/f2fs/<disk>/gc_urgent_sleep_time Date: August 2017
fs/f2fs/gc.c +2 -0
@@ -251,6 +251,8 @@ static int select_gc_type(struct f2fs_sb_info *sbi, int gc_type)switch (sbi->gc_mode) {case GC_IDLE_CB : +case GC_URGENT_LOW : +case GC_URGENT_MID : gc_mode =GC_CB ;break ;case GC_IDLE_GREEDY :
Signature · 1 line
2.43.0