aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Morse <james.morse@arm.com>2019-01-29 13:48:41 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-02-07 17:10:45 -0500
commitfb7be08f1a091ec243780bfdad4bf0c492057808 (patch)
treeb19b32d9887a4a310657ed8690c5c9f17e4a2185
parente147133a42cb9df6cbc99503fdf58d0e6388bf2a (diff)
ACPI / APEI: Make estatus pool allocation a static size
Adding new NMI-like notifications duplicates the calls that grow and shrink the estatus pool. This is all pretty pointless, as the size is capped to 64K. Allocate this for each ghes and drop the code that grows and shrinks the pool. Suggested-by: Borislav Petkov <bp@suse.de> Signed-off-by: James Morse <james.morse@arm.com> Reviewed-by: Borislav Petkov <bp@suse.de> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/apei/ghes.c49
-rw-r--r--drivers/acpi/apei/hest.c2
-rw-r--r--include/acpi/ghes.h2
3 files changed, 8 insertions, 45 deletions
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 4150c72c78cb..33144ab0661a 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -162,27 +162,18 @@ static void ghes_iounmap_irq(void)
162 clear_fixmap(FIX_APEI_GHES_IRQ); 162 clear_fixmap(FIX_APEI_GHES_IRQ);
163} 163}
164 164
165static int ghes_estatus_pool_expand(unsigned long len); //temporary 165int ghes_estatus_pool_init(int num_ghes)
166
167int ghes_estatus_pool_init(void)
168{ 166{
167 unsigned long addr, len;
168
169 ghes_estatus_pool = gen_pool_create(GHES_ESTATUS_POOL_MIN_ALLOC_ORDER, -1); 169 ghes_estatus_pool = gen_pool_create(GHES_ESTATUS_POOL_MIN_ALLOC_ORDER, -1);
170 if (!ghes_estatus_pool) 170 if (!ghes_estatus_pool)
171 return -ENOMEM; 171 return -ENOMEM;
172 172
173 return ghes_estatus_pool_expand(GHES_ESTATUS_CACHE_AVG_SIZE * 173 len = GHES_ESTATUS_CACHE_AVG_SIZE * GHES_ESTATUS_CACHE_ALLOCED_MAX;
174 GHES_ESTATUS_CACHE_ALLOCED_MAX); 174 len += (num_ghes * GHES_ESOURCE_PREALLOC_MAX_SIZE);
175}
176
177static int ghes_estatus_pool_expand(unsigned long len)
178{
179 unsigned long size, addr;
180
181 ghes_estatus_pool_size_request += PAGE_ALIGN(len);
182 size = gen_pool_size(ghes_estatus_pool);
183 if (size >= ghes_estatus_pool_size_request)
184 return 0;
185 175
176 ghes_estatus_pool_size_request = PAGE_ALIGN(len);
186 addr = (unsigned long)vmalloc(PAGE_ALIGN(len)); 177 addr = (unsigned long)vmalloc(PAGE_ALIGN(len));
187 if (!addr) 178 if (!addr)
188 return -ENOMEM; 179 return -ENOMEM;
@@ -956,32 +947,8 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
956 return ret; 947 return ret;
957} 948}
958 949
959static unsigned long ghes_esource_prealloc_size(
960 const struct acpi_hest_generic *generic)
961{
962 unsigned long block_length, prealloc_records, prealloc_size;
963
964 block_length = min_t(unsigned long, generic->error_block_length,
965 GHES_ESTATUS_MAX_SIZE);
966 prealloc_records = max_t(unsigned long,
967 generic->records_to_preallocate, 1);
968 prealloc_size = min_t(unsigned long, block_length * prealloc_records,
969 GHES_ESOURCE_PREALLOC_MAX_SIZE);
970
971 return prealloc_size;
972}
973
974static void ghes_estatus_pool_shrink(unsigned long len)
975{
976 ghes_estatus_pool_size_request -= PAGE_ALIGN(len);
977}
978
979static void ghes_nmi_add(struct ghes *ghes) 950static void ghes_nmi_add(struct ghes *ghes)
980{ 951{
981 unsigned long len;
982
983 len = ghes_esource_prealloc_size(ghes->generic);
984 ghes_estatus_pool_expand(len);
985 mutex_lock(&ghes_list_mutex); 952 mutex_lock(&ghes_list_mutex);
986 if (list_empty(&ghes_nmi)) 953 if (list_empty(&ghes_nmi))
987 register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, "ghes"); 954 register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, "ghes");
@@ -991,8 +958,6 @@ static void ghes_nmi_add(struct ghes *ghes)
991 958
992static void ghes_nmi_remove(struct ghes *ghes) 959static void ghes_nmi_remove(struct ghes *ghes)
993{ 960{
994 unsigned long len;
995
996 mutex_lock(&ghes_list_mutex); 961 mutex_lock(&ghes_list_mutex);
997 list_del_rcu(&ghes->list); 962 list_del_rcu(&ghes->list);
998 if (list_empty(&ghes_nmi)) 963 if (list_empty(&ghes_nmi))
@@ -1003,8 +968,6 @@ static void ghes_nmi_remove(struct ghes *ghes)
1003 * freed after NMI handler finishes. 968 * freed after NMI handler finishes.
1004 */ 969 */
1005 synchronize_rcu(); 970 synchronize_rcu();
1006 len = ghes_esource_prealloc_size(ghes->generic);
1007 ghes_estatus_pool_shrink(len);
1008} 971}
1009 972
1010static void ghes_nmi_init_cxt(void) 973static void ghes_nmi_init_cxt(void)
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index e33bfd9d256c..8113ddb14d28 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -211,7 +211,7 @@ static int __init hest_ghes_dev_register(unsigned int ghes_count)
211 if (rc) 211 if (rc)
212 goto err; 212 goto err;
213 213
214 rc = ghes_estatus_pool_init(); 214 rc = ghes_estatus_pool_init(ghes_count);
215 if (rc) 215 if (rc)
216 goto err; 216 goto err;
217 217
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 46ef5566e052..cd9ee507d860 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -52,7 +52,7 @@ enum {
52 GHES_SEV_PANIC = 0x3, 52 GHES_SEV_PANIC = 0x3,
53}; 53};
54 54
55int ghes_estatus_pool_init(void); 55int ghes_estatus_pool_init(int num_ghes);
56 56
57/* From drivers/edac/ghes_edac.c */ 57/* From drivers/edac/ghes_edac.c */
58 58