示例#1
0
def test_sq_cq_around(nvme0):
    cq = IOCQ(nvme0, 1, 3, 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 = 1
    sq[1] = SQE(1<<16+0, 1); sq.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[0][3] == 0x10004
    assert cq[2][3] == 0x10002
    cq.head = 2
    assert cq[2][3] == 0x10002
    assert cq[1][3] == 0x10003
    assert cq[0][3] == 0x00001

    sq.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_another_sq(nvme0):
    cq = IOCQ(nvme0, 1, 3, PRP())

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

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

    # 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)
    assert cq[0][3] == 0x00001

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

    # send commands, and check cqe
    sq[0] = SQE(4 << 16 + 0, 1)
    sq.tail = 1
    time.sleep(0.1)
    assert cq[0][2] == 0x10001
    assert cq[0][3] == 0x10004
    assert cq[1][2] == 0
    assert cq[2][2] == 0

    # send commands, and check cqe
    sq[1] = SQE(3 << 16 + 0, 1)
    sq.tail = 0
    time.sleep(0.1)
    assert cq[0][2] == 0x10001
    assert cq[0][3] == 0x10004
    assert cq[1][2] == 0x10000
    assert cq[1][3] == 0x10003
    assert cq[2][2] == 0

    # send commands, and check cqe
    sq[0] = SQE(2 << 16 + 0, 1)
    sq.tail = 1
    time.sleep(0.1)
    assert cq[0][2] == 0x10001
    assert cq[0][3] == 0x10004
    assert cq[1][2] == 0x10000
    assert cq[1][3] == 0x10003
    assert cq[2][2] == 0

    # free one cqe before get 3rd cqe
    cq.head = 1
    time.sleep(0.1)
    assert cq[2][2] == 0x10001
    assert cq[2][3] == 0x10002

    # send commands, and check cqe
    sq[1] = SQE(1 << 16 + 0, 1)
    sq.tail = 0
    time.sleep(0.1)
    cq.head = 2
    time.sleep(0.1)
    assert cq[0][2] == 0x10000
    assert cq[0][3] == 0x00001
    assert cq[1][2] == 0x10000
    assert cq[1][3] == 0x10003
    assert cq[2][2] == 0x10001
    assert cq[2][3] == 0x10002
示例#5
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()
示例#6
0
def test_cq_doorbell_invalid(nvme0, head):
    cq = IOCQ(nvme0, 1, 5, PRP())
    sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1)
    sq.tail = 1

    time.sleep(0.1)
    cq.head = head
    #Invalid Doorbell Write Value
    with pytest.warns(UserWarning, match="AER notification is triggered: 0x10100"):
        nvme0.getfeatures(7).waitdone()
    sq.delete()
    cq.delete()
示例#7
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()
示例#8
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
示例#9
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()
示例#10
0
def test_p_invert_after_cq_2_pass(nvme0):
    """
    The value of the Phase Tag is inverted each pass filling the Complete Queue.
    """

    # cqid: 1, PC, depth: 2
    cq = IOCQ(nvme0, 1, 2, PRP())

    # create four SQ, both use the same CQ
    sq3 = IOSQ(nvme0, 3, 10, PRP(), cqid=1)

    # IO command templates: opcode and namespace
    write_cmd = SQE(1, 1)

    # write in sq3
    w1 = SQE(*write_cmd)
    write_buf = PRP(ptype=32, pvalue=0xaaaaaaaa)
    w1.prp1 = write_buf
    w1[10] = 1
    w1[12] = 1 # 0based
    w1.cid = 0x123
    sq3[0] = w1
    sq3.tail = 1

    # add some delay, so ssd should finish w1 before w2
    time.sleep(0.1)

    # write in sq5
    w1.cid = 0x567
    sq3[1] = w1
    sq3.tail = 2

    logging.info("aaa")
    # cqe for w1
    while CQE(cq[0]).p == 0: pass
    cqe = CQE(cq[0])
    assert cqe.cid == 0x123
    assert cqe.sqid == 3
    assert cqe.sqhd == 1
    cq.head = 1

    # cqe for w2
    logging.info("bbb")
    while CQE(cq[1]).p == 0: pass
    logging.info("ccc")
    cqe = CQE(cq[1])
    assert cqe.cid == 0x567
    assert cqe.sqid == 3
    assert cqe.sqhd == 2
    cq.head = 0

    assert CQE(cq[0]).p == 1
    assert CQE(cq[1]).p == 1

    # write in sq3
    w1.cid = 0x147
    sq3[2] = w1
    sq3.tail = 3

    # add some delay, so ssd should finish w1 before w2
    time.sleep(0.1)

    # write in sq5
    w1.cid = 0x167
    sq3[3] = w1
    sq3.tail = 4

    # cqe for w3
    while CQE(cq[0]).p == 1: pass
    cqe = CQE(cq[0])
    assert cqe.cid == 0x147
    assert cqe.sqid == 3
    assert cqe.sqhd == 3
    cq.head = 1

    # cqe for w4
    while CQE(cq[1]).p == 1: pass
    cqe = CQE(cq[1])
    assert cqe.cid == 0x167
    assert cqe.sqid == 3
    assert cqe.sqhd == 4
    cq.head = 0

    assert CQE(cq[0]).p == 0
    assert CQE(cq[1]).p == 0
示例#11
0
def test_controller_mdts(nvme0,nvme0n1):
    if nvme0.mdts == 1024*1024: # up to 1MB
        pytest.skip("mdts is maximum")

    mps_min = (nvme0.cap>>48) & 0xf
    logging.info("mps_min:{}".format(mps_min))

    mdts=nvme0.id_data(77,77)
    logging.info("mdts:{}".format(mdts))
    max_data_size=(2**mdts)*(2**(12+mps_min))
    logging.info(max_data_size)
    max_pages=max_data_size//4//1024
    pages=max_pages-1
    max_lba=max_data_size//512

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

    # prp for the long buffer
    write_buf_1 = PRP(ptype=32, pvalue=0xaaaaaaaa)
    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] = max_lba-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
    assert cqe.status == 0
    cq.head = 1

    w2 = SQE(1, 1)
    w2.prp1 = write_buf_1
    w2.prp2 = prp_list_head
    w2[12] = max_lba # 0based, nlba
    w2.cid = 0x234
    sq[1] = w2
    sq.tail = 2

    time.sleep(1)
    cqe = CQE(cq[1])
    logging.info(cqe)
    assert cqe.p == 1
    assert cqe.cid == 0x234
    assert cqe.sqhd == 2
    assert cqe.status == 2
    cq.head = 2

    r1 = SQE(2, 1)
    r1.prp1 = write_buf_1
    r1.prp2 = prp_list_head
    r1[12] = max_lba # 0based, nlba
    r1.cid = 0x345
    sq[2] = r1
    sq.tail = 3

    time.sleep(1)
    cqe = CQE(cq[2])
    logging.info(cqe)
    assert cqe.p == 1
    assert cqe.cid == 0x345
    assert cqe.sqhd == 3
    assert cqe.status == 2
    cq.head = 3

    r2 = SQE(2, 1)
    r2.prp1 = write_buf_1
    r2.prp2 = prp_list_head
    r2[12] = max_lba-1 # 0based, nlba
    r2.cid = 0x456
    sq[3] = r2
    sq.tail = 4

    time.sleep(1)
    cqe = CQE(cq[3])
    logging.info(cqe)
    assert cqe.p == 1
    assert cqe.cid == 0x456
    assert cqe.sqhd == 4
    assert cqe.status == 0
    cq.head = 4

    sq.delete()
    cq.delete()