src/worker.cc
// Copy a block of memory quickly, while keeping a CRC of the data.
// Result check if the CRC mismatches.
Copy a block of memory quickly, while keeping a CRC of the data.
Result check if the CRC mismatches.
Copy a block of memory quickly while keeping a CRC of the data . Result check if the CRC mismatches .
int WorkerThread::CrcCopyPage(struct page_entry *dstpe,
                              struct page_entry *srcpe) {
  int errors = 0;
  const int blocksize = 4096;
  const int blockwords = blocksize / wordsize_;
  int blocks = sat_->page_length() / blocksize;
  uint64 *targetmembase = static_cast<uint64*>(dstpe->addr);
  uint64 *sourcemembase = static_cast<uint64*>(srcpe->addr);
  const AdlerChecksum *expectedcrc = srcpe->pattern->crc();
  for (int currentblock = 0; currentblock < blocks; currentblock++) {
    uint64 *targetmem = targetmembase + currentblock * blockwords;
    uint64 *sourcemem = sourcemembase + currentblock * blockwords;
    AdlerChecksum crc;
    if (tag_mode_) {
      AdlerAddrMemcpyC(targetmem, sourcemem, blocksize, &crc, srcpe);
    } else {
      AdlerMemcpyC(targetmem, sourcemem, blocksize, &crc);
    }
    if (!crc.Equals(*expectedcrc)) {
      logprintf(11, "Log: CrcCopyPage Falling through to slow compare, "
                "CRC mismatch %s != %s\n", crc.ToHexString().c_str(),
                expectedcrc->ToHexString().c_str());
      int errorcount = CheckRegion(sourcemem,
                                   srcpe->pattern,
                                   blocksize,
                                   currentblock * blocksize, 0);
      if (errorcount == 0) {
        logprintf(0, "Log: CrcCopyPage CRC mismatch %s != %s, "
                     "but no miscompares found. Retrying with fresh data.\n",
                  crc.ToHexString().c_str(),
                  expectedcrc->ToHexString().c_str());
        if (!tag_mode_) {
          memcpy(sourcemem, targetmem, blocksize);
          errorcount = CheckRegion(sourcemem,
                                   srcpe->pattern,
                                   blocksize,
                                   currentblock * blocksize, 0);
          if (errorcount == 0) {
            int apic_id = apicid();
            logprintf(0, "Process Error: CPU %d(0x%s) CrcCopyPage "
                         "CRC mismatch %s != %s, "
                         "but no miscompares found on second pass.\n",
                      apic_id, CurrentCpusFormat().c_str(),
                      crc.ToHexString().c_str(),
                      expectedcrc->ToHexString().c_str());
            struct ErrorRecord er;
            er.actual = sourcemem[0];
            er.expected = 0x0;
            er.vaddr = sourcemem;
            ProcessError(&er, 0, "Hardware Error");
          }
        }
      }
      errors += errorcount;
    }
  }
  int leftovers = sat_->page_length() % blocksize;
  if (leftovers) {
    uint64 *targetmem = targetmembase + blocks * blockwords;
    uint64 *sourcemem = sourcemembase + blocks * blockwords;
    errors += CheckRegion(sourcemem,
                          srcpe->pattern,
                          leftovers,
                          blocks * blocksize, 0);
    int leftoverwords = leftovers / wordsize_;
    for (int i = 0; i < leftoverwords; i++) {
      targetmem[i] = sourcemem[i];
    }
  }
  dstpe->pattern = srcpe->pattern;
  if (errors) {
    FillPage(dstpe);
  }
  return errors;
}
int WorkerThread :: CrcCopyPage ( struct page_entry * dstpe , struct page_entry * srcpe ) { int errors = 0 ; const int blocksize = 4096 ; const int blockwords = blocksize / wordsize_ ; int blocks = sat_ -> page_length ( ) / blocksize ; uint64 * targetmembase = static_cast < uint64 * > ( dstpe -> addr ) ; uint64 * sourcemembase = static_cast < uint64 * > ( srcpe -> addr ) ; const AdlerChecksum * expectedcrc = srcpe -> pattern -> crc ( ) ; for ( int currentblock = 0 ; currentblock < blocks ; currentblock ++ ) { uint64 * targetmem = targetmembase + currentblock * blockwords ; uint64 * sourcemem = sourcemembase + currentblock * blockwords ; AdlerChecksum crc ; if ( tag_mode_ ) { AdlerAddrMemcpyC ( targetmem , sourcemem , blocksize , & crc , srcpe ) ; } else { AdlerMemcpyC ( targetmem , sourcemem , blocksize , & crc ) ; } if ( ! crc . Equals ( * expectedcrc ) ) { logprintf ( 11 , " " " \n " , crc . ToHexString ( ) . c_str ( ) , expectedcrc -> ToHexString ( ) . c_str ( ) ) ; int errorcount = CheckRegion ( sourcemem , srcpe -> pattern , blocksize , currentblock * blocksize , 0 ) ; if ( errorcount == 0 ) { logprintf ( 0 , " " " \n " , crc . ToHexString ( ) . c_str ( ) , expectedcrc -> ToHexString ( ) . c_str ( ) ) ; if ( ! tag_mode_ ) { memcpy ( sourcemem , targetmem , blocksize ) ; errorcount = CheckRegion ( sourcemem , srcpe -> pattern , blocksize , currentblock * blocksize , 0 ) ; if ( errorcount == 0 ) { int apic_id = apicid ( ) ; logprintf ( 0 , " " " " " \n " , apic_id , CurrentCpusFormat ( ) . c_str ( ) , crc . ToHexString ( ) . c_str ( ) , expectedcrc -> ToHexString ( ) . c_str ( ) ) ; struct ErrorRecord er ; er . actual = sourcemem [ 0 ] ; er . expected = 0x0 ; er . vaddr = sourcemem ; ProcessError ( & er , 0 , " " ) ; } } } errors += errorcount ; } } int leftovers = sat_ -> page_length ( ) % blocksize ; if ( leftovers ) { uint64 * targetmem = targetmembase + blocks * blockwords ; uint64 * sourcemem = sourcemembase + blocks * blockwords ; errors += CheckRegion ( sourcemem , srcpe -> pattern , leftovers , blocks * blocksize , 0 ) ; int leftoverwords = leftovers / wordsize_ ; for ( int i = 0 ; i < leftoverwords ; i ++ ) { targetmem [ i ] = sourcemem [ i ] ; } } dstpe -> pattern = srcpe -> pattern ; if ( errors ) { FillPage ( dstpe ) ; } return errors ; }
Copy a block of memory quickly, while keeping a CRC of the data.
Copy a block of memory quickly while keeping a CRC of the data .
// Base addresses for memory copy // Remember the expected CRC // Investigate miscompares. // Copy the data originally read from this region back again. // This data should have any corruption read originally while // calculating the CRC. // For odd length transfers, we should never hit this. // Update pattern reference to reflect new contents. // Clean clean clean the errors away. // TODO(nsanders): Maybe we should patch rather than fill? Filling may // cause bad data to be propogated across the page.