From: Bruce Richardson Date: Wed, 13 Oct 2021 15:17:24 +0000 (+0100) Subject: dmadev: add channel status check for testing use X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=5e0f85912754bf0d50c940165c40cac68e7c762f;p=dpdk.git dmadev: add channel status check for testing use Add in a function to check if a device or vchan has completed all jobs assigned to it, without gathering in the results. This is primarily for use in testing, to allow the hardware to be in a known-state prior to gathering completions. Signed-off-by: Bruce Richardson Reviewed-by: Conor Walsh Reviewed-by: Kevin Laatz --- diff --git a/drivers/dma/skeleton/skeleton_dmadev.c b/drivers/dma/skeleton/skeleton_dmadev.c index 22a73c6178..dd2f1c9b57 100644 --- a/drivers/dma/skeleton/skeleton_dmadev.c +++ b/drivers/dma/skeleton/skeleton_dmadev.c @@ -79,7 +79,7 @@ cpucopy_thread(void *param) hw->zero_req_count = 0; rte_memcpy(desc->dst, desc->src, desc->len); - hw->completed_count++; + __atomic_add_fetch(&hw->completed_count, 1, __ATOMIC_RELEASE); (void)rte_ring_enqueue(hw->desc_completed, (void *)desc); } @@ -257,6 +257,21 @@ skeldma_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan, return vchan_setup(hw, conf->nb_desc); } +static int +skeldma_vchan_status(const struct rte_dma_dev *dev, + uint16_t vchan, enum rte_dma_vchan_status *status) +{ + struct skeldma_hw *hw = dev->data->dev_private; + + RTE_SET_USED(vchan); + + *status = RTE_DMA_VCHAN_IDLE; + if (hw->submitted_count != __atomic_load_n(&hw->completed_count, __ATOMIC_ACQUIRE) + || hw->zero_req_count == 0) + *status = RTE_DMA_VCHAN_ACTIVE; + return 0; +} + static int skeldma_stats_get(const struct rte_dma_dev *dev, uint16_t vchan, struct rte_dma_stats *stats, uint32_t stats_sz) @@ -424,6 +439,7 @@ static const struct rte_dma_dev_ops skeldma_ops = { .dev_close = skeldma_close, .vchan_setup = skeldma_vchan_setup, + .vchan_status = skeldma_vchan_status, .stats_get = skeldma_stats_get, .stats_reset = skeldma_stats_reset, diff --git a/drivers/dma/skeleton/skeleton_dmadev.h b/drivers/dma/skeleton/skeleton_dmadev.h index eaa52364bf..91eb5460fc 100644 --- a/drivers/dma/skeleton/skeleton_dmadev.h +++ b/drivers/dma/skeleton/skeleton_dmadev.h @@ -54,7 +54,7 @@ struct skeldma_hw { /* Cache delimiter for cpucopy thread's operation data */ char cache2 __rte_cache_aligned; - uint32_t zero_req_count; + volatile uint32_t zero_req_count; uint64_t completed_count; }; diff --git a/lib/dmadev/rte_dmadev.c b/lib/dmadev/rte_dmadev.c index 7099bbb28d..3f9154e619 100644 --- a/lib/dmadev/rte_dmadev.c +++ b/lib/dmadev/rte_dmadev.c @@ -679,6 +679,23 @@ rte_dma_stats_reset(int16_t dev_id, uint16_t vchan) return (*dev->dev_ops->stats_reset)(dev, vchan); } +int +rte_dma_vchan_status(int16_t dev_id, uint16_t vchan, enum rte_dma_vchan_status *status) +{ + struct rte_dma_dev *dev = &rte_dma_devices[dev_id]; + + if (!rte_dma_is_valid(dev_id)) + return -EINVAL; + + if (vchan >= dev->data->dev_conf.nb_vchans) { + RTE_DMA_LOG(ERR, "Device %u vchan %u out of range\n", dev_id, vchan); + return -EINVAL; + } + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vchan_status, -ENOTSUP); + return (*dev->dev_ops->vchan_status)(dev, vchan, status); +} + static const char * dma_capability_name(uint64_t capability) { diff --git a/lib/dmadev/rte_dmadev.h b/lib/dmadev/rte_dmadev.h index e46c001404..e35aca7d1c 100644 --- a/lib/dmadev/rte_dmadev.h +++ b/lib/dmadev/rte_dmadev.h @@ -645,6 +645,40 @@ int rte_dma_stats_get(int16_t dev_id, uint16_t vchan, __rte_experimental int rte_dma_stats_reset(int16_t dev_id, uint16_t vchan); +/** + * device vchannel status + * + * Enum with the options for the channel status, either idle, active or halted due to error + * @see rte_dma_vchan_status + */ +enum rte_dma_vchan_status { + RTE_DMA_VCHAN_IDLE, /**< not processing, awaiting ops */ + RTE_DMA_VCHAN_ACTIVE, /**< currently processing jobs */ + RTE_DMA_VCHAN_HALTED_ERROR, /**< not processing due to error, cannot accept new ops */ +}; + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Determine if all jobs have completed on a device channel. + * This function is primarily designed for testing use, as it allows a process to check if + * all jobs are completed, without actually gathering completions from those jobs. + * + * @param dev_id + * The identifier of the device. + * @param vchan + * The identifier of virtual DMA channel. + * @param[out] status + * The vchan status + * @return + * 0 - call completed successfully + * < 0 - error code indicating there was a problem calling the API + */ +__rte_experimental +int +rte_dma_vchan_status(int16_t dev_id, uint16_t vchan, enum rte_dma_vchan_status *status); + /** * @warning * @b EXPERIMENTAL: this API may change without prior notice. diff --git a/lib/dmadev/rte_dmadev_pmd.h b/lib/dmadev/rte_dmadev_pmd.h index 23b07a4e1c..b97b5bf10b 100644 --- a/lib/dmadev/rte_dmadev_pmd.h +++ b/lib/dmadev/rte_dmadev_pmd.h @@ -54,6 +54,10 @@ typedef int (*rte_dma_stats_get_t)(const struct rte_dma_dev *dev, /** @internal Used to reset basic statistics. */ typedef int (*rte_dma_stats_reset_t)(struct rte_dma_dev *dev, uint16_t vchan); +/** @internal Used to check if a virtual channel has finished all jobs. */ +typedef int (*rte_dma_vchan_status_t)(const struct rte_dma_dev *dev, uint16_t vchan, + enum rte_dma_vchan_status *status); + /** @internal Used to dump internal information. */ typedef int (*rte_dma_dump_t)(const struct rte_dma_dev *dev, FILE *f); @@ -74,6 +78,7 @@ struct rte_dma_dev_ops { rte_dma_stats_get_t stats_get; rte_dma_stats_reset_t stats_reset; + rte_dma_vchan_status_t vchan_status; rte_dma_dump_t dev_dump; }; diff --git a/lib/dmadev/version.map b/lib/dmadev/version.map index e17207b212..8785e14648 100644 --- a/lib/dmadev/version.map +++ b/lib/dmadev/version.map @@ -20,6 +20,7 @@ EXPERIMENTAL { rte_dma_stop; rte_dma_submit; rte_dma_vchan_setup; + rte_dma_vchan_status; local: *; };