Re: [RFC PATCH] ACPI / amba: Skip creating amba device when associated cpu is not online

From: Mathieu Poirier
Date: Thu Jan 27 2022 - 15:28:40 EST


Hi Cheng,

I am severely behind in my patch review process and as such will not
be able to start reviewing your work before the week of February 7th.

Thanks,
Mathieu

On Fri, 7 Jan 2022 at 01:47, chenxiang <chenxiang66@xxxxxxxxxxxxx> wrote:
>
> From: Xiang Chen <chenxiang66@xxxxxxxxxxxxx>
>
> If not up all the cpus with command line "maxcpus=x", system will be
> blocked.
> We find that some amba devices such as ETM devices, are associated with
> special cpus, and if the cpu is not up, the register of associated device
> is not allowed to access. BIOS reports all the ETM device nodes and a
> amba device is created for every ETM device, so even if one cpu is not up,
> the amba device will still be created for the associated device, and also
> the register of device (pid and cid) will be accessed when adding amba
> device which will cause the issue.
> To fix it, skip creating amba device if it is associated with a cpu which
> is not online.
>
> Signed-off-by: Xiang Chen <chenxiang66@xxxxxxxxxxxxx>
> ---
> drivers/acpi/acpi_amba.c | 36 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 36 insertions(+)
>
> diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c
> index ab8a4e0191b1..2369198f734b 100644
> --- a/drivers/acpi/acpi_amba.c
> +++ b/drivers/acpi/acpi_amba.c
> @@ -16,6 +16,7 @@
> #include <linux/ioport.h>
> #include <linux/kernel.h>
> #include <linux/module.h>
> +#include <acpi/processor.h>
>
> #include "internal.h"
>
> @@ -45,6 +46,35 @@ static void amba_register_dummy_clk(void)
> clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL);
> }
>
> +static int acpi_handle_to_cpuid(acpi_handle handle)
> +{
> + int cpu = -1;
> + struct acpi_processor *pr;
> +
> + for_each_possible_cpu(cpu) {
> + pr = per_cpu(processors, cpu);
> + if (pr && pr->handle == handle)
> + break;
> + }
> +
> + return cpu;
> +}
> +
> +static int acpi_dev_get_cpu(struct acpi_device *adev)
> +{
> + acpi_handle cpu_handle;
> + acpi_status status;
> + int cpu;
> +
> + status = acpi_get_parent(adev->handle, &cpu_handle);
> + if (ACPI_FAILURE(status))
> + return -1;
> + cpu = acpi_handle_to_cpuid(cpu_handle);
> + if (cpu >= nr_cpu_ids)
> + return -1;
> + return cpu;
> +}
> +
> static int amba_handler_attach(struct acpi_device *adev,
> const struct acpi_device_id *id)
> {
> @@ -54,11 +84,17 @@ static int amba_handler_attach(struct acpi_device *adev,
> bool address_found = false;
> int irq_no = 0;
> int ret;
> + int cpu;
>
> /* If the ACPI node already has a physical device attached, skip it. */
> if (adev->physical_node_count)
> return 0;
>
> + /* If the cpu associated with the device is not online, skip it. */
> + cpu = acpi_dev_get_cpu(adev);
> + if (cpu >= 0 && !cpu_online(cpu))
> + return 0;
> +
> dev = amba_device_alloc(dev_name(&adev->dev), 0, 0);
> if (!dev) {
> dev_err(&adev->dev, "%s(): amba_device_alloc() failed\n",
> --
> 2.33.0
>