cregit-Linux how code gets into the kernel

Release 4.14 arch/x86/kernel/cpu/mcheck/mce-genpool.c

/*
 * MCE event pool management in MCE context
 *
 * Copyright (C) 2015 Intel Corp.
 * Author: Chen, Gong <gong.chen@linux.intel.com>
 *
 * This file is licensed under GPLv2.
 */
#include <linux/smp.h>
#include <linux/mm.h>
#include <linux/genalloc.h>
#include <linux/llist.h>
#include "mce-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. Use
 * 2 pages to save MCE events for now (~80 MCE records at most).
 */

#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
 * an equivalent one is present in the list.
 */

static bool is_duplicate_mce_record(struct mce_evt_llist *t, struct mce_evt_llist *l) { struct mce_evt_llist *node; struct mce *m1, *m2; m1 = &t->mce; llist_for_each_entry(node, &l->llnode, llnode) { m2 = &node->mce; if (!mce_cmp(m1, m2)) return true; } return false; }

Contributors

PersonTokensPropCommitsCommitProp
Tony Luck69100.00%1100.00%
Total69100.00%1100.00%

/* * 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) { struct llist_node *head; LLIST_HEAD(new_head); struct mce_evt_llist *node, *t; head = llist_del_all(&mce_event_llist); if (!head) return NULL; /* squeeze out duplicates while reversing order */ llist_for_each_entry_safe(node, t, head, llnode) { if (!is_duplicate_mce_record(node, t)) llist_add(&node->llnode, &new_head); } return new_head.first; }

Contributors

PersonTokensPropCommitsCommitProp
Tony Luck82100.00%1100.00%
Total82100.00%1100.00%


void mce_gen_pool_process(struct work_struct *__unused) { struct llist_node *head; struct mce_evt_llist *node, *tmp; struct mce *mce; head = llist_del_all(&mce_event_llist); if (!head) return; head = llist_reverse_order(head); llist_for_each_entry_safe(node, tmp, head, llnode) { mce = &node->mce; blocking_notifier_call_chain(&x86_mce_decoder_chain, 0, mce); gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node)); } }

Contributors

PersonTokensPropCommitsCommitProp
Chen Gong8488.42%125.00%
Tony Luck66.32%125.00%
Borislav Petkov44.21%125.00%
Vishal Verma11.05%125.00%
Total95100.00%4100.00%


bool mce_gen_pool_empty(void) { return llist_empty(&mce_event_llist); }

Contributors

PersonTokensPropCommitsCommitProp
Chen Gong14100.00%1100.00%
Total14100.00%1100.00%


int mce_gen_pool_add(struct mce *mce) { struct mce_evt_llist *node; if (!mce_evt_pool) return -EINVAL; node = (void *)gen_pool_alloc(mce_evt_pool, sizeof(*node)); if (!node) { pr_warn_ratelimited("MCE records pool full!\n"); return -ENOMEM; } memcpy(&node->mce, mce, sizeof(*mce)); llist_add(&node->llnode, &mce_event_llist); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Chen Gong87100.00%1100.00%
Total87100.00%1100.00%


static int mce_gen_pool_create(void) { struct gen_pool *tmpp; int ret = -ENOMEM; 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); if (ret) { gen_pool_destroy(tmpp); goto out; } mce_evt_pool = tmpp; out: return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Chen Gong85100.00%1100.00%
Total85100.00%1100.00%


int mce_gen_pool_init(void) { /* Just init mce_gen_pool once. */ if (mce_evt_pool) return 0; return mce_gen_pool_create(); }

Contributors

PersonTokensPropCommitsCommitProp
Chen Gong19100.00%1100.00%
Total19100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Chen Gong32966.73%120.00%
Tony Luck15932.25%240.00%
Borislav Petkov40.81%120.00%
Vishal Verma10.20%120.00%
Total493100.00%5100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.