ioat: allow ring to be physically discontiguous

The IOAT "ring" is actually just a circular linked list of descriptors;
the descriptors do not need to be in a single physically contiguous
region.  This can be accomodated by calling spdk_vtophys() on each
descriptor rather than assuming they are all in a single contiguous
region.

Also store the physical address of each descriptor in its associated
software descriptor context to avoid the need to call spdk_vtophys()
during runtime.

Change-Id: Ic8636bbc61deb496a0c6d0ea56b75d298f5f426c
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/417782
Reviewed-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
Daniel Verkamp 2018-07-03 10:15:41 -07:00 committed by Changpeng Liu
parent 2470278c92
commit 104fa6e722
2 changed files with 13 additions and 12 deletions

View File

@ -151,13 +151,6 @@ ioat_get_ring_entry(struct spdk_ioat_chan *ioat, uint32_t index,
*hw_desc = &ioat->hw_ring[i];
}
static uint64_t
ioat_get_desc_phys_addr(struct spdk_ioat_chan *ioat, uint32_t index)
{
return ioat->hw_ring_phys_addr +
ioat_get_ring_index(ioat, index) * sizeof(union spdk_ioat_hw_desc);
}
static void
ioat_submit_single(struct spdk_ioat_chan *ioat)
{
@ -336,7 +329,7 @@ ioat_process_channel_events(struct spdk_ioat_chan *ioat)
desc->callback_fn(desc->callback_arg);
}
hw_desc_phys_addr = ioat_get_desc_phys_addr(ioat, ioat->tail);
hw_desc_phys_addr = desc->phys_addr;
ioat->tail++;
} while (hw_desc_phys_addr != completed_descriptor);
@ -372,6 +365,7 @@ ioat_channel_start(struct spdk_ioat_chan *ioat)
uint64_t status;
int i, num_descriptors;
uint64_t comp_update_bus_addr = 0;
uint64_t phys_addr;
if (ioat_map_pci_bar(ioat) != 0) {
SPDK_ERRLOG("ioat_map_pci_bar() failed\n");
@ -421,13 +415,20 @@ ioat_channel_start(struct spdk_ioat_chan *ioat)
}
ioat->hw_ring = spdk_dma_zmalloc(num_descriptors * sizeof(union spdk_ioat_hw_desc), 64,
&ioat->hw_ring_phys_addr);
NULL);
if (!ioat->hw_ring) {
return -1;
}
for (i = 0; i < num_descriptors; i++) {
ioat->hw_ring[i].generic.next = ioat_get_desc_phys_addr(ioat, i + 1);
phys_addr = spdk_vtophys(&ioat->hw_ring[i]);
if (phys_addr == SPDK_VTOPHYS_ERROR) {
SPDK_ERRLOG("Failed to translate descriptor %u to physical address\n", i);
return -1;
}
ioat->ring[i].phys_addr = phys_addr;
ioat->hw_ring[ioat_get_ring_index(ioat, i - 1)].generic.next = phys_addr;
}
ioat->head = 0;
@ -438,7 +439,7 @@ ioat_channel_start(struct spdk_ioat_chan *ioat)
ioat->regs->chanctrl = SPDK_IOAT_CHANCTRL_ANY_ERR_ABORT_EN;
ioat_write_chancmp(ioat, comp_update_bus_addr);
ioat_write_chainaddr(ioat, ioat->hw_ring_phys_addr);
ioat_write_chainaddr(ioat, ioat->ring[0].phys_addr);
ioat_prep_null(ioat);
ioat_flush(ioat);

View File

@ -45,6 +45,7 @@
#define IOAT_DEFAULT_ORDER 15
struct ioat_descriptor {
uint64_t phys_addr;
spdk_ioat_req_cb callback_fn;
void *callback_arg;
};
@ -66,7 +67,6 @@ struct spdk_ioat_chan {
struct ioat_descriptor *ring;
union spdk_ioat_hw_desc *hw_ring;
uint64_t hw_ring_phys_addr;
uint32_t dma_capabilities;
/* tailq entry for attached_chans */