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]

Reply via email to