diff --git a/CHANGELOG.md b/CHANGELOG.md index 6058888c3..54189ade4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,9 @@ chained accelerated CRC32 computation support. ### nvme +Added new functions `spdk_nvme_ctrlr_get_pmrsz`, `spdk_nvme_ctrlr_enable_pmr`, +`spdk_nvme_ctrlr_disable_pmr`, `spdk_nvme_ctrlr_map_pmr` and `spdk_nvme_ctrlr_unmap_pmr`. + Added NVMe transport operations to enable, disable, map and unmap the PMR. Added `spdk_nvme_qpair_get_optimal_poll_group` function and `qpair_get_optimal_poll_group` diff --git a/include/spdk/nvme.h b/include/spdk/nvme.h index f2d4f8640..f5a8f73c9 100644 --- a/include/spdk/nvme.h +++ b/include/spdk/nvme.h @@ -1094,6 +1094,15 @@ union spdk_nvme_cmbsz_register spdk_nvme_ctrlr_get_regs_cmbsz(struct spdk_nvme_c */ union spdk_nvme_pmrcap_register spdk_nvme_ctrlr_get_regs_pmrcap(struct spdk_nvme_ctrlr *ctrlr); +/** + * Get the NVMe controller PMR size. + * + * \param ctrlr Opaque handle to NVMe controller. + * + * \return the NVMe controller PMR size or 0 if PMR is not supported. + */ +uint64_t spdk_nvme_ctrlr_get_pmrsz(struct spdk_nvme_ctrlr *ctrlr); + /** * Get the number of namespaces for the given NVMe controller. * @@ -2227,6 +2236,56 @@ void *spdk_nvme_ctrlr_map_cmb(struct spdk_nvme_ctrlr *ctrlr, size_t *size); */ void spdk_nvme_ctrlr_unmap_cmb(struct spdk_nvme_ctrlr *ctrlr); +/** + * Enable the Persistent Memory Region + * + * \param ctrlr Controller that contains the Persistent Memory Region + * + * \return 0 on success. Negated errno on the following error conditions: + * -ENOTSUP: PMR is not supported by the Controller. + * -EIO: Registers access failure. + * -EINVAL: PMR Time Units Invalid or PMR is already enabled. + * -ETIMEDOUT: Timed out to Enable PMR. + * -ENOSYS: Transport does not support Enable PMR function. + */ +int spdk_nvme_ctrlr_enable_pmr(struct spdk_nvme_ctrlr *ctrlr); + +/** + * Disable the Persistent Memory Region + * + * \param ctrlr Controller that contains the Persistent Memory Region + * + * \return 0 on success. Negated errno on the following error conditions: + * -ENOTSUP: PMR is not supported by the Controller. + * -EIO: Registers access failure. + * -EINVAL: PMR Time Units Invalid or PMR is already disabled. + * -ETIMEDOUT: Timed out to Disable PMR. + * -ENOSYS: Transport does not support Disable PMR function. + */ +int spdk_nvme_ctrlr_disable_pmr(struct spdk_nvme_ctrlr *ctrlr); + +/** + * Map the Persistent Memory Region so that it's data is + * visible from the CPU. + * + * \param ctrlr Controller that contains the Persistent Memory Region + * \param size Size of the region that was mapped. + * + * \return Pointer to Persistent Memory Region, or NULL on failure. + */ +void *spdk_nvme_ctrlr_map_pmr(struct spdk_nvme_ctrlr *ctrlr, size_t *size); + +/** + * Free the Persistent Memory Region. + * + * \param ctrlr Controller from which to unmap the Persistent Memory Region. + * + * \return 0 on success, negative errno on failure. + * -ENXIO: Either PMR is not supported by the Controller or the PMR is already unmapped. + * -ENOSYS: Transport does not support Unmap PMR function. + */ +int spdk_nvme_ctrlr_unmap_pmr(struct spdk_nvme_ctrlr *ctrlr); + /** * Get the transport ID for a given NVMe controller. * diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index dc95ff734..d15ebdd73 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -3614,6 +3614,12 @@ union spdk_nvme_pmrcap_register spdk_nvme_ctrlr_get_regs_pmrcap(struct spdk_nvme return pmrcap; } +uint64_t +spdk_nvme_ctrlr_get_pmrsz(struct spdk_nvme_ctrlr *ctrlr) +{ + return ctrlr->pmr_size; +} + uint32_t spdk_nvme_ctrlr_get_num_ns(struct spdk_nvme_ctrlr *ctrlr) { @@ -4093,6 +4099,54 @@ spdk_nvme_ctrlr_unmap_cmb(struct spdk_nvme_ctrlr *ctrlr) nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock); } +int +spdk_nvme_ctrlr_enable_pmr(struct spdk_nvme_ctrlr *ctrlr) +{ + int rc; + + nvme_robust_mutex_lock(&ctrlr->ctrlr_lock); + rc = nvme_transport_ctrlr_enable_pmr(ctrlr); + nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock); + + return rc; +} + +int +spdk_nvme_ctrlr_disable_pmr(struct spdk_nvme_ctrlr *ctrlr) +{ + int rc; + + nvme_robust_mutex_lock(&ctrlr->ctrlr_lock); + rc = nvme_transport_ctrlr_disable_pmr(ctrlr); + nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock); + + return rc; +} + +void * +spdk_nvme_ctrlr_map_pmr(struct spdk_nvme_ctrlr *ctrlr, size_t *size) +{ + void *buf; + + nvme_robust_mutex_lock(&ctrlr->ctrlr_lock); + buf = nvme_transport_ctrlr_map_pmr(ctrlr, size); + nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock); + + return buf; +} + +int +spdk_nvme_ctrlr_unmap_pmr(struct spdk_nvme_ctrlr *ctrlr) +{ + int rc; + + nvme_robust_mutex_lock(&ctrlr->ctrlr_lock); + rc = nvme_transport_ctrlr_unmap_pmr(ctrlr); + nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock); + + return rc; +} + bool spdk_nvme_ctrlr_is_discovery(struct spdk_nvme_ctrlr *ctrlr) { diff --git a/lib/nvme/spdk_nvme.map b/lib/nvme/spdk_nvme.map index 4881bc768..f9d95dba2 100644 --- a/lib/nvme/spdk_nvme.map +++ b/lib/nvme/spdk_nvme.map @@ -42,6 +42,7 @@ spdk_nvme_ctrlr_get_regs_vs; spdk_nvme_ctrlr_get_regs_cmbsz; spdk_nvme_ctrlr_get_regs_pmrcap; + spdk_nvme_ctrlr_get_pmrsz; spdk_nvme_ctrlr_get_num_ns; spdk_nvme_ctrlr_get_pci_device; spdk_nvme_ctrlr_get_max_xfer_size; @@ -90,6 +91,10 @@ spdk_nvme_ctrlr_reserve_cmb; spdk_nvme_ctrlr_map_cmb; spdk_nvme_ctrlr_unmap_cmb; + spdk_nvme_ctrlr_enable_pmr; + spdk_nvme_ctrlr_disable_pmr; + spdk_nvme_ctrlr_map_pmr; + spdk_nvme_ctrlr_unmap_pmr; spdk_nvme_ctrlr_get_transport_id; spdk_nvme_ctrlr_alloc_qid; spdk_nvme_ctrlr_free_qid; diff --git a/test/unit/lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c b/test/unit/lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c index 6ef4d5454..fa97fd491 100644 --- a/test/unit/lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c +++ b/test/unit/lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c @@ -158,6 +158,30 @@ nvme_transport_ctrlr_unmap_cmb(struct spdk_nvme_ctrlr *ctrlr) return 0; } +int +nvme_transport_ctrlr_enable_pmr(struct spdk_nvme_ctrlr *ctrlr) +{ + return 0; +} + +int +nvme_transport_ctrlr_disable_pmr(struct spdk_nvme_ctrlr *ctrlr) +{ + return 0; +} + +void * +nvme_transport_ctrlr_map_pmr(struct spdk_nvme_ctrlr *ctrlr, size_t *size) +{ + return NULL; +} + +int +nvme_transport_ctrlr_unmap_pmr(struct spdk_nvme_ctrlr *ctrlr) +{ + return 0; +} + struct spdk_nvme_qpair * nvme_transport_ctrlr_create_io_qpair(struct spdk_nvme_ctrlr *ctrlr, uint16_t qid, const struct spdk_nvme_io_qpair_opts *opts)