void smf_checkmem_dimm( dim_t maxlen, inst_t instrument, int nrelated, smf_modeltype *modeltyps, dim_t nmodels, dim_t msize, AstKeyMap *keymap, size_t available, dim_t maxfilelen, size_t *necessary, int *status ) { /* Local Variables */ int dofft=0; /* flag if we need temp space for FFTs */ dim_t i; /* Loop counter */ dim_t gain_box; /* Length of blocks for GAI/COM model */ AstKeyMap *kmap=NULL; /* Local keymap */ dim_t nblock; /* Number of blocks for GAI/COM model */ size_t ncol; /* Number of columns */ size_t ndet; /* Number of detectors each time step */ size_t ndks; /* dksquid samples in a subarray, ncol*maxlen */ size_t nrow; /* Number of rows */ size_t nsamp; /* bolo samples in a subarray, ndet*maxlen */ const char *tempstr=NULL; /* Temporary pointer to static char buffer */ size_t total = 0; /* Total bytes required */ /* Main routine */ if (*status != SAI__OK) return; /* Check inputs */ if( maxlen < 1 ) { *status = SAI__ERROR; errRep("", FUNC_NAME ": maxlen cannot be < 1", status); return; } if( (nrelated < 1) || (nrelated > SMF__MXSMF) ) { msgSeti("NREL",nrelated); msgSeti("MAXREL",SMF__MXSMF); *status = SAI__ERROR; errRep("", FUNC_NAME ": nrelated, ^NREL, must be in the range [1,^MAXREL]", status); return; } if( modeltyps ) { if( nmodels < 1 ) { *status = SAI__ERROR; errRep("", FUNC_NAME ": modeltyps specified, mmodels cannot be < 1", status); return; } } if( *status == SAI__OK ) { /* Work out the data dimensions */ switch( instrument ) { case INST__SCUBA2: /* Kludgey, but at least we check SC2STORE__COL_INDEX so this will help us catch possible future problems if order is changed */ if( SC2STORE__COL_INDEX ) { ncol = 32; nrow = 40; } else { ncol = 40; nrow = 32; } ndet = ncol*nrow; break; default: *status = SAI__ERROR; errRep("", FUNC_NAME ": Invalid instrument given.", status); } } /* Number of samples in a full data cube for one subarray */ nsamp = ndet*maxlen; /* Check to see if we need to do filtering as part of pre-processing. If so, we need an extra nsamp-sized buffer to store the FFT. */ smf_get_cleanpar( keymap, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dofft, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, status ); /* Calculate memory usage of static model components: -------------------- */ if( *status == SAI__OK ) { total += nsamp*smf_dtype_sz(SMF__DOUBLE,status)*nrelated; /* RES */ total += nsamp*smf_dtype_sz(SMF__INTEGER,status)*nrelated; /* LUT */ total += nsamp*smf_dtype_sz(SMF__QUALTYPE,status)*nrelated; /* QUA */ } /* Add on memory usage for the JCMTState (one per time slice per array) */ if( *status == SAI__OK ) { total += maxlen*sizeof(JCMTState)*nrelated; } /* Add on space for dark squids */ ndks = ncol*maxlen; total += ndks*smf_dtype_sz(SMF__DOUBLE,status)*nrelated; /* Add on space for fakemap */ astMapGet0C( keymap, "FAKEMAP", &tempstr ); if( tempstr ) { total += msize*sizeof(double); } /* Apply fudge factor */ total *= CHECKMEM_FUDGE; /* Calculate memory usage of dynamic model components: ------------------- */ if( *status == SAI__OK ) { /* Most of these will have data arrays associated with each subarray (hence the multiplication by nrelated). An exception is SMF__COM for which a single-common mode is used across all subarrays. */ if( modeltyps ) { for( i=0; i<nmodels; i++ ) { switch( modeltyps[i] ) { case SMF__NOI: /* SMF__NOI also estimates the noise in each detector from the power spectra, requiring a temporary buffer to store an FFT. Currently we just store one variance per detector */ dofft = 1; total += ndet*smf_dtype_sz(SMF__DOUBLE,status)*nrelated; break; case SMF__COM: CHECK_MASK("COM") total += maxlen*smf_dtype_sz(SMF__DOUBLE,status); break; case SMF__EXT: total += nsamp*smf_dtype_sz(SMF__DOUBLE,status)*nrelated; break; case SMF__DKS: total += (maxlen + nrow*3)*ncol*smf_dtype_sz(SMF__DOUBLE,status) * nrelated; break; case SMF__GAI: /* Every COM.GAIN_BOX samples there are 3 planes of data corresponding to each bolometer in the subarray. The conversion of COM.GAIN_BOX from seconds to samples within smf_get_nsamp assumes a sample rate of 200 Hz. Later downsampling may result in a lower sample rate, but at least we are erring on the conservative side by assuming 200 Hz. */ if( astMapGet0A( keymap, "COM", &kmap ) ) { smf_get_nsamp( kmap, "GAIN_BOX", NULL, &gain_box, status ); nblock = maxlen/gain_box; if( nblock == 0 ) nblock = 1; total += nblock*3*nrow*ncol*smf_dtype_sz(SMF__DOUBLE,status)*nrelated; kmap = astAnnul( kmap ); } break; case SMF__FLT: /* Presently the filter temporarily transforms the entire data cube into a second array. We therefore need to ensure enough memory to temporarily store the data cube twice. */ CHECK_MASK("FLT") dofft = 1; total += nsamp*smf_dtype_sz(SMF__DOUBLE,status)*nrelated; break; case SMF__PLN: total += nsamp*smf_dtype_sz(SMF__DOUBLE,status)*nrelated; break; case SMF__SMO: total += nsamp*smf_dtype_sz(SMF__DOUBLE,status)*nrelated; break; case SMF__TMP: /* An externally supplied template. The model just stores the gain, offset and correlation coefficient for each bolometer, similar to SMF__GAI except with only one chunk considered */ total += 3*nrow*ncol*smf_dtype_sz(SMF__DOUBLE,status)*nrelated; break; case SMF__TWO: /* two common-mode time series and coefficients for all the detectors */ total += 2*(ndet+maxlen)*smf_dtype_sz(SMF__DOUBLE,status)*nrelated; break; case SMF__AST: /* Mostly accounted for as static memory usage above, but add space for mask if required */ CHECK_MASK("AST") break; default: *status = SAI__ERROR; errRep("", FUNC_NAME ": Invalid smf_modeltype given.", status); } /* Exit on bad status */ if( *status != SAI__OK ) { i = nmodels; } } } /* Calculate temporary space here -------------------------------------- */ if( *status == SAI__OK ) { size_t temp=0; /* current temp memory required */ size_t maxtemp=0; /* max temp memory required */ /* Some temp space required when we initially read in the data. Normally smf_concat_smfGroup will smf_open_and_flatfield one file at a time before copying into the concatenated data array. If there are N time slices in a file, smf_open_and_flatfield will usually require space both for the raw, and double-precision flatfielded data simultaneously. This is an upper limit, since if previously flatfielded data are provided no extra space for the raw data will be required. We use the supplied maxfilelen to figure out this maximum temporary buffer size. Remember to account for bolo data, dark squids, and JCMTState. Also, the way smf_iteratemap is currently written, a concatenated memory-mapped pointing LUT is initially created, and then copied to a new malloc'd array, so we need extra temp space for the full LUT. */ temp = (ndet + ncol)*( smf_dtype_sz(SMF__INTEGER,status)+ smf_dtype_sz(SMF__DOUBLE,status) )*maxfilelen + 2*maxfilelen*sizeof(JCMTState); temp += nsamp*smf_dtype_sz(SMF__INTEGER,status)*nrelated; if( temp > maxtemp ) maxtemp = temp; /* If we are doing FFTs */ if( dofft ) { temp = nsamp*smf_dtype_sz(SMF__DOUBLE,status)*nrelated; if( temp > maxtemp ) maxtemp = temp; } /* Data cleaning... seems to be a lot. Just putting in a rough estimate of 3 extra full sized arrays for the standard options. */ temp = 3.*nsamp*smf_dtype_sz(SMF__DOUBLE,status); if( temp > maxtemp ) maxtemp = temp; /* Add on the maximum chunk of temporary memory that is required */ total += maxtemp; } /* Set bad status if too big */ if( (*status == SAI__OK) && (total > available) ) { *status = SMF__NOMEM; msgSeti("REQ",total/SMF__MIB); msgSeti("AVAIL",available/SMF__MIB); errRep("", FUNC_NAME ": Requested memory ^REQ MiB for map exceeds available ^AVAIL MiB", status); } /* Return the required space */ if( necessary ) { *necessary = total; } } }
/* * Verify that CPUs don't have unexpected differences that will cause problems. */ static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur) { unsigned int cpu = smp_processor_id(); struct cpuinfo_arm64 *boot = &boot_cpu_data; unsigned int diff = 0; /* * The kernel can handle differing I-cache policies, but otherwise * caches should look identical. Userspace JITs will make use of * *minLine. */ diff |= CHECK_MASK(ctr, 0xffff3fff, boot, cur, cpu); /* * Userspace may perform DC ZVA instructions. Mismatched block sizes * could result in too much or too little memory being zeroed if a * process is preempted and migrated between CPUs. */ diff |= CHECK(dczid, boot, cur, cpu); /* If different, timekeeping will be broken (especially with KVM) */ diff |= CHECK(cntfrq, boot, cur, cpu); /* * Even in big.LITTLE, processors should be identical instruction-set * wise. */ diff |= CHECK(id_aa64isar0, boot, cur, cpu); diff |= CHECK(id_aa64isar1, boot, cur, cpu); /* * Differing PARange support is fine as long as all peripherals and * memory are mapped within the minimum PARange of all CPUs. * Linux should not care about secure memory. * ID_AA64MMFR1 is currently RES0. */ diff |= CHECK_MASK(id_aa64mmfr0, 0xffffffffffff0ff0, boot, cur, cpu); diff |= CHECK(id_aa64mmfr1, boot, cur, cpu); /* * EL3 is not our concern. * ID_AA64PFR1 is currently RES0. */ diff |= CHECK_MASK(id_aa64pfr0, 0xffffffffffff0fff, boot, cur, cpu); diff |= CHECK(id_aa64pfr1, boot, cur, cpu); /* * If we have AArch32, we care about 32-bit features for compat. These * registers should be RES0 otherwise. */ diff |= CHECK(id_isar0, boot, cur, cpu); diff |= CHECK(id_isar1, boot, cur, cpu); diff |= CHECK(id_isar2, boot, cur, cpu); diff |= CHECK(id_isar3, boot, cur, cpu); diff |= CHECK(id_isar4, boot, cur, cpu); diff |= CHECK(id_isar5, boot, cur, cpu); diff |= CHECK(id_mmfr0, boot, cur, cpu); diff |= CHECK(id_mmfr1, boot, cur, cpu); diff |= CHECK(id_mmfr2, boot, cur, cpu); diff |= CHECK(id_mmfr3, boot, cur, cpu); diff |= CHECK(id_pfr0, boot, cur, cpu); diff |= CHECK(id_pfr1, boot, cur, cpu); /* * Mismatched CPU features are a recipe for disaster. Don't even * pretend to support them. */ WARN_TAINT_ONCE(diff, TAINT_CPU_OUT_OF_SPEC, "Unsupported CPU feature variation."); }
/** ========================================================================= */ static int report_error(mysql_connection_t *conn, char *mask_str) { int rc = 0; unsigned int num_fields; unsigned int num_rows, i; MYSQL_RES *res; MYSQL_ROW row; mask_val_t *mask_vals = parse_mask(mask_str); if (QUERY(conn, "select pe.SymbolErrors, pe.LinkRecovers," " pe.LinkDowned, pe.RcvErrors, pe.RcvRemotePhysErrors," " pe.RcvSwitchRelayErrors, pe.XmtDiscards," " pe.XmtConstraintErrors, pe.RcvConstraintErrors," " pe.LinkIntegrityErrors, pe.ExcBufOverrunErrors," " pe.VL15Dropped, n.name, pe.port, n.guid," " pd.xmit_data, pd.rcv_data, pd.xmit_pkts, pd.rcv_pkts," " pd.unicast_xmit_pkts, pd.unicast_rcv_pkts," " pd.multicast_xmit_pkts, pd.multicast_rcv_pkts, " " pd.port " " from " " port_errors as pe,nodes as n,port_data_counters as pd " " where" " n.guid=pe.guid and n.guid=pd.guid and pe.port=pd.port;" )) { fprintf(stderr, "Failed to query node errors\n"); return (1); } res = mysql_store_result(conn->conn); if ((num_fields = mysql_num_fields(res)) != 24) { fprintf(stderr, "%s:%d Failed to query node errors %d != 24\n", __FUNCTION__, __LINE__, num_fields); rc = 1; goto free_res; } num_rows = mysql_num_rows(res); if (num_rows == 0) { fprintf(stderr, "Failed to find any nodes in DB\n"); rc = 1; goto free_res; } for (i = 0; i < num_rows; i++) { uint64_t SymbolErrors; uint64_t LinkRecovers; uint64_t LinkDowned; uint64_t RcvErrors; uint64_t RcvRemotePhysErrors; uint64_t RcvSwitchRelayErrors; uint64_t XmtDiscards; uint64_t XmtConstraintErrors; uint64_t RcvConstraintErrors; uint64_t LinkIntegrityErrors; uint64_t ExcBufOverrunErrors; uint64_t VL15Dropped; uint64_t total = 0; row = mysql_fetch_row(res); SymbolErrors = COL_TO_UINT64(0); total += CHECK_MASK(SymbolErrors, mask_vals); LinkRecovers = COL_TO_UINT64(1); total += CHECK_MASK(LinkRecovers, mask_vals); LinkDowned = COL_TO_UINT64(2); total += CHECK_MASK(LinkDowned, mask_vals); RcvErrors = COL_TO_UINT64(3); total += CHECK_MASK(RcvErrors, mask_vals); RcvRemotePhysErrors = COL_TO_UINT64(4); total += CHECK_MASK(RcvRemotePhysErrors, mask_vals); RcvSwitchRelayErrors = COL_TO_UINT64(5); total += CHECK_MASK(RcvSwitchRelayErrors, mask_vals); XmtDiscards = COL_TO_UINT64(6); total += CHECK_MASK(XmtDiscards, mask_vals); XmtConstraintErrors = COL_TO_UINT64(7); total += CHECK_MASK(XmtConstraintErrors, mask_vals); RcvConstraintErrors = COL_TO_UINT64(8); total += CHECK_MASK(RcvConstraintErrors, mask_vals); LinkIntegrityErrors = COL_TO_UINT64(9); total += CHECK_MASK(LinkIntegrityErrors, mask_vals); ExcBufOverrunErrors = COL_TO_UINT64(10); total += CHECK_MASK(ExcBufOverrunErrors, mask_vals); VL15Dropped = COL_TO_UINT64(11); total += CHECK_MASK(VL15Dropped, mask_vals); if (total > 0) { char node_desc[65]; char *node_name = NULL; strncpy(node_desc, row[12], 64); node_name = remap_node_name(node_name_map, COL_TO_UINT64(14), node_desc); print_report_error_res(node_name, row, total); free(node_name); } } free_res: mysql_free_result(res); return (rc); }