src/worker.cc
// Print error information about a data miscompare.
Print error information about a data miscompare.
Print error information about a data miscompare .
void WorkerThread::ProcessError(struct ErrorRecord *error,
                                int priority,
                                const char *message) {
  char dimm_string[256] = "";
  int apic_id = apicid();
  os_->Flush(error->vaddr);
  error->reread = *(error->vaddr);
  char *good = reinterpret_cast<char*>(&(error->expected));
  char *bad = reinterpret_cast<char*>(&(error->actual));
  sat_assert(error->expected != error->actual);
  unsigned int offset = 0;
  for (offset = 0; offset < (sizeof(error->expected) - 1); offset++) {
    if (good[offset] != bad[offset])
      break;
  }
  error->vbyteaddr = reinterpret_cast<char*>(error->vaddr) + offset;
  error->paddr = os_->VirtualToPhysical(error->vbyteaddr);
  os_->FindDimm(error->paddr, dimm_string, sizeof(dimm_string));
  if (priority < 5) {
    os_->error_diagnoser_->AddMiscompareError(dimm_string,
                                              reinterpret_cast<uint64>
                                              (error->vaddr), 1);
    logprintf(priority,
              "%s: miscompare on CPU %d(0x%s) at %p(0x%llx:%s): "
              "read:0x%016llx, reread:0x%016llx expected:0x%016llx\n",
              message,
              apic_id,
              CurrentCpusFormat().c_str(),
              error->vaddr,
              error->paddr,
              dimm_string,
              error->actual,
              error->reread,
              error->expected);
  }
  *(error->vaddr) = error->expected;
  os_->Flush(error->vaddr);
}
void WorkerThread :: ProcessError ( struct ErrorRecord * error , int priority , const char * message ) { char dimm_string [ 256 ] = " " ; int apic_id = apicid ( ) ; os_ -> Flush ( error -> vaddr ) ; error -> reread = * ( error -> vaddr ) ; char * good = reinterpret_cast < char * > ( & ( error -> expected ) ) ; char * bad = reinterpret_cast < char * > ( & ( error -> actual ) ) ; sat_assert ( error -> expected != error -> actual ) ; unsigned int offset = 0 ; for ( offset = 0 ; offset < ( sizeof ( error -> expected ) - 1 ) ; offset ++ ) { if ( good [ offset ] != bad [ offset ] ) break ; } error -> vbyteaddr = reinterpret_cast < char * > ( error -> vaddr ) + offset ; error -> paddr = os_ -> VirtualToPhysical ( error -> vbyteaddr ) ; os_ -> FindDimm ( error -> paddr , dimm_string , sizeof ( dimm_string ) ) ; if ( priority < 5 ) { os_ -> error_diagnoser_ -> AddMiscompareError ( dimm_string , reinterpret_cast < uint64 > ( error -> vaddr ) , 1 ) ; logprintf ( priority , " " " \n " , message , apic_id , CurrentCpusFormat ( ) . c_str ( ) , error -> vaddr , error -> paddr , dimm_string , error -> actual , error -> reread , error -> expected ) ; } * ( error -> vaddr ) = error -> expected ; os_ -> Flush ( error -> vaddr ) ; }
Print error information about a data miscompare.
Print error information about a data miscompare .
// Determine if this is a write or read error. // Find physical address if possible. // Pretty print DIMM mapping if available. // Report parseable error. // Run miscompare error through diagnoser for logging and reporting. // Overwrite incorrect data with correct data to prevent // future miscompares when this data is reused.