示例#1
0
def test_create_sq_with_invalid_prp_offset(nvme0):
    prp = PRP(4096)
    cq = IOCQ(nvme0, 1, 10, prp)

    #Spec NVM-Express-1_4-2019.06.10-Ratified
    #Figure 153: In both cases, the PRP Entry shall have an offset of 0h.
    prp.offset = 0
    IOSQ(nvme0, 1, 10, prp, cqid=1).delete()

    prp.offset = 2048
    with pytest.warns(UserWarning, match="ERROR status: 00/13"):
        IOSQ(nvme0, 1, 10, prp, cqid=1).delete()

    prp.offset = 2050
    with pytest.warns(UserWarning, match="ERROR status: 00/13"):
        IOSQ(nvme0, 1, 10, prp, cqid=1).delete()

    prp.offset = 4095
    with pytest.warns(UserWarning, match="ERROR status: 00/13"):
        IOSQ(nvme0, 2, 10, prp, cqid=1).delete()

    prp.offset = 255
    with pytest.warns(UserWarning, match="ERROR status: 00/13"):
        IOSQ(nvme0, 2, 10, prp, cqid=1).delete()

    cq.delete()
示例#2
0
def test_cq_p_phase_bit(nvme0):
    cq = IOCQ(nvme0, 1, 3, PRP())
    sq = IOSQ(nvme0, 1, 5, PRP(), cqid=1)

    # send commands
    sq[0] = SQE(4 << 16 + 0, 1)
    sq[1] = SQE(3 << 16 + 0, 1)
    sq[2] = SQE(2 << 16 + 0, 1)
    sq[3] = SQE(1 << 16 + 0, 1)
    sq.tail = 4

    # check cq
    time.sleep(0.1)
    assert cq[0][3] == 0x10004
    assert cq[1][3] == 0x10003
    assert cq[2][3] == 0

    cq.head = 1
    time.sleep(0.1)
    assert cq[2][3] == 0x10002
    assert cq[0][3] == 0x10004

    cq.head = 2
    time.sleep(0.1)
    # p-bit changed to 0
    assert cq[0][3] == 0x00001
示例#3
0
def test_sq_cq_around(nvme0):
    cq = IOCQ(nvme0, 1, 3, PRP())
    sq = IOSQ(nvme0, 1, 5, PRP(), cqid=1)

    # send commands
    sq[0] = SQE(4 << 16 + 0, 1)
    sq[1] = SQE(3 << 16 + 0, 1)
    sq[2] = SQE(2 << 16 + 0, 1)
    sq[3] = SQE(1 << 16 + 0, 1)
    sq.tail = 4

    # check cq
    time.sleep(0.1)
    assert cq[0][3] == 0x10004
    assert cq[1][3] == 0x10003
    assert cq[2][3] == 0

    cq.head = 1
    time.sleep(0.1)
    assert cq[0][3] == 0x10004
    assert cq[2][3] == 0x10002

    cq.head = 2
    time.sleep(0.1)
    assert cq[2][3] == 0x10002
    assert cq[1][3] == 0x10003
    assert cq[0][3] == 0x00001

    sq.delete()
    cq.delete()
示例#4
0
def test_sq_cq_another_sq(nvme0):
    cq = IOCQ(nvme0, 1, 3, PRP())

    # send commands in sq1
    sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1)
    sq[0] = SQE(4<<16+0, 1); sq.tail = 1
    sq[1] = SQE(3<<16+0, 1); sq.tail = 0

    sq2 = IOSQ(nvme0, 2, 2, PRP(), cqid=1)
    sq2[0] = SQE(2<<16+0, 1); sq2.tail = 1
    sq2[1] = SQE(1<<16+0, 1); sq2.tail = 0

    # check cq
    time.sleep(0.1)
    assert cq[0][3] == 0x10004
    assert cq[1][3] == 0x10003
    assert cq[2][3] == 0
    cq.head = 1
    assert cq[2][3] == 0x10002
    assert cq[0][3] == 0x10004
    cq.head = 2
    assert cq[0][3] == 0x00001

    sq.delete()
    sq2.delete()
    cq.delete()
示例#5
0
def test_sq_doorbell(nvme0):
    cq = IOCQ(nvme0, 1, 5, PRP())
    sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1)
    sq.tail = 1

    time.sleep(0.1)
    sq.delete()
    cq.delete()
示例#6
0
def test_cid_conflict(nvme0):
    mdts_lba = nvme0.mdts // 512
    cq = IOCQ(nvme0, 1, 20, PRP())
    sq = IOSQ(nvme0, 1, 20, PRP(), cqid=1)

    # prp for the long buffer
    write_buf_1 = PRP(ptype=32, pvalue=0xaaaaaaaa)
    pages = mdts_lba // 8
    pages -= 1

    prp_list = PRPList()
    prp_list_head = prp_list
    while pages:
        logging.info(pages)
        for i in range(63):
            if pages:
                prp_list[i] = PRP()
                pages -= 1
                logging.debug(pages)
        if pages > 1:
            tmp = PRPList()
            prp_list[63] = tmp
            prp_list = tmp
            logging.debug("prp_list")
        elif pages == 1:
            prp_list[63] = PRP()
            pages -= 1
            logging.debug(pages)

    #send first cmd
    w1 = SQE((1 << 16) + 1, 1)
    w1.prp1 = write_buf_1
    w1.prp2 = prp_list_head
    w1[12] = mdts_lba - 1  # 0based, nlba
    sq[0] = w1
    sq[1] = w1
    logging.info(sq[0])
    logging.info(sq[1])
    assert sq[0][0] >> 16 == 1
    assert sq[1][0] >> 16 == 1
    sq.tail = 2

    time.sleep(1)
    logging.info(cq[0])
    logging.info(cq[1])
    cqe = CQE(cq[0])
    assert cqe.p == 1
    status = (cqe[3] >> 17) & 0x3ff
    assert status == 0 or status == 0x0003
    cqe = CQE(cq[1])
    assert cqe.p == 1
    status = (cqe[3] >> 17) & 0x3ff
    assert status == 0 or status == 0x0003
    cq.head = 2

    sq.delete()
    cq.delete()
示例#7
0
def test_create_sq_physically_contiguous(nvme0):
    if not nvme0.cap & 0x10000:
        pytest.skip("pc is not required")

    cq = IOCQ(nvme0, 2, 10, PRP(4096))
    with pytest.warns(UserWarning, match="ERROR status: 00/02"):
        IOSQ(nvme0, 1, 2, PRP(4096), pc=False, cqid=2)
    IOSQ(nvme0, 1, 2, PRP(4096), pc=True, cqid=2).delete()
    cq.delete()
示例#8
0
def _test_cq_sqhd_aer(nvme0, buf):
    #Create cq and sq
    a = ()
    cq = IOCQ(nvme0, 1, 5, PRP())
    sq = IOSQ(nvme0, 1, 5, PRP(), cqid=1)

    #Trigger aer cmd response by invaild doorbell write value
    sq.tail = 5
    time.sleep(0.1)

    #Invalid Doorbell Write Value
    with pytest.warns(UserWarning,
                      match="AER notification is triggered: 0x10100"):
        nvme0.waitdone()
    sq.delete()
    cq.delete()

    def call_back_cpl(cpl):
        nonlocal a
        a = cpl

    #Check normal cmd cqe sqhd value
    nvme0.getlogpage(1, buf, cb=call_back_cpl).waitdone()
    sqhd1 = a[2] & 0xffff
    logging.info(sqhd1)

    nvme0.aer(cb=call_back_cpl)
    nvme0.getlogpage(1, buf, cb=call_back_cpl).waitdone()
    sqhd2 = a[2] & 0xffff
    logging.info(sqhd2)
    assert sqhd2 == sqhd1 + 2

    #Trigger aer cmd response by invaild doorbell write value
    cq = IOCQ(nvme0, 1, 5, PRP())
    sq = IOSQ(nvme0, 1, 5, PRP(), cqid=1)
    sq.tail = 5
    time.sleep(0.1)

    #Invalid Doorbell Write Value
    with pytest.warns(UserWarning,
                      match="AER notification is triggered: 0x10100"):
        nvme0.waitdone()
        #verify aer cmd cqe sqhd
        sqhd_aer = a[2] & 0xffff
        sqhd_aer = sqhd2 + 2
        logging.info("aer sqhd is {}".format(sqhd_aer))

    sq.delete()
    cq.delete()

    #verify the following cmd cqe sqhd
    nvme0.getlogpage(1, buf, cb=call_back_cpl).waitdone()
    sqhd3 = a[2] & 0xffff
    assert sqhd3 == sqhd_aer + 3
    logging.info(sqhd3)
示例#9
0
def test_sq_doorbell_invalid(nvme0, tail):
    cq = IOCQ(nvme0, 1, 5, PRP())
    sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1)
    sq.tail = tail

    time.sleep(0.1)
    #Invalid Doorbell Write Value
    with pytest.warns(UserWarning, match="AER notification is triggered: 0x10100"):
        nvme0.getfeatures(7).waitdone()
    sq.delete()
    cq.delete()
示例#10
0
def test_sq_reserved(nvme0):
    cq = IOCQ(nvme0, 1, 3, PRP())
    sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1)

    # Reserved field is non-zero.
    sq[0] = SQE((1<<16) + (7<<10) + 0, 1); sq.tail = 1; time.sleep(0.1)

    # check cq
    time.sleep(0.1)
    assert cq[0][3] == 0x10001
    sq.delete()
    cq.delete()
示例#11
0
def test_sq_fuse_is_zero(nvme0):
    cq = IOCQ(nvme0, 1, 3, PRP())
    sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1)

    # FUSE field is zero.
    sq[0] = SQE((1<<16) + (0<<8), 1); sq.tail = 1; time.sleep(0.1)

    # check cq
    time.sleep(0.1)
    assert cq[0][3] == 0x10001
    sq.delete()
    cq.delete()
示例#12
0
def test_sq_fuse_is_reserved(nvme0):
    cq = IOCQ(nvme0, 1, 3, PRP())
    sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1)

    # FUSE field is 0x3(Reserved).
    sq[0] = SQE((1<<16) + (3<<8), 1); sq.tail = 1; time.sleep(0.1)

    # check cq
    time.sleep(0.1)
    #sct=0,sc=2(Invalid Field in Command)
    assert cq[0][3]>>17 == 0x0002
    sq.delete()
    cq.delete()
示例#13
0
def test_sq_ns_invalid(nvme0,ns_id):
    cq = IOCQ(nvme0, 1, 3, PRP())
    sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1)

    # ns field is invalid.
    sq[0] = SQE(2, ns_id); sq.tail = 1; time.sleep(0.1)

    # check cq
    time.sleep(0.1)
    #sct=0,sc=0x0b(Invalid Namespace or Format)
    assert (cq[0][3]>>17)&0x3ff == 0x000b

    sq.delete()
    cq.delete()    
示例#14
0
def test_sq_opc_invalid_nvm_cmd(nvme0,opc_id):
    cq = IOCQ(nvme0, 1, 3, PRP())
    sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1)

    # OPC field is invalid.
    sq[0] = SQE((1<<16) + opc_id, 1); sq.tail = 1; time.sleep(0.1)

    # check cq
    time.sleep(0.1)
    #sct=0,sc=1(Invalid Command Opcode)
    assert (cq[0][3]>>17)&0x3ff == 0x0001

    sq.delete()
    cq.delete()
示例#15
0
def test_sq_cid1(nvme0):
    cq = IOCQ(nvme0, 1, 3, PRP())
    sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1)

    # send discontinuous cid commands
    sq[0] = SQE(4<<16+0, 1); sq.tail = 1; time.sleep(0.1)
    sq[1] = SQE(1<<16+0, 1); sq.tail = 2; time.sleep(0.1)

    # check cq
    time.sleep(0.1)
    assert cq[0][3] == 0x10004
    assert cq[1][3] == 0x10001
    sq.delete()
    cq.delete()
示例#16
0
def test_sq_cid2(nvme0):
    cq = IOCQ(nvme0, 1, 3, PRP())
    sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1)

    # send max/min cid commands
    sq[0] = SQE(0xFFFF<<16+0, 1); 
    sq[1] = SQE(0<<16+0, 1); sq.tail = 2; time.sleep(0.1)

    # check cq
    time.sleep(0.1)
    assert cq[0][3] == 0x1FFFF
    assert cq[1][3] == 0x10000
    sq.delete()
    cq.delete()
示例#17
0
def test_write_mdts(nvme0, mdts):

    cq = IOCQ(nvme0, 1, 2, PRP())
    sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1)

    # prp for the long buffer
    write_buf_1 = PRP(ptype=32, pvalue=0xaaaaaaaa)
    pages = mdts // 8
    pages -= 1

    prp_list = PRPList()
    prp_list_head = prp_list
    while pages:
        for i in range(511):
            if pages:
                prp_list[i] = PRP()
                pages -= 1
                logging.debug(pages)
        if pages > 1:
            tmp = PRPList()
            prp_list[511] = tmp
            prp_list = tmp
            logging.debug("prp_list")
        elif pages == 1:
            prp_list[511] = PRP()
            pages -= 1
            logging.debug(pages)

    w1 = SQE(1, 1)
    w1.prp1 = write_buf_1
    w1.prp2 = prp_list_head
    w1[12] = mdts - 1  # 0based, nlba
    w1.cid = 0x123
    sq[0] = w1
    sq.tail = 1

    time.sleep(1)
    cqe = CQE(cq[0])
    logging.info(cqe)
    assert cqe.p == 1
    assert cqe.cid == 0x123
    assert cqe.sqhd == 1
    logging.info("cqe status is {}".format(cqe.status))
    assert cqe.status == 0 or cqe.status == 2
    cq.head = 1

    sq.delete()
    cq.delete()
示例#18
0
def test_delete_sq_with_invalid_id(nvme0, ncqa):
    def delete_sq(nvme0, qid):
        nvme0.send_cmd(0x00, cdw10=qid).waitdone()

    # pass case
    cq = IOCQ(nvme0, 1, 10, PRP(4096))
    IOSQ(nvme0, 5, 10, PRP(4096), cqid=1)
    delete_sq(nvme0, 5)
    cq.delete()

    # sqid: 0
    with pytest.warns(UserWarning, match="ERROR status: 01/01"):
        delete_sq(nvme0, 0)

    # sqid: 0xffff
    with pytest.warns(UserWarning, match="ERROR status: 01/01"):
        delete_sq(nvme0, 0xffff)

    # sqid: larger than supported number of queue
    with pytest.warns(UserWarning, match="ERROR status: 01/01"):
        delete_sq(nvme0, ncqa + 1)

    # sqid: duplicated cqid
    with pytest.warns(UserWarning, match="ERROR status: 01/01"):
        delete_sq(nvme0, ncqa + 0xff)

    # sqid: not existed
    with pytest.warns(UserWarning, match="ERROR status: 01/01"):
        delete_sq(nvme0, 5)
示例#19
0
def test_default_round_robin(nvme0):
    # 1 admin, 8 io queue
    sq_list = []
    cq = IOCQ(nvme0, 1, 1024, PRP(1024*64))
    for i in range(8):
        sq_list.append(IOSQ(nvme0, i+1, 128, PRP(128*64), cqid=1))

    # fill 100 flush commands in each queue
    for sq in sq_list:
        for i in range(100):
            sq[i] = SQE(i<<16+0, 1)

    # fire all sq, low prio first
    for sq in sq_list:
        sq.tail = 100

    # check the latency of admin command
    start = time.time()
    nvme0.getfeatures(7).waitdone()
    logging.info("admin latency when IO busy: %f" % (time.time()-start))

    # check sqid of the whole cq
    time.sleep(1)
    logging.debug([cq[i][2]>>16 for i in range(100*8)])
    # assert all urgent IO completed first
    last_sqid = {cq[i][2]>>16 for i in range(700, 800)}
    assert len(last_sqid) >= 7

    # delete all queues
    for sq in sq_list:
        sq.delete()
    cq.delete()
示例#20
0
def test_create_sq_with_invalid_cqid(nvme0, mqes):
    cdw0 = nvme0.getfeatures(0x07).waitdone()
    ncqr = (cdw0 >> 16) & 0xffff

    with pytest.warns(UserWarning, match="ERROR status: 01/01"):
        IOSQ(nvme0, 1, mqes, PRP(4096), cqid=0)

    with pytest.warns(UserWarning, match="ERROR status: 01/01"):
        IOSQ(nvme0, 1, mqes, PRP(4096), cqid=0xffff)

    with pytest.warns(UserWarning, match="ERROR status: 01/00"):
        IOSQ(nvme0, 1, mqes, PRP(4096), cqid=ncqr)

    with pytest.warns(UserWarning, match="ERROR status: 01/00"):
        IOSQ(nvme0, 1, mqes, PRP(4096), cqid=ncqr + 1)

    with pytest.warns(UserWarning, match="ERROR status: 01/01"):
        IOSQ(nvme0, 1, mqes, PRP(4096), cqid=ncqr + 0xff)
示例#21
0
def test_create_sq_invalid_queue_address_offset(nvme0):
    cq = IOCQ(nvme0, 3, 10, PRP(4096))

    queue = PRP(4096)
    queue.offset = 1
    with pytest.warns(UserWarning, match="ERROR status: 00/13"):
        IOSQ(nvme0, 1, 10, queue, cqid=3)

    cq.delete()
示例#22
0
def test_pcie_link_control_aspm(nvme0, pcie, aspm):  #1:0
    linkctrl_addr = pcie.cap_offset(0x10) + 16
    linkctrl = pcie.register(linkctrl_addr, 2)
    logging.info("link control register [0x%x]= 0x%x" %
                 (linkctrl_addr, linkctrl))

    # set ASPM control
    pcie[linkctrl_addr] = (linkctrl & 0xfc) | aspm
    linkctrl = pcie.register(linkctrl_addr, 2)
    logging.info("link control register [0x%x]= 0x%x" %
                 (linkctrl_addr, linkctrl))

    # IO queue for read commands
    cq = IOCQ(nvme0, 1, 16, PRP())
    sq = IOSQ(nvme0, 1, 16, PRP(), cqid=1)

    # read lba 0 for 1000 times, interleaved with delays
    read_cmd = SQE(2, 1)
    read_cmd.prp1 = PRPList()
    pbit = 1
    for i in range(100):
        logging.debug(i)
        slot = i % 16
        if slot == 0:
            pbit = not pbit
        next_slot = slot + 1
        if next_slot == 16:
            next_slot = 0
        sq[slot] = read_cmd
        sq.tail = next_slot
        while cq[slot].p == pbit:
            pass
        cq.head = next_slot

        # delay to trigger ASPM
        time.sleep(0.01)

    sq.delete()
    cq.delete()

    time.sleep(1)

    #return ASPM L0
    pcie[linkctrl_addr] = (linkctrl & 0xfc) | 0
示例#23
0
def test_reset_with_outstanding_io(nvme0, nvme0n1, delay, io_count=100):
    nvme0n1.format(512)
    logging.debug("format done")

    cq = IOCQ(nvme0, 1, 128, PRP(1024 * 64))
    sq = IOSQ(nvme0, 1, 128, PRP(1024 * 64), cqid=1)

    write_cmd = SQE(1, 1)
    write_cmd[12] = 7  # 4K write
    buf_list = []
    for i in range(io_count):
        buf = PRP(ptype=32, pvalue=i)  # use cid as data pattern
        buf_list.append(buf)
        write_cmd.prp1 = buf
        write_cmd.cid = i
        write_cmd[10] = i
        sq[i] = write_cmd
    sq.tail = io_count

    # reset while io is active
    logging.debug("write done")
    time.sleep(delay)
    nvme0.reset()

    # read after reset with outstanding writes
    cq = IOCQ(nvme0, 1, 128, PRP(1024 * 64))
    sq = IOSQ(nvme0, 1, 128, PRP(1024 * 64), cqid=1)

    read_cmd = SQE(2, 1)
    read_cmd[12] = 7  # 4K read
    buf_list = []
    for i in range(io_count):
        buf = PRP()
        buf_list.append(buf)
        read_cmd.prp1 = buf
        read_cmd.cid = i
        read_cmd[10] = i
        sq[i] = read_cmd
    sq.tail = io_count
    logging.debug("read done")

    # data verify
    time.sleep(3)
    assert cq[io_count - 1].p != 0
    for i in range(io_count):
        cid = cq[i].cid
        dp = buf_list[cq[i].cid].data(3, 0)  # check data pattern
        logging.debug("cpl %d: cid %d, data pattern %d" % (i, cid, dp))
        assert dp == 0 or dp == cid

    sq.delete()
    cq.delete()
示例#24
0
def test_sq_overflow(nvme0):
    cq = IOCQ(nvme0, 1, 5, PRP())
    sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1)

    # send commands
    sq[0] = SQE(4 << 16 + 0, 1)
    sq.tail = 1
    time.sleep(0.1)
    sq[1] = SQE(3 << 16 + 0, 1)
    sq.tail = 0
    time.sleep(0.1)

    # check cq
    assert cq[0][3] == 0x10004
    assert cq[1][3] == 0x10003
    assert cq[2][3] == 0

    time.sleep(1)
    assert cq[2][3] == 0
    assert cq[3][3] == 0
    assert cq[4][3] == 0
    logging.debug(sq[0])
    logging.debug(cq[0])

    sq.delete()
    cq.delete()
示例#25
0
def test_controller_cc_en(nvme0):
    en=nvme0[0x14]&0x1
    logging.info("en:{}".format(en))
    logging.info("cc:{}".format(nvme0[0x14]))
    assert nvme0[0x14] == 0x00460001

    cq = IOCQ(nvme0, 1, 3, PRP())
    sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1)
    sq[0] = SQE(2, 1); sq.tail = 1; time.sleep(0.1)
    # check cq
    time.sleep(0.1)
    assert (cq[0][3]>>17)&0x3ff == 0x0000

    sq.delete()
    cq.delete()

    #change cc.en from '1' to '0'
    nvme0[0x14] = 0

    #wait csts.rdy change from '1' to '0'
    while not (nvme0[0x1c]&0x1)==0:
        pass

    nvme0.aer()
    try:
        nvme0.waitdone()
    except Exception as e:
        logging.warning(e)

    if 0 != nvme0.init_adminq():
        raise NvmeEnumerateError("fail to init admin queue")

    #change cc.en from '0' to '1'
    nvme0[0x14] = 0x00460001

    #wait csts.rdy change from '0' to '1'
    while not (nvme0[0x1c]&0x1)==1:
        pass

    assert nvme0[0x14] ==0x00460001
示例#26
0
def test_sq_overflow(nvme0):
    cq = IOCQ(nvme0, 1, 5, PRP())
    sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1)

    # send commands
    sq[0] = SQE(4<<16+0, 1); sq.tail = 1
    sq[1] = SQE(3<<16+0, 1); sq.tail = 0
    sq[0] = SQE(2<<16+0, 1); sq.tail = 0
    with pytest.warns(UserWarning, match="AER notification is triggered: 0x10100"):
        nvme0.getfeatures(7).waitdone()

    # check cq
    time.sleep(0.1)
    assert cq[0][3] == 0x10004
    assert cq[1][3] == 0x10003
    assert cq[2][3] == 0

    time.sleep(1)
    assert cq[2][3] == 0
    assert cq[3][3] == 0
    assert cq[4][3] == 0
    logging.info(sq[0])
    logging.info(cq[0])

    sq.delete()
    cq.delete()
示例#27
0
def test_invalid_offset_prp_in_list(nvme0):
    cq = IOCQ(nvme0, 1, 10, PRP())
    sq = IOSQ(nvme0, 1, 10, PRP(), cqid=1)

    buf = PRP(ptype=32, pvalue=0xffffffff)
    buf.offset = 0x10

    prp_list = PRPList()
    prp_list.offset = 0x20

    for i in range(8):
        tmp = PRP(ptype=32, pvalue=0xffffffff)
        tmp.offset = 0x10
        prp_list[i] = tmp

    logging.info(prp_list.dump(64))
    print(buf.dump(32))
    for i in range(8):
        print(prp_list[i].dump(32))

    cmd = SQE(2, 1)
    cmd.prp1 = buf
    cmd.prp2 = prp_list
    cmd[12] = 0x4000001f
    sq[0] = cmd
    logging.info(sq[0])
    sq.tail = 1
    while CQE(cq[0]).p == 0:
        pass
    cq.head = 1
    logging.info(cq[0])
    logging.info(hex(cq[0][3] >> 17))
    print(buf.dump(32))
    for i in range(8):
        print(prp_list[i].dump(32))
    status = (cq[0][3] >> 17) & 0x3ff
    assert status == 0x0013 or status == 0

    sq.delete()
    cq.delete()
示例#28
0
def test_delete_cq_with_sq(nvme0, nsq=3, sqid=2):
    cq = IOCQ(nvme0, 2, 10, PRP(4096))
    sq_list = []
    for i in range(nsq):
        sq_list.append(IOSQ(nvme0, sqid + i, 10, PRP(4096), cqid=2))

    # delete cq before corresponding sq
    with pytest.warns(UserWarning, match="ERROR status: 01/0c"):
        cq.delete()

    for sq in sq_list:
        sq.delete()
    cq.delete()
示例#29
0
def test_controller_cap_mqes(nvme0):
    mqes = 1+(nvme0.cap&0xffff)
    logging.info(mqes)
    assert mqes >= 2
    
    if mqes == 64*1024:
        pytest.skip("mqes is maximum")

    with pytest.warns(UserWarning, match="ERROR status: 01/02"):
        cq = IOCQ(nvme0, 1, mqes+1, PRP())

    cq = IOCQ(nvme0, 1, mqes, PRP())
    with pytest.warns(UserWarning, match="ERROR status: 01/02"):
        sq = IOSQ(nvme0, 1, mqes+1, PRP(), cqid=1)
示例#30
0
def test_weighed_round_robin(nvme0):
    if (nvme0.cap >> 17) & 0x1 == 0:
        pytest.skip("WRR is not supported")

    assert nvme0[0x14] == 0x00460801
    nvme0.setfeatures(1, cdw11=0x07030103).waitdone()
    cdw0 = nvme0.getfeatures(1).waitdone()
    assert cdw0 == 0x07030103

    start = time.time()
    nvme0.getfeatures(7).waitdone()
    logging.info("admin latency: %f" % (time.time() - start))

    # create the senario of Figure 138 in NVMe spec v1.4
    # 1 admin, 2 urgent, 2 high, 2 medium, 2 low
    sq_list = []
    cq = IOCQ(nvme0, 1, 1024, PRP(1024 * 64))
    for i in range(8):
        sq_list.append(
            IOSQ(nvme0, i + 1, 128, PRP(128 * 64), cqid=1, qprio=i // 2))

    # fill 100 flush commands in each queue
    for sq in sq_list:
        for i in range(100):
            sq[i] = SQE(i << 16 + 0, 1)

    # fire all sq, low prio first
    for sq in sq_list[::-1]:
        sq.tail = 100

    # check the latency of admin command
    start = time.time()
    nvme0.getfeatures(7).waitdone()
    logging.info("admin latency when IO busy: %f" % (time.time() - start))

    # check sqid of the whole cq
    time.sleep(3)
    logging.info([cq[i][2] >> 16 for i in range(100 * 8)])
    # assert all urgent IO completed first
    last_sqid = {cq[i][2] >> 16 for i in range(300, 800)}
    logging.debug(last_sqid)
    assert 1 not in last_sqid
    assert 2 not in last_sqid

    # delete all queues
    for sq in sq_list:
        sq.delete()
    cq.delete()