// SPDX-License-Identifier: GPL-2.0-only /* * MCE event pool management in MCE context * * Copyright (C) 2015 Intel Corp. * Author: Chen, Gong <[email protected]> */ #include <linux/smp.h> #include <linux/mm.h> #include <linux/genalloc.h> #include <linux/llist.h> #include "internal.h" /* * printk() is not safe in MCE context. This is a lock-less memory allocator * 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. * Allocate on a sliding scale based on number of CPUs. */ #define MCE_MIN_ENTRIES … #define MCE_PER_CPU … static struct gen_pool *mce_evt_pool; static LLIST_HEAD(mce_event_llist); /* * Compare the record "t" with each of the records on list "l" to see if * an equivalent one is present in the list. */ static bool is_duplicate_mce_record(struct mce_evt_llist *t, struct mce_evt_llist *l) { … } /* * The system has panicked - we'd like to peruse the list of MCE records * that have been queued, but not seen by anyone yet. The list is in * reverse time order, so we need to reverse it. While doing that we can * also drop duplicate records (these were logged because some banks are * shared between cores or by all threads on a socket). */ struct llist_node *mce_gen_pool_prepare_records(void) { … } void mce_gen_pool_process(struct work_struct *__unused) { … } bool mce_gen_pool_empty(void) { … } int mce_gen_pool_add(struct mce *mce) { … } static int mce_gen_pool_create(void) { … } int mce_gen_pool_init(void) { … }