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];
|
*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
|
static void
|
||||||
ioat_submit_single(struct spdk_ioat_chan *ioat)
|
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);
|
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++;
|
ioat->tail++;
|
||||||
} while (hw_desc_phys_addr != completed_descriptor);
|
} while (hw_desc_phys_addr != completed_descriptor);
|
||||||
|
|
||||||
@ -372,6 +365,7 @@ ioat_channel_start(struct spdk_ioat_chan *ioat)
|
|||||||
uint64_t status;
|
uint64_t status;
|
||||||
int i, num_descriptors;
|
int i, num_descriptors;
|
||||||
uint64_t comp_update_bus_addr = 0;
|
uint64_t comp_update_bus_addr = 0;
|
||||||
|
uint64_t phys_addr;
|
||||||
|
|
||||||
if (ioat_map_pci_bar(ioat) != 0) {
|
if (ioat_map_pci_bar(ioat) != 0) {
|
||||||
SPDK_ERRLOG("ioat_map_pci_bar() failed\n");
|
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 = spdk_dma_zmalloc(num_descriptors * sizeof(union spdk_ioat_hw_desc), 64,
|
||||||
&ioat->hw_ring_phys_addr);
|
NULL);
|
||||||
if (!ioat->hw_ring) {
|
if (!ioat->hw_ring) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_descriptors; i++) {
|
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;
|
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->regs->chanctrl = SPDK_IOAT_CHANCTRL_ANY_ERR_ABORT_EN;
|
||||||
ioat_write_chancmp(ioat, comp_update_bus_addr);
|
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_prep_null(ioat);
|
||||||
ioat_flush(ioat);
|
ioat_flush(ioat);
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#define IOAT_DEFAULT_ORDER 15
|
#define IOAT_DEFAULT_ORDER 15
|
||||||
|
|
||||||
struct ioat_descriptor {
|
struct ioat_descriptor {
|
||||||
|
uint64_t phys_addr;
|
||||||
spdk_ioat_req_cb callback_fn;
|
spdk_ioat_req_cb callback_fn;
|
||||||
void *callback_arg;
|
void *callback_arg;
|
||||||
};
|
};
|
||||||
@ -66,7 +67,6 @@ struct spdk_ioat_chan {
|
|||||||
|
|
||||||
struct ioat_descriptor *ring;
|
struct ioat_descriptor *ring;
|
||||||
union spdk_ioat_hw_desc *hw_ring;
|
union spdk_ioat_hw_desc *hw_ring;
|
||||||
uint64_t hw_ring_phys_addr;
|
|
||||||
uint32_t dma_capabilities;
|
uint32_t dma_capabilities;
|
||||||
|
|
||||||
/* tailq entry for attached_chans */
|
/* tailq entry for attached_chans */
|
||||||
|
Loading…
Reference in New Issue
Block a user