diff mbox

[2/3] GHES: Move memory initialisation to ghes_probe()

Message ID 20170801133608.21017-3-punit.agrawal@arm.com (mailing list archive)
State Changes Requested, archived
Headers show

Commit Message

Punit Agrawal Aug. 1, 2017, 1:36 p.m. UTC
During the driver init, the ghes driver initialises some data structures
which are only used if a GHES platform device is probed. Similarly, the
init function also checks for support for firmware first mode.

Create a function, ghes_common_init(), that performs the initialisations
and checks that are currently performed on driver init. The function is
called when the GHES device is probed.

Delaying initialisation and checks until probe has the added benefit of
reducing driver prints on systems that do not support ACPI APEI.

Signed-off-by: Punit Agrawal <punit.agrwal@arm.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: James Morse <james.morse@arm.com>
---
 drivers/acpi/apei/ghes.c | 77 +++++++++++++++++++++++++++---------------------
 1 file changed, 43 insertions(+), 34 deletions(-)

Comments

Punit Agrawal Aug. 1, 2017, 2:04 p.m. UTC | #1
Punit Agrawal <punit.agrawal@arm.com> writes:

> During the driver init, the ghes driver initialises some data structures
> which are only used if a GHES platform device is probed. Similarly, the
> init function also checks for support for firmware first mode.
>
> Create a function, ghes_common_init(), that performs the initialisations
> and checks that are currently performed on driver init. The function is
> called when the GHES device is probed.
>
> Delaying initialisation and checks until probe has the added benefit of
> reducing driver prints on systems that do not support ACPI APEI.
>
> Signed-off-by: Punit Agrawal <punit.agrwal@arm.com>

I managed to get my email wrong in the signed-off-by. And git send-email
usage propagated it to the senders.

Corrected it locally but will wait for comments on the code before
re-sending.

> Cc: Borislav Petkov <bp@suse.de>
> Cc: James Morse <james.morse@arm.com>
> ---
>  drivers/acpi/apei/ghes.c | 77 +++++++++++++++++++++++++++---------------------
>  1 file changed, 43 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index 007b38abcb34..befb18338acb 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
> @@ -1088,12 +1088,53 @@ static inline void ghes_nmi_init_cxt(void)
>  }
>  #endif /* CONFIG_HAVE_ACPI_APEI_NMI */
>  
> +static int ghes_common_init(void)
> +{
> +	int rc;
> +	static bool initialised;
> +
> +	if (initialised)
> +		return 0;
> +
> +	ghes_nmi_init_cxt();
> +
> +	rc = ghes_ioremap_init();
> +	if (rc)
> +		goto err;
> +
> +	rc = ghes_estatus_pool_init();
> +	if (rc)
> +		goto err_ioremap_exit;
> +
> +	rc = apei_osc_setup();
> +	if (rc == 0 && osc_sb_apei_support_acked)
> +		pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit and WHEA _OSC.\n");
> +	else if (rc == 0 && !osc_sb_apei_support_acked)
> +		pr_info(GHES_PFX "APEI firmware first mode is enabled by WHEA _OSC.\n");
> +	else if (rc && osc_sb_apei_support_acked)
> +		pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n");
> +	else
> +		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
> +
> +	initialised = true;
> +	return 0;
> +
> +err_ioremap_exit:
> +	ghes_ioremap_exit();
> +err:
> +	return rc;
> +}
> +
>  static int ghes_probe(struct platform_device *ghes_dev)
>  {
>  	struct acpi_hest_generic *generic;
>  	struct ghes *ghes = NULL;
>  
> -	int rc = -EINVAL;
> +	int rc;
> +
> +	rc = ghes_common_init();
> +	if (rc)
> +		return rc;
>  
>  	generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data;
>  	if (!generic->enabled)
> @@ -1268,8 +1309,6 @@ static struct platform_driver ghes_platform_driver = {
>  
>  static int __init ghes_init(void)
>  {
> -	int rc;
> -
>  	if (acpi_disabled)
>  		return -ENODEV;
>  
> @@ -1283,36 +1322,6 @@ static int __init ghes_init(void)
>  		return -EINVAL;
>  	}
>  
> -	ghes_nmi_init_cxt();
> -
> -	rc = ghes_ioremap_init();
> -	if (rc)
> -		goto err;
> -
> -	rc = ghes_estatus_pool_init();
> -	if (rc)
> -		goto err_ioremap_exit;
> -
> -	rc = platform_driver_register(&ghes_platform_driver);
> -	if (rc)
> -		goto err_pool_exit;
> -
> -	rc = apei_osc_setup();
> -	if (rc == 0 && osc_sb_apei_support_acked)
> -		pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit and WHEA _OSC.\n");
> -	else if (rc == 0 && !osc_sb_apei_support_acked)
> -		pr_info(GHES_PFX "APEI firmware first mode is enabled by WHEA _OSC.\n");
> -	else if (rc && osc_sb_apei_support_acked)
> -		pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n");
> -	else
> -		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
> -
> -	return 0;
> -err_pool_exit:
> -	ghes_estatus_pool_exit();
> -err_ioremap_exit:
> -	ghes_ioremap_exit();
> -err:
> -	return rc;
> +	return platform_driver_register(&ghes_platform_driver);
>  }
>  device_initcall(ghes_init);
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Borislav Petkov Aug. 14, 2017, 7:22 p.m. UTC | #2
On Tue, Aug 01, 2017 at 02:36:07PM +0100, Punit Agrawal wrote:
> During the driver init, the ghes driver initialises some data structures

Let's stick to "GHES" in capital letters everywhere.

> which are only used if a GHES platform device is probed. Similarly, the
> init function also checks for support for firmware first mode.
> 
> Create a function, ghes_common_init(), that performs the initialisations
> and checks that are currently performed on driver init. The function is
> called when the GHES device is probed.
> 
> Delaying initialisation and checks until probe has the added benefit of
> reducing driver prints on systems that do not support ACPI APEI.
> 
> Signed-off-by: Punit Agrawal <punit.agrwal@arm.com>
> Cc: Borislav Petkov <bp@suse.de>
> Cc: James Morse <james.morse@arm.com>
> ---
>  drivers/acpi/apei/ghes.c | 77 +++++++++++++++++++++++++++---------------------
>  1 file changed, 43 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index 007b38abcb34..befb18338acb 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
> @@ -1088,12 +1088,53 @@ static inline void ghes_nmi_init_cxt(void)
>  }
>  #endif /* CONFIG_HAVE_ACPI_APEI_NMI */
>  
> +static int ghes_common_init(void)
> +{
> +	int rc;
> +	static bool initialised;
> +
> +	if (initialised)
> +		return 0;

Can't say that I like it. Especially for this "initialised" thing, which
practically says that this code doesn't conceptually belong here because
we have to explicitly force it to execute it only once. Even though we
have execute-once path in ghes_init().

What would be much better IMHO is if ghes_init() checked for some APEI
table which is missing on your system and exited early. That would save
us all the trouble and solve the situation properly ...
Borislav Petkov Aug. 15, 2017, 8:35 a.m. UTC | #3
On Tue, Aug 15, 2017 at 11:10:05AM +0100, Punit Agrawal wrote:
> In the absence of any GHES entries these are wasted.

I know. This whole APEI init code would need a proper cleanup, like
acpi_pci_root_init() calls acpi_hest_init() and it shouldn't have to
communicate through a variable with GHES whether to init or not but it
should initialize GHES itself. And ghes_init() being a device_initcall()
is just yuck.

Something for the todo list I guess...

> The system does not provide the Hardware Error Source Table (HEST) which
> is checked in the hest driver (drivers/acpi/apei/hest.c).
> 
> I think I'll go with your original suggestion to change hest_disable
> from a boolean to something with more states. Re-checking for the HEST
> table again feels like duplication.
> 
> Makes sense?

Right, and then depending on the setting of hest_disable, either issue
the "HEST is not enabled" message or not.

Thanks.
Punit Agrawal Aug. 15, 2017, 10:10 a.m. UTC | #4
Hi Boris,

Borislav Petkov <bp@suse.de> writes:

> On Tue, Aug 01, 2017 at 02:36:07PM +0100, Punit Agrawal wrote:
>> During the driver init, the ghes driver initialises some data structures
>
> Let's stick to "GHES" in capital letters everywhere.
>
>> which are only used if a GHES platform device is probed. Similarly, the
>> init function also checks for support for firmware first mode.
>> 
>> Create a function, ghes_common_init(), that performs the initialisations
>> and checks that are currently performed on driver init. The function is
>> called when the GHES device is probed.
>> 
>> Delaying initialisation and checks until probe has the added benefit of
>> reducing driver prints on systems that do not support ACPI APEI.
>> 
>> Signed-off-by: Punit Agrawal <punit.agrwal@arm.com>
>> Cc: Borislav Petkov <bp@suse.de>
>> Cc: James Morse <james.morse@arm.com>
>> ---
>>  drivers/acpi/apei/ghes.c | 77 +++++++++++++++++++++++++++---------------------
>>  1 file changed, 43 insertions(+), 34 deletions(-)
>> 
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>> index 007b38abcb34..befb18338acb 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -1088,12 +1088,53 @@ static inline void ghes_nmi_init_cxt(void)
>>  }
>>  #endif /* CONFIG_HAVE_ACPI_APEI_NMI */
>>  
>> +static int ghes_common_init(void)
>> +{
>> +	int rc;
>> +	static bool initialised;
>> +
>> +	if (initialised)
>> +		return 0;
>
> Can't say that I like it. Especially for this "initialised" thing, which
> practically says that this code doesn't conceptually belong here because
> we have to explicitly force it to execute it only once. Even though we
> have execute-once path in ghes_init().

I can see your point. My rationale for the change was that the allocated
resources are only ever useful if there is an actual GHES device in the
system - which we can't know until we hit probe.

In the absence of any GHES entries these are wasted.

>
> What would be much better IMHO is if ghes_init() checked for some APEI
> table which is missing on your system and exited early. That would save
> us all the trouble and solve the situation properly ...

The system does not provide the Hardware Error Source Table (HEST) which
is checked in the hest driver (drivers/acpi/apei/hest.c).

I think I'll go with your original suggestion to change hest_disable
from a boolean to something with more states. Re-checking for the HEST
table again feels like duplication.

Makes sense?

Thanks for taking a look at the patches.

Punit

>
> -- 
> Regards/Gruss,
>     Boris.
>
> SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Punit Agrawal Aug. 15, 2017, 10:31 a.m. UTC | #5
[ thanks for dropping the bad email! ]

Borislav Petkov <bp@suse.de> writes:

> On Tue, Aug 15, 2017 at 11:10:05AM +0100, Punit Agrawal wrote:
>> In the absence of any GHES entries these are wasted.
>
> I know. This whole APEI init code would need a proper cleanup, like
> acpi_pci_root_init() calls acpi_hest_init() and it shouldn't have to
> communicate through a variable with GHES whether to init or not but it
> should initialize GHES itself. And ghes_init() being a device_initcall()
> is just yuck.

I'd seen the link between acpi_pci_root_init() and acpi_hest_init() but
didn't want to open another can of worms... :)

$SUBJECT was my attempt (small) at improving the situation but I guess I
didn't go far enough.

>
> Something for the todo list I guess...
>
>> The system does not provide the Hardware Error Source Table (HEST) which
>> is checked in the hest driver (drivers/acpi/apei/hest.c).
>> 
>> I think I'll go with your original suggestion to change hest_disable
>> from a boolean to something with more states. Re-checking for the HEST
>> table again feels like duplication.
>> 
>> Makes sense?
>
> Right, and then depending on the setting of hest_disable, either issue
> the "HEST is not enabled" message or not.

Ack!

>
> Thanks.
>
> -- 
> Regards/Gruss,
>     Boris.
>
> SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Borislav Petkov Aug. 15, 2017, 10:56 a.m. UTC | #6
On Tue, Aug 15, 2017 at 11:31:57AM +0100, Punit Agrawal wrote:
> I'd seen the link between acpi_pci_root_init() and acpi_hest_init() but
> didn't want to open another can of worms... :)
> 
> $SUBJECT was my attempt (small) at improving the situation but I guess I
> didn't go far enough.

Well, one fine day, if you feel bored and your hands are itching to do
some hacking, I won't be mad atcha if you did a second try...

:-)))
diff mbox

Patch

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 007b38abcb34..befb18338acb 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -1088,12 +1088,53 @@  static inline void ghes_nmi_init_cxt(void)
 }
 #endif /* CONFIG_HAVE_ACPI_APEI_NMI */
 
+static int ghes_common_init(void)
+{
+	int rc;
+	static bool initialised;
+
+	if (initialised)
+		return 0;
+
+	ghes_nmi_init_cxt();
+
+	rc = ghes_ioremap_init();
+	if (rc)
+		goto err;
+
+	rc = ghes_estatus_pool_init();
+	if (rc)
+		goto err_ioremap_exit;
+
+	rc = apei_osc_setup();
+	if (rc == 0 && osc_sb_apei_support_acked)
+		pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit and WHEA _OSC.\n");
+	else if (rc == 0 && !osc_sb_apei_support_acked)
+		pr_info(GHES_PFX "APEI firmware first mode is enabled by WHEA _OSC.\n");
+	else if (rc && osc_sb_apei_support_acked)
+		pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n");
+	else
+		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
+
+	initialised = true;
+	return 0;
+
+err_ioremap_exit:
+	ghes_ioremap_exit();
+err:
+	return rc;
+}
+
 static int ghes_probe(struct platform_device *ghes_dev)
 {
 	struct acpi_hest_generic *generic;
 	struct ghes *ghes = NULL;
 
-	int rc = -EINVAL;
+	int rc;
+
+	rc = ghes_common_init();
+	if (rc)
+		return rc;
 
 	generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data;
 	if (!generic->enabled)
@@ -1268,8 +1309,6 @@  static struct platform_driver ghes_platform_driver = {
 
 static int __init ghes_init(void)
 {
-	int rc;
-
 	if (acpi_disabled)
 		return -ENODEV;
 
@@ -1283,36 +1322,6 @@  static int __init ghes_init(void)
 		return -EINVAL;
 	}
 
-	ghes_nmi_init_cxt();
-
-	rc = ghes_ioremap_init();
-	if (rc)
-		goto err;
-
-	rc = ghes_estatus_pool_init();
-	if (rc)
-		goto err_ioremap_exit;
-
-	rc = platform_driver_register(&ghes_platform_driver);
-	if (rc)
-		goto err_pool_exit;
-
-	rc = apei_osc_setup();
-	if (rc == 0 && osc_sb_apei_support_acked)
-		pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit and WHEA _OSC.\n");
-	else if (rc == 0 && !osc_sb_apei_support_acked)
-		pr_info(GHES_PFX "APEI firmware first mode is enabled by WHEA _OSC.\n");
-	else if (rc && osc_sb_apei_support_acked)
-		pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n");
-	else
-		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
-
-	return 0;
-err_pool_exit:
-	ghes_estatus_pool_exit();
-err_ioremap_exit:
-	ghes_ioremap_exit();
-err:
-	return rc;
+	return platform_driver_register(&ghes_platform_driver);
 }
 device_initcall(ghes_init);