Re: [PATCH v4] powerpc:85xx: Add missing of_node_put() in sgy_cst1000
Le 17/06/2022 à 08:45, Liang He a écrit : > > > > At 2022-06-17 14:28:56, "Christophe Leroy" > wrote: >> >> >> Le 17/06/2022 à 08:08, Liang He a écrit : >>> In gpio_halt_probe(), of_find_matching_node() will return a node >>> pointer with refcount incremented. We should use of_node_put() in >>> fail path or when it is not used anymore. >>> >>> Signed-off-by: Liang He >>> --- >>>changelog: >>>v4: reuse exist 'err' and use a simple code style, advised by CJ >>>v3: use local 'child_node' advised by Michael. >>>v2: use goto-label patch style advised by Christophe Leroy. >>>v1: add of_node_put() before each exit. >>> >>>arch/powerpc/platforms/85xx/sgy_cts1000.c | 35 ++- >>>1 file changed, 22 insertions(+), 13 deletions(-) >>> >>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c >>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c >>> index 98ae64075193..e4588943fe7e 100644 >>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c >>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c >>> @@ -71,6 +71,7 @@ static int gpio_halt_probe(struct platform_device *pdev) >>>{ >>> enum of_gpio_flags flags; >>> struct device_node *node = pdev->dev.of_node; >>> + struct device_node *child_node; >>> int gpio, err, irq; >>> int trigger; >>> >>> @@ -78,26 +79,29 @@ static int gpio_halt_probe(struct platform_device *pdev) >>> return -ENODEV; >>> >>> /* If there's no matching child, this isn't really an error */ >>> - halt_node = of_find_matching_node(node, child_match); >>> - if (!halt_node) >>> + child_node = of_find_matching_node(node, child_match); >>> + if (!child_node) >>> return 0; >>> >>> /* Technically we could just read the first one, but punish >>> * DT writers for invalid form. */ >>> - if (of_gpio_count(halt_node) != 1) >>> - return -EINVAL; >>> + if (of_gpio_count(child_node) != 1) { >>> + err = -EINVAL; >>> + goto err_put; >>> + } >>> >>> /* Get the gpio number relative to the dynamic base. */ >>> - gpio = of_get_gpio_flags(halt_node, 0, &flags); >>> - if (!gpio_is_valid(gpio)) >>> - return -EINVAL; >>> + gpio = of_get_gpio_flags(child_node, 0, &flags); >>> + if (!gpio_is_valid(gpio)) { >>> + err = -EINVAL; >>> + gotot err_put; >> >> Did you test the build ? > > Sorry for this fault. > > In fact, I am still finding an efficient way to building different arch > source code as I only have x86-64. > > Now I am try using QEMU. > > Anyway, sorry for this fault. You can find cross compilers for most architectures for x86-64 here : https://mirrors.edge.kernel.org/pub/tools/crosstool/ Christophe
Re:Re: [PATCH v4] powerpc:85xx: Add missing of_node_put() in sgy_cst1000
At 2022-06-17 14:28:56, "Christophe Leroy" wrote: > > >Le 17/06/2022 à 08:08, Liang He a écrit : >> In gpio_halt_probe(), of_find_matching_node() will return a node >> pointer with refcount incremented. We should use of_node_put() in >> fail path or when it is not used anymore. >> >> Signed-off-by: Liang He >> --- >> changelog: >> v4: reuse exist 'err' and use a simple code style, advised by CJ >> v3: use local 'child_node' advised by Michael. >> v2: use goto-label patch style advised by Christophe Leroy. >> v1: add of_node_put() before each exit. >> >> arch/powerpc/platforms/85xx/sgy_cts1000.c | 35 ++- >> 1 file changed, 22 insertions(+), 13 deletions(-) >> >> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c >> b/arch/powerpc/platforms/85xx/sgy_cts1000.c >> index 98ae64075193..e4588943fe7e 100644 >> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c >> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c >> @@ -71,6 +71,7 @@ static int gpio_halt_probe(struct platform_device *pdev) >> { >> enum of_gpio_flags flags; >> struct device_node *node = pdev->dev.of_node; >> +struct device_node *child_node; >> int gpio, err, irq; >> int trigger; >> >> @@ -78,26 +79,29 @@ static int gpio_halt_probe(struct platform_device *pdev) >> return -ENODEV; >> >> /* If there's no matching child, this isn't really an error */ >> -halt_node = of_find_matching_node(node, child_match); >> -if (!halt_node) >> +child_node = of_find_matching_node(node, child_match); >> +if (!child_node) >> return 0; >> >> /* Technically we could just read the first one, but punish >> * DT writers for invalid form. */ >> -if (of_gpio_count(halt_node) != 1) >> -return -EINVAL; >> +if (of_gpio_count(child_node) != 1) { >> +err = -EINVAL; >> +goto err_put; >> +} >> >> /* Get the gpio number relative to the dynamic base. */ >> -gpio = of_get_gpio_flags(halt_node, 0, &flags); >> -if (!gpio_is_valid(gpio)) >> -return -EINVAL; >> +gpio = of_get_gpio_flags(child_node, 0, &flags); >> +if (!gpio_is_valid(gpio)) { >> +err = -EINVAL; >> +gotot err_put; > >Did you test the build ? Sorry for this fault. In fact, I am still finding an efficient way to building different arch source code as I only have x86-64. Now I am try using QEMU. Anyway, sorry for this fault. > >> +} >> >> err = gpio_request(gpio, "gpio-halt"); >> if (err) { >> printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n", >> gpio); >> -halt_node = NULL; >> -return err; >> +goto err_put; >> } >> >> trigger = (flags == OF_GPIO_ACTIVE_LOW); >> @@ -105,15 +109,14 @@ static int gpio_halt_probe(struct platform_device >> *pdev) >> gpio_direction_output(gpio, !trigger); >> >> /* Now get the IRQ which tells us when the power button is hit */ >> -irq = irq_of_parse_and_map(halt_node, 0); >> +irq = irq_of_parse_and_map(child_node, 0); >> err = request_irq(irq, gpio_halt_irq, IRQF_TRIGGER_RISING | >> - IRQF_TRIGGER_FALLING, "gpio-halt", halt_node); >> + IRQF_TRIGGER_FALLING, "gpio-halt", child_node); >> if (err) { >> printk(KERN_ERR "gpio-halt: error requesting IRQ %d for " >> "GPIO %d.\n", irq, gpio); >> gpio_free(gpio); >> -halt_node = NULL; >> -return err; >> +goto err_put; >> } >> >> /* Register our halt function */ >> @@ -123,7 +126,12 @@ static int gpio_halt_probe(struct platform_device *pdev) >> printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" >> " irq).\n", gpio, trigger, irq); >> >> +halt_node = child_node; >> return 0; >> + >> +err_put: >> +of_node_put(child_node); >> +return err; >> } >> >> static int gpio_halt_remove(struct platform_device *pdev) >> @@ -139,6 +147,7 @@ static int gpio_halt_remove(struct platform_device *pdev) >> >> gpio_free(gpio); >> >> +of_node_put(halt_node); >> halt_node = NULL; >> } >>
Re: [PATCH v4] powerpc:85xx: Add missing of_node_put() in sgy_cst1000
Le 17/06/2022 à 08:08, Liang He a écrit : > In gpio_halt_probe(), of_find_matching_node() will return a node > pointer with refcount incremented. We should use of_node_put() in > fail path or when it is not used anymore. > > Signed-off-by: Liang He > --- > changelog: > v4: reuse exist 'err' and use a simple code style, advised by CJ > v3: use local 'child_node' advised by Michael. > v2: use goto-label patch style advised by Christophe Leroy. > v1: add of_node_put() before each exit. > > arch/powerpc/platforms/85xx/sgy_cts1000.c | 35 ++- > 1 file changed, 22 insertions(+), 13 deletions(-) > > diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c > b/arch/powerpc/platforms/85xx/sgy_cts1000.c > index 98ae64075193..e4588943fe7e 100644 > --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c > +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c > @@ -71,6 +71,7 @@ static int gpio_halt_probe(struct platform_device *pdev) > { > enum of_gpio_flags flags; > struct device_node *node = pdev->dev.of_node; > + struct device_node *child_node; > int gpio, err, irq; > int trigger; > > @@ -78,26 +79,29 @@ static int gpio_halt_probe(struct platform_device *pdev) > return -ENODEV; > > /* If there's no matching child, this isn't really an error */ > - halt_node = of_find_matching_node(node, child_match); > - if (!halt_node) > + child_node = of_find_matching_node(node, child_match); > + if (!child_node) > return 0; > > /* Technically we could just read the first one, but punish >* DT writers for invalid form. */ > - if (of_gpio_count(halt_node) != 1) > - return -EINVAL; > + if (of_gpio_count(child_node) != 1) { > + err = -EINVAL; > + goto err_put; > + } > > /* Get the gpio number relative to the dynamic base. */ > - gpio = of_get_gpio_flags(halt_node, 0, &flags); > - if (!gpio_is_valid(gpio)) > - return -EINVAL; > + gpio = of_get_gpio_flags(child_node, 0, &flags); > + if (!gpio_is_valid(gpio)) { > + err = -EINVAL; > + gotot err_put; Did you test the build ? > + } > > err = gpio_request(gpio, "gpio-halt"); > if (err) { > printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n", > gpio); > - halt_node = NULL; > - return err; > + goto err_put; > } > > trigger = (flags == OF_GPIO_ACTIVE_LOW); > @@ -105,15 +109,14 @@ static int gpio_halt_probe(struct platform_device *pdev) > gpio_direction_output(gpio, !trigger); > > /* Now get the IRQ which tells us when the power button is hit */ > - irq = irq_of_parse_and_map(halt_node, 0); > + irq = irq_of_parse_and_map(child_node, 0); > err = request_irq(irq, gpio_halt_irq, IRQF_TRIGGER_RISING | > - IRQF_TRIGGER_FALLING, "gpio-halt", halt_node); > + IRQF_TRIGGER_FALLING, "gpio-halt", child_node); > if (err) { > printk(KERN_ERR "gpio-halt: error requesting IRQ %d for " > "GPIO %d.\n", irq, gpio); > gpio_free(gpio); > - halt_node = NULL; > - return err; > + goto err_put; > } > > /* Register our halt function */ > @@ -123,7 +126,12 @@ static int gpio_halt_probe(struct platform_device *pdev) > printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" > " irq).\n", gpio, trigger, irq); > > + halt_node = child_node; > return 0; > + > +err_put: > + of_node_put(child_node); > + return err; > } > > static int gpio_halt_remove(struct platform_device *pdev) > @@ -139,6 +147,7 @@ static int gpio_halt_remove(struct platform_device *pdev) > > gpio_free(gpio); > > + of_node_put(halt_node); > halt_node = NULL; > } >
[PATCH v4] powerpc:85xx: Add missing of_node_put() in sgy_cst1000
In gpio_halt_probe(), of_find_matching_node() will return a node pointer with refcount incremented. We should use of_node_put() in fail path or when it is not used anymore. Signed-off-by: Liang He --- changelog: v4: reuse exist 'err' and use a simple code style, advised by CJ v3: use local 'child_node' advised by Michael. v2: use goto-label patch style advised by Christophe Leroy. v1: add of_node_put() before each exit. arch/powerpc/platforms/85xx/sgy_cts1000.c | 35 ++- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c index 98ae64075193..e4588943fe7e 100644 --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c @@ -71,6 +71,7 @@ static int gpio_halt_probe(struct platform_device *pdev) { enum of_gpio_flags flags; struct device_node *node = pdev->dev.of_node; + struct device_node *child_node; int gpio, err, irq; int trigger; @@ -78,26 +79,29 @@ static int gpio_halt_probe(struct platform_device *pdev) return -ENODEV; /* If there's no matching child, this isn't really an error */ - halt_node = of_find_matching_node(node, child_match); - if (!halt_node) + child_node = of_find_matching_node(node, child_match); + if (!child_node) return 0; /* Technically we could just read the first one, but punish * DT writers for invalid form. */ - if (of_gpio_count(halt_node) != 1) - return -EINVAL; + if (of_gpio_count(child_node) != 1) { + err = -EINVAL; + goto err_put; + } /* Get the gpio number relative to the dynamic base. */ - gpio = of_get_gpio_flags(halt_node, 0, &flags); - if (!gpio_is_valid(gpio)) - return -EINVAL; + gpio = of_get_gpio_flags(child_node, 0, &flags); + if (!gpio_is_valid(gpio)) { + err = -EINVAL; + gotot err_put; + } err = gpio_request(gpio, "gpio-halt"); if (err) { printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n", gpio); - halt_node = NULL; - return err; + goto err_put; } trigger = (flags == OF_GPIO_ACTIVE_LOW); @@ -105,15 +109,14 @@ static int gpio_halt_probe(struct platform_device *pdev) gpio_direction_output(gpio, !trigger); /* Now get the IRQ which tells us when the power button is hit */ - irq = irq_of_parse_and_map(halt_node, 0); + irq = irq_of_parse_and_map(child_node, 0); err = request_irq(irq, gpio_halt_irq, IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, "gpio-halt", halt_node); + IRQF_TRIGGER_FALLING, "gpio-halt", child_node); if (err) { printk(KERN_ERR "gpio-halt: error requesting IRQ %d for " "GPIO %d.\n", irq, gpio); gpio_free(gpio); - halt_node = NULL; - return err; + goto err_put; } /* Register our halt function */ @@ -123,7 +126,12 @@ static int gpio_halt_probe(struct platform_device *pdev) printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" " irq).\n", gpio, trigger, irq); + halt_node = child_node; return 0; + +err_put: + of_node_put(child_node); + return err; } static int gpio_halt_remove(struct platform_device *pdev) @@ -139,6 +147,7 @@ static int gpio_halt_remove(struct platform_device *pdev) gpio_free(gpio); + of_node_put(halt_node); halt_node = NULL; } -- 2.25.1
Re:Re: [PATCH v3] powerpc:85xx: Add missing of_node_put() in sgy_cst1000
At 2022-06-17 13:37:12, "Christophe JAILLET" wrote: >Le 17/06/2022 à 07:22, Liang He a écrit : >> In gpio_halt_probe(), of_find_matching_node() will return a node >> pointer with refcount incremented. We should use of_node_put() in >> fail path or when it is not used anymore. >> >> Signed-off-by: Liang He >> --- >> arch/powerpc/platforms/85xx/sgy_cts1000.c | 39 +++ >> 1 file changed, 25 insertions(+), 14 deletions(-) >> >> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c >> b/arch/powerpc/platforms/85xx/sgy_cts1000.c >> index 98ae64075193..a8690fc552cf 100644 >> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c >> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c >> @@ -71,33 +71,39 @@ static int gpio_halt_probe(struct platform_device *pdev) >> { >> enum of_gpio_flags flags; >> struct device_node *node = pdev->dev.of_node; >> +struct device_node *child_node; >> int gpio, err, irq; >> int trigger; >> +int ret; >> >> if (!node) >> return -ENODEV; >> >> /* If there's no matching child, this isn't really an error */ >> -halt_node = of_find_matching_node(node, child_match); >> -if (!halt_node) >> +child_node = of_find_matching_node(node, child_match); >> +if (!child_node) >> return 0; >> >> /* Technically we could just read the first one, but punish >> * DT writers for invalid form. */ >> -if (of_gpio_count(halt_node) != 1) >> -return -EINVAL; >> +if (of_gpio_count(child_node) != 1) { >> +ret = -EINVAL; >> +goto err_put; >> +} >> >> /* Get the gpio number relative to the dynamic base. */ >> -gpio = of_get_gpio_flags(halt_node, 0, &flags); >> -if (!gpio_is_valid(gpio)) >> -return -EINVAL; >> +gpio = of_get_gpio_flags(child_node, 0, &flags); >> +if (!gpio_is_valid(gpio)) { >> +ret = -EINVAL; >> +gotot err_put; >> +} >> >> err = gpio_request(gpio, "gpio-halt"); >> if (err) { >> printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n", >> gpio); >> -halt_node = NULL; >> -return err; >> +ret = err; > >Sorry for not seeing and asking before, but why do you need 'ret'? >Can't you use the existing 'err' in place in this whole patch? > Thanks, CJ. Your advice is good and I have not noticed the 'err'. >> +goto err_put; >> } >> >> trigger = (flags == OF_GPIO_ACTIVE_LOW); >> @@ -105,15 +111,15 @@ static int gpio_halt_probe(struct platform_device >> *pdev) >> gpio_direction_output(gpio, !trigger); >> >> /* Now get the IRQ which tells us when the power button is hit */ >> -irq = irq_of_parse_and_map(halt_node, 0); >> +irq = irq_of_parse_and_map(child_node, 0); >> err = request_irq(irq, gpio_halt_irq, IRQF_TRIGGER_RISING | >> - IRQF_TRIGGER_FALLING, "gpio-halt", halt_node); >> + IRQF_TRIGGER_FALLING, "gpio-halt", child_node); >> if (err) { >> printk(KERN_ERR "gpio-halt: error requesting IRQ %d for " >> "GPIO %d.\n", irq, gpio); >> gpio_free(gpio); >> -halt_node = NULL; >> -return err; >> +ret = err; >> +goto err_put; >> } >> >> /* Register our halt function */ >> @@ -122,8 +128,12 @@ static int gpio_halt_probe(struct platform_device *pdev) >> >> printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" >> " irq).\n", gpio, trigger, irq); >> +ret = 0; >> +halt_node = of_node_get(child_node); > >LGTM, but my preferred style would be: > halt_node = child_node; > return 0; >I'm not a maintainer, so this is just my opinion and it is mostly a >mater of taste. > >CJ Thanks, CJ. Now, I also prefer this style and I will use it. > >> >> -return 0; >> +err_put: >> +of_node_put(child_node); >> +return ret; >> } >> >> static int gpio_halt_remove(struct platform_device *pdev) >> @@ -139,6 +149,7 @@ static int gpio_halt_remove(struct platform_device *pdev) >> >> gpio_free(gpio); >> >> +of_node_put(halt_node); >> halt_node = NULL; >> } >>
Re: [PATCH v3] powerpc:85xx: Add missing of_node_put() in sgy_cst1000
Le 17/06/2022 à 07:22, Liang He a écrit : In gpio_halt_probe(), of_find_matching_node() will return a node pointer with refcount incremented. We should use of_node_put() in fail path or when it is not used anymore. Signed-off-by: Liang He --- arch/powerpc/platforms/85xx/sgy_cts1000.c | 39 +++ 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c index 98ae64075193..a8690fc552cf 100644 --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c @@ -71,33 +71,39 @@ static int gpio_halt_probe(struct platform_device *pdev) { enum of_gpio_flags flags; struct device_node *node = pdev->dev.of_node; + struct device_node *child_node; int gpio, err, irq; int trigger; + int ret; if (!node) return -ENODEV; /* If there's no matching child, this isn't really an error */ - halt_node = of_find_matching_node(node, child_match); - if (!halt_node) + child_node = of_find_matching_node(node, child_match); + if (!child_node) return 0; /* Technically we could just read the first one, but punish * DT writers for invalid form. */ - if (of_gpio_count(halt_node) != 1) - return -EINVAL; + if (of_gpio_count(child_node) != 1) { + ret = -EINVAL; + goto err_put; + } /* Get the gpio number relative to the dynamic base. */ - gpio = of_get_gpio_flags(halt_node, 0, &flags); - if (!gpio_is_valid(gpio)) - return -EINVAL; + gpio = of_get_gpio_flags(child_node, 0, &flags); + if (!gpio_is_valid(gpio)) { + ret = -EINVAL; + gotot err_put; + } err = gpio_request(gpio, "gpio-halt"); if (err) { printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n", gpio); - halt_node = NULL; - return err; + ret = err; Sorry for not seeing and asking before, but why do you need 'ret'? Can't you use the existing 'err' in place in this whole patch? + goto err_put; } trigger = (flags == OF_GPIO_ACTIVE_LOW); @@ -105,15 +111,15 @@ static int gpio_halt_probe(struct platform_device *pdev) gpio_direction_output(gpio, !trigger); /* Now get the IRQ which tells us when the power button is hit */ - irq = irq_of_parse_and_map(halt_node, 0); + irq = irq_of_parse_and_map(child_node, 0); err = request_irq(irq, gpio_halt_irq, IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, "gpio-halt", halt_node); + IRQF_TRIGGER_FALLING, "gpio-halt", child_node); if (err) { printk(KERN_ERR "gpio-halt: error requesting IRQ %d for " "GPIO %d.\n", irq, gpio); gpio_free(gpio); - halt_node = NULL; - return err; + ret = err; + goto err_put; } /* Register our halt function */ @@ -122,8 +128,12 @@ static int gpio_halt_probe(struct platform_device *pdev) printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" " irq).\n", gpio, trigger, irq); + ret = 0; + halt_node = of_node_get(child_node); LGTM, but my preferred style would be: halt_node = child_node; return 0; I'm not a maintainer, so this is just my opinion and it is mostly a mater of taste. CJ - return 0; +err_put: + of_node_put(child_node); + return ret; } static int gpio_halt_remove(struct platform_device *pdev) @@ -139,6 +149,7 @@ static int gpio_halt_remove(struct platform_device *pdev) gpio_free(gpio); + of_node_put(halt_node); halt_node = NULL; }
Re:Re: [PATCH] powerpc: powernv: Fix refcount leak bug in opal-powercap
At 2022-06-17 13:01:27, "Christophe JAILLET" wrote: >Le 17/06/2022 à 06:20, Liang He a écrit : >> In opal_powercap_init(), of_find_compatible_node() will return >> a node pointer with refcount incremented. We should use of_node_put() >> in fail path or when it is not used anymore. >> >> Besides, for_each_child_of_node() will automatically *inc* and *dec* >> refcount during iteration. However, we should add the of_node_put() >> if there is a break. > >Hi, > >I'm not sure that your patch is right here. Because of this *inc* and >*dec* things, do we still need to of_node_put(powercap) once we have >entered for_each_child_of_node? > >I think that this reference will be released on the first iteration of >the loop. > Hi, CJ, Thanks for your reply and I want have a discuss. Based on my review on the src of 'of_get_next_child', there is only *inc* for next and *dec* for pre as follow. (|node| == powercap) ==__of_get_next_child( |node|, prev)== ... next = prev? prev->sibling:|node|->child; of_node_get(next); of_node_put(prev); ... = However, there is no any code to release the |node| (i.e., *powercap*). Am I right? If I am wrong, please correct me, thanks. > >Maybe of_node_put(powercap) should be duplicated everywhere it is >relevant and removed from the error handling path? >Or an additional reference should be taken before the loop? >Or adding a new label with "powercap = NULL" and branching there when >needed? > >CJ If my understanding is right, I think current patch is right. Otherwise, I will make a new patch to handle that, Thanks. Liang > >> >> Signed-off-by: Liang He >> --- >> arch/powerpc/platforms/powernv/opal-powercap.c | 5 - >> 1 file changed, 4 insertions(+), 1 deletion(-) >> >> diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c >> b/arch/powerpc/platforms/powernv/opal-powercap.c >> index 64506b46e77b..b102477d3f95 100644 >> --- a/arch/powerpc/platforms/powernv/opal-powercap.c >> +++ b/arch/powerpc/platforms/powernv/opal-powercap.c >> @@ -153,7 +153,7 @@ void __init opal_powercap_init(void) >> pcaps = kcalloc(of_get_child_count(powercap), sizeof(*pcaps), >> GFP_KERNEL); >> if (!pcaps) >> -return; >> +goto out_powercap; >> >> powercap_kobj = kobject_create_and_add("powercap", opal_kobj); >> if (!powercap_kobj) { >> @@ -236,6 +236,9 @@ void __init opal_powercap_init(void) >> kfree(pcaps[i].pg.name); >> } >> kobject_put(powercap_kobj); >> +of_node_put(node); >> out_pcaps: >> kfree(pcaps); >> +out_powercap: >> +of_node_put(powercap); >> }
[PATCH v3] powerpc:85xx: Add missing of_node_put() in sgy_cst1000
In gpio_halt_probe(), of_find_matching_node() will return a node pointer with refcount incremented. We should use of_node_put() in fail path or when it is not used anymore. Signed-off-by: Liang He --- arch/powerpc/platforms/85xx/sgy_cts1000.c | 39 +++ 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c index 98ae64075193..a8690fc552cf 100644 --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c @@ -71,33 +71,39 @@ static int gpio_halt_probe(struct platform_device *pdev) { enum of_gpio_flags flags; struct device_node *node = pdev->dev.of_node; + struct device_node *child_node; int gpio, err, irq; int trigger; + int ret; if (!node) return -ENODEV; /* If there's no matching child, this isn't really an error */ - halt_node = of_find_matching_node(node, child_match); - if (!halt_node) + child_node = of_find_matching_node(node, child_match); + if (!child_node) return 0; /* Technically we could just read the first one, but punish * DT writers for invalid form. */ - if (of_gpio_count(halt_node) != 1) - return -EINVAL; + if (of_gpio_count(child_node) != 1) { + ret = -EINVAL; + goto err_put; + } /* Get the gpio number relative to the dynamic base. */ - gpio = of_get_gpio_flags(halt_node, 0, &flags); - if (!gpio_is_valid(gpio)) - return -EINVAL; + gpio = of_get_gpio_flags(child_node, 0, &flags); + if (!gpio_is_valid(gpio)) { + ret = -EINVAL; + gotot err_put; + } err = gpio_request(gpio, "gpio-halt"); if (err) { printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n", gpio); - halt_node = NULL; - return err; + ret = err; + goto err_put; } trigger = (flags == OF_GPIO_ACTIVE_LOW); @@ -105,15 +111,15 @@ static int gpio_halt_probe(struct platform_device *pdev) gpio_direction_output(gpio, !trigger); /* Now get the IRQ which tells us when the power button is hit */ - irq = irq_of_parse_and_map(halt_node, 0); + irq = irq_of_parse_and_map(child_node, 0); err = request_irq(irq, gpio_halt_irq, IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, "gpio-halt", halt_node); + IRQF_TRIGGER_FALLING, "gpio-halt", child_node); if (err) { printk(KERN_ERR "gpio-halt: error requesting IRQ %d for " "GPIO %d.\n", irq, gpio); gpio_free(gpio); - halt_node = NULL; - return err; + ret = err; + goto err_put; } /* Register our halt function */ @@ -122,8 +128,12 @@ static int gpio_halt_probe(struct platform_device *pdev) printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" " irq).\n", gpio, trigger, irq); + ret = 0; + halt_node = of_node_get(child_node); - return 0; +err_put: + of_node_put(child_node); + return ret; } static int gpio_halt_remove(struct platform_device *pdev) @@ -139,6 +149,7 @@ static int gpio_halt_remove(struct platform_device *pdev) gpio_free(gpio); + of_node_put(halt_node); halt_node = NULL; } -- 2.25.1
Re:Re:Re: [PATCH v2] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c
2022-06-17 12:29:02,"Michael Ellerman" 写道: >"Liang He" writes: >> At 2022-06-17 07:37:06, "Michael Ellerman" wrote: >>>Christophe JAILLET writes: Le 16/06/2022 à 17:19, Liang He a écrit : > In gpio_halt_probe(), of_find_matching_node() will return a node pointer > with > refcount incremented. We should use of_node_put() in each fail path or > when it > is not used anymore. > > Signed-off-by: Liang He > --- > changelog: > > v2: use goto-label patch style advised by Christophe. > v1: add of_node_put() before each exit. > > arch/powerpc/platforms/85xx/sgy_cts1000.c | 27 +++ > 1 file changed, 18 insertions(+), 9 deletions(-) > > diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c > b/arch/powerpc/platforms/85xx/sgy_cts1000.c > index 98ae64075193..e280f963d88c 100644 > --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c > +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c > @@ -73,6 +73,7 @@ static int gpio_halt_probe(struct platform_device *pdev) >>>... > @@ -122,8 +127,12 @@ static int gpio_halt_probe(struct platform_device > *pdev) > > printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" > " irq).\n", gpio, trigger, irq); > + ret = 0; > > - return 0; > +err_put: > + of_node_put(halt_node); > + halt_node = NULL; Hi, so now we set 'halt_node' to NULL even in the normal case. This is really spurious. Look at gpio_halt_cb(), but I think that this is just wrong and badly breaks this driver. >>> >>>I agree, thanks for reviewing. >>> >>>I think the cleanest solution is to use a local variable for the node in >>>the body of gpio_halt_probe(), and only assign to halt_node once all the >>>checks have passed. >>> >>>So something like: >>> >>>struct device_node *child_node; >>> >>> child_node = of_find_matching_node(node, child_match); >>>... >>> >>> printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" >>>" irq).\n", gpio, trigger, irq); >>>ret = 0; >>>halt_node = of_node_get(child_node); >>> >>>out_put: >>>of_node_put(child_node); >>> >>> return ret; >>>} >>> >>> >>>cheers >> >> Hi, Michael and Christophe, >> >> I am writing the new patch based on Michael's advice. However, I wonder if >> there is >> any place to call of_node_put(halt_node)? As I do not exactly know if >> gpio_halt_remove() >> or anyother place can correctly release this global reference? >> If not, it is correct that I add a of_node_put(halt_node) in >> gpio_halt_remove(), right? > >Yes I think so, just before it's set to NULL, eg: > >diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c >b/arch/powerpc/platforms/85xx/sgy_cts1000.c >index 98ae64075193..7beb3cd420ba 100644 >--- a/arch/powerpc/platforms/85xx/sgy_cts1000.c >+++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c >@@ -139,6 +139,7 @@ static int gpio_halt_remove(struct platform_device *pdev) > > gpio_free(gpio); > >+ of_node_put(halt_node); > halt_node = NULL; > } > > >cheers Ok, I will make the new patch soon.
Re: [PATCH] powerpc: powernv: Fix refcount leak bug in opal-powercap
Le 17/06/2022 à 06:20, Liang He a écrit : In opal_powercap_init(), of_find_compatible_node() will return a node pointer with refcount incremented. We should use of_node_put() in fail path or when it is not used anymore. Besides, for_each_child_of_node() will automatically *inc* and *dec* refcount during iteration. However, we should add the of_node_put() if there is a break. Hi, I'm not sure that your patch is right here. Because of this *inc* and *dec* things, do we still need to of_node_put(powercap) once we have entered for_each_child_of_node? I think that this reference will be released on the first iteration of the loop. Maybe of_node_put(powercap) should be duplicated everywhere it is relevant and removed from the error handling path? Or an additional reference should be taken before the loop? Or adding a new label with "powercap = NULL" and branching there when needed? CJ Signed-off-by: Liang He --- arch/powerpc/platforms/powernv/opal-powercap.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c index 64506b46e77b..b102477d3f95 100644 --- a/arch/powerpc/platforms/powernv/opal-powercap.c +++ b/arch/powerpc/platforms/powernv/opal-powercap.c @@ -153,7 +153,7 @@ void __init opal_powercap_init(void) pcaps = kcalloc(of_get_child_count(powercap), sizeof(*pcaps), GFP_KERNEL); if (!pcaps) - return; + goto out_powercap; powercap_kobj = kobject_create_and_add("powercap", opal_kobj); if (!powercap_kobj) { @@ -236,6 +236,9 @@ void __init opal_powercap_init(void) kfree(pcaps[i].pg.name); } kobject_put(powercap_kobj); + of_node_put(node); out_pcaps: kfree(pcaps); +out_powercap: + of_node_put(powercap); }
[PATCH] selftests/powerpc: Fix matrix multiply assist test
The ISA states: "when ACC[i] contains defined data, the contents of VSRs 4×i to 4×i+3 are undefined until either a VSX Move From ACC instruction is used to copy the contents of ACC[i] to VSRs 4×i to 4×i+3 or some other instruction directly writes to one of these VSRs." We aren't doing this. This test only works on Power10 because the hardware implementation happens to map ACC0 to VSRs 0-3, but will fail on any other implementation that doesn't do this. So add xxmfacc between writing to the accumulator and accessing the VSRs. Fixes commit 3527e1ab9a79 ("selftests/powerpc: Add matrix multiply assist (MMA) test") Signed-off-by: Rashmica Gupta --- tools/testing/selftests/powerpc/math/mma.S | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/testing/selftests/powerpc/math/mma.S b/tools/testing/selftests/powerpc/math/mma.S index 8528c9849565..61cc88b1b26b 100644 --- a/tools/testing/selftests/powerpc/math/mma.S +++ b/tools/testing/selftests/powerpc/math/mma.S @@ -20,6 +20,9 @@ test_mma: /* xvi16ger2s */ .long 0xec042958 + /* Deprime the accumulator - xxmfacc 0 */ + .long 0x7c000162 + /* Store result in image passed in r5 */ stxvw4x 0,0,5 addi5,5,16 -- 2.35.3
[PATCH] powerpc/signal: Update comment for clarity
The comment being referred to was deleted in commit af1bbc3dd3d5 ("powerpc: Remove UP only lazy floating point and vector optimisations"). Add a bit more detail so it's clear why we need to clear the FP/VEC/VSX bits here. Signed-off-by: Rashmica Gupta --- arch/powerpc/kernel/signal_64.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 472596a109e2..86bb5bb4c143 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -377,9 +377,12 @@ static long notrace __unsafe_restore_sigcontext(struct task_struct *tsk, sigset_ unsafe_get_user(set->sig[0], &sc->oldmask, efault_out); /* -* Force reload of FP/VEC. -* This has to be done before copying stuff into tsk->thread.fpr/vr -* for the reasons explained in the previous comment. +* Force reload of FP/VEC/VSX so userspace sees any changes. +* Clear these bits from the user process' MSR before copying into the +* thread struct. If we are rescheduled or preempted and another task +* uses FP/VEC/VSX, and this process has the MSR bits set, then the +* context switch code will save the current CPU state into the +* thread_struct - possibly overwriting the data we are updating here. */ regs_set_return_msr(regs, regs->msr & ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC | MSR_VSX)); -- 2.35.3
Re:Re: [PATCH v2] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c
"Liang He" writes: > At 2022-06-17 07:37:06, "Michael Ellerman" wrote: >>Christophe JAILLET writes: >>> Le 16/06/2022 à 17:19, Liang He a écrit : In gpio_halt_probe(), of_find_matching_node() will return a node pointer with refcount incremented. We should use of_node_put() in each fail path or when it is not used anymore. Signed-off-by: Liang He --- changelog: v2: use goto-label patch style advised by Christophe. v1: add of_node_put() before each exit. arch/powerpc/platforms/85xx/sgy_cts1000.c | 27 +++ 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c index 98ae64075193..e280f963d88c 100644 --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c @@ -73,6 +73,7 @@ static int gpio_halt_probe(struct platform_device *pdev) >>... @@ -122,8 +127,12 @@ static int gpio_halt_probe(struct platform_device *pdev) printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" " irq).\n", gpio, trigger, irq); + ret = 0; - return 0; +err_put: + of_node_put(halt_node); + halt_node = NULL; >>> >>> Hi, >>> so now we set 'halt_node' to NULL even in the normal case. >>> This is really spurious. >>> >>> Look at gpio_halt_cb(), but I think that this is just wrong and badly >>> breaks this driver. >> >>I agree, thanks for reviewing. >> >>I think the cleanest solution is to use a local variable for the node in >>the body of gpio_halt_probe(), and only assign to halt_node once all the >>checks have passed. >> >>So something like: >> >>struct device_node *child_node; >> >> child_node = of_find_matching_node(node, child_match); >>... >> >> printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" >> " irq).\n", gpio, trigger, irq); >>ret = 0; >>halt_node = of_node_get(child_node); >> >>out_put: >>of_node_put(child_node); >> >> return ret; >>} >> >> >>cheers > > Hi, Michael and Christophe, > > I am writing the new patch based on Michael's advice. However, I wonder if > there is > any place to call of_node_put(halt_node)? As I do not exactly know if > gpio_halt_remove() > or anyother place can correctly release this global reference? > If not, it is correct that I add a of_node_put(halt_node) in > gpio_halt_remove(), right? Yes I think so, just before it's set to NULL, eg: diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c index 98ae64075193..7beb3cd420ba 100644 --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c @@ -139,6 +139,7 @@ static int gpio_halt_remove(struct platform_device *pdev) gpio_free(gpio); + of_node_put(halt_node); halt_node = NULL; } cheers
[PATCH] powerpc: make facility_unavailable_exception 64s
The facility unavailable exception is only available on ppc book3s machines so use CONFIG_PPC_BOOK3S_64 rather than CONFIG_PPC64. tm_unavailable is only called from facility_unavailable_exception so can also be under this Kconfig symbol. Signed-off-by: Rashmica Gupta --- arch/powerpc/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 3aaa50e5c72f..dadfcef5d6db 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1676,7 +1676,7 @@ DEFINE_INTERRUPT_HANDLER(vsx_unavailable_exception) die("Unrecoverable VSX Unavailable Exception", regs, SIGABRT); } -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3S_64 static void tm_unavailable(struct pt_regs *regs) { #ifdef CONFIG_PPC_TRANSACTIONAL_MEM -- 2.35.3
[PATCH] powerpc: powernv: Fix refcount leak bug in opal-powercap
In opal_powercap_init(), of_find_compatible_node() will return a node pointer with refcount incremented. We should use of_node_put() in fail path or when it is not used anymore. Besides, for_each_child_of_node() will automatically *inc* and *dec* refcount during iteration. However, we should add the of_node_put() if there is a break. Signed-off-by: Liang He --- arch/powerpc/platforms/powernv/opal-powercap.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c index 64506b46e77b..b102477d3f95 100644 --- a/arch/powerpc/platforms/powernv/opal-powercap.c +++ b/arch/powerpc/platforms/powernv/opal-powercap.c @@ -153,7 +153,7 @@ void __init opal_powercap_init(void) pcaps = kcalloc(of_get_child_count(powercap), sizeof(*pcaps), GFP_KERNEL); if (!pcaps) - return; + goto out_powercap; powercap_kobj = kobject_create_and_add("powercap", opal_kobj); if (!powercap_kobj) { @@ -236,6 +236,9 @@ void __init opal_powercap_init(void) kfree(pcaps[i].pg.name); } kobject_put(powercap_kobj); + of_node_put(node); out_pcaps: kfree(pcaps); +out_powercap: + of_node_put(powercap); } -- 2.25.1
Re:Re: [PATCH v2] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c
At 2022-06-17 07:37:06, "Michael Ellerman" wrote: >Christophe JAILLET writes: >> Le 16/06/2022 à 17:19, Liang He a écrit : >>> In gpio_halt_probe(), of_find_matching_node() will return a node pointer >>> with >>> refcount incremented. We should use of_node_put() in each fail path or when >>> it >>> is not used anymore. >>> >>> Signed-off-by: Liang He >>> --- >>> changelog: >>> >>> v2: use goto-label patch style advised by Christophe. >>> v1: add of_node_put() before each exit. >>> >>> arch/powerpc/platforms/85xx/sgy_cts1000.c | 27 +++ >>> 1 file changed, 18 insertions(+), 9 deletions(-) >>> >>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c >>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c >>> index 98ae64075193..e280f963d88c 100644 >>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c >>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c >>> @@ -73,6 +73,7 @@ static int gpio_halt_probe(struct platform_device *pdev) >... >>> @@ -122,8 +127,12 @@ static int gpio_halt_probe(struct platform_device >>> *pdev) >>> >>> printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" >>>" irq).\n", gpio, trigger, irq); >>> + ret = 0; >>> >>> - return 0; >>> +err_put: >>> + of_node_put(halt_node); >>> + halt_node = NULL; >> >> Hi, >> so now we set 'halt_node' to NULL even in the normal case. >> This is really spurious. >> >> Look at gpio_halt_cb(), but I think that this is just wrong and badly >> breaks this driver. > >I agree, thanks for reviewing. > >I think the cleanest solution is to use a local variable for the node in >the body of gpio_halt_probe(), and only assign to halt_node once all the >checks have passed. > >So something like: > >struct device_node *child_node; > > child_node = of_find_matching_node(node, child_match); >... > > printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" > " irq).\n", gpio, trigger, irq); >ret = 0; >halt_node = of_node_get(child_node); > >out_put: >of_node_put(child_node); > > return ret; >} > > >cheers Hi, Michael and Christophe, I am writing the new patch based on Michael's advice. However, I wonder if there is any place to call of_node_put(halt_node)? As I do not exactly know if gpio_halt_remove() or anyother place can correctly release this global reference? If not, it is correct that I add a of_node_put(halt_node) in gpio_halt_remove(), right? Thanks and wait for your replies. Liang
Re: [PATCH] ibmvfc: multiqueue bug fixes
On Thu, 16 Jun 2022 12:11:24 -0700, Tyrel Datwyler wrote: > Fixes for a couple observed crashes of the ibmvfc driver when in MQ mode. > > Tyrel Datwyler (2): > ibmvfc: store vhost pointer during subcrq allocation > ibmvfc: alloc/free queue resource only during probe/remove > > drivers/scsi/ibmvscsi/ibmvfc.c | 82 ++ > drivers/scsi/ibmvscsi/ibmvfc.h | 2 +- > 2 files changed, 65 insertions(+), 19 deletions(-) > > [...] Applied to 5.19/scsi-fixes, thanks! [1/1] ibmvfc: store vhost pointer during subcrq allocation https://git.kernel.org/mkp/scsi/c/aeaadcde1a60 -- Martin K. Petersen Oracle Linux Engineering
Re:Re: [PATCH v2] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c
At 2022-06-17 07:37:06, "Michael Ellerman" wrote: >Christophe JAILLET writes: >> Le 16/06/2022 à 17:19, Liang He a écrit : >>> In gpio_halt_probe(), of_find_matching_node() will return a node pointer >>> with >>> refcount incremented. We should use of_node_put() in each fail path or when >>> it >>> is not used anymore. >>> >>> Signed-off-by: Liang He >>> --- >>> changelog: >>> >>> v2: use goto-label patch style advised by Christophe. >>> v1: add of_node_put() before each exit. >>> >>> arch/powerpc/platforms/85xx/sgy_cts1000.c | 27 +++ >>> 1 file changed, 18 insertions(+), 9 deletions(-) >>> >>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c >>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c >>> index 98ae64075193..e280f963d88c 100644 >>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c >>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c >>> @@ -73,6 +73,7 @@ static int gpio_halt_probe(struct platform_device *pdev) >... >>> @@ -122,8 +127,12 @@ static int gpio_halt_probe(struct platform_device >>> *pdev) >>> >>> printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" >>>" irq).\n", gpio, trigger, irq); >>> + ret = 0; >>> >>> - return 0; >>> +err_put: >>> + of_node_put(halt_node); >>> + halt_node = NULL; >> >> Hi, >> so now we set 'halt_node' to NULL even in the normal case. >> This is really spurious. >> >> Look at gpio_halt_cb(), but I think that this is just wrong and badly >> breaks this driver. > >I agree, thanks for reviewing. > >I think the cleanest solution is to use a local variable for the node in >the body of gpio_halt_probe(), and only assign to halt_node once all the >checks have passed. > >So something like: > >struct device_node *child_node; > > child_node = of_find_matching_node(node, child_match); >... > > printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" > " irq).\n", gpio, trigger, irq); >ret = 0; >halt_node = of_node_get(child_node); > >out_put: >of_node_put(child_node); > > return ret; >} > > >cheers Thanks, Michael and Christophe. I will send a patch based on your reviews. Liang
[powerpc:next-test] BUILD SUCCESS 028de148fa5a5465ed75d39ea79ad8ebd1b35e2f
: mips ath79_defconfig armmulti_v5_defconfig arm ep93xx_defconfig armmvebu_v5_defconfig arm collie_defconfig powerpc tqm5200_defconfig mips ip22_defconfig x86_64randconfig-k001 x86_64randconfig-a005 x86_64randconfig-a003 x86_64randconfig-a001 i386 randconfig-a002 i386 randconfig-a006 i386 randconfig-a004 x86_64randconfig-a012 x86_64randconfig-a014 x86_64randconfig-a016 i386 randconfig-a011 i386 randconfig-a013 i386 randconfig-a015 riscvrandconfig-r042-20220616 hexagon randconfig-r041-20220616 hexagon randconfig-r045-20220616 s390 randconfig-r044-20220616 -- 0-DAY CI Kernel Test Service https://01.org/lkp
[powerpc:merge] BUILD SUCCESS bcd1c02813b8ab4ae019c65ffb716c9f579868e7
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git merge branch HEAD: bcd1c02813b8ab4ae019c65ffb716c9f579868e7 Automatic merge of 'master' into merge (2022-06-15 08:29) elapsed time: 2781m configs tested: 83 configs skipped: 3 The following configs have been built successfully. More configs may be tested in the coming days. gcc tested configs: arm64 defconfig arm64allyesconfig arm defconfig arm allyesconfig arm allmodconfig ia64 allmodconfig ia64 allyesconfig ia64defconfig m68k allyesconfig m68k allmodconfig m68kdefconfig nios2 defconfig arc allyesconfig cskydefconfig nios2allyesconfig alpha defconfig alphaallyesconfig xtensa allyesconfig arc defconfig sh allmodconfig s390defconfig s390 allmodconfig parisc defconfig parisc64defconfig parisc allyesconfig s390 allyesconfig sparcallyesconfig sparc defconfig i386 allyesconfig i386defconfig i386 debian-10.3-kselftests i386 debian-10.3 mips allyesconfig mips allmodconfig powerpc allyesconfig powerpc allnoconfig powerpc allmodconfig x86_64randconfig-a002 x86_64randconfig-a004 x86_64randconfig-a006 i386 randconfig-a001 i386 randconfig-a003 i386 randconfig-a005 x86_64randconfig-a013 x86_64randconfig-a011 x86_64randconfig-a015 i386 randconfig-a012 i386 randconfig-a014 i386 randconfig-a016 arc randconfig-r043-20220616 riscv defconfig riscvnommu_virt_defconfig riscv rv32_defconfig riscvnommu_k210_defconfig riscv allnoconfig riscvallmodconfig riscvallyesconfig um x86_64_defconfig um i386_defconfig x86_64 kexec x86_64 defconfig x86_64 allyesconfig x86_64 rhel-8.3 x86_64 rhel-8.3-func x86_64 rhel-8.3-syz x86_64rhel-8.3-kselftests x86_64 rhel-8.3-kunit clang tested configs: x86_64randconfig-a001 x86_64randconfig-a003 x86_64randconfig-a005 i386 randconfig-a002 i386 randconfig-a006 i386 randconfig-a004 x86_64randconfig-a012 x86_64randconfig-a014 x86_64randconfig-a016 i386 randconfig-a013 i386 randconfig-a011 i386 randconfig-a015 riscvrandconfig-r042-20220616 hexagon randconfig-r041-20220616 hexagon randconfig-r045-20220616 s390 randconfig-r044-20220616 -- 0-DAY CI Kernel Test Service https://01.org/lkp
[powerpc:fixes-test] BUILD SUCCESS 294958ca9dd4be4204d6cf1ece8f403801dad2b2
configs: mips ath79_defconfig armmulti_v5_defconfig arm ep93xx_defconfig armmvebu_v5_defconfig arm collie_defconfig powerpc tqm5200_defconfig mips ip22_defconfig x86_64randconfig-k001 x86_64randconfig-a005 x86_64randconfig-a003 x86_64randconfig-a001 i386 randconfig-a002 i386 randconfig-a006 i386 randconfig-a004 x86_64randconfig-a012 x86_64randconfig-a014 x86_64randconfig-a016 i386 randconfig-a011 i386 randconfig-a013 i386 randconfig-a015 riscvrandconfig-r042-20220616 hexagon randconfig-r041-20220616 hexagon randconfig-r045-20220616 s390 randconfig-r044-20220616 -- 0-DAY CI Kernel Test Service https://01.org/lkp
Re: [PATCH v2] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c
Christophe JAILLET writes: > Le 16/06/2022 à 17:19, Liang He a écrit : >> In gpio_halt_probe(), of_find_matching_node() will return a node pointer with >> refcount incremented. We should use of_node_put() in each fail path or when >> it >> is not used anymore. >> >> Signed-off-by: Liang He >> --- >> changelog: >> >> v2: use goto-label patch style advised by Christophe. >> v1: add of_node_put() before each exit. >> >> arch/powerpc/platforms/85xx/sgy_cts1000.c | 27 +++ >> 1 file changed, 18 insertions(+), 9 deletions(-) >> >> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c >> b/arch/powerpc/platforms/85xx/sgy_cts1000.c >> index 98ae64075193..e280f963d88c 100644 >> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c >> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c >> @@ -73,6 +73,7 @@ static int gpio_halt_probe(struct platform_device *pdev) ... >> @@ -122,8 +127,12 @@ static int gpio_halt_probe(struct platform_device *pdev) >> >> printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" >> " irq).\n", gpio, trigger, irq); >> +ret = 0; >> >> -return 0; >> +err_put: >> +of_node_put(halt_node); >> +halt_node = NULL; > > Hi, > so now we set 'halt_node' to NULL even in the normal case. > This is really spurious. > > Look at gpio_halt_cb(), but I think that this is just wrong and badly > breaks this driver. I agree, thanks for reviewing. I think the cleanest solution is to use a local variable for the node in the body of gpio_halt_probe(), and only assign to halt_node once all the checks have passed. So something like: struct device_node *child_node; child_node = of_find_matching_node(node, child_match); ... printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" " irq).\n", gpio, trigger, irq); ret = 0; halt_node = of_node_get(child_node); out_put: of_node_put(child_node); return ret; } cheers
[PATCH v2] macintosh: via-pmu-backlight: Use backlight helper
backlight_properties.fb_blank is deprecated. The states it represents are handled by other properties; but instead of accessing those properties directly, drivers should use the helpers provided by backlight.h. Instead of retrieving the backlight brightness in struct backlight_properties manually, and then checking whether the backlight should be on at all, use backlight_get_brightness() which does all this and insulates this from future changes. Signed-off-by: Stephen Kitt Cc: Benjamin Herrenschmidt Cc: Michael Ellerman Cc: Christophe Leroy Cc: linuxppc-dev@lists.ozlabs.org --- Changes since v2: clarified commit title --- drivers/macintosh/via-pmu-backlight.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index 2194016122d2..c2d87e7fa85b 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c @@ -71,12 +71,7 @@ static int pmu_backlight_get_level_brightness(int level) static int __pmu_backlight_update_status(struct backlight_device *bd) { struct adb_request req; - int level = bd->props.brightness; - - - if (bd->props.power != FB_BLANK_UNBLANK || - bd->props.fb_blank != FB_BLANK_UNBLANK) - level = 0; + int level = backlight_get_brightness(bd); if (level > 0) { int pmulevel = pmu_backlight_get_level_brightness(level); base-commit: f2906aa863381afb0015a9eb7fefad885d4e5a56 -- 2.30.2
[PATCH 07/11] ASoC: fsl: fsl_sai: use pm_runtime_resume_and_get()
Simplify the flow. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan --- sound/soc/fsl/fsl_sai.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 4f5bd9597c746..b6407d4d3e09d 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -1141,11 +1141,9 @@ static int fsl_sai_probe(struct platform_device *pdev) goto err_pm_disable; } - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - pm_runtime_put_noidle(dev); + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) goto err_pm_get_sync; - } /* Get sai version */ ret = fsl_sai_check_version(dev); -- 2.34.1
[PATCH 3/4] hugetlb: do not update address in huge_pmd_unshare
As an optimization for loops sequentially processing hugetlb address ranges, huge_pmd_unshare would update a passed address if it unshared a pmd. Updating a loop control variable outside the loop like this is generally a bad idea. These loops are now using hugetlb_mask_last_page to optimize scanning when non-present ptes are discovered. The same can be done when huge_pmd_unshare returns 1 indicating a pmd was unshared. Remove address update from huge_pmd_unshare. Change the passed argument type and update all callers. In loops sequentially processing addresses use hugetlb_mask_last_page to update address if pmd is unshared. Signed-off-by: Mike Kravetz Acked-by: Muchun Song Reviewed-by: Baolin Wang --- include/linux/hugetlb.h | 4 ++-- mm/hugetlb.c| 47 ++--- mm/rmap.c | 4 ++-- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index e37465e830fe..ee9a28ef26ee 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -199,7 +199,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz); unsigned long hugetlb_mask_last_page(struct hstate *h); int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep); + unsigned long addr, pte_t *ptep); void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, unsigned long *start, unsigned long *end); struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, @@ -246,7 +246,7 @@ static inline struct address_space *hugetlb_page_mapping_lock_write( static inline int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { return 0; } diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 7c4a82848603..f7da2d54ef39 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4949,7 +4949,6 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, struct mm_struct *mm = vma->vm_mm; unsigned long old_end = old_addr + len; unsigned long last_addr_mask; - unsigned long old_addr_copy; pte_t *src_pte, *dst_pte; struct mmu_notifier_range range; bool shared_pmd = false; @@ -4977,14 +4976,10 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, if (huge_pte_none(huge_ptep_get(src_pte))) continue; - /* old_addr arg to huge_pmd_unshare() is a pointer and so the -* arg may be modified. Pass a copy instead to preserve the -* value in old_addr. -*/ - old_addr_copy = old_addr; - - if (huge_pmd_unshare(mm, vma, &old_addr_copy, src_pte)) { + if (huge_pmd_unshare(mm, vma, old_addr, src_pte)) { shared_pmd = true; + old_addr |= last_addr_mask; + new_addr |= last_addr_mask; continue; } @@ -5049,10 +5044,11 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct } ptl = huge_pte_lock(h, mm, ptep); - if (huge_pmd_unshare(mm, vma, &address, ptep)) { + if (huge_pmd_unshare(mm, vma, address, ptep)) { spin_unlock(ptl); tlb_flush_pmd_range(tlb, address & PUD_MASK, PUD_SIZE); force_flush = true; + address |= last_addr_mask; continue; } @@ -6347,7 +6343,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, continue; } ptl = huge_pte_lock(h, mm, ptep); - if (huge_pmd_unshare(mm, vma, &address, ptep)) { + if (huge_pmd_unshare(mm, vma, address, ptep)) { /* * When uffd-wp is enabled on the vma, unshare * shouldn't happen at all. Warn about it if it @@ -6357,6 +6353,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, pages++; spin_unlock(ptl); shared_pmd = true; + address |= last_addr_mask; continue; } pte = huge_ptep_get(ptep); @@ -6780,11 +6777,11 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, * 0 the underlying pte page is not shared, or it is the last user */ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
[PATCH 4/4] hugetlb: Lazy page table copies in fork()
Lazy page table copying at fork time was introduced with commit commit d992895ba2b2 ("[PATCH] Lazy page table copies in fork()"). At the time, hugetlb was very new and did not support page faulting. As a result, it was excluded. When full page fault support was added for hugetlb, the exclusion was not removed. Simply remove the check that prevents lazy copying of hugetlb page tables at fork. Of course, like other mappings this only applies to shared mappings. Lazy page table copying at fork will be less advantageous for hugetlb mappings because: - There are fewer page table entries with hugetlb - hugetlb pmds can be shared instead of copied In any case, completely eliminating the copy at fork time should speed things up. Signed-off-by: Mike Kravetz Acked-by: Muchun Song Acked-by: David Hildenbrand --- mm/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index fee2884481f2..90d2a614b2de 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1262,7 +1262,7 @@ vma_needs_copy(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma) if (userfaultfd_wp(dst_vma)) return true; - if (src_vma->vm_flags & (VM_HUGETLB | VM_PFNMAP | VM_MIXEDMAP)) + if (src_vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) return true; if (src_vma->anon_vma) -- 2.35.3
[PATCH 2/4] arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page
From: Baolin Wang The HugeTLB address ranges are linearly scanned during fork, unmap and remap operations, and the linear scan can skip to the end of range mapped by the page table page if hitting a non-present entry, which can help to speed linear scanning of the HugeTLB address ranges. So hugetlb_mask_last_page() is introduced to help to update the address in the loop of HugeTLB linear scanning with getting the last huge page mapped by the associated page table page[1], when a non-present entry is encountered. Considering ARM64 specific cont-pte/pmd size HugeTLB, this patch implemented an ARM64 specific hugetlb_mask_last_page() to help this case. [1] https://lore.kernel.org/linux-mm/20220527225849.284839-1-mike.krav...@oracle.com/ Signed-off-by: Baolin Wang Signed-off-by: Mike Kravetz --- arch/arm64/mm/hugetlbpage.c | 20 1 file changed, 20 insertions(+) diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index e2a5ec9fdc0d..ddeafee7c4de 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -368,6 +368,26 @@ pte_t *huge_pte_offset(struct mm_struct *mm, return NULL; } +unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + unsigned long hp_size = huge_page_size(h); + + switch (hp_size) { + case PUD_SIZE: + return PGDIR_SIZE - PUD_SIZE; + case CONT_PMD_SIZE: + return PUD_SIZE - CONT_PMD_SIZE; + case PMD_SIZE: + return PUD_SIZE - PMD_SIZE; + case CONT_PTE_SIZE: + return PMD_SIZE - CONT_PTE_SIZE; + default: + break; + } + + return ~0UL; +} + pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags) { size_t pagesize = 1UL << shift; -- 2.35.3
[PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present
HugeTLB address ranges are linearly scanned during fork, unmap and remap operations. If a non-present entry is encountered, the code currently continues to the next huge page aligned address. However, a non-present entry implies that the page table page for that entry is not present. Therefore, the linear scan can skip to the end of range mapped by the page table page. This can speed operations on large sparsely populated hugetlb mappings. Create a new routine hugetlb_mask_last_page() that will return an address mask. When the mask is ORed with an address, the result will be the address of the last huge page mapped by the associated page table page. Use this mask to update addresses in routines which linearly scan hugetlb address ranges when a non-present pte is encountered. hugetlb_mask_last_page is related to the implementation of huge_pte_offset as hugetlb_mask_last_page is called when huge_pte_offset returns NULL. This patch only provides a complete hugetlb_mask_last_page implementation when CONFIG_ARCH_WANT_GENERAL_HUGETLB is defined. Architectures which provide their own versions of huge_pte_offset can also provide their own version of hugetlb_mask_last_page. Signed-off-by: Mike Kravetz Tested-by: Baolin Wang Reviewed-by: Baolin Wang --- include/linux/hugetlb.h | 1 + mm/hugetlb.c| 62 + 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 642a39016f9a..e37465e830fe 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -197,6 +197,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long sz); pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz); +unsigned long hugetlb_mask_last_page(struct hstate *h); int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long *addr, pte_t *ptep); void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 259b9c41892f..7c4a82848603 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4740,6 +4740,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, unsigned long npages = pages_per_huge_page(h); struct address_space *mapping = src_vma->vm_file->f_mapping; struct mmu_notifier_range range; + unsigned long last_addr_mask; int ret = 0; if (cow) { @@ -4759,11 +4760,14 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, i_mmap_lock_read(mapping); } + last_addr_mask = hugetlb_mask_last_page(h); for (addr = src_vma->vm_start; addr < src_vma->vm_end; addr += sz) { spinlock_t *src_ptl, *dst_ptl; src_pte = huge_pte_offset(src, addr, sz); - if (!src_pte) + if (!src_pte) { + addr |= last_addr_mask; continue; + } dst_pte = huge_pte_alloc(dst, dst_vma, addr, sz); if (!dst_pte) { ret = -ENOMEM; @@ -4780,8 +4784,10 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, * after taking the lock below. */ dst_entry = huge_ptep_get(dst_pte); - if ((dst_pte == src_pte) || !huge_pte_none(dst_entry)) + if ((dst_pte == src_pte) || !huge_pte_none(dst_entry)) { + addr |= last_addr_mask; continue; + } dst_ptl = huge_pte_lock(h, dst, dst_pte); src_ptl = huge_pte_lockptr(h, src, src_pte); @@ -4942,6 +4948,7 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, unsigned long sz = huge_page_size(h); struct mm_struct *mm = vma->vm_mm; unsigned long old_end = old_addr + len; + unsigned long last_addr_mask; unsigned long old_addr_copy; pte_t *src_pte, *dst_pte; struct mmu_notifier_range range; @@ -4957,12 +4964,16 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, flush_cache_range(vma, range.start, range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); /* Prevent race with file truncation */ i_mmap_lock_write(mapping); for (; old_addr < old_end; old_addr += sz, new_addr += sz) { src_pte = huge_pte_offset(mm, old_addr, sz); - if (!src_pte) + if (!src_pte) { + old_addr |= last_addr_mask; + new_addr |= last_addr_mask; continue; + } if (huge_pte_none(huge_ptep_get(src_pte))) continue; @@ -
[PATCH 0/4] hugetlb: speed up linear address scanning
At unmap, fork and remap time hugetlb address ranges are linearly scanned. We can optimize these scans if the ranges are sparsely populated. Also, enable page table "Lazy copy" for hugetlb at fork. NOTE: Architectures not defining CONFIG_ARCH_WANT_GENERAL_HUGETLB need to add an arch specific version hugetlb_mask_last_page() to take advantage of sparse address scanning improvements. Baolin Wang added the routine for arm64. Other architectures which could be optimized are: ia64, mips, parisc, powerpc, s390, sh and sparc. Baolin Wang (1): arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page Mike Kravetz (3): hugetlb: skip to end of PT page mapping when pte not present hugetlb: do not update address in huge_pmd_unshare hugetlb: Lazy page table copies in fork() arch/arm64/mm/hugetlbpage.c | 20 +++ include/linux/hugetlb.h | 5 +- mm/hugetlb.c| 109 +--- mm/memory.c | 2 +- mm/rmap.c | 4 +- 5 files changed, 103 insertions(+), 37 deletions(-) -- 2.35.3
Re: [RFC PATCH 3/6] testing/pkeys: Add additional test for pkey_alloc()
On 6/16/22 12:25, Sohil Mehta wrote: > Should we have different return error codes when compile support is > disabled vs when runtime support is missing? It doesn't *really* matter. Programs have to be able to run on old kernels which will return ENOSYS. So, _when_ new kernels return ENOSYS or ENOSPC is pretty immaterial.
Re: [RFC PATCH 4/6] pkeys: Lift pkey hardware check for pkey_alloc()
diff --git a/mm/mprotect.c b/mm/mprotect.c index ba5592655ee3..56d35de33725 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -773,6 +773,9 @@ SYSCALL_DEFINE2(pkey_alloc, unsigned long, flags, unsigned long, init_val) int pkey; int ret; + if (!arch_pkeys_enabled()) + return -ENOSPC; + See comments in patch 3/6. Since we are modifying (fixing) old behavior, should we just return ENOSYS to make this consistent? Sohil /* No flags supported yet. */ if (flags) return -EINVAL;
Re: [RFC PATCH 3/6] testing/pkeys: Add additional test for pkey_alloc()
On 6/10/2022 4:35 PM, ira.we...@intel.com wrote: +void test_pkey_alloc_on_unsupported_cpu(void) +{ + int test_pkey = sys_pkey_alloc(0, 0); + + dprintf1("pkey_alloc: %d (%d %s)\n", test_pkey, errno, +strerror(errno)); + pkey_assert(test_pkey < 0); + pkey_assert(errno == ENOSPC); This assert fails on a kernel with CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS disabled. Since pkey_alloc() is an architecture dependent syscall, ENOSYS is returned instead of ENOSPC when support is disabled at compile time. See kernel/sys_ni.c This brings us to an interesting question. Should we have different return error codes when compile support is disabled vs when runtime support is missing? Here is the current behavior for pkey_alloc(): No compile time support -> return ENOSYS No runtime support (but compile time support present) -> return ENOSPC I would think applications would prefer the same error code. But, I am not sure if we can achieve this now due to ABI reasons. +} +
[PATCH] ibmvfc: alloc/free queue resource only during probe/remove
Currently, the sub-queues and event pool resources are alloc/free'd for every CRQ connection event such as reset and LPM. This exposes the driver to a couple issues. First the inefficiency of freeing and reallocating memory that can simply be resued after being sanitized. Further, a system under memory pressue runs the risk of allocation failures that could result in a cripled driver. Finally, there is a race window where command submission/compeletion can try to pull/return elements from/to an event pool that is being deleted or already has been deleted due to the lack of host state around freeing/allocating resources. The following is an example of list corruption following a live partition migration (LPM): Oops: Exception in kernel mode, sig: 5 [#1] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries Modules linked in: vfat fat isofs cdrom ext4 mbcache jbd2 nft_counter nft_compat nf_tables nfnetlink rpadlpar_io rpaphp xsk_diag nfsv3 nfs_acl nfs lockd grace fscache netfs rfkill bonding tls sunrpc pseries_rng drm drm_panel_orientation_quirks xfs libcrc32c dm_service_time sd_mod t10_pi sg ibmvfc scsi_transport_fc ibmveth vmx_crypto dm_multipath dm_mirror dm_region_hash dm_log dm_mod ipmi_devintf ipmi_msghandler fuse CPU: 0 PID: 2108 Comm: ibmvfc_0 Kdump: loaded Not tainted 5.14.0-70.9.1.el9_0.ppc64le #1 NIP: c07c4bb0 LR: c07c4bac CTR: 005b9a10 REGS: c0025c10b760 TRAP: 0700 Not tainted (5.14.0-70.9.1.el9_0.ppc64le) MSR: 8282b033 CR: 2800028f XER: 000f CFAR: c01f55bc IRQMASK: 0 GPR00: c07c4bac c0025c10ba00 c2a47c00 004e GPR04: c031e3006f88 c031e308bd00 c0025c10b768 0027 GPR08: c031e3009dc0 0031e0eb GPR12: c031e2a8 c2dd c0187108 c0020fcee2c0 GPR16: GPR20: c00802f81300 GPR24: 5deadbeef100 5deadbeef122 c00263ba6910 c0024cc88000 GPR28: 003c c002430a c002430ac300 c300 NIP [c07c4bb0] __list_del_entry_valid+0x90/0x100 LR [c07c4bac] __list_del_entry_valid+0x8c/0x100 Call Trace: [c0025c10ba00] [c07c4bac] __list_del_entry_valid+0x8c/0x100 (unreliable) [c0025c10ba60] [c00802f42284] ibmvfc_free_queue+0xec/0x210 [ibmvfc] [c0025c10bb10] [c00802f4246c] ibmvfc_deregister_scsi_channel+0xc4/0x160 [ibmvfc] [c0025c10bba0] [c00802f42580] ibmvfc_release_sub_crqs+0x78/0x130 [ibmvfc] [c0025c10bc20] [c00802f4f6cc] ibmvfc_do_work+0x5c4/0xc70 [ibmvfc] [c0025c10bce0] [c00802f4fdec] ibmvfc_work+0x74/0x1e8 [ibmvfc] [c0025c10bda0] [c01872b8] kthread+0x1b8/0x1c0 [c0025c10be10] [c000cd64] ret_from_kernel_thread+0x5c/0x64 Instruction dump: 40820034 3861 38210060 4e800020 7c0802a6 7c641b78 3c62fe7a 7d254b78 3863b590 f8010070 4ba309cd 6000 <0fe0> 7c0802a6 3c62fe7a 3863b640 ---[ end trace 11a2b65a92f8b66c ]--- ibmvfc 3003: Send warning. Receive queue closed, will retry. Add registration/deregistartion helpers that are called instead during connection resets to sanitize and reconfigure the queues. Fixes: 3034ebe26389 ("scsi: ibmvfc: Add alloc/dealloc routines for SCSI Sub-CRQ Channels") Cc: sta...@vger.kernel.org Signed-off-by: Tyrel Datwyler Reviewed-by: Brian King --- drivers/scsi/ibmvscsi/ibmvfc.c | 79 ++ 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 9fc0ffda6ae8..00684e11976b 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -160,8 +160,8 @@ static void ibmvfc_npiv_logout(struct ibmvfc_host *); static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *); static void ibmvfc_tgt_move_login(struct ibmvfc_target *); -static void ibmvfc_release_sub_crqs(struct ibmvfc_host *); -static void ibmvfc_init_sub_crqs(struct ibmvfc_host *); +static void ibmvfc_dereg_sub_crqs(struct ibmvfc_host *); +static void ibmvfc_reg_sub_crqs(struct ibmvfc_host *); static const char *unknown_error = "unknown error"; @@ -917,7 +917,7 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost) struct vio_dev *vdev = to_vio_dev(vhost->dev); unsigned long flags; - ibmvfc_release_sub_crqs(vhost); + ibmvfc_dereg_sub_crqs(vhost); /* Re-enable the CRQ */ do { @@ -936,7 +936,7 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost) spin_unlock(vhost->crq.q_lock); spin_unlock_irqrestore(vhost->host->host_lock, flags); - ibmvfc_init_sub_crqs(vhost); + ibmvfc_reg_sub_crqs(vhost); return rc; } @@ -955,7 +955,7 @@ static int ibmvfc_reset_crq(struct ibmvf
[PATCH] ibmvfc: store vhost pointer during subcrq allocation
Currently the back pointer from a queue to the vhost adapter isn't set until after subcrq interrupt registration. The value is available when a queue is first allocated and can/should be also set for primary and async queues as well as subcrq's. This fixes a crash observed during kexec/kdump on Power 9 with legacy XICS interrupt controller where a pending subcrq interrupt from the previous kernel can be replayed immediately upon IRQ registration resulting in dereference of a garbage backpointer in ibmvfc_interrupt_scsi. Kernel attempted to read user page (58) - exploit attempt? (uid: 0) BUG: Kernel NULL pointer dereference on read at 0x0058 Faulting instruction address: 0xc00803216a08 Oops: Kernel access of bad area, sig: 11 [#1] ... NIP [c00803216a08] ibmvfc_interrupt_scsi+0x40/0xb0 [ibmvfc] LR [c82079e8] __handle_irq_event_percpu+0x98/0x270 Call Trace: [c00047fa3d80] [c000123e6180] 0xc000123e6180 (unreliable) [c00047fa3df0] [c82079e8] __handle_irq_event_percpu+0x98/0x270 [c00047fa3ea0] [c8207d18] handle_irq_event+0x98/0x188 [c00047fa3ef0] [c820f564] handle_fasteoi_irq+0xc4/0x310 [c00047fa3f40] [c8205c60] generic_handle_irq+0x50/0x80 [c00047fa3f60] [c8015c40] __do_irq+0x70/0x1a0 [c00047fa3f90] [c8016d7c] __do_IRQ+0x9c/0x130 [c00014622f60] [2000] 0x2000 [c00014622ff0] [c8016e50] do_IRQ+0x40/0xa0 [c00014623020] [c8017044] replay_soft_interrupts+0x194/0x2f0 [c00014623210] [c80172a8] arch_local_irq_restore+0x108/0x170 [c00014623240] [c8eb1008] _raw_spin_unlock_irqrestore+0x58/0xb0 [c00014623270] [c820b12c] __setup_irq+0x49c/0x9f0 [c00014623310] [c820b7c0] request_threaded_irq+0x140/0x230 [c00014623380] [c00803212a50] ibmvfc_register_scsi_channel+0x1e8/0x2f0 [ibmvfc] [c00014623450] [c00803213d1c] ibmvfc_init_sub_crqs+0xc4/0x1f0 [ibmvfc] [c000146234d0] [c008032145a8] ibmvfc_reset_crq+0x150/0x210 [ibmvfc] [c00014623550] [c008032147c8] ibmvfc_init_crq+0x160/0x280 [ibmvfc] [c000146235f0] [c0080321a9cc] ibmvfc_probe+0x2a4/0x530 [ibmvfc] Fixes: 3034ebe263897 ("scsi: ibmvfc: Add alloc/dealloc routines for SCSI Sub-CRQ Channels") Cc: sta...@vger.kernel.org Signed-off-by: Tyrel Datwyler Reviewed-by: Brian King --- drivers/scsi/ibmvscsi/ibmvfc.c | 3 ++- drivers/scsi/ibmvscsi/ibmvfc.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index d0eab5700dc5..9fc0ffda6ae8 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -5682,6 +5682,8 @@ static int ibmvfc_alloc_queue(struct ibmvfc_host *vhost, queue->cur = 0; queue->fmt = fmt; queue->size = PAGE_SIZE / fmt_size; + + queue->vhost = vhost; return 0; } @@ -5790,7 +5792,6 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost, } scrq->hwq_id = index; - scrq->vhost = vhost; LEAVE; return 0; diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index 3718406e0988..c39a245f43d0 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h @@ -789,6 +789,7 @@ struct ibmvfc_queue { spinlock_t _lock; spinlock_t *q_lock; + struct ibmvfc_host *vhost; struct ibmvfc_event_pool evt_pool; struct list_head sent; struct list_head free; @@ -797,7 +798,6 @@ struct ibmvfc_queue { union ibmvfc_iu cancel_rsp; /* Sub-CRQ fields */ - struct ibmvfc_host *vhost; unsigned long cookie; unsigned long vios_cookie; unsigned long hw_irq; -- 2.35.3
[PATCH] ibmvfc: multiqueue bug fixes
Fixes for a couple observed crashes of the ibmvfc driver when in MQ mode. Tyrel Datwyler (2): ibmvfc: store vhost pointer during subcrq allocation ibmvfc: alloc/free queue resource only during probe/remove drivers/scsi/ibmvscsi/ibmvfc.c | 82 ++ drivers/scsi/ibmvscsi/ibmvfc.h | 2 +- 2 files changed, 65 insertions(+), 19 deletions(-) -- 2.35.3
Re: [PATCH v2] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c
Le 16/06/2022 à 17:19, Liang He a écrit : In gpio_halt_probe(), of_find_matching_node() will return a node pointer with refcount incremented. We should use of_node_put() in each fail path or when it is not used anymore. Signed-off-by: Liang He --- changelog: v2: use goto-label patch style advised by Christophe. v1: add of_node_put() before each exit. arch/powerpc/platforms/85xx/sgy_cts1000.c | 27 +++ 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c index 98ae64075193..e280f963d88c 100644 --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c @@ -73,6 +73,7 @@ static int gpio_halt_probe(struct platform_device *pdev) struct device_node *node = pdev->dev.of_node; int gpio, err, irq; int trigger; + int ret; if (!node) return -ENODEV; @@ -84,20 +85,24 @@ static int gpio_halt_probe(struct platform_device *pdev) /* Technically we could just read the first one, but punish * DT writers for invalid form. */ - if (of_gpio_count(halt_node) != 1) - return -EINVAL; + if (of_gpio_count(halt_node) != 1) { + ret = -EINVAL; + goto err_put; + } /* Get the gpio number relative to the dynamic base. */ gpio = of_get_gpio_flags(halt_node, 0, &flags); - if (!gpio_is_valid(gpio)) - return -EINVAL; + if (!gpio_is_valid(gpio)) { + ret = -EINVAL; + gotot err_put; + } err = gpio_request(gpio, "gpio-halt"); if (err) { printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n", gpio); - halt_node = NULL; - return err; + ret = err; + goto err_put; } trigger = (flags == OF_GPIO_ACTIVE_LOW); @@ -112,8 +117,8 @@ static int gpio_halt_probe(struct platform_device *pdev) printk(KERN_ERR "gpio-halt: error requesting IRQ %d for " "GPIO %d.\n", irq, gpio); gpio_free(gpio); - halt_node = NULL; - return err; + ret = err; + goto err_put; } /* Register our halt function */ @@ -122,8 +127,12 @@ static int gpio_halt_probe(struct platform_device *pdev) printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" " irq).\n", gpio, trigger, irq); + ret = 0; - return 0; +err_put: + of_node_put(halt_node); + halt_node = NULL; Hi, so now we set 'halt_node' to NULL even in the normal case. This is really spurious. Look at gpio_halt_cb(), but I think that this is just wrong and badly breaks this driver. CJ + return ret; } static int gpio_halt_remove(struct platform_device *pdev)
Re: [PATCH v2 0/4] pseries-wdt: initial support for H_WATCHDOG-based watchdog timers
Hi, Update: checking out 'dmesg' more carefully I found out that the module probe is failing with the following message: [ 186.298424][ T811] pseries-wdt: probe of pseries-wdt.0 failed with error -5 This fail is consistent. If I remove the module and modprobe it again the same error happens. The message is being throw by pseries_wdt_probe() (patch 4/4). Back in QEMU, in Alexey's H_WATCHDOG implementation [1], I see that h_watchdog is returning H_PARAMETER because the retrieved 'watchdogNumber' is zero. Also, the pseries_wdt module still appears in 'lsmod' despite this probe error. Not sure if this is a bug: [root@fedora ~]# rmmod pseries_wdt [root@fedora ~]# modprobe pseries_wdt [ 1792.846769][ T865] pseries-wdt: probe of pseries-wdt.0 failed with error -5 [root@fedora ~]# lsmod | grep pseries pseries_wdt 262144 0 [root@fedora ~]# For reference this is all the output of 'lsmod' in the guest: [root@fedora ~]# lsmod Module Size Used by pseries_wdt 262144 0 nfnetlink 262144 1 evdev 327680 1 input_leds262144 0 led_class 262144 1 input_leds fuse 458752 1 xfs 1835008 2 libcrc32c 262144 1 xfs virtio_scsi 327680 2 virtio_pci262144 0 virtio327680 2 virtio_scsi,virtio_pci vmx_crypto262144 0 gf128mul 262144 1 vmx_crypto crc32c_vpmsum 327680 1 virtio_ring 327680 3 virtio_scsi,virtio_pci,virtio virtio_pci_legacy_dev 262144 1 virtio_pci virtio_pci_modern_dev 262144 1 virtio_pci autofs4 327680 2 Given that the error is being thrown by Alexey's QEMU code, I'll bring it up in the QEMU mailing list in [1] and follow it up from there. [1] https://patchwork.ozlabs.org/project/qemu-ppc/patch/20220608030153.1862335-1-...@ozlabs.ru/ Thanks, Daniel On 6/15/22 22:43, Daniel Henrique Barboza wrote: Hi, I tried this series out with mainline QEMU built with Alexey's patch [1] and I wasn't able to get it to work. I'm using a simple QEMU command line booting a fedora36 guest in a Power9 boston host: sudo ./qemu-system-ppc64 \ -M pseries,cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken,cap-ccf-assist=off,ic-mode=dual \ -m 4G -accel kvm -cpu POWER9 -smp 1,maxcpus=1,threads=1,cores=1,sockets=1 \ -device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x2 \ -drive file=/home/danielhb/fedora36.qcow2,if=none,id=drive-scsi0-0-0-0,format=qcow2,cache=none \ -device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=2 \ -device qemu-xhci,id=usb,bus=pci.0,addr=0x4 -nographic -display none Guest is running v5.19-rc2 with this series applied. Kernel config consists of 'pseries_le_defconfig' plus the following 'watchdog' related changes: [root@fedora ~]# cat linux/.config | grep PSERIES_WDT CONFIG_PSERIES_WDT=y [root@fedora ~]# cat linux/.config | grep -i watchdog CONFIG_PPC_WATCHDOG=y CONFIG_HAVE_NMI_WATCHDOG=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y CONFIG_WATCHDOG_NOWAYOUT=y CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y CONFIG_WATCHDOG_OPEN_TIMEOUT=0 # CONFIG_WATCHDOG_SYSFS is not set # CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set # Watchdog Pretimeout Governors # CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set # Watchdog Device Drivers # CONFIG_SOFT_WATCHDOG is not set # CONFIG_XILINX_WATCHDOG is not set # CONFIG_ZIIRAVE_WATCHDOG is not set # CONFIG_CADENCE_WATCHDOG is not set # CONFIG_DW_WATCHDOG is not set # CONFIG_MAX63XX_WATCHDOG is not set CONFIG_WATCHDOG_RTAS=y # PCI-based Watchdog Cards # CONFIG_PCIPCWATCHDOG is not set # USB-based Watchdog Cards # CONFIG_USBPCWATCHDOG is not set # CONFIG_WQ_WATCHDOG is not set [root@fedora ~]# Kernel command line: [root@fedora ~]# cat /proc/cmdline BOOT_IMAGE=(ieee1275/disk,msdos2)/vmlinuz-5.19.0-rc2-00054-g12ede8ffb103 \ root=/dev/mapper/fedora_fedora-root ro rd.lvm.lv=fedora_fedora/root \ pseries-wdt.timeout=60 pseries-wdt.nowayout=1 pseries-wdt.action=2 With all that, executing echo V > /dev/watchdog0 Does nothing. dmesg is clean and the guest doesn't reboot after the 60 sec timeout. I also tried with PSERIES_WDT being compiled as a module instead of built-in. Same results. What am I missing? [1] https://patchwork.ozlabs.org/project/qemu-ppc/patch/20220608030153.1862335-1-...@ozlabs.ru/ Thanks, Daniel On 6/2/22 14:53, Scott Cheloha wrote: PAPR v2.12 defines a new hypercall, H_WATCHDOG. This patch series adds support for this hypercall to powerpc/pseries kernels and introduces a new watchdog driver, "pseries-wdt", for the virtual timers exposed by the hypercall. This series is preceded by the following: RFC v1: https://lore.kernel.org/linux-watchdog/20220413165104.179144-1-chel...@linux.ibm.com/ RFC v2: https://lore.kernel.org/linux-watchdog/20220509174357.5448-1-chel...@linux.ibm.com/ PATCH v1: https://lore.kernel.org/linux-watchdog/20220520183552.33426-1-chel.
Re: [PATCH v2 0/4] pseries-wdt: initial support for H_WATCHDOG-based watchdog timers
On 6/16/22 13:44, Tyrel Datwyler wrote: On 6/15/22 18:43, Daniel Henrique Barboza wrote: Hi, I tried this series out with mainline QEMU built with Alexey's patch [1] and I wasn't able to get it to work. I'm using a simple QEMU command line booting a fedora36 guest in a Power9 boston host: I would assume the H_WATCHDOG hypercall is not implemented by the qemu pseries machine type. It is a very new hypercall. Alexey implemented QEMU support for this hypercall here: "[qemu] ppc/spapr: Implement H_WATCHDOG" https://patchwork.ozlabs.org/project/qemu-ppc/patch/20220608030153.1862335-1-...@ozlabs.ru/ It is under review in the QEMU mailing list. I tried it out with this series and wasn't able to get it to work. Thanks, Daniel -Tyrel sudo ./qemu-system-ppc64 \ -M pseries,cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken,cap-ccf-assist=off,ic-mode=dual \ -m 4G -accel kvm -cpu POWER9 -smp 1,maxcpus=1,threads=1,cores=1,sockets=1 \ -device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x2 \ -drive file=/home/danielhb/fedora36.qcow2,if=none,id=drive-scsi0-0-0-0,format=qcow2,cache=none \ -device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=2 \ -device qemu-xhci,id=usb,bus=pci.0,addr=0x4 -nographic -display none Guest is running v5.19-rc2 with this series applied. Kernel config consists of 'pseries_le_defconfig' plus the following 'watchdog' related changes: [root@fedora ~]# cat linux/.config | grep PSERIES_WDT CONFIG_PSERIES_WDT=y [root@fedora ~]# cat linux/.config | grep -i watchdog CONFIG_PPC_WATCHDOG=y CONFIG_HAVE_NMI_WATCHDOG=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y CONFIG_WATCHDOG_NOWAYOUT=y CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y CONFIG_WATCHDOG_OPEN_TIMEOUT=0 # CONFIG_WATCHDOG_SYSFS is not set # CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set # Watchdog Pretimeout Governors # CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set # Watchdog Device Drivers # CONFIG_SOFT_WATCHDOG is not set # CONFIG_XILINX_WATCHDOG is not set # CONFIG_ZIIRAVE_WATCHDOG is not set # CONFIG_CADENCE_WATCHDOG is not set # CONFIG_DW_WATCHDOG is not set # CONFIG_MAX63XX_WATCHDOG is not set CONFIG_WATCHDOG_RTAS=y # PCI-based Watchdog Cards # CONFIG_PCIPCWATCHDOG is not set # USB-based Watchdog Cards # CONFIG_USBPCWATCHDOG is not set # CONFIG_WQ_WATCHDOG is not set [root@fedora ~]# Kernel command line: [root@fedora ~]# cat /proc/cmdline BOOT_IMAGE=(ieee1275/disk,msdos2)/vmlinuz-5.19.0-rc2-00054-g12ede8ffb103 \ root=/dev/mapper/fedora_fedora-root ro rd.lvm.lv=fedora_fedora/root \ pseries-wdt.timeout=60 pseries-wdt.nowayout=1 pseries-wdt.action=2 With all that, executing echo V > /dev/watchdog0 Does nothing. dmesg is clean and the guest doesn't reboot after the 60 sec timeout. I also tried with PSERIES_WDT being compiled as a module instead of built-in. Same results. What am I missing? [1] https://patchwork.ozlabs.org/project/qemu-ppc/patch/20220608030153.1862335-1-...@ozlabs.ru/ Thanks, Daniel On 6/2/22 14:53, Scott Cheloha wrote: PAPR v2.12 defines a new hypercall, H_WATCHDOG. This patch series adds support for this hypercall to powerpc/pseries kernels and introduces a new watchdog driver, "pseries-wdt", for the virtual timers exposed by the hypercall. This series is preceded by the following: RFC v1: https://lore.kernel.org/linux-watchdog/20220413165104.179144-1-chel...@linux.ibm.com/ RFC v2: https://lore.kernel.org/linux-watchdog/20220509174357.5448-1-chel...@linux.ibm.com/ PATCH v1: https://lore.kernel.org/linux-watchdog/20220520183552.33426-1-chel...@linux.ibm.com/ Changes of note from PATCH v1: - Trim down the large comment documenting the H_WATCHDOG hypercall. The comment is likely to rot, so remove anything we aren't using and anything overly obvious. - Remove any preprocessor definitions not actually used in the module right now. If we want to use other features offered by the hypercall we can add them in later. They're just clutter until then. - Simplify the "action" module parameter. The value is now an index into an array of possible timeoutAction values. This design removes the need for the custom get/set methods used in PATCH v1. Now we merely need to check that the "action" value is a valid index during pseries_wdt_probe(). Easy. - Make the timeoutAction a member of pseries_wdt, "action". This eliminates the use of a global variable during pseries_wdt_start(). - Use watchdog_init_timeout() idiomatically. Check its return value and error out of pseries_wdt_probe() if it fails.
Re: [FSL P50x0] Keyboard and mouse don't work anymore after the devicetree updates for 5.19
On 13 June 2022 at 05:57 pm, Rob Herring wrote: On Thu, Jun 9, 2022 at 12:03 PM Christian Zigotzky wrote: On 06 June 2022 at 07:06 pm, Rob Herring wrote: On Mon, Jun 6, 2022 at 11:14 AM Christian Zigotzky wrote: On 06 June 2022 at 04:58 pm, Rob Herring wrote: On Fri, May 27, 2022 at 9:23 AM Rob Herring wrote: On Fri, May 27, 2022 at 3:33 AM Christian Zigotzky wrote: On 27 May 2022 at 10:14 am, Prabhakar Mahadev Lad wrote: Hi, -Original Message- From: Christian Zigotzky On 27 May 2022 at 09:56 am, Prabhakar Mahadev Lad wrote: Hi, -Original Message- From: Christophe Leroy [...] Looks like the driver which you are using has not been converted to use platform_get_irq(), could you please check that. Cheers, Prabhakar Do you mean the mouse and keyboard driver? No it could be your gpio/pinctrl driver assuming the keyboard/mouse are using GPIO's. If you are using interrupts then it might be some hierarchal irqc driver in drivers/irqchip/. Cheers, Prabhakar Good to know. I only use unmodified drivers from the official Linux kernel so it's not an issue of the Cyrus+ board. The issue is in drivers/usb/host/fsl-mph-dr-of.c which copies the resources to a child platform device. Can you try the following change: diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 44a7e58a26e3..47d9b7be60da 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -80,8 +80,6 @@ static struct platform_device *fsl_usb2_device_register( const char *name, int id) { struct platform_device *pdev; - const struct resource *res = ofdev->resource; - unsigned int num = ofdev->num_resources; int retval; pdev = platform_device_alloc(name, id); @@ -106,11 +104,7 @@ static struct platform_device *fsl_usb2_device_register( if (retval) goto error; - if (num) { - retval = platform_device_add_resources(pdev, res, num); - if (retval) - goto error; - } + pdev->dev.of_node = ofdev->dev.of_node; >From the log, I think you also need to add this line: pdev->dev.of_node_reused = true; retval = platform_device_add(pdev); if (retval) Hello Rob, Thanks a lot for your answer. Is the following patch correct? Yes --- a/drivers/usb/host/fsl-mph-dr-of.c2022-05-28 09:10:26.797688422 +0200 +++ b/drivers/usb/host/fsl-mph-dr-of.c2022-05-28 09:15:01.668594809 +0200 @@ -80,8 +80,6 @@ static struct platform_device *fsl_usb2_ const char *name, int id) { struct platform_device *pdev; -const struct resource *res = ofdev->resource; -unsigned int num = ofdev->num_resources; int retval; pdev = platform_device_alloc(name, id); @@ -106,11 +104,7 @@ static struct platform_device *fsl_usb2_ if (retval) goto error; -if (num) { -retval = platform_device_add_resources(pdev, res, num); -if (retval) -goto error; -} +pdev->dev.of_node = ofdev->dev.of_node; +pdev->dev.of_node_reused = true; retval = platform_device_add(pdev); if (retval) --- Thanks, Christian Hello Rob, I tested this patch today and unfortunately the issue still exists. The log is the same? Rob Yes, it's the same. Link: http://www.xenosoft.de/dmesg_FSL_P5040_Void_PPC-2.txt -- Christian
Re: [PATCH v2 0/4] pseries-wdt: initial support for H_WATCHDOG-based watchdog timers
On 6/15/22 18:43, Daniel Henrique Barboza wrote: > Hi, > > I tried this series out with mainline QEMU built with Alexey's patch [1] > and I wasn't able to get it to work. I'm using a simple QEMU command line > booting a fedora36 guest in a Power9 boston host: I would assume the H_WATCHDOG hypercall is not implemented by the qemu pseries machine type. It is a very new hypercall. -Tyrel > > sudo ./qemu-system-ppc64 \ > -M > pseries,cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken,cap-ccf-assist=off,ic-mode=dual > \ > -m 4G -accel kvm -cpu POWER9 -smp 1,maxcpus=1,threads=1,cores=1,sockets=1 \ > -device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x2 \ > -drive > file=/home/danielhb/fedora36.qcow2,if=none,id=drive-scsi0-0-0-0,format=qcow2,cache=none > \ > -device > scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=2 > \ > -device qemu-xhci,id=usb,bus=pci.0,addr=0x4 -nographic -display none > > > Guest is running v5.19-rc2 with this series applied. Kernel config consists of > 'pseries_le_defconfig' plus the following 'watchdog' related changes: > > [root@fedora ~]# cat linux/.config | grep PSERIES_WDT > CONFIG_PSERIES_WDT=y > > [root@fedora ~]# cat linux/.config | grep -i watchdog > CONFIG_PPC_WATCHDOG=y > CONFIG_HAVE_NMI_WATCHDOG=y > CONFIG_WATCHDOG=y > CONFIG_WATCHDOG_CORE=y > CONFIG_WATCHDOG_NOWAYOUT=y > CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y > CONFIG_WATCHDOG_OPEN_TIMEOUT=0 > # CONFIG_WATCHDOG_SYSFS is not set > # CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set > # Watchdog Pretimeout Governors > # CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set > # Watchdog Device Drivers > # CONFIG_SOFT_WATCHDOG is not set > # CONFIG_XILINX_WATCHDOG is not set > # CONFIG_ZIIRAVE_WATCHDOG is not set > # CONFIG_CADENCE_WATCHDOG is not set > # CONFIG_DW_WATCHDOG is not set > # CONFIG_MAX63XX_WATCHDOG is not set > CONFIG_WATCHDOG_RTAS=y > # PCI-based Watchdog Cards > # CONFIG_PCIPCWATCHDOG is not set > # USB-based Watchdog Cards > # CONFIG_USBPCWATCHDOG is not set > # CONFIG_WQ_WATCHDOG is not set > [root@fedora ~]# > > > > Kernel command line: > > [root@fedora ~]# cat /proc/cmdline > BOOT_IMAGE=(ieee1275/disk,msdos2)/vmlinuz-5.19.0-rc2-00054-g12ede8ffb103 \ > root=/dev/mapper/fedora_fedora-root ro rd.lvm.lv=fedora_fedora/root \ > pseries-wdt.timeout=60 pseries-wdt.nowayout=1 pseries-wdt.action=2 > > > With all that, executing > > echo V > /dev/watchdog0 > > Does nothing. dmesg is clean and the guest doesn't reboot after the 60 sec > timeout. I also tried with PSERIES_WDT being compiled as a module instead > of built-in. Same results. > > > What am I missing? > > > [1] > https://patchwork.ozlabs.org/project/qemu-ppc/patch/20220608030153.1862335-1-...@ozlabs.ru/ > > > > > Thanks, > > > Daniel > > > > > On 6/2/22 14:53, Scott Cheloha wrote: >> PAPR v2.12 defines a new hypercall, H_WATCHDOG. This patch series >> adds support for this hypercall to powerpc/pseries kernels and >> introduces a new watchdog driver, "pseries-wdt", for the virtual >> timers exposed by the hypercall. >> >> This series is preceded by the following: >> >> RFC v1: >> https://lore.kernel.org/linux-watchdog/20220413165104.179144-1-chel...@linux.ibm.com/ >> >> RFC v2: >> https://lore.kernel.org/linux-watchdog/20220509174357.5448-1-chel...@linux.ibm.com/ >> >> PATCH v1: >> https://lore.kernel.org/linux-watchdog/20220520183552.33426-1-chel...@linux.ibm.com/ >> >> >> Changes of note from PATCH v1: >> >> - Trim down the large comment documenting the H_WATCHDOG hypercall. >> The comment is likely to rot, so remove anything we aren't using >> and anything overly obvious. >> >> - Remove any preprocessor definitions not actually used in the module >> right now. If we want to use other features offered by the hypercall >> we can add them in later. They're just clutter until then. >> >> - Simplify the "action" module parameter. The value is now an index >> into an array of possible timeoutAction values. This design removes >> the need for the custom get/set methods used in PATCH v1. >> >> Now we merely need to check that the "action" value is a valid >> index during pseries_wdt_probe(). Easy. >> >> - Make the timeoutAction a member of pseries_wdt, "action". This >> eliminates the use of a global variable during pseries_wdt_start(). >> >> - Use watchdog_init_timeout() idiomatically. Check its return value >> and error out of pseries_wdt_probe() if it fails. >> >>
[PATCH] powerpc: sysdev: xive: Fix refcount leak in native.c
In xive_native_init(), of_find_compatible_node() will return a node pointer with refcount incremented. We should use of_node_put() in each fail path or when it is not used anymore. Signed-off-by: Liang He --- arch/powerpc/sysdev/xive/native.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index d25d8c692909..3925825954bc 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -579,12 +579,12 @@ bool __init xive_native_init(void) /* Resource 1 is HV window */ if (of_address_to_resource(np, 1, &r)) { pr_err("Failed to get thread mgmnt area resource\n"); - return false; + goto err_put; } tima = ioremap(r.start, resource_size(&r)); if (!tima) { pr_err("Failed to map thread mgmnt area\n"); - return false; + goto err_put; } /* Read number of priorities */ @@ -612,7 +612,7 @@ bool __init xive_native_init(void) /* Resource 2 is OS window */ if (of_address_to_resource(np, 2, &r)) { pr_err("Failed to get thread mgmnt area resource\n"); - return false; + goto err_put; } xive_tima_os = r.start; @@ -624,7 +624,7 @@ bool __init xive_native_init(void) rc = opal_xive_reset(OPAL_XIVE_MODE_EXPL); if (rc) { pr_err("Switch to exploitation mode failed with error %lld\n", rc); - return false; + goto err_put; } /* Setup some dummy HV pool VPs */ @@ -634,10 +634,15 @@ bool __init xive_native_init(void) if (!xive_core_init(np, &xive_native_ops, tima, TM_QW3_HV_PHYS, max_prio)) { opal_xive_reset(OPAL_XIVE_MODE_EMU); - return false; + goto err_put; } + of_node_put(np); pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10)); return true; + +err_put: + of_node_put(np); + return false; } static bool xive_native_provision_pages(void) -- 2.25.1
[PATCH v2] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c
In gpio_halt_probe(), of_find_matching_node() will return a node pointer with refcount incremented. We should use of_node_put() in each fail path or when it is not used anymore. Signed-off-by: Liang He --- changelog: v2: use goto-label patch style advised by Christophe. v1: add of_node_put() before each exit. arch/powerpc/platforms/85xx/sgy_cts1000.c | 27 +++ 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c index 98ae64075193..e280f963d88c 100644 --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c @@ -73,6 +73,7 @@ static int gpio_halt_probe(struct platform_device *pdev) struct device_node *node = pdev->dev.of_node; int gpio, err, irq; int trigger; + int ret; if (!node) return -ENODEV; @@ -84,20 +85,24 @@ static int gpio_halt_probe(struct platform_device *pdev) /* Technically we could just read the first one, but punish * DT writers for invalid form. */ - if (of_gpio_count(halt_node) != 1) - return -EINVAL; + if (of_gpio_count(halt_node) != 1) { + ret = -EINVAL; + goto err_put; + } /* Get the gpio number relative to the dynamic base. */ gpio = of_get_gpio_flags(halt_node, 0, &flags); - if (!gpio_is_valid(gpio)) - return -EINVAL; + if (!gpio_is_valid(gpio)) { + ret = -EINVAL; + gotot err_put; + } err = gpio_request(gpio, "gpio-halt"); if (err) { printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n", gpio); - halt_node = NULL; - return err; + ret = err; + goto err_put; } trigger = (flags == OF_GPIO_ACTIVE_LOW); @@ -112,8 +117,8 @@ static int gpio_halt_probe(struct platform_device *pdev) printk(KERN_ERR "gpio-halt: error requesting IRQ %d for " "GPIO %d.\n", irq, gpio); gpio_free(gpio); - halt_node = NULL; - return err; + ret = err; + goto err_put; } /* Register our halt function */ @@ -122,8 +127,12 @@ static int gpio_halt_probe(struct platform_device *pdev) printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" " irq).\n", gpio, trigger, irq); + ret = 0; - return 0; +err_put: + of_node_put(halt_node); + halt_node = NULL; + return ret; } static int gpio_halt_remove(struct platform_device *pdev) -- 2.25.1
Re:Re: [PATCH] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c
At 2022-06-16 22:49:36, "Christophe Leroy" wrote: > > >Le 15/06/2022 à 14:07, Liang He a écrit : >> [You don't often get email from win...@126.com. Learn why this is important >> at https://aka.ms/LearnAboutSenderIdentification ] >> >> Signed-off-by: Liang He >> --- >> arch/powerpc/platforms/85xx/sgy_cts1000.c | 10 ++ >> 1 file changed, 10 insertions(+) >> >> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c >> b/arch/powerpc/platforms/85xx/sgy_cts1000.c >> index 98ae64075193..2a45b30852b2 100644 >> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c >> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c >> @@ -85,17 +85,24 @@ static int gpio_halt_probe(struct platform_device *pdev) >> /* Technically we could just read the first one, but punish >> * DT writers for invalid form. */ >> if (of_gpio_count(halt_node) != 1) >> + { >> + of_node_put(halt_node); > >Duplicating the same code at multiple exit points is bad practice. > >If you can't do a simple 'return' exit, you should use 'goto' to a >common error path exit. Thanks for your valuable advice, I will resend a new patch for that. > >> return -EINVAL; >> + } >> >> /* Get the gpio number relative to the dynamic base. */ >> gpio = of_get_gpio_flags(halt_node, 0, &flags); >> if (!gpio_is_valid(gpio)) >> + { >> + of_node_put(halt_node); >> return -EINVAL; >> + } >> >> err = gpio_request(gpio, "gpio-halt"); >> if (err) { >> printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n", >> gpio); >> + of_node_put(halt_node); >> halt_node = NULL; >> return err; >> } >> @@ -112,6 +119,7 @@ static int gpio_halt_probe(struct platform_device *pdev) >> printk(KERN_ERR "gpio-halt: error requesting IRQ %d for " >> "GPIO %d.\n", irq, gpio); >> gpio_free(gpio); >> + of_node_put(halt_node); >> halt_node = NULL; >> return err; >> } >> @@ -123,6 +131,8 @@ static int gpio_halt_probe(struct platform_device *pdev) >> printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" >> " irq).\n", gpio, trigger, irq); >> >> + of_node_put(halt_node); >> + >> return 0; >> } >> >> -- >> 2.25.1 >>
Re: [PATCH] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c
Le 15/06/2022 à 14:07, Liang He a écrit : > [You don't often get email from win...@126.com. Learn why this is important > at https://aka.ms/LearnAboutSenderIdentification ] > > Signed-off-by: Liang He > --- > arch/powerpc/platforms/85xx/sgy_cts1000.c | 10 ++ > 1 file changed, 10 insertions(+) > > diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c > b/arch/powerpc/platforms/85xx/sgy_cts1000.c > index 98ae64075193..2a45b30852b2 100644 > --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c > +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c > @@ -85,17 +85,24 @@ static int gpio_halt_probe(struct platform_device *pdev) > /* Technically we could just read the first one, but punish > * DT writers for invalid form. */ > if (of_gpio_count(halt_node) != 1) > + { > + of_node_put(halt_node); Duplicating the same code at multiple exit points is bad practice. If you can't do a simple 'return' exit, you should use 'goto' to a common error path exit. > return -EINVAL; > + } > > /* Get the gpio number relative to the dynamic base. */ > gpio = of_get_gpio_flags(halt_node, 0, &flags); > if (!gpio_is_valid(gpio)) > + { > + of_node_put(halt_node); > return -EINVAL; > + } > > err = gpio_request(gpio, "gpio-halt"); > if (err) { > printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n", > gpio); > + of_node_put(halt_node); > halt_node = NULL; > return err; > } > @@ -112,6 +119,7 @@ static int gpio_halt_probe(struct platform_device *pdev) > printk(KERN_ERR "gpio-halt: error requesting IRQ %d for " > "GPIO %d.\n", irq, gpio); > gpio_free(gpio); > + of_node_put(halt_node); > halt_node = NULL; > return err; > } > @@ -123,6 +131,8 @@ static int gpio_halt_probe(struct platform_device *pdev) > printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" > " irq).\n", gpio, trigger, irq); > > + of_node_put(halt_node); > + > return 0; > } > > -- > 2.25.1 >
[PATCH] powerpc: platforms: 52xx: Fix refcount leak in media5200.c
In media5200_init_irq(), of_find_compatible_node() will return a node pointer with refcount incremented. We should use of_node_put() in fail path or when it is not used anymore. Don't worry about 'fpga_np==NULL' as of_node_put() can correctly handle it. Signed-off-by: Liang He --- arch/powerpc/platforms/52xx/media5200.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c index ee367ff3ec8a..33a35fff11b5 100644 --- a/arch/powerpc/platforms/52xx/media5200.c +++ b/arch/powerpc/platforms/52xx/media5200.c @@ -174,6 +174,8 @@ static void __init media5200_init_irq(void) goto out; pr_debug("%s: allocated irqhost\n", __func__); + of_node_put(fpga_np); + irq_set_handler_data(cascade_virq, &media5200_irq); irq_set_chained_handler(cascade_virq, media5200_irq_cascade); @@ -181,6 +183,7 @@ static void __init media5200_init_irq(void) out: pr_err("Could not find Media5200 FPGA; PCI interrupts will not work\n"); + of_node_put(fpga_np); } /* -- 2.25.1
Re: [RFC PATCH 4/4] objtool/powerpc: Add --mcount specific implementation
Le 16/06/2022 à 15:57, Peter Zijlstra a écrit : > On Thu, Jun 16, 2022 at 01:40:34PM +, Christophe Leroy wrote: >> sizeof(u64) is always 8 by definition. >> >> So if size is 8 we are working on a binary file for a 64 bits target, if >> not it means we are working for a 32 bits target. > > Cross-builds invalidate this I think. Best to look at something like: > >elf->ehdr.e_ident[EI_CLASS] == ELFCLASS32 > > Yes that's what it does indirectly: int size = elf_class_size(elf); With static inline int elf_class_size(struct elf *elf) { if (elf->ehdr.e_ident[EI_CLASS] == ELFCLASS32) return sizeof(u32); else return sizeof(u64); }
[PATCH] arch: powerpc: platforms: 85xx: Fix refcount leak bug in ksi8560.c
In ksi8560_setup_arch(), of_find_compatible_node() will return a node pointer with refcount incremented. We should use of_node_put() when it is not used anymore. Signed-off-by: Liang He --- arch/powerpc/platforms/85xx/ksi8560.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c index bdf9d42f8521..a22f02b0fc77 100644 --- a/arch/powerpc/platforms/85xx/ksi8560.c +++ b/arch/powerpc/platforms/85xx/ksi8560.c @@ -133,6 +133,8 @@ static void __init ksi8560_setup_arch(void) else printk(KERN_ERR "Can't find CPLD in device tree\n"); + of_node_put(cpld); + if (ppc_md.progress) ppc_md.progress("ksi8560_setup_arch()", 0); -- 2.25.1
Re: [RFC PATCH 4/4] objtool/powerpc: Add --mcount specific implementation
On Thu, Jun 16, 2022 at 01:40:34PM +, Christophe Leroy wrote: > sizeof(u64) is always 8 by definition. > > So if size is 8 we are working on a binary file for a 64 bits target, if > not it means we are working for a 32 bits target. Cross-builds invalidate this I think. Best to look at something like: elf->ehdr.e_ident[EI_CLASS] == ELFCLASS32
Re: [RFC PATCH 4/4] objtool/powerpc: Add --mcount specific implementation
Le 16/06/2022 à 15:34, Naveen N. Rao a écrit : > Christophe Leroy wrote: >> >> >> Le 25/05/2022 à 19:27, Christophe Leroy a écrit : >>> >>> >>> Le 24/05/2022 à 15:33, Christophe Leroy a écrit : Le 24/05/2022 à 13:00, Sathvika Vasireddy a écrit : >> >>> +{ >>> + switch (elf->ehdr.e_machine) { >>> + case EM_X86_64: >>> + return R_X86_64_64; >>> + case EM_PPC64: >>> + return R_PPC64_ADDR64; >>> + default: >>> + WARN("unknown machine..."); >>> + exit(-1); >>> + } >>> +} >> Wouldn't it be better to make that function arch specific ? > > This is so that we can support cross architecture builds. > I'm not sure I follow you here. This is only based on the target, it doesn't depend on the build host so I can't the link with cross arch builds. The same as you have arch_decode_instruction(), you could have arch_elf_reloc_type_long() It would make sense indeed, because there is no point in supporting X86 relocation when you don't support X86 instruction decoding. >>> >>> Could simply be some macro defined in >>> tools/objtool/arch/powerpc/include/arch/elf.h and >>> tools/objtool/arch/x86/include/arch/elf.h >>> >>> The x86 version would be: >>> >>> #define R_ADDR(elf) R_X86_64_64 >>> >>> And the powerpc version would be: >>> >>> #define R_ADDR(elf) (elf->ehdr.e_machine == EM_PPC64 ? R_PPC64_ADDR64 >>> : R_PPC_ADDR32) >>> >> >> Well, looking once more, and taking into account the patch from Chen >> https://lore.kernel.org/lkml/20220531020744.236970-4-chenzhong...@huawei.com/ >> >> >> >> It would be easier to just define two macros: >> >> #define R_ABS64 R_PPC64_ADDR64 >> #define R_ABS32 R_PPC_ADDR32 >> >> And then in the caller, as we know the size, do something like >> >> size == sizeof(u64) ? R_ABS64 : R_ABS32; > > How does 'sizeof(u64)' work here? > sizeof(u64) is always 8 by definition. So if size is 8 we are working on a binary file for a 64 bits target, if not it means we are working for a 32 bits target. Christophe
Re: [RFC PATCH 4/4] objtool/powerpc: Add --mcount specific implementation
Christophe Leroy wrote: Le 25/05/2022 à 19:27, Christophe Leroy a écrit : Le 24/05/2022 à 15:33, Christophe Leroy a écrit : Le 24/05/2022 à 13:00, Sathvika Vasireddy a écrit : +{ + switch (elf->ehdr.e_machine) { + case EM_X86_64: + return R_X86_64_64; + case EM_PPC64: + return R_PPC64_ADDR64; + default: + WARN("unknown machine..."); + exit(-1); + } +} Wouldn't it be better to make that function arch specific ? This is so that we can support cross architecture builds. I'm not sure I follow you here. This is only based on the target, it doesn't depend on the build host so I can't the link with cross arch builds. The same as you have arch_decode_instruction(), you could have arch_elf_reloc_type_long() It would make sense indeed, because there is no point in supporting X86 relocation when you don't support X86 instruction decoding. Could simply be some macro defined in tools/objtool/arch/powerpc/include/arch/elf.h and tools/objtool/arch/x86/include/arch/elf.h The x86 version would be: #define R_ADDR(elf) R_X86_64_64 And the powerpc version would be: #define R_ADDR(elf) (elf->ehdr.e_machine == EM_PPC64 ? R_PPC64_ADDR64 : R_PPC_ADDR32) Well, looking once more, and taking into account the patch from Chen https://lore.kernel.org/lkml/20220531020744.236970-4-chenzhong...@huawei.com/ It would be easier to just define two macros: #define R_ABS64 R_PPC64_ADDR64 #define R_ABS32 R_PPC_ADDR32 And then in the caller, as we know the size, do something like size == sizeof(u64) ? R_ABS64 : R_ABS32; How does 'sizeof(u64)' work here? - Naveen
Re: [PATCH] powerpc/mm: Move CMA reservations after initmem_init()
On 16 Jun 2022, at 8:00, Michael Ellerman wrote: > After commit 11ac3e87ce09 ("mm: cma: use pageblock_order as the single > alignment") there is an error at boot about the KVM CMA reservation > failing, eg: > > kvm_cma_reserve: reserving 6553 MiB for global area > cma: Failed to reserve 6553 MiB > > That makes it impossible to start KVM guests using the hash MMU with > more than 2G of memory, because the VM is unable to allocate a large > enough region for the hash page table, eg: > > $ qemu-system-ppc64 -enable-kvm -M pseries -m 4G ... > qemu-system-ppc64: Failed to allocate KVM HPT of order 25: Cannot allocate > memory > > Aneesh pointed out that this happens because when kvm_cma_reserve() is > called, pageblock_order has not been initialised yet, and is still zero, > causing the checks in cma_init_reserved_mem() against > CMA_MIN_ALIGNMENT_PAGES to fail. > > Fix it by moving the call to kvm_cma_reserve() after initmem_init(). The > pageblock_order is initialised in sparse_init() which is called from > initmem_init(). > > Also move the hugetlb CMA reservation. > > Fixes: 11ac3e87ce09 ("mm: cma: use pageblock_order as the single alignment") > Signed-off-by: Michael Ellerman > --- > arch/powerpc/kernel/setup-common.c | 13 +++-- > 1 file changed, 7 insertions(+), 6 deletions(-) > > diff --git a/arch/powerpc/kernel/setup-common.c > b/arch/powerpc/kernel/setup-common.c > index eb0077b302e2..1a02629ec70b 100644 > --- a/arch/powerpc/kernel/setup-common.c > +++ b/arch/powerpc/kernel/setup-common.c > @@ -935,12 +935,6 @@ void __init setup_arch(char **cmdline_p) > /* Print various info about the machine that has been gathered so far. > */ > print_system_info(); > > - /* Reserve large chunks of memory for use by CMA for KVM. */ > - kvm_cma_reserve(); > - > - /* Reserve large chunks of memory for us by CMA for hugetlb */ > - gigantic_hugetlb_cma_reserve(); > - > klp_init_thread_info(&init_task); > > setup_initial_init_mm(_stext, _etext, _edata, _end); > @@ -955,6 +949,13 @@ 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. > + */ > + kvm_cma_reserve(); > + gigantic_hugetlb_cma_reserve(); > + > early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); > > if (ppc_md.setup_arch) > -- > 2.35.3 Thank you for the fix. Reviewed-by: Zi Yan -- Best Regards, Yan, Zi signature.asc Description: OpenPGP digital signature
Re: [PATCH] powerpc/mm: Move CMA reservations after initmem_init()
Michael Ellerman writes: > After commit 11ac3e87ce09 ("mm: cma: use pageblock_order as the single > alignment") there is an error at boot about the KVM CMA reservation > failing, eg: > > kvm_cma_reserve: reserving 6553 MiB for global area > cma: Failed to reserve 6553 MiB > > That makes it impossible to start KVM guests using the hash MMU with > more than 2G of memory, because the VM is unable to allocate a large > enough region for the hash page table, eg: > > $ qemu-system-ppc64 -enable-kvm -M pseries -m 4G ... > qemu-system-ppc64: Failed to allocate KVM HPT of order 25: Cannot allocate > memory > > Aneesh pointed out that this happens because when kvm_cma_reserve() is > called, pageblock_order has not been initialised yet, and is still zero, > causing the checks in cma_init_reserved_mem() against > CMA_MIN_ALIGNMENT_PAGES to fail. > > Fix it by moving the call to kvm_cma_reserve() after initmem_init(). The > pageblock_order is initialised in sparse_init() which is called from > initmem_init(). > > Also move the hugetlb CMA reservation. > Reviewed-by: Aneesh Kumar K.V > Fixes: 11ac3e87ce09 ("mm: cma: use pageblock_order as the single alignment") > Signed-off-by: Michael Ellerman > --- > arch/powerpc/kernel/setup-common.c | 13 +++-- > 1 file changed, 7 insertions(+), 6 deletions(-) > > diff --git a/arch/powerpc/kernel/setup-common.c > b/arch/powerpc/kernel/setup-common.c > index eb0077b302e2..1a02629ec70b 100644 > --- a/arch/powerpc/kernel/setup-common.c > +++ b/arch/powerpc/kernel/setup-common.c > @@ -935,12 +935,6 @@ void __init setup_arch(char **cmdline_p) > /* Print various info about the machine that has been gathered so far. > */ > print_system_info(); > > - /* Reserve large chunks of memory for use by CMA for KVM. */ > - kvm_cma_reserve(); > - > - /* Reserve large chunks of memory for us by CMA for hugetlb */ > - gigantic_hugetlb_cma_reserve(); > - > klp_init_thread_info(&init_task); > > setup_initial_init_mm(_stext, _etext, _edata, _end); > @@ -955,6 +949,13 @@ 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. > + */ > + kvm_cma_reserve(); > + gigantic_hugetlb_cma_reserve(); > + > early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); > > if (ppc_md.setup_arch) > -- > 2.35.3
[PATCH] powerpc/mm: Move CMA reservations after initmem_init()
After commit 11ac3e87ce09 ("mm: cma: use pageblock_order as the single alignment") there is an error at boot about the KVM CMA reservation failing, eg: kvm_cma_reserve: reserving 6553 MiB for global area cma: Failed to reserve 6553 MiB That makes it impossible to start KVM guests using the hash MMU with more than 2G of memory, because the VM is unable to allocate a large enough region for the hash page table, eg: $ qemu-system-ppc64 -enable-kvm -M pseries -m 4G ... qemu-system-ppc64: Failed to allocate KVM HPT of order 25: Cannot allocate memory Aneesh pointed out that this happens because when kvm_cma_reserve() is called, pageblock_order has not been initialised yet, and is still zero, causing the checks in cma_init_reserved_mem() against CMA_MIN_ALIGNMENT_PAGES to fail. Fix it by moving the call to kvm_cma_reserve() after initmem_init(). The pageblock_order is initialised in sparse_init() which is called from initmem_init(). Also move the hugetlb CMA reservation. Fixes: 11ac3e87ce09 ("mm: cma: use pageblock_order as the single alignment") Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/setup-common.c | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index eb0077b302e2..1a02629ec70b 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -935,12 +935,6 @@ void __init setup_arch(char **cmdline_p) /* Print various info about the machine that has been gathered so far. */ print_system_info(); - /* Reserve large chunks of memory for use by CMA for KVM. */ - kvm_cma_reserve(); - - /* Reserve large chunks of memory for us by CMA for hugetlb */ - gigantic_hugetlb_cma_reserve(); - klp_init_thread_info(&init_task); setup_initial_init_mm(_stext, _etext, _edata, _end); @@ -955,6 +949,13 @@ 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. +*/ + kvm_cma_reserve(); + gigantic_hugetlb_cma_reserve(); + early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); if (ppc_md.setup_arch) -- 2.35.3
[PATCH kernel] pseries/iommu/ddw: Fix kdump to work in absence of ibm,dma-window
The pseries platform uses 32bit default DMA window (always 4K pages) and optional 64bit DMA window available via DDW ("Dynamic DMA Windows"), 64K or 2M pages. For ages the default one was not removed and a huge window was created in addition. Things changed with SRIOV-enabled PowerVM which creates a default-and-bigger DMA window in 64bit space (still using 4K pages) for IOV VFs so certain OSes do not need to use the DDW API in order to utilize all available TCE budget. Linux on the other hand removes the default window and creates a bigger one (with more TCEs or/and a bigger page size - 64K/2M) in a bid to map the entire RAM, and if the new window size is smaller than that - it still uses this new bigger window. The result is that the default window is removed but the "ibm,dma-window" property is not. When kdump is invoked, the existing code tries reusing the existing 64bit DMA window which location and parameters are stored in the device tree but this fails as the new property does not make it to the kdump device tree blob. So the code falls back to the default window which does not exist anymore although the device tree says that it does. The result of that is that PCI devices become unusable and cannot be used for kdumping. This preserves the DMA64 and DIRECT64 properties in the device tree blob for the crash kernel. Since the crash kernel setup is done after device drivers are loaded and probed, the proper DMA config is stored at least for boot time devices. Because DDW window is optional and the code configures the default window first, the existing code creates an IOMMU table descriptor for the non-existing default DMA window. It is harmless for kdump as it does not touch the actual window (only reads what is mapped and marks those IO pages as used) but it is bad for kexec which clears it thinking it is a smaller default window rather than a bigger DDW window. This removes the "ibm,dma-window" property from the device tree after a bigger window is created and the crash kernel setup picks it up. Signed-off-by: Alexey Kardashevskiy --- arch/powerpc/kexec/file_load_64.c | 52 +++ arch/powerpc/platforms/pseries/iommu.c | 88 +++--- 2 files changed, 102 insertions(+), 38 deletions(-) diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c index b4981b651d9a..b4b486b68b63 100644 --- a/arch/powerpc/kexec/file_load_64.c +++ b/arch/powerpc/kexec/file_load_64.c @@ -1038,6 +1038,48 @@ static int update_cpus_node(void *fdt) return ret; } +static int copy_dma_property(void *fdt, int node_offset, const struct device_node *dn, +const char *propname) +{ + const void *prop, *fdtprop; + int len = 0, fdtlen = 0, ret; + + prop = of_get_property(dn, propname, &len); + fdtprop = fdt_getprop(fdt, node_offset, propname, &fdtlen); + + if (fdtprop && !prop) + ret = fdt_delprop(fdt, node_offset, propname); + else if (prop) + ret = fdt_setprop(fdt, node_offset, propname, prop, len); + + return ret; +} + +static int update_pci_nodes(void *fdt, const char *dmapropname) +{ + struct device_node *dn; + int pci_offset, root_offset, ret = 0; + + if (!firmware_has_feature(FW_FEATURE_LPAR)) + return 0; + + root_offset = fdt_path_offset(fdt, "/"); + for_each_node_with_property(dn, dmapropname) { + pci_offset = fdt_subnode_offset(fdt, root_offset, of_node_full_name(dn)); + if (pci_offset < 0) + continue; + + ret = copy_dma_property(fdt, pci_offset, dn, "ibm,dma-window"); + if (ret < 0) + break; + ret = copy_dma_property(fdt, pci_offset, dn, dmapropname); + if (ret < 0) + break; + } + + return ret; +} + /** * setup_new_fdt_ppc64 - Update the flattend device-tree of the kernel * being loaded. @@ -1099,6 +1141,16 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt, if (ret < 0) goto out; +#define DIRECT64_PROPNAME "linux,direct64-ddr-window-info" +#define DMA64_PROPNAME "linux,dma64-ddr-window-info" + ret = update_pci_nodes(fdt, DIRECT64_PROPNAME); + if (ret < 0) + goto out; + + ret = update_pci_nodes(fdt, DMA64_PROPNAME); + if (ret < 0) + goto out; + /* Update memory reserve map */ ret = get_reserved_memory_ranges(&rmem); if (ret) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index fba64304e859..af3c871668df 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -700,6 +700,33 @@ struct iommu_table_ops iommu_table_lpar_multi_ops = { .get = tce_get_pSeriesLP }; +/* + * Find nearest ibm,dma-window (default DMA window
Re: [PATCH 2/6] powerpc: Provide syscall wrapper
On Thu, Jun 16, 2022 at 7:42 AM Rohan McLure wrote: > > As for SPU's, the issue here is that include/linux/syscalls.h only > provides prototypes for sys_... handlers. So spu_callbacks.c must > reference these symbols for the translation unit to compile. A solution > may be for spu_syscall_table to be made extern linkage and populated in > the same manner as systbl.S. I suggest we simply omit support for sycall > wrappers with the Cell processor. The compat syscalls should all be declared in linux/compat.h. I think in general the C based syscall tables are better because they enforce the presence of a declaration for each syscall, and that helps with type safety. Arnd
[PATCH] selftests/powerpc: Add missing files to .gitignores
These were missed when the respective tests were added, add them now. Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/math/.gitignore | 1 + tools/testing/selftests/powerpc/mce/.gitignore | 1 + tools/testing/selftests/powerpc/pmu/ebb/.gitignore | 1 + tools/testing/selftests/powerpc/security/.gitignore | 1 + 4 files changed, 4 insertions(+) create mode 100644 tools/testing/selftests/powerpc/mce/.gitignore diff --git a/tools/testing/selftests/powerpc/math/.gitignore b/tools/testing/selftests/powerpc/math/.gitignore index d0c23b2e4b60..07b4893ef7af 100644 --- a/tools/testing/selftests/powerpc/math/.gitignore +++ b/tools/testing/selftests/powerpc/math/.gitignore @@ -7,3 +7,4 @@ fpu_signal vmx_signal vsx_preempt fpu_denormal +mma diff --git a/tools/testing/selftests/powerpc/mce/.gitignore b/tools/testing/selftests/powerpc/mce/.gitignore new file mode 100644 index ..f5921462a495 --- /dev/null +++ b/tools/testing/selftests/powerpc/mce/.gitignore @@ -0,0 +1 @@ +inject-ra-err diff --git a/tools/testing/selftests/powerpc/pmu/ebb/.gitignore b/tools/testing/selftests/powerpc/pmu/ebb/.gitignore index 2920fb39439b..64d8dfdac74a 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/.gitignore +++ b/tools/testing/selftests/powerpc/pmu/ebb/.gitignore @@ -21,3 +21,4 @@ back_to_back_ebbs_test lost_exception_test no_handler_test cycles_with_mmcr2_test +regs_access_pmccext_test diff --git a/tools/testing/selftests/powerpc/security/.gitignore b/tools/testing/selftests/powerpc/security/.gitignore index 93614b125ded..9357b186b13c 100644 --- a/tools/testing/selftests/powerpc/security/.gitignore +++ b/tools/testing/selftests/powerpc/security/.gitignore @@ -2,3 +2,4 @@ rfi_flush entry_flush spectre_v2 +uaccess_flush -- 2.35.3