예제 #1
0
void
IO::WaitForReap(string grpName, string testName, uint32_t ms,
    SharedCQPtr cq, SharedCmdPtr cmd, uint32_t &numCE, uint32_t &isrCount,
    string qualify, bool verbose)
{
    string work;

    LOG_NRM("Wait for the CE to arrive in CQ %d", cq->GetQId());
    if (cq->ReapInquiryWaitSpecify(ms, 1, numCE, isrCount) == false) {
        work = str(boost::format(
            "Unable to see any CE's in CQ %d, dump entire CQ") % cq->GetQId());
        cq->Dump(
            FileSystem::PrepDumpFile(grpName, testName, "cq." + cmd->GetName(),
            qualify), work);
        throw FrmwkEx(HERE, work);
    } else if (numCE != 1) {
        work = str(boost::format(
            "Unable to see any CE's in CQ %d, dump entire CQ") % cq->GetQId());
        cq->Dump(
            FileSystem::PrepDumpFile(grpName, testName, "cq." + cmd->GetName(),
            qualify), work);
        throw FrmwkEx(HERE, "1 cmd caused %d CE's to arrive in CQ %d",
            numCE, cq->GetQId());
    }
    if (verbose) {
        work = str(boost::format("Just B4 reaping CQ %d, dump entire CQ") %
            cq->GetQId());
        cq->Dump(FileSystem::PrepDumpFile(grpName, testName,
            "cq." + cmd->GetName(), qualify), work);
    }
}
예제 #2
0
void
LBAOutOfRangeBare_r10b::SendCmdToHdw(SharedSQPtr sq, SharedCQPtr cq,
    SharedCmdPtr cmd, string qualify)
{
    uint16_t numCE;
    uint32_t isrCount;
    uint32_t isrCountB4;
    string work;



    if ((numCE = cq->ReapInquiry(isrCountB4, true)) != 0) {
        LOG_ERR("Require 0 CE's within CQ %d, not upheld, found %d",
            cq->GetQId(), numCE);
        throw exception();
    }

    LOG_NRM("Send the cmd to hdw via SQ %d", sq->GetQId());
    sq->Send(cmd);
    work = str(boost::format(
        "Just B4 ringing SQ %d doorbell, dump entire SQ") % sq->GetQId());
    sq->Dump(FileSystem::PrepLogFile(mGrpName, mTestName,
        "sq." + cmd->GetName(), qualify), work);
    sq->Ring();


    LOG_NRM("Wait for the CE to arrive in CQ %d", cq->GetQId());
    if (cq->ReapInquiryWaitSpecify(DEFAULT_CMD_WAIT_ms, 1, numCE, isrCount)
        == false) {

        LOG_ERR("Unable to see CE for issued cmd");
        work = str(boost::format(
            "Unable to see any CE's in CQ %d, dump entire CQ") % cq->GetQId());
        cq->Dump(
            FileSystem::PrepLogFile(mGrpName, mTestName, "cq." + cmd->GetName(),
            qualify), work);
        throw exception();
    } else if (numCE != 1) {
        LOG_ERR("1 cmd caused %d CE's to arrive in CQ %d", numCE, cq->GetQId());
        throw exception();
    }
    work = str(boost::format("Just B4 reaping CQ %d, dump entire CQ") %
        cq->GetQId());
    cq->Dump(FileSystem::PrepLogFile(mGrpName, mTestName,
        "cq." + cmd->GetName(), qualify), work);

    // throws if an error occurs
    IO::ReapCE(cq, numCE, isrCount, mGrpName, mTestName, qualify,
        CESTAT_LBA_OUT_RANGE);

    // Single cmd submitted on empty ASQ should always yield 1 IRQ on ACQ
    if (gCtrlrConfig->IrqsEnabled() && cq->GetIrqEnabled() &&
        (isrCount != (isrCountB4 + 1))) {

        LOG_ERR("CQ using IRQ's, but IRQ count not expected (%d != %d)",
            isrCount, (isrCountB4 + 1));
        throw exception();
    }
}
예제 #3
0
파일: sq.cpp 프로젝트: 16aug/tnvme
void
SQ::Send(SharedCmdPtr cmd, uint16_t &uniqueId)
{
    int rc;
    struct nvme_64b_send io;


    // Detect if doing something that looks suspicious/incorrect/illegal
    if (gCtrlrConfig->IsStateEnabled() == false)
        LOG_WARN("Sending cmds to a disabled DUT is suspicious");

    io.q_id = GetQId();
    io.bit_mask = (send_64b_bitmask)(cmd->GetPrpBitmask() |
        cmd->GetMetaBitmask());
    io.meta_buf_id = cmd->GetMetaBufferID();
    io.data_buf_size = cmd->GetPrpBufferSize();
    io.data_buf_ptr = cmd->GetROPrpBuffer();
    io.cmd_buf_ptr = cmd->GetCmd()->GetBuffer();
    io.data_dir = cmd->GetDataDir();

    LOG_NRM("Send cmd opcode 0x%02X, payload size 0x%04X, to SQ id 0x%02X",
        cmd->GetOpcode(), io.data_buf_size, io.q_id);

    if ((rc = ioctl(mFd, NVME_IOCTL_SEND_64B_CMD, &io)) < 0)
        throw FrmwkEx(HERE, "Error sending cmd, rc =%d", rc);

    // Allow tnvme to learn of the unique cmd ID which was assigned by dnvme
    uniqueId = io.unique_id;
    cmd->SetCID(io.unique_id);
}
예제 #4
0
void
InvalidNamspc_r10b::SendCmdToHdw(SharedSQPtr sq, SharedCQPtr cq,
                                 SharedCmdPtr cmd, string qualify)
{
    uint32_t isrCount;
    uint32_t numCE;
    uint32_t ceRemain;
    uint32_t numReaped;
    string work;
    uint16_t uniqueId;


    LOG_NRM("Send the cmd to hdw via SQ %d", sq->GetQId());
    sq->Send(cmd, uniqueId);
    sq->Ring();

    LOG_NRM("Wait for the CE to arrive in CQ %d", cq->GetQId());
    if (cq->ReapInquiryWaitSpecify(DEFAULT_CMD_WAIT_ms, 1, numCE, isrCount)
            == false) {

        work = str(boost::format(
                       "Unable to see any CE's in CQ %d, dump entire CQ") % cq->GetQId());
        cq->Dump(
            FileSystem::PrepDumpFile(mGrpName, mTestName, "cq." +
                                     cmd->GetName(), qualify), work);
        throw FrmwkEx(HERE, "Unable to see CE for issued cmd");
    } else if (numCE != 1) {
        work = str(boost::format(
                       "Unable to see any CE's in CQ %d, dump entire CQ") % cq->GetQId());
        cq->Dump(
            FileSystem::PrepDumpFile(mGrpName, mTestName, "cq." +
                                     cmd->GetName(), qualify), work);
        throw FrmwkEx(HERE, "1 cmd caused %d CE's to arrive in CQ %d",
                      numCE, cq->GetQId());
    }

    LOG_NRM("The CQ's metrics before reaping holds head_ptr");
    struct nvme_gen_cq cqMetrics = cq->GetQMetrics();
    KernelAPI::LogCQMetrics(cqMetrics);

    LOG_NRM("Reaping CE from CQ %d, requires memory to hold CE", cq->GetQId());
    SharedMemBufferPtr ceMem = SharedMemBufferPtr(new MemBuffer());
    if ((numReaped = cq->Reap(ceRemain, ceMem, isrCount, numCE, true)) != 1) {
        work = str(boost::format("Verified CE's exist, desired %d, reaped %d")
                   % numCE % numReaped);
        cq->Dump(
            FileSystem::PrepDumpFile(mGrpName, mTestName, "cq.error", qualify),
            work);
        throw FrmwkEx(HERE, work);
    }
    union CE ce = cq->PeekCE(cqMetrics.head_ptr);
    ProcessCE::Validate(ce, CESTAT_INVAL_NAMSPC);  // throws upon error
}
예제 #5
0
void
IO::SendAndReapCmdFail(string grpName, string testName, uint32_t ms,
    SharedSQPtr sq, SharedCQPtr cq, SharedCmdPtr cmd, string qualify,
    bool verbose)
{
    uint32_t numCE;
    uint32_t isrCount;
    string work;
    uint16_t uniqueId;

    if ((numCE = cq->ReapInquiry(isrCount, true)) != 0) {
        cq->Dump(
            FileSystem::PrepDumpFile(grpName, testName, "cq",
            "notEmpty"), "Test assumption have not been met");
        throw FrmwkEx(HERE, "Require 0 CE's within CQ %d, not upheld, found %d",
            cq->GetQId(), numCE);
    }

    LOG_NRM("Send the cmd to hdw via SQ %d", sq->GetQId());
    sq->Send(cmd, uniqueId);
    if (verbose) {
        work = str(boost::format(
            "Just B4 ringing SQ %d doorbell, dump entire SQ") % sq->GetQId());
        sq->Dump(FileSystem::PrepDumpFile(grpName, testName,
            "sq." + cmd->GetName(), qualify), work);
    }
    sq->Ring();

    LOG_NRM("Wait for the CE to arrive in CQ %d", cq->GetQId());
    if (cq->ReapInquiryWaitSpecifyQ(ms, 1, numCE, isrCount) == true) {
        /* Found a CE...reap it then throw so that it gets cleared from CQ */
        if (verbose) {
            work = str(boost::format("Just B4 reaping CQ %d, dump entire CQ") %
                cq->GetQId());
            cq->Dump(FileSystem::PrepDumpFile(grpName, testName,
                "cq." + cmd->GetName(), qualify), work);
        }

        // throws if an error occurs
        ReapCEIgnore(cq, numCE, isrCount, grpName, testName, qualify);
        if (verbose) {
            cmd->Dump(FileSystem::PrepDumpFile(grpName, testName,
                cmd->GetName(), qualify), "A cmd's contents dumped");
        }

        throw FrmwkEx(HERE, "Command was successfully processed and its "
            "completion was reaped from the CQ");
    }
}
예제 #6
0
uint16_t
IO::SendCmd(string grpName, string testName, SharedSQPtr sq,
    SharedCQPtr cq, SharedCmdPtr cmd, uint32_t &numCE, uint32_t &isrCount,
    string qualify, bool verbose)
{
    string work;
    uint16_t uniqueId;

    if ((numCE = cq->ReapInquiry(isrCount, true)) != 0) {
        cq->Dump(
            FileSystem::PrepDumpFile(grpName, testName, "cq",
            "notEmpty"), "Test assumption have not been met");
        throw FrmwkEx(HERE, "Require 0 CE's within CQ %d, not upheld, found %d",
            cq->GetQId(), numCE);
    }

    LOG_NRM("Send the cmd to hdw via SQ %d", sq->GetQId());
    sq->Send(cmd, uniqueId);
    if (verbose) {
        work = str(boost::format(
            "Just B4 ringing SQ %d doorbell, dump entire SQ") % sq->GetQId());
        sq->Dump(FileSystem::PrepDumpFile(grpName, testName,
            "sq." + cmd->GetName(), qualify), work);
    }
    sq->Ring();
    return uniqueId;
}
예제 #7
0
union CE
IO::SendAndReapCmdWhole(string grpName, string testName, uint32_t ms,
    SharedSQPtr sq, SharedCQPtr cq, SharedCmdPtr cmd, string qualify,
    bool verbose)
{
    uint32_t numCE;
    uint32_t isrCount;
    string work;

    SendCmd(grpName, testName, sq, cq, cmd, numCE, isrCount, qualify, verbose);
    WaitForReap(grpName, testName, ms, cq, cmd, numCE, isrCount, qualify,
        verbose);

    // throws if an error occurs
    union CE retCE = ReapCEWhole(cq, numCE, isrCount, grpName,
        testName, qualify);
    if (verbose) {
        cmd->Dump(FileSystem::PrepDumpFile(grpName, testName,
            cmd->GetName(), qualify), "A cmd's contents dumped");
    }
    return retCE;
}
예제 #8
0
CEStat
IO::SendAndReapCmd(string grpName, string testName, uint32_t ms,
    SharedSQPtr sq, SharedCQPtr cq, SharedCmdPtr cmd, string qualify,
    bool verbose, std::vector<CEStat> &status,
    CEStat (*Reap)(SharedCQPtr, uint32_t, uint32_t &, string, string,
            string, std::vector<CEStat> &, bool))
{
    uint32_t numCE;
    uint32_t isrCount;
    string work;

    SendCmd(grpName, testName, sq, cq, cmd, numCE, isrCount, qualify, verbose);
    WaitForReap(grpName, testName, ms, cq, cmd, numCE, isrCount, qualify,
        verbose);

    // throws if an error occurs
    CEStat retStat =
        Reap(cq, numCE, isrCount, grpName, testName, qualify, status, true);
    if (verbose) {
        cmd->Dump(FileSystem::PrepDumpFile(grpName, testName,
            cmd->GetName(), qualify), "A cmd's contents dumped");
    }
    return retStat;
}
예제 #9
0
void
IllegalCreateQs_r10b::SendToxicCmd(SharedASQPtr asq, SharedACQPtr acq,
    SharedCmdPtr cmd, uint8_t dw, uint32_t mask, uint32_t val, CEStat status)
{
    uint16_t uniqueId;
    uint32_t isrCnt;
    uint32_t numCE;
    string work;

    LOG_NRM("Send the cmd to hdw via ASQ");
    asq->Send(cmd, uniqueId);

    work = str(boost::format("%s.pure.%d") % cmd->GetName().c_str() % uniqueId);
    asq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "asq"
        + cmd->GetName(), work), "Just B4 modifying, dump ASQ");

    ASQCmdToxify(asq, dw, mask, val);
    work = str(boost::format("%s.toxic.%d") % cmd->GetName().c_str() % uniqueId);
    asq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "asq", work),
        "Just B4 ringing doorbell, dump ASQ");

    asq->Ring();

    LOG_NRM("Wait for the CE to arrive in CQ %d", acq->GetQId());
    if (acq->ReapInquiryWaitSpecify(DEFAULT_CMD_WAIT_ms, 1, numCE, isrCnt)
        == false) {
        acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "acq.fail"),
            "Dump Entire ACQ");
        asq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "asq.fail"),
            "Dump Entire ASQ");
        throw FrmwkEx(HERE, "Unable to see CEs for issued cmd");
    }

    work = str(boost::format("acq.%d") % uniqueId);
    IO::ReapCE(acq, 1, isrCnt, mGrpName, mTestName, work, status);
}
예제 #10
0
void
MaxIOQMSIXManyTo1_r10b::SendCmdAndReap(SharedIOSQPtr iosq, SharedIOCQPtr iocq,
    SharedCmdPtr cmd, uint32_t anticipatedIrqs)
{
    uint16_t uniqueId;
    uint32_t numCE;
    string work;
    uint32_t isrCount;

    LOG_NRM("Send the cmd to hdw via IOSQ #%d", iosq->GetQId());
    iosq->Send(cmd, uniqueId);
    work = str(boost::format("ioqId.%d.%s") % iosq->GetQId() %
        cmd->GetName().c_str());
    iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq", work),
        "Just B4 ringing doorbell, dump IOSQ");
    iosq->Ring();

    LOG_NRM("Wait for the CE to arrive in CQ %d", iocq->GetQId());
    if (iocq->ReapInquiryWaitSpecify(DEFAULT_CMD_WAIT_ms, 1, numCE, isrCount)
        == false) {
        iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.fail",
            work), "Dump Entire IOCQ");
        iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq.fail",
            work), "Dump Entire IOSQ");
        throw FrmwkEx(HERE, "Unable to see CEs for issued cmd");
    }

    work = str(boost::format("iocq.%d") % uniqueId);
    IO::ReapCE(iocq, 1, isrCount, mGrpName, mTestName, work);

    if (isrCount != anticipatedIrqs) {
        iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.fail",
            work), "Dump Entire IOCQ");
        iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq.fail",
            work), "Dump Entire IOSQ");
        throw FrmwkEx(HERE, "Anticipated ISRs #%d but fired #%d",
            anticipatedIrqs, isrCount);
    }
}