nvme_pci: Correct bug in CMB allocation
There was a bug reported by Cunyin Chang with regards to how the cmb_current_offset was calculated when the CMB offset into the CMB BAR is non-zero. This patch fixes this issue and also fixes the problem that the last valid offset into the BAR *may* differ if registration is utilized or not (due to the 2MiB alignment and length requirements for registered memory). Change-Id: Id08d6a5a40b828338f6a66599171cc8dd59768a3 Signed-off-by: Stephen Bates <sbates@raithlin.com> Reviewed-on: https://review.gerrithub.io/401832 Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
736f6937f6
commit
627bee96a4
@ -85,9 +85,12 @@ struct nvme_pcie_ctrlr {
|
|||||||
/* Controller memory buffer size in Bytes */
|
/* Controller memory buffer size in Bytes */
|
||||||
uint64_t cmb_size;
|
uint64_t cmb_size;
|
||||||
|
|
||||||
/* Current offset of controller memory buffer */
|
/* Current offset of controller memory buffer, relative to start of BAR virt addr */
|
||||||
uint64_t cmb_current_offset;
|
uint64_t cmb_current_offset;
|
||||||
|
|
||||||
|
/* Last valid offset into CMB, this differs if CMB memory registration occurs or not */
|
||||||
|
uint64_t cmb_max_offset;
|
||||||
|
|
||||||
void *cmb_mem_register_addr;
|
void *cmb_mem_register_addr;
|
||||||
size_t cmb_mem_register_size;
|
size_t cmb_mem_register_size;
|
||||||
|
|
||||||
@ -490,6 +493,7 @@ nvme_pcie_ctrlr_map_cmb(struct nvme_pcie_ctrlr *pctrlr)
|
|||||||
pctrlr->cmb_bar_phys_addr = bar_phys_addr;
|
pctrlr->cmb_bar_phys_addr = bar_phys_addr;
|
||||||
pctrlr->cmb_size = size;
|
pctrlr->cmb_size = size;
|
||||||
pctrlr->cmb_current_offset = offset;
|
pctrlr->cmb_current_offset = offset;
|
||||||
|
pctrlr->cmb_max_offset = offset + size;
|
||||||
|
|
||||||
if (!cmbsz.bits.sqs) {
|
if (!cmbsz.bits.sqs) {
|
||||||
pctrlr->ctrlr.opts.use_cmb_sqs = false;
|
pctrlr->ctrlr.opts.use_cmb_sqs = false;
|
||||||
@ -516,7 +520,8 @@ nvme_pcie_ctrlr_map_cmb(struct nvme_pcie_ctrlr *pctrlr)
|
|||||||
SPDK_ERRLOG("spdk_mem_register() failed\n");
|
SPDK_ERRLOG("spdk_mem_register() failed\n");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
pctrlr->cmb_current_offset = mem_register_start - ((uint64_t)pctrlr->cmb_bar_virt_addr + offset);
|
pctrlr->cmb_current_offset = mem_register_start - ((uint64_t)pctrlr->cmb_bar_virt_addr);
|
||||||
|
pctrlr->cmb_max_offset = mem_register_end - ((uint64_t)pctrlr->cmb_bar_virt_addr);
|
||||||
pctrlr->cmb_io_data_supported = true;
|
pctrlr->cmb_io_data_supported = true;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -557,7 +562,9 @@ nvme_pcie_ctrlr_alloc_cmb(struct spdk_nvme_ctrlr *ctrlr, uint64_t length, uint64
|
|||||||
round_offset = pctrlr->cmb_current_offset;
|
round_offset = pctrlr->cmb_current_offset;
|
||||||
round_offset = (round_offset + (aligned - 1)) & ~(aligned - 1);
|
round_offset = (round_offset + (aligned - 1)) & ~(aligned - 1);
|
||||||
|
|
||||||
if (round_offset + length > pctrlr->cmb_size) {
|
/* CMB may only consume part of the BAR, calculate accordingly */
|
||||||
|
if (round_offset + length > pctrlr->cmb_max_offset) {
|
||||||
|
SPDK_ERRLOG("Tried to allocate past valid CMB range!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user