void WriteDataPat_r10b::SendToIOSQ(SharedIOSQPtr iosq, SharedIOCQPtr iocq, SharedWritePtr writeCmd, string qualifier) { uint32_t numCE; uint32_t ceRemain; uint32_t numReaped; uint32_t isrCount; uint16_t uniqueId; LOG_NRM("Send the cmd to hdw via %s IOSQ", qualifier.c_str()); iosq->Send(writeCmd, uniqueId); iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq", qualifier), "Just B4 ringing SQ doorbell, dump entire IOSQ contents"); iosq->Ring(); LOG_NRM("Wait for the CE to arrive in IOCQ"); if (iocq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(1), 1, numCE, isrCount) == false) { iocq->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", qualifier), "Unable to see any CE's in IOCQ, dump entire CQ contents"); throw FrmwkEx(HERE, "Unable to see completion of cmd"); } else if (numCE != 1) { iocq->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", qualifier), "Unable to see any CE's in IOCQ, dump entire CQ contents"); throw FrmwkEx(HERE, "The IOCQ should only have 1 CE as a result of a cmd"); } iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", qualifier), "Just B4 reaping IOCQ, dump entire CQ contents"); LOG_NRM("The CQ's metrics B4 reaping holds head_ptr needed"); struct nvme_gen_cq iocqMetrics = iocq->GetQMetrics(); KernelAPI::LogCQMetrics(iocqMetrics); LOG_NRM("Reaping CE from IOCQ, requires memory to hold reaped CE"); SharedMemBufferPtr ceMemIOCQ = SharedMemBufferPtr(new MemBuffer()); if ((numReaped = iocq->Reap(ceRemain, ceMemIOCQ, isrCount, numCE, true)) != 1) { throw FrmwkEx(HERE, "Verified there was 1 CE, but reaping produced %d", numReaped); } LOG_NRM("The reaped CE is..."); iocq->LogCE(iocqMetrics.head_ptr); union CE ce = iocq->PeekCE(iocqMetrics.head_ptr); ProcessCE::Validate(ce); // throws upon error }
void IOQRollChkDiff_r10b::ReapAndVerifyCE(SharedIOCQPtr iocq, uint32_t expectedVal) { uint32_t numCE; uint32_t ceRemain; uint32_t numReaped; uint32_t isrCount; LOG_NRM("Wait for the CE to arrive in IOCQ %d", iocq->GetQId()); if (iocq->ReapInquiryWaitSpecify(DEFAULT_CMD_WAIT_ms, 1, numCE, isrCount) == false) { iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", "reapInq"), "Unable to see any CE's in IOCQ, dump entire CQ contents"); throw FrmwkEx(HERE, "Unable to see completion of cmd"); } else if (numCE != 1) { throw FrmwkEx(HERE, "The IOCQ should only have 1 CE as a result of a cmd"); } LOG_NRM("The CQ's metrics before reaping holds head_ptr"); struct nvme_gen_cq iocqMetrics = iocq->GetQMetrics(); LOG_NRM("Reaping CE from IOCQ, requires memory to hold reaped CE"); SharedMemBufferPtr ceMemIOCQ = SharedMemBufferPtr(new MemBuffer()); if ((numReaped = iocq->Reap(ceRemain, ceMemIOCQ, isrCount, numCE, true)) != 1) { throw FrmwkEx(HERE, "Verified there was 1 CE, but reaping produced %d", numReaped); } union CE ce = iocq->PeekCE(iocqMetrics.head_ptr); ProcessCE::Validate(ce, CESTAT_SUCCESS); // throws upon error if (ce.n.SQID != IOQ_ID) { iocq->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", "CE.SQID"), "CE SQ ID Inconsistent"); throw FrmwkEx(HERE, "Expected CE.SQID = 0x%04X in IOCQ CE but actual " "CE.SQID = 0x%04X", IOQ_ID, ce.n.SQID); } if (ce.n.SQHD != expectedVal) { iocq->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", "CE.SQHD"), "CE SQ Head Pointer Inconsistent"); throw FrmwkEx(HERE, "Expected CE.SQHD = 0x%04X in IOCQ CE but actual " "CE.SQHD = 0x%04X", expectedVal, ce.n.SQHD); } }
void CIDAcceptedIOSQ_r10b::ReapVerifyCID(SharedIOSQPtr iosq, SharedIOCQPtr iocq, uint16_t expCID) { uint32_t isrCount; uint32_t ceRemain; uint32_t numReaped; uint32_t numCE; if (iocq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(1), 1, numCE, isrCount) == false) { iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.fail"), "Dump Entire IOCQ"); iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq.fail"), "Dump Entire IOSQ"); throw FrmwkEx(HERE, "Unable to see CEs for issued cmd"); } SharedMemBufferPtr ceMem = SharedMemBufferPtr(new MemBuffer()); if ((numReaped = iocq->Reap(ceRemain, ceMem, isrCount, numCE, true)) != 1) { iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.fail"), "Dump Entire IOCQ"); iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq.fail"), "Dump Entire IOSQ"); throw FrmwkEx(HERE, "Unable to reap on IOCQ"); } union CE *ce = (union CE *)ceMem->GetBuffer(); ProcessCE::Validate(*ce); // throws upon error if (ce->n.CID != expCID) { iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.fail"), "Dump Entire IOCQ"); iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq.fail"), "Dump Entire IOSQ"); throw FrmwkEx(HERE, "Received CID %d but expected %d", ce->n.CID, expCID); } if (ce->n.SQID != iosq->GetQId()) { iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.fail"), "Dump Entire IOCQ"); iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq.fail"), "Dump Entire IOSQ"); throw FrmwkEx(HERE, "Rx'd SDID %d but expt'd %d", ce->n.SQID, iosq->GetQId()); } }
void QIDVariations_r10b::ReapVerifyOnCQ(SharedIOCQPtr iocq, SharedIOSQPtr iosq) { uint32_t numCE; uint32_t ceRemain; uint32_t numReaped; uint32_t isrCount; LOG_NRM("Reap and verify CE."); SharedMemBufferPtr ceMemIOCQ = SharedMemBufferPtr(new MemBuffer()); for (uint32_t nCmds = 1; nCmds < iosq->GetNumEntries(); nCmds++) { LOG_NRM("Wait for the CE to arrive in IOCQ"); if (iocq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(1), 1, numCE, isrCount) == false) { iocq->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", "reapInq"), "Unable to see any CE's in IOCQ, dump entire CQ contents"); throw FrmwkEx(HERE, "Unable to see completion of cmd"); } LOG_NRM("The CQ's metrics B4 reaping holds head_ptr needed"); struct nvme_gen_cq iocqMetrics = iocq->GetQMetrics(); KernelAPI::LogCQMetrics(iocqMetrics); if ((numReaped = iocq->Reap(ceRemain, ceMemIOCQ, isrCount, 1, true)) != 1) { iocq->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", "reap"), "Unable to see any CE's in IOCQ, dump entire CQ contents"); throw FrmwkEx(HERE, "Verified there was 1 CE, but reaping failed"); } LOG_NRM("The reaped CE is..."); iocq->LogCE(iocqMetrics.head_ptr); union CE ce = iocq->PeekCE(iocqMetrics.head_ptr); ProcessCE::Validate(ce); // throws upon error if (ce.n.SQID != iosq->GetQId()) { iocq->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", "sqId"), "Wrong SQID in the CE of IOCQ, dump entire CQ contents"); throw FrmwkEx(HERE, "Invalid SQID %d in CE, expected SQID", ce.n.SQID, iosq->GetQId()); } } }
void ManyCmdSubmit_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ uint32_t nCmds; uint32_t isrCount; uint32_t ceRemain; uint32_t numReaped; uint32_t numCE; uint16_t uniqueId; // Lookup objs which were created in a prior test within group SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)) SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)) LOG_NRM("Determine the max IOQ entries supported"); uint64_t ctrlCapReg; if (gRegisters->Read(CTLSPC_CAP, ctrlCapReg) == false) throw FrmwkEx(HERE, "Unable to determine MQES"); uint32_t maxIOQEntries = (uint32_t)(ctrlCapReg & CAP_MQES); maxIOQEntries += 1; // convert to 1-based. LOG_NRM("Create contig IOQ's"); SharedIOCQPtr iocq = Queues::CreateIOCQContigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, maxIOQEntries, false, IOCQ_CONTIG_GROUP_ID, true, 0); SharedIOSQPtr iosq = Queues::CreateIOSQContigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, maxIOQEntries, false, IOSQ_CONTIG_GROUP_ID, IOQ_ID, 0); SharedWritePtr writeCmd = SetWriteCmd(); uint32_t increment = 1; for (uint32_t x = 1; x < maxIOQEntries; x += increment) { LOG_NRM("Sending #%d simultaneous NVM write cmds to IOSQ", x); // Issue x simultaneous NVM write cmds. for (nCmds = 1; nCmds <= x; nCmds++) iosq->Send(writeCmd, uniqueId); iosq->Ring(); // Variable wait time w.r.t "x" and expect all CE's to arrive in CQ. if (iocq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(x), x, numCE, isrCount) == false) { iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.reqpinq." + writeCmd->GetName()), "Dump Entire IOCQ"); LogCEAndCQMetrics(iocq); throw FrmwkEx(HERE, "Unable to see CEs for issued cmds #%d", x); } else if (numCE != x) { iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.reqpinq." + writeCmd->GetName()), "Dump Entire IOCQ"); LogCEAndCQMetrics(iocq); throw FrmwkEx(HERE, "The IOCQ should only have #%d CE's as a result " "of #%d simultaneous cmds but found #%d", x, x, numCE); } SharedMemBufferPtr ceMem = SharedMemBufferPtr(new MemBuffer()); if ((numReaped = iocq->Reap(ceRemain, ceMem, isrCount, x, true)) != x) { iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.reap." + writeCmd->GetName()), "Dump Entire IOCQ"); LogCEAndCQMetrics(iocq); throw FrmwkEx(HERE, "Unable to reap on IOCQ #%d. Reaped #%d of #%d", IOQ_ID, numReaped, x); } // Testing every cmd takes numerous hrs, so compromise. if ((maxIOQEntries - 1000) % x == 0) increment = 100; else if ((x % 1000) == 0) increment = 1000; else if ((maxIOQEntries - 100) % x == 0) increment = 10; else if ((x % 100) == 0) increment = 100; else if ((maxIOQEntries - 10) % x == 0) increment = 1; else if ((x % 10) == 0) increment = 10; } // Delete IOSQ before the IOCQ to comply with spec. Queues::DeleteIOSQToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, asq, acq); Queues::DeleteIOCQToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iocq, asq, acq); }