1 /* 2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation, version 2 of the 8 * License. 9 */ 10 11 #ifndef _MCTELEM_H 12 13 #define _MCTELEM_H 14 15 #include <xen/init.h> 16 #include <xen/smp.h> 17 #include <asm/traps.h> 18 19 /* Helper functions used for collecting error telemetry. 20 * 21 * mctelem_init preallocates a number of data areas for use during 22 * machine check data "logout". Two classes are distinguished - 23 * urgent uses, intended for use from machine check exception handlers, 24 * and non-urgent uses intended for use from error pollers. 25 * Associated with each logout entry of whatever class is a data area 26 * sized per the single argument to mctelem_init. mctelem_init should be 27 * called from MCA init code before anybody has the chance to change the 28 * machine check vector with mcheck_mca_logout or to use mcheck_mca_logout. 29 * 30 * To reserve an entry of a given class for use in logout, call 31 * mctelem_reserve (or use the common handler functions which do all this 32 * for you). This returns an opaque cookie, or NULL if no elements are 33 * available. Elements are reserved with an atomic operation so no deadlock 34 * will occur if, for example, a machine check exception interrupts a 35 * scheduled error poll. The implementation will raid free non-urgent 36 * entries if all urgent entries are in use when an urgent request is received. 37 * Once an entry is reserved the caller must eventually perform exactly 38 * one of two actions: mctelem_commit or mctelem_dismiss. 39 * 40 * On mctelem_commit the entry is appended to a processing list; mctelem_dismiss 41 * frees the element without processing. After either call the cookie 42 * must not be referenced again. 43 * 44 * To consume committed telemetry call mctelem_consume_oldest_begin 45 * which will return a cookie referencing the oldest (first committed) 46 * entry of the requested class. Access the associated data using 47 * mctelem_dataptr and when finished use mctelem_consume_oldest_end - in the 48 * begin .. end bracket you are guaranteed that the entry can't be freed 49 * even if it is ack'd elsewhere). Once the ultimate consumer of the 50 * telemetry has processed it to stable storage it should acknowledge 51 * the telemetry quoting the cookie id, at which point we will free 52 * the element from the processing list. 53 */ 54 55 typedef struct mctelem_cookie *mctelem_cookie_t; 56 57 typedef enum mctelem_class { 58 MC_URGENT, 59 MC_NONURGENT 60 } mctelem_class_t; 61 62 extern void mctelem_init(unsigned int); 63 extern mctelem_cookie_t mctelem_reserve(mctelem_class_t); 64 extern void *mctelem_dataptr(mctelem_cookie_t); 65 extern void mctelem_commit(mctelem_cookie_t); 66 extern void mctelem_dismiss(mctelem_cookie_t); 67 extern mctelem_cookie_t mctelem_consume_oldest_begin(mctelem_class_t); 68 extern void mctelem_consume_oldest_end(mctelem_cookie_t); 69 extern void mctelem_ack(mctelem_class_t, mctelem_cookie_t); 70 extern void mctelem_defer(mctelem_cookie_t, bool lmce); 71 extern void mctelem_process_deferred(unsigned int, 72 int (*)(mctelem_cookie_t), bool lmce); 73 bool mctelem_has_deferred(unsigned int); 74 bool mctelem_has_deferred_lmce(unsigned int cpu); 75 76 #endif 77