Commit fb7be08f authored by James Morse's avatar James Morse Committed by Rafael J. Wysocki

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: default avatarBorislav Petkov <bp@suse.de>
Signed-off-by: default avatarJames Morse <james.morse@arm.com>
Reviewed-by: default avatarBorislav Petkov <bp@suse.de>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent e147133a
...@@ -162,27 +162,18 @@ static void ghes_iounmap_irq(void) ...@@ -162,27 +162,18 @@ static void ghes_iounmap_irq(void)
clear_fixmap(FIX_APEI_GHES_IRQ); clear_fixmap(FIX_APEI_GHES_IRQ);
} }
static int ghes_estatus_pool_expand(unsigned long len); //temporary int ghes_estatus_pool_init(int num_ghes)
int ghes_estatus_pool_init(void)
{ {
unsigned long addr, len;
ghes_estatus_pool = gen_pool_create(GHES_ESTATUS_POOL_MIN_ALLOC_ORDER, -1); ghes_estatus_pool = gen_pool_create(GHES_ESTATUS_POOL_MIN_ALLOC_ORDER, -1);
if (!ghes_estatus_pool) if (!ghes_estatus_pool)
return -ENOMEM; return -ENOMEM;
return ghes_estatus_pool_expand(GHES_ESTATUS_CACHE_AVG_SIZE * len = GHES_ESTATUS_CACHE_AVG_SIZE * GHES_ESTATUS_CACHE_ALLOCED_MAX;
GHES_ESTATUS_CACHE_ALLOCED_MAX); len += (num_ghes * GHES_ESOURCE_PREALLOC_MAX_SIZE);
}
static int ghes_estatus_pool_expand(unsigned long len)
{
unsigned long size, addr;
ghes_estatus_pool_size_request += PAGE_ALIGN(len);
size = gen_pool_size(ghes_estatus_pool);
if (size >= ghes_estatus_pool_size_request)
return 0;
ghes_estatus_pool_size_request = PAGE_ALIGN(len);
addr = (unsigned long)vmalloc(PAGE_ALIGN(len)); addr = (unsigned long)vmalloc(PAGE_ALIGN(len));
if (!addr) if (!addr)
return -ENOMEM; return -ENOMEM;
...@@ -956,32 +947,8 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) ...@@ -956,32 +947,8 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
return ret; return ret;
} }
static unsigned long ghes_esource_prealloc_size(
const struct acpi_hest_generic *generic)
{
unsigned long block_length, prealloc_records, prealloc_size;
block_length = min_t(unsigned long, generic->error_block_length,
GHES_ESTATUS_MAX_SIZE);
prealloc_records = max_t(unsigned long,
generic->records_to_preallocate, 1);
prealloc_size = min_t(unsigned long, block_length * prealloc_records,
GHES_ESOURCE_PREALLOC_MAX_SIZE);
return prealloc_size;
}
static void ghes_estatus_pool_shrink(unsigned long len)
{
ghes_estatus_pool_size_request -= PAGE_ALIGN(len);
}
static void ghes_nmi_add(struct ghes *ghes) static void ghes_nmi_add(struct ghes *ghes)
{ {
unsigned long len;
len = ghes_esource_prealloc_size(ghes->generic);
ghes_estatus_pool_expand(len);
mutex_lock(&ghes_list_mutex); mutex_lock(&ghes_list_mutex);
if (list_empty(&ghes_nmi)) if (list_empty(&ghes_nmi))
register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, "ghes"); register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, "ghes");
...@@ -991,8 +958,6 @@ static void ghes_nmi_add(struct ghes *ghes) ...@@ -991,8 +958,6 @@ static void ghes_nmi_add(struct ghes *ghes)
static void ghes_nmi_remove(struct ghes *ghes) static void ghes_nmi_remove(struct ghes *ghes)
{ {
unsigned long len;
mutex_lock(&ghes_list_mutex); mutex_lock(&ghes_list_mutex);
list_del_rcu(&ghes->list); list_del_rcu(&ghes->list);
if (list_empty(&ghes_nmi)) if (list_empty(&ghes_nmi))
...@@ -1003,8 +968,6 @@ static void ghes_nmi_remove(struct ghes *ghes) ...@@ -1003,8 +968,6 @@ static void ghes_nmi_remove(struct ghes *ghes)
* freed after NMI handler finishes. * freed after NMI handler finishes.
*/ */
synchronize_rcu(); synchronize_rcu();
len = ghes_esource_prealloc_size(ghes->generic);
ghes_estatus_pool_shrink(len);
} }
static void ghes_nmi_init_cxt(void) static void ghes_nmi_init_cxt(void)
......
...@@ -211,7 +211,7 @@ static int __init hest_ghes_dev_register(unsigned int ghes_count) ...@@ -211,7 +211,7 @@ static int __init hest_ghes_dev_register(unsigned int ghes_count)
if (rc) if (rc)
goto err; goto err;
rc = ghes_estatus_pool_init(); rc = ghes_estatus_pool_init(ghes_count);
if (rc) if (rc)
goto err; goto err;
......
...@@ -52,7 +52,7 @@ enum { ...@@ -52,7 +52,7 @@ enum {
GHES_SEV_PANIC = 0x3, GHES_SEV_PANIC = 0x3,
}; };
int ghes_estatus_pool_init(void); int ghes_estatus_pool_init(int num_ghes);
/* From drivers/edac/ghes_edac.c */ /* From drivers/edac/ghes_edac.c */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment