Nvme部分

目前维护的版本是76a9d8e333f081a9df30b5f8706e9be81517665c,"Update ZNS support statements"

基本数据结构

FemuCtrl

typedef struct FemuCtrl {
    PCIDevice       parent_obj;
    MemoryRegion    iomem;
    MemoryRegion    ctrl_mem;
    NvmeBar         bar;

    /* Coperd: ZNS FIXME */
    QemuUUID        uuid;
    uint32_t        zasl_bs;
    uint8_t         zasl;
    bool            zoned;
    bool            cross_zone_read;
    uint64_t        zone_size_bs;
    bool            zone_cap_bs;
    uint32_t        max_active_zones;
    uint32_t        max_open_zones;
    uint32_t        zd_extension_size;

    const uint32_t  *iocs;
    uint8_t         csi;
    NvmeIdNsZoned   *id_ns_zoned;
    NvmeZone        *zone_array;
    QTAILQ_HEAD(, NvmeZone) exp_open_zones;
    QTAILQ_HEAD(, NvmeZone) imp_open_zones;
    QTAILQ_HEAD(, NvmeZone) closed_zones;
    QTAILQ_HEAD(, NvmeZone) full_zones;
    uint32_t        num_zones;
    uint64_t        zone_size;
    uint64_t        zone_capacity;
    uint32_t        zone_size_log2;
    uint8_t         *zd_extensions;
    int32_t         nr_open_zones;
    int32_t         nr_active_zones;

    /* Coperd: OC2.0 FIXME */
    NvmeParams  params;
    FemuExtCtrlOps ext_ops;

    time_t      start_time;
    uint16_t    temperature;
    uint16_t    page_size;
    uint16_t    page_bits;
    uint16_t    max_prp_ents;
    uint16_t    cqe_size;
    uint16_t    sqe_size;
    uint16_t    oacs;
    uint16_t    oncs;
    uint32_t    reg_size;
    uint32_t    num_namespaces;
    uint32_t    num_io_queues;
    uint32_t    max_q_ents;
    uint64_t    ns_size;
    uint8_t     db_stride;
    uint8_t     aerl;
    uint8_t     acl;
    uint8_t     elpe;
    uint8_t     elp_index;
    uint8_t     error_count;
    uint8_t     mdts;
    uint8_t     cqr;
    uint8_t     max_sqes;
    uint8_t     max_cqes;
    uint8_t     meta;
    uint8_t     vwc;
    uint8_t     mc;
    uint8_t     dpc;
    uint8_t     dps;
    uint8_t     nlbaf;
    uint8_t     extended;
    uint8_t     lba_index;
    uint8_t     mpsmin;
    uint8_t     mpsmax;
    uint8_t     ms;
    uint8_t     ms_max;
    uint8_t     intc;
    uint8_t     intc_thresh;
    uint8_t     intc_time;
    uint8_t     outstanding_aers;
    uint8_t     temp_warn_issued;
    uint8_t     num_errors;
    uint8_t     cqes_pending;
    uint16_t    vid;
    uint16_t    did;
    uint8_t     dlfeat;
    uint32_t    cmbsz;
    uint32_t    cmbloc;
    uint8_t     *cmbuf;

    QemuThread  *poller;
    bool        dataplane_started;
    bool        vector_poll_started;

    char            *serial;
    NvmeErrorLog    *elpes;
    NvmeRequest     **aer_reqs;
    NvmeNamespace   *namespaces;
    NvmeSQueue      **sq;
    NvmeCQueue      **cq;
    NvmeSQueue      admin_sq;
    NvmeCQueue      admin_cq;
    NvmeFeatureVal  features;
    NvmeIdCtrl      id_ctrl;

    QSIMPLEQ_HEAD(aer_queue, NvmeAsyncEvent) aer_queue;
    QEMUTimer       *aer_timer;
    uint8_t         aer_mask;

    uint64_t        dbs_addr;
    uint64_t        eis_addr;
    uint64_t        dbs_addr_hva;
    uint64_t        eis_addr_hva;

    uint8_t         femu_mode;
    uint8_t         lver; /* Coperd: OCSSD version, 0x1 -> OC1.2, 0x2 -> OC2.0 */
    uint32_t        memsz;
    OcCtrlParams    oc_params;

    Oc12Ctrl  *oc12_ctrl;
    volatile int64_t chip_next_avail_time[FEMU_MAX_NUM_CHIPS];
    pthread_spinlock_t chip_locks[FEMU_MAX_NUM_CHIPS];
    volatile int64_t chnl_next_avail_time[FEMU_MAX_NUM_CHNLS];
    pthread_spinlock_t chnl_locks[FEMU_MAX_NUM_CHNLS];

    /* Latency numbers for whitebox-mode only */
    int64_t upg_rd_lat_ns; /* upper page in MLC/TLC/QLC */
    int64_t cpg_rd_lat_ns; /* center page in TLC */
    int64_t cupg_rd_lat_ns; /* center-upper page in QLC */
    int64_t clpg_rd_lat_ns; /* center-lower page in QLC */
    int64_t lpg_rd_lat_ns; /* lower page in MLC/TLC/QLC */
    int64_t upg_wr_lat_ns;
    int64_t cpg_wr_lat_ns;
    int64_t cupg_wr_lat_ns;
    int64_t clpg_wr_lat_ns;
    int64_t lpg_wr_lat_ns;
    int64_t blk_er_lat_ns;
    int64_t chnl_pg_xfer_lat_ns;

    struct ssd      *ssd;
    SsdDramBackend  *mbe;
    int             completed;

    char            devname[64];
    struct rte_ring **to_ftl;
    struct rte_ring **to_poller;
    pqueue_t        **pq;
    bool            *should_isr;
    bool            poller_on;

    int64_t         nr_tt_ios;
    int64_t         nr_tt_late_ios;
    bool            print_log;

    uint8_t         multipoller_enabled;
    uint32_t        num_poller;

    /* Nand Flash Type: SLC/MLC/TLC/QLC/PLC */
    uint8_t         flash_type;
} FemuCtrl;

基本函数

nvme_check_sqid

int nvme_check_sqid(FemuCtrl *n, uint16_t sqid)

  函数的输入是FemuCtrl和一个sqid,主要是用来判断sqid的合理性:

  1. sqid不大于n->num_io_queues;

  2. n->sq[sqid]!=NULL

  上述两个条件同时满足,才是一个合理的sqid,返回0;否则返回-1;

nvme_check_cqid

int nvme_check_sqid(FemuCtrl *n, uint16_t cqid)

  函数的输入是FemuCtrl和一个cqid,主要是用来判断cqid的合理性:

  1. cqid不大于n->num_io_queues;

  2. n->cq[cqid]!=NULL

  上述两个条件同时满足,才是一个合理的cqid,返回0;否则返回-1;

nvme_inc_cq_tail

void nvme_inc_cq_tail(NvmeCQueue *cq)

Last updated

Was this helpful?