On 2021/9/17 23:24, Kevin Laatz wrote: > Add data path functions for enqueuing and submitting operations to DSA > devices. > > Signed-off-by: Bruce Richardson <bruce.richard...@intel.com> > Signed-off-by: Kevin Laatz <kevin.la...@intel.com> > Reviewed-by: Conor Walsh <conor.wa...@intel.com> > --- > doc/guides/dmadevs/idxd.rst | 64 +++++++++++++++ > drivers/dma/idxd/idxd_common.c | 136 +++++++++++++++++++++++++++++++ > drivers/dma/idxd/idxd_internal.h | 5 ++ > drivers/dma/idxd/meson.build | 1 + > 4 files changed, 206 insertions(+) >
[snip] > + > +static __rte_always_inline int > +__idxd_write_desc(struct rte_dma_dev *dev, > + const uint32_t op_flags, > + const rte_iova_t src, > + const rte_iova_t dst, > + const uint32_t size, > + const uint32_t flags) > +{ > + struct idxd_dmadev *idxd = dev->dev_private; > + uint16_t mask = idxd->desc_ring_mask; > + uint16_t job_id = idxd->batch_start + idxd->batch_size; > + /* we never wrap batches, so we only mask the start and allow > start+size to overflow */ > + uint16_t write_idx = (idxd->batch_start & mask) + idxd->batch_size; > + > + /* first check batch ring space then desc ring space */ > + if ((idxd->batch_idx_read == 0 && idxd->batch_idx_write == > idxd->max_batches) || > + idxd->batch_idx_write + 1 == idxd->batch_idx_read) > + return -1; > + if (((write_idx + 1) & mask) == (idxd->ids_returned & mask)) > + return -1; Please return -ENOSPC when the ring is full. > + > + /* write desc. Note: descriptors don't wrap, but the completion address > does */ > + const uint64_t op_flags64 = (uint64_t)(op_flags | > IDXD_FLAG_COMPLETION_ADDR_VALID) << 32; > + const uint64_t comp_addr = __desc_idx_to_iova(idxd, write_idx & mask); > + _mm256_store_si256((void *)&idxd->desc_ring[write_idx], > + _mm256_set_epi64x(dst, src, comp_addr, op_flags64)); > + _mm256_store_si256((void *)&idxd->desc_ring[write_idx].size, > + _mm256_set_epi64x(0, 0, 0, size)); > + > + idxd->batch_size++; > + > + rte_prefetch0_write(&idxd->desc_ring[write_idx + 1]); > + > + if (flags & RTE_DMA_OP_FLAG_SUBMIT) > + __submit(idxd); > + > + return job_id; > +} > + > +int > +idxd_enqueue_copy(struct rte_dma_dev *dev, uint16_t qid __rte_unused, > rte_iova_t src, > + rte_iova_t dst, unsigned int length, uint64_t flags) > +{ > + /* we can take advantage of the fact that the fence flag in dmadev and > DSA are the same, > + * but check it at compile time to be sure. > + */ > + RTE_BUILD_BUG_ON(RTE_DMA_OP_FLAG_FENCE != IDXD_FLAG_FENCE); > + uint32_t memmove = (idxd_op_memmove << IDXD_CMD_OP_SHIFT) | > + IDXD_FLAG_CACHE_CONTROL | (flags & IDXD_FLAG_FENCE); > + return __idxd_write_desc(dev, memmove, src, dst, length, flags); > +} > + [snip]