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:
parent
2470278c92
commit
104fa6e722
@ -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);
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user