WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] mce: Add a x86_mcinfo_reserve() function,

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] mce: Add a x86_mcinfo_reserve() function, to reserve space from mc_info.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 19 Apr 2010 18:50:15 -0700
Delivery-date: Mon, 19 Apr 2010 18:50:54 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1271663733 -3600
# Node ID 6860c523d2daf1d110b130a9596469a0957b4032
# Parent  6233eb0f29ba6b89b4dd14fe3d385e85924cd9f1
mce: Add a x86_mcinfo_reserve() function, to reserve space from mc_info.

With this method, we don't need to collect bank and globalinformation
to a local variable and do x86_mcinfo_add() to copy that information
to mc_info.  This avoid copy and also we can be aware earlier if there
is enough space in the mc_info.

Also extract function that get global/bank information to seperated
function mca_init_bank/mca_init_global.

It's meaningless to get the current information in mce context, keep
it here but should be removed in future.

Also a flag added to mc_info, to indicate some information is lost due
to OOM.

Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxxx>
---
 xen/arch/x86/cpu/mcheck/mce.c         |  209 ++++++++++++++++++++--------------
 xen/arch/x86/cpu/mcheck/mce.h         |    3 
 xen/include/public/arch-x86/xen-mca.h |    3 
 3 files changed, 128 insertions(+), 87 deletions(-)

diff -r 6233eb0f29ba -r 6860c523d2da xen/arch/x86/cpu/mcheck/mce.c
--- a/xen/arch/x86/cpu/mcheck/mce.c     Mon Apr 19 08:54:53 2010 +0100
+++ b/xen/arch/x86/cpu/mcheck/mce.c     Mon Apr 19 08:55:33 2010 +0100
@@ -125,6 +125,88 @@ void mce_need_clearbank_register(mce_nee
     mc_need_clearbank_scan = cbfunc;
 }
 
+static struct mcinfo_bank *mca_init_bank(enum mca_source who,
+                                         struct mc_info *mi, int bank)
+{
+       struct mcinfo_bank *mib;
+       uint64_t addr=0, misc = 0;
+
+       if (!mi)
+               return NULL;
+
+       mib = x86_mcinfo_reserve(mi, sizeof(struct mcinfo_bank));
+       if (!mib)
+       {
+               mi->flags |= MCINFO_FLAGS_UNCOMPLETE;
+               return NULL;
+       }
+
+       memset(mib, 0, sizeof (struct mcinfo_bank));
+       mca_rdmsrl(MSR_IA32_MC0_STATUS + bank * 4, mib->mc_status);
+
+       mib->common.type = MC_TYPE_BANK;
+       mib->common.size = sizeof (struct mcinfo_bank);
+       mib->mc_bank = bank;
+
+       addr = misc = 0;
+       if (mib->mc_status & MCi_STATUS_MISCV)
+               mca_rdmsrl(MSR_IA32_MC0_MISC + 4 * bank, mib->mc_misc);
+
+       if (mib->mc_status & MCi_STATUS_ADDRV)
+       {
+               mca_rdmsrl(MSR_IA32_MC0_ADDR + 4 * bank, mib->mc_addr);
+
+               if (mfn_valid(paddr_to_pfn(mib->mc_addr))) {
+                       struct domain *d;
+
+                       d = maddr_get_owner(mib->mc_addr);
+                       if (d != NULL && (who == MCA_POLLER ||
+                                 who == MCA_CMCI_HANDLER))
+                               mib->mc_domid = d->domain_id;
+               }
+       }
+
+       if (who == MCA_CMCI_HANDLER) {
+               mca_rdmsrl(MSR_IA32_MC0_CTL2 + bank, mib->mc_ctrl2);
+               rdtscll(mib->mc_tsc);
+       }
+
+       return mib;
+}
+
+static int mca_init_global(uint32_t flags, struct mcinfo_global *mig)
+{
+       uint64_t status;
+       int cpu_nr;
+       struct vcpu *v = current;
+       struct domain *d;
+
+       /* Set global information */
+       memset(mig, 0, sizeof (struct mcinfo_global));
+       mig->common.type = MC_TYPE_GLOBAL;
+       mig->common.size = sizeof (struct mcinfo_global);
+       mca_rdmsrl(MSR_IA32_MCG_STATUS, status);
+       mig->mc_gstatus = status;
+       mig->mc_domid = mig->mc_vcpuid = -1;
+       mig->mc_flags = flags;
+       cpu_nr = smp_processor_id();
+       /* Retrieve detector information */
+       x86_mc_get_cpu_info(cpu_nr, &mig->mc_socketid,
+         &mig->mc_coreid, &mig->mc_core_threadid,
+         &mig->mc_apicid, NULL, NULL, NULL);
+
+       /* This is really meaningless */
+       if (v != NULL && ((d = v->domain) != NULL)) {
+               mig->mc_domid = d->domain_id;
+               mig->mc_vcpuid = v->vcpu_id;
+       } else {
+               mig->mc_domid = -1;
+               mig->mc_vcpuid = -1;
+       }
+
+       return 0;
+}
+
 /* Utility function to perform MCA bank telemetry readout and to push that
  * telemetry towards an interested dom0 for logging and diagnosis.
  * The caller - #MC handler or MCA poll function - must arrange that we
@@ -139,64 +221,38 @@ mctelem_cookie_t mcheck_mca_logout(enum 
 mctelem_cookie_t mcheck_mca_logout(enum mca_source who, cpu_banks_t bankmask,
     struct mca_summary *sp, cpu_banks_t* clear_bank)
 {
-       struct vcpu *v = current;
-       struct domain *d;
-       uint64_t gstatus, status, addr, misc;
-       struct mcinfo_global mcg;       /* on stack */
-       struct mcinfo_common *mic;
-       struct mcinfo_global *mig;      /* on stack */
+       uint64_t gstatus, status;
+       struct mcinfo_global *mig = NULL;       /* on stack */
        mctelem_cookie_t mctc = NULL;
-       uint32_t uc = 0, pcc = 0, recover, need_clear = 1 ;
+       uint32_t uc = 0, pcc = 0, recover, need_clear = 1, mc_flags = 0;
        struct mc_info *mci = NULL;
        mctelem_class_t which = MC_URGENT;      /* XXXgcc */
-       unsigned int cpu_nr;
        int errcnt = 0;
        int i;
        enum mca_extinfo cbret = MCA_EXTINFO_IGNORED;
 
-       cpu_nr = smp_processor_id();
-       BUG_ON(cpu_nr != v->processor);
-
        mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus);
-
-       memset(&mcg, 0, sizeof (mcg));
-       mcg.common.type = MC_TYPE_GLOBAL;
-       mcg.common.size = sizeof (mcg);
-       if (v != NULL && ((d = v->domain) != NULL)) {
-               mcg.mc_domid = d->domain_id;
-               mcg.mc_vcpuid = v->vcpu_id;
-       } else {
-               mcg.mc_domid = -1;
-               mcg.mc_vcpuid = -1;
-       }
-       mcg.mc_gstatus = gstatus;       /* MCG_STATUS */
-
        switch (who) {
        case MCA_MCE_HANDLER:
        case MCA_MCE_SCAN:
-               mcg.mc_flags = MC_FLAG_MCE;
+               mc_flags = MC_FLAG_MCE;
                which = MC_URGENT;
                break;
 
        case MCA_POLLER:
        case MCA_RESET:
-               mcg.mc_flags = MC_FLAG_POLLED;
+               mc_flags = MC_FLAG_POLLED;
                which = MC_NONURGENT;
                break;
 
        case MCA_CMCI_HANDLER:
-               mcg.mc_flags = MC_FLAG_CMCI;
+               mc_flags = MC_FLAG_CMCI;
                which = MC_NONURGENT;
                break;
 
        default:
                BUG();
        }
-
-       /* Retrieve detector information */
-       x86_mc_get_cpu_info(cpu_nr, &mcg.mc_socketid,
-           &mcg.mc_coreid, &mcg.mc_core_threadid,
-           &mcg.mc_apicid, NULL, NULL, NULL);
 
        /* If no mc_recovery_scan callback handler registered,
         * this error is not recoverable
@@ -204,7 +260,7 @@ mctelem_cookie_t mcheck_mca_logout(enum 
        recover = (mc_recoverable_scan)? 1: 0;
 
        for (i = 0; i < 32 && i < nr_mce_banks; i++) {
-               struct mcinfo_bank mcb;         /* on stack */
+               struct mcinfo_bank *mib;                /* on stack */
 
                /* Skip bank if corresponding bit in bankmask is clear */
                if (!test_bit(i, bankmask))
@@ -227,17 +283,16 @@ mctelem_cookie_t mcheck_mca_logout(enum 
                 * a poller;  this can fail (for example dom0 may not
                 * yet have consumed past telemetry). */
                if (errcnt == 0) {
-                       if ((mctc = mctelem_reserve(which)) != NULL) {
+                       if ( (mctc = mctelem_reserve(which)) != NULL ) {
                                mci = mctelem_dataptr(mctc);
                                mcinfo_clear(mci);
+                               mig = (struct mcinfo_global*)x86_mcinfo_reserve
+                                 (mci, sizeof(struct mcinfo_global));
+                               /* mc_info should at least hold up the global 
information */
+                               ASSERT(mig);
+                               mca_init_global(mc_flags, mig);
                        }
                }
-
-               memset(&mcb, 0, sizeof (mcb));
-               mcb.common.type = MC_TYPE_BANK;
-               mcb.common.size = sizeof (mcb);
-               mcb.mc_bank = i;
-               mcb.mc_status = status;
 
                /* form a mask of which banks have logged uncorrected errors */
                if ((status & MCi_STATUS_UC) != 0)
@@ -252,37 +307,7 @@ mctelem_cookie_t mcheck_mca_logout(enum 
                  */
                        recover = mc_recoverable_scan(status);
 
-               addr = misc = 0;
-
-               if (status & MCi_STATUS_ADDRV) {
-                       mca_rdmsrl(MSR_IA32_MC0_ADDR + 4 * i, addr);
-                       if (mfn_valid(paddr_to_pfn(addr))) {
-                               d = maddr_get_owner(addr);
-                               if (d != NULL && (who == MCA_POLLER ||
-                                   who == MCA_CMCI_HANDLER))
-                                       mcb.mc_domid = d->domain_id;
-                       }
-               }
-
-               if (status & MCi_STATUS_MISCV)
-                       mca_rdmsrl(MSR_IA32_MC0_MISC + 4 * i, misc);
-
-               mcb.mc_addr = addr;
-               mcb.mc_misc = misc;
-
-               if (who == MCA_CMCI_HANDLER) {
-                       mca_rdmsrl(MSR_IA32_MC0_CTL2 + i, mcb.mc_ctrl2);
-                       rdtscll(mcb.mc_tsc);
-               }
-
-               /* Increment the error count;  if this is the first bank
-                * with a valid error then add the global info to the mcinfo. */
-               if (errcnt++ == 0 && mci != NULL)
-                       x86_mcinfo_add(mci, &mcg);
-
-               /* Add the bank data */
-               if (mci != NULL)
-                       x86_mcinfo_add(mci, &mcb);
+               mib = mca_init_bank(who, mci, i);
 
                if (mc_callback_bank_extended && cbret != MCA_EXTINFO_GLOBAL) {
                        cbret = mc_callback_bank_extended(mci, i, status);
@@ -298,12 +323,8 @@ mctelem_cookie_t mcheck_mca_logout(enum 
                wmb();
        }
 
-       if (mci != NULL && errcnt > 0) {
-               x86_mcinfo_lookup(mic, mci, MC_TYPE_GLOBAL);
-               mig = container_of(mic, struct mcinfo_global, common);
-               if (mic == NULL)
-                       ;
-               else if (pcc)
+       if (mig && errcnt > 0) {
+               if (pcc)
                        mig->mc_flags |= MC_FLAG_UNCORRECTABLE;
                else if (uc)
                        mig->mc_flags |= MC_FLAG_RECOVERABLE;
@@ -758,13 +779,12 @@ static void mcinfo_clear(struct mc_info 
        x86_mcinfo_nentries(mi) = 0;
 }
 
-int x86_mcinfo_add(struct mc_info *mi, void *mcinfo)
+void *x86_mcinfo_reserve(struct mc_info *mi, int size)
 {
        int i;
        unsigned long end1, end2;
-       struct mcinfo_common *mic, *mic_base, *mic_index;
-
-       mic = (struct mcinfo_common *)mcinfo;
+       struct mcinfo_common *mic_base, *mic_index;
+
        mic_index = mic_base = x86_mcinfo_first(mi);
 
        /* go to first free entry */
@@ -774,16 +794,35 @@ int x86_mcinfo_add(struct mc_info *mi, v
 
        /* check if there is enough size */
        end1 = (unsigned long)((uint8_t *)mic_base + sizeof(struct mc_info));
-       end2 = (unsigned long)((uint8_t *)mic_index + mic->size);
+       end2 = (unsigned long)((uint8_t *)mic_index + size);
 
        if (end1 < end2)
-               return x86_mcerr("mcinfo_add: no more sparc", -ENOSPC);
+       {
+               mce_printk(MCE_CRITICAL,
+                       "mcinfo_add: No space left in mc_info\n");
+               return NULL;
+       }
 
        /* there's enough space. add entry. */
-       memcpy(mic_index, mic, mic->size);
        x86_mcinfo_nentries(mi)++;
 
-       return 0;
+    return mic_index;
+}
+
+void *x86_mcinfo_add(struct mc_info *mi, void *mcinfo)
+{
+       struct mcinfo_common *mic, *buf;
+
+       mic = (struct mcinfo_common *)mcinfo;
+       buf = x86_mcinfo_reserve(mi, mic->size);
+
+       if ( !buf )
+               mce_printk(MCE_CRITICAL,
+                       "mcinfo_add: No space left in mc_info\n");
+       else
+               memcpy(buf, mic, mic->size);
+
+       return buf;
 }
 
 /* Dump machine check information in a format,
diff -r 6233eb0f29ba -r 6860c523d2da xen/arch/x86/cpu/mcheck/mce.h
--- a/xen/arch/x86/cpu/mcheck/mce.h     Mon Apr 19 08:54:53 2010 +0100
+++ b/xen/arch/x86/cpu/mcheck/mce.h     Mon Apr 19 08:55:33 2010 +0100
@@ -161,7 +161,8 @@ typedef enum mca_extinfo (*x86_mce_callb
     (struct mc_info *, uint16_t, uint64_t);
 extern void x86_mce_callback_register(x86_mce_callback_t);
 
-int x86_mcinfo_add(struct mc_info *mi, void *mcinfo);
+void *x86_mcinfo_add(struct mc_info *mi, void *mcinfo);
+void *x86_mcinfo_reserve(struct mc_info *mi, int size);
 void x86_mcinfo_dump(struct mc_info *mi);
 
 int fill_vmsr_data(struct mcinfo_bank *mc_bank, struct domain *d,
diff -r 6233eb0f29ba -r 6860c523d2da xen/include/public/arch-x86/xen-mca.h
--- a/xen/include/public/arch-x86/xen-mca.h     Mon Apr 19 08:54:53 2010 +0100
+++ b/xen/include/public/arch-x86/xen-mca.h     Mon Apr 19 08:55:33 2010 +0100
@@ -233,10 +233,11 @@ struct mcinfo_recovery
 #define MCINFO_HYPERCALLSIZE   1024
 #define MCINFO_MAXSIZE         768
 
+#define MCINFO_FLAGS_UNCOMPLETE 0x1
 struct mc_info {
     /* Number of mcinfo_* entries in mi_data */
     uint32_t mi_nentries;
-    uint32_t _pad0;
+    uint32_t flags;
     uint64_t mi_data[(MCINFO_MAXSIZE - 1) / 8];
 };
 typedef struct mc_info mc_info_t;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] mce: Add a x86_mcinfo_reserve() function, to reserve space from mc_info., Xen patchbot-unstable <=