diff options
author | Borislav Petkov <bp@suse.de> | 2015-03-18 04:41:35 -0400 |
---|---|---|
committer | Borislav Petkov <bp@suse.de> | 2015-04-27 15:16:06 -0400 |
commit | 115684961a335a1c97074158e8f789118ac8b00d (patch) | |
tree | df7ff553f8705c2099b384dacc85990885e6d00d /drivers/acpi/apei | |
parent | b787f68c36d49bb1d9236f403813641efa74a031 (diff) |
GHES: Carve out error queueing in a separate function
Make the handler more readable.
No functionality change.
Signed-off-by: Borislav Petkov <bp@suse.de>
Diffstat (limited to 'drivers/acpi/apei')
-rw-r--r-- | drivers/acpi/apei/ghes.c | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index e82d0976a5d0..fe1e41bf5609 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -797,6 +797,32 @@ static void ghes_print_queued_estatus(void) | |||
797 | } | 797 | } |
798 | } | 798 | } |
799 | 799 | ||
800 | /* Save estatus for further processing in IRQ context */ | ||
801 | static void __process_error(struct ghes *ghes) | ||
802 | { | ||
803 | #ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG | ||
804 | u32 len, node_len; | ||
805 | struct ghes_estatus_node *estatus_node; | ||
806 | struct acpi_hest_generic_status *estatus; | ||
807 | |||
808 | if (ghes_estatus_cached(ghes->estatus)) | ||
809 | return; | ||
810 | |||
811 | len = cper_estatus_len(ghes->estatus); | ||
812 | node_len = GHES_ESTATUS_NODE_LEN(len); | ||
813 | |||
814 | estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool, node_len); | ||
815 | if (!estatus_node) | ||
816 | return; | ||
817 | |||
818 | estatus_node->ghes = ghes; | ||
819 | estatus_node->generic = ghes->generic; | ||
820 | estatus = GHES_ESTATUS_FROM_NODE(estatus_node); | ||
821 | memcpy(estatus, ghes->estatus, len); | ||
822 | llist_add(&estatus_node->llnode, &ghes_estatus_llist); | ||
823 | #endif | ||
824 | } | ||
825 | |||
800 | static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) | 826 | static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) |
801 | { | 827 | { |
802 | struct ghes *ghes, *ghes_global = NULL; | 828 | struct ghes *ghes, *ghes_global = NULL; |
@@ -832,32 +858,13 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) | |||
832 | } | 858 | } |
833 | 859 | ||
834 | list_for_each_entry_rcu(ghes, &ghes_nmi, list) { | 860 | list_for_each_entry_rcu(ghes, &ghes_nmi, list) { |
835 | #ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG | ||
836 | u32 len, node_len; | ||
837 | struct ghes_estatus_node *estatus_node; | ||
838 | struct acpi_hest_generic_status *estatus; | ||
839 | #endif | ||
840 | if (!(ghes->flags & GHES_TO_CLEAR)) | 861 | if (!(ghes->flags & GHES_TO_CLEAR)) |
841 | continue; | 862 | continue; |
842 | #ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG | 863 | |
843 | if (ghes_estatus_cached(ghes->estatus)) | 864 | __process_error(ghes); |
844 | goto next; | ||
845 | /* Save estatus for further processing in IRQ context */ | ||
846 | len = cper_estatus_len(ghes->estatus); | ||
847 | node_len = GHES_ESTATUS_NODE_LEN(len); | ||
848 | estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool, | ||
849 | node_len); | ||
850 | if (estatus_node) { | ||
851 | estatus_node->ghes = ghes; | ||
852 | estatus_node->generic = ghes->generic; | ||
853 | estatus = GHES_ESTATUS_FROM_NODE(estatus_node); | ||
854 | memcpy(estatus, ghes->estatus, len); | ||
855 | llist_add(&estatus_node->llnode, &ghes_estatus_llist); | ||
856 | } | ||
857 | next: | ||
858 | #endif | ||
859 | ghes_clear_estatus(ghes); | 865 | ghes_clear_estatus(ghes); |
860 | } | 866 | } |
867 | |||
861 | #ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG | 868 | #ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG |
862 | irq_work_queue(&ghes_proc_irq_work); | 869 | irq_work_queue(&ghes_proc_irq_work); |
863 | #endif | 870 | #endif |