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

Reply via email to