Hello Chengwen,
On Mon, 2 Mar 2026 at 12:02, Chengwen Feng <[email protected]> wrote:
>
> As we know, the uacce driver (e.g. hisi_acc DMA driver) reads the API of
> the hardware device (through /sysfs/class/uacce/xxx/api) and compares it
> with the API supported by the driver to match the corresponding hardware
> device.
>
> Hardware devices will continue to evolve, which means their APIs will
> change, but business requirements demand that they support old
> programming interfaces as much as possible.
>
> To adapt to this situation, this commit supports forward compatibility
> of driver APIs. For example, if the driver supports the hisi_qm_v5 API,
> it can drive the hardware device that supports the hisi_qm_v6 or
> hisi_qm_v7 API.
>
> In addition, a driver flag (RTE_UACCE_DRV_FORWARD_COMPATIBILITY_DEV) is
> introduced. The driver supports forward compatibility of APIs only when
> this flag is defined.
>
> Signed-off-by: Chengwen Feng <[email protected]>
> ---
> drivers/bus/uacce/bus_uacce_driver.h | 5 +++
> drivers/bus/uacce/uacce.c | 51 ++++++++++++++++++++++++++--
> 2 files changed, 53 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/bus/uacce/bus_uacce_driver.h
> b/drivers/bus/uacce/bus_uacce_driver.h
> index 618e0f9b76..c7445778a6 100644
> --- a/drivers/bus/uacce/bus_uacce_driver.h
> +++ b/drivers/bus/uacce/bus_uacce_driver.h
> @@ -50,6 +50,7 @@ struct rte_uacce_device {
> char dev_root[RTE_UACCE_DEV_PATH_SIZE]; /**< Sysfs path with device
> name. */
> char cdev_path[RTE_UACCE_DEV_PATH_SIZE]; /**< Device path in devfs. */
> char api[RTE_UACCE_API_NAME_SIZE]; /**< Device context type. */
> + uint32_t api_ver; /**< Device api version used
> for compatibility. */
I have some problem with this field.
See below.
> char algs[RTE_UACCE_ALGS_NAME_SIZE]; /**< Device supported
> algorithms. */
> uint32_t flags; /**< Device flags. */
> int numa_node; /**< NUMA node connection,
> -1 if unknown. */
> @@ -100,8 +101,12 @@ struct rte_uacce_driver {
> rte_uacce_probe_t *probe; /**< Device probe function. */
> rte_uacce_remove_t *remove; /**< Device remove function.
> */
> const struct rte_uacce_id *id_table; /**< ID table, NULL
> terminated. */
> + uint32_t drv_flags; /**< Flags RTE_UACCE_DRV_*. */
> };
>
> +/** Device driver supports forward compatibility device */
> +#define RTE_UACCE_DRV_FORWARD_COMPATIBILITY_DEV 0x1
> +
> /**
> * Get available queue number.
> *
> diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
> index 79f990c54c..a471edcad0 100644
> --- a/drivers/bus/uacce/uacce.c
> +++ b/drivers/bus/uacce/uacce.c
> @@ -2,6 +2,7 @@
> * Copyright(c) 2024 HiSilicon Limited
> */
>
> +#include <ctype.h>
> #include <dirent.h>
> #include <errno.h>
> #include <fcntl.h>
> @@ -324,19 +325,62 @@ uacce_scan(void)
> return -1;
> }
>
> +static uint32_t
> +uacce_calc_api_ver(const char *api, int *offset)
> +{
> + int len = strlen(api);
> + int end = len - 1;
> + unsigned long ver;
> +
> + while (end >= 0 && isdigit(api[end]))
> + end--;
> +
> + if (end <= 0 || end == len - 1 || api[end] != 'v')
> + return 0;
> +
> + ver = strtoul(api + end + 1, NULL, 10);
> + if (ver > UINT32_MAX)
> + return 0;
> +
> + if (offset != NULL)
> + *offset = end + 1;
> + return (uint32_t)ver;
> +}
> +
> +static bool
> +uacce_match_api(const struct rte_uacce_device *dev, bool forward_compat,
> + const struct rte_uacce_id *id_table)
> +{
> + int dev_ver_off = 0, id_ver_off = 0;
> + uint32_t dev_ver, id_ver;
> +
> + if (!forward_compat)
> + return strcmp(id_table->dev_api, dev->api) == 0;
> +
> + dev_ver = uacce_calc_api_ver(dev->api, &dev_ver_off);
> + id_ver = uacce_calc_api_ver(id_table->dev_api, &id_ver_off);
> + return dev_ver > 0 && id_ver > 0 && dev_ver_off == id_ver_off &&
> + strncmp(id_table->dev_api, dev->api, dev_ver_off) == 0 &&
> + dev_ver >= id_ver;
> +}
> +
> static bool
> -uacce_match(const struct rte_uacce_driver *dr, const struct rte_uacce_device
> *dev)
> +uacce_match(const struct rte_uacce_driver *dr, struct rte_uacce_device *dev)
A matching helper should only match, and not modify the object.
> {
> + bool forward_compat = !!(dr->drv_flags &
> RTE_UACCE_DRV_FORWARD_COMPATIBILITY_DEV);
> + uint32_t api_ver = uacce_calc_api_ver(dev->api, NULL);
This conversion from a string to integer could be placed in the scanning step.
Why place it here?
The dev->api_ver has no in-tree user.
This field was (silently?) dropped by my best AI friend in the bus
refactoring series I posted.
https://patchwork.dpdk.org/project/dpdk/patch/[email protected]/
Please advise if I can drop this field (it is just the integer value
extracted from dev->api afaiu), or if it should be moved to the
scanning step.
--
David Marchand