Commit 104fa6e7 authored by Daniel Verkamp's avatar Daniel Verkamp Committed by Changpeng Liu
Browse files

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: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/417782


Reviewed-by: default avatarDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
parent 2470278c
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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 */