Re: [PATCH 2/2] x86/MCE: Add command line option to extend MCE Records pool

From: Tony Luck
Date: Mon Feb 12 2024 - 16:37:23 EST


On Mon, Feb 12, 2024 at 07:41:03PM +0000, Luck, Tony wrote:
> > It needs a proper explanation why that's ok rather than an empirical
> > test only.
>
> start_kernel()
> ... setup_arch()
> .... acpi stuff parses MADT and sets bits in possible map
>
> ... arch_cpu_finalize_init()
> ... calls mce_gen_pool_init()

This made me question the "we don't have an allocator in
mce_gen_pool_init()". Because if we got through all the
ACPI stuff, we surely have an allocator.

Below patch doesn't explode at runtime.

-Tony

diff --git a/arch/x86/kernel/cpu/mce/genpool.c b/arch/x86/kernel/cpu/mce/genpool.c
index fbe8b61c3413..81de877f2a51 100644
--- a/arch/x86/kernel/cpu/mce/genpool.c
+++ b/arch/x86/kernel/cpu/mce/genpool.c
@@ -16,14 +16,12 @@
* used to save error information organized in a lock-less list.
*
* This memory pool is only to be used to save MCE records in MCE context.
- * MCE events are rare, so a fixed size memory pool should be enough. Use
- * 2 pages to save MCE events for now (~80 MCE records at most).
+ * MCE events are rare, so a fixed size memory pool should be enough.
+ * Allocate on a sliding scale based on number of CPUs.
*/
-#define MCE_POOLSZ (2 * PAGE_SIZE)

static struct gen_pool *mce_evt_pool;
static LLIST_HEAD(mce_event_llist);
-static char gen_pool_buf[MCE_POOLSZ];

/*
* Compare the record "t" with each of the records on list "l" to see if
@@ -118,14 +116,23 @@ int mce_gen_pool_add(struct mce *mce)

static int mce_gen_pool_create(void)
{
+ int mce_numrecords, mce_poolsz;
struct gen_pool *tmpp;
int ret = -ENOMEM;
+ void *mce_pool;

tmpp = gen_pool_create(ilog2(sizeof(struct mce_evt_llist)), -1);
if (!tmpp)
goto out;

- ret = gen_pool_add(tmpp, (unsigned long)gen_pool_buf, MCE_POOLSZ, -1);
+ mce_numrecords = max(80, num_possible_cpus() * 8);
+ mce_poolsz = mce_numrecords * ilog2(sizeof(struct mce_evt_llist));
+ mce_pool = kmalloc(mce_poolsz, GFP_KERNEL);
+ if (!mce_pool) {
+ gen_pool_destroy(tmpp);
+ goto out;
+ }
+ ret = gen_pool_add(tmpp, (unsigned long)mce_pool, mce_poolsz, -1);
if (ret) {
gen_pool_destroy(tmpp);
goto out;
--
2.43.0