[dpdk-dev] [PATCH v2] ethdev: fix xstats retrieve by id API
Van Haaren, Harry
harry.van.haaren at intel.com
Thu Oct 19 13:06:37 CEST 2017
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Ferruh Yigit
> Sent: Wednesday, October 18, 2017 10:49 PM
> To: Ivan Malov <Ivan.Malov at oktetlabs.ru>; Daly, Lee <lee.daly at intel.com>;
> thomas at monjalon.net
> Cc: dev at dpdk.org; Kozak, KubaX <kubax.kozak at intel.com>
> Subject: Re: [dpdk-dev] [PATCH v2] ethdev: fix xstats retrieve by id API
>
> On 10/18/2017 4:10 AM, Ivan Malov wrote:
> > On 10/12/2017 2:31 PM, Lee Daly wrote:
> >> From: Lee <lee.daly at intel.com>
> >>
> >> Fix xstats functions, rte_eth_xstats_get_names_by_id()
> >> and rte_eth_xstats_get_by_id(), in current implementation
> >> ethdev level reads all xstat values and filters out
> >> the ones requested by the application. This behavior doesn't
> >> benefit from PMD ops and doesn't provide the benefit the
> >> API was created in the first place for. APIs are also unnecessarily
> >> complicated. Both APIs have different returns for the same params.
> >>
> >> In this fix, instead of reading all the stats and finding the
> >> requested value, drivers can provide ops to get selected xstats.
> >> API no longer crashes with certain params,
> >>
> >> rte_eth_get_by_id returned seg fault with
> >> "ids = NULL && values != NULL && n<max"
> >> rte_eth_get_names_by_id returned seg fault with
> >> "ids = NULL && values != NULL && n=0"
> >> These now return max number of stats available, matching the other API.
> >>
> >> rte_eth_get_by_id returned seg fault with
> >> "ids != NULL && values = NULL && n<max"
> >> This now returns -22,(EINVAL).
> >>
> >> Standardized variable/parameter names between the 2 APIs.
> >>
> >> Overall code complexity reduced.
> >>
> >> Fixes: 79c913a42f0e ("ethdev: retrieve xstats by ID")
> >> Cc: kubax.kozak at intel.com
> >>
> >> Signed-off-by: Lee Daly <lee.daly at intel.com>
> >> Reviewed-by: Ferruh Yigit <ferruh.yigit at intel.com>
> >
> > I have a serious concern regarding the patch. There is a common scenario
> > of rte_eth_xstats_get_names_by_id() usage, and the patch breaks it.
> > Typically, the function is called with 'ids = NULL' and 'xstats_names =
> NULL'
> > in order to get the number of figures. Then the function is called one
> more
> > time with appropriate storage for 'xstats_names'. According to the patch,
> > on the former step get_xstats_count() is called to count the figures
> available.
> > The resulting number counts for PMD statistics + RTE_NB_STATS + some
> amount of
> > per-queue figures. However, on the latter step the following may take
> place:
> >
> >> + if (dev->dev_ops->xstats_get_names_by_id != NULL)
> >> + return (*dev->dev_ops->xstats_get_names_by_id)(
> >> + dev, xstats_names, ids, size);
> >
> > This obviously means that in the case when 'xstats_get_names_by_id' is
> present,
> > it will be called directly, and RTE statistics will not be filled in the
> storage
> > before the PMD figures. Accordingly, the value returned by the function in
> this
> > case will count for PMD figures only (i.e. will be less than the value
> obtained
> > on the first step). This is an obvious malfunction, and it would be
> desirable
> > to provide a fix for that. I hope for your understanding.
>
> Hi Ivan,
>
> You are right, this is broken.
>
> But the problem is, ethdev API works with ids which are "basic + xstat" and
> PMD dev_ops
> works with ids which are "xstat". This mismatch ends up
> xstats_get_names_by_id() dev_ops
> being called to get all values, and filtering done in ethdev API, as done in
> previous
> implementation.
>
> If we use xstats_get_names_by_id() to get all values, why we have it at all,
> there is
> already a dev_ops to get all values.
>
> I believe we have two options,
>
> 1- Remove this by _by_id() dev_ops, but keep ethdev APIs, and APIs does the
> filtering of
> the ids. This may be missing if any PMD has an optimal way of getting subset
> of ids, this
> is the main reason of the devops.
Lets not remove the _by_id() opts, because that removes the possibility for PMDs to optimize the get_by_id() case.
> 2- Convert ids for PMD usage, what do you think about following fix:
> (same thing for rte_eth_xstats_get_by_id() also of course)
A quick test of this patch allows proc-info to work again to dump xstats of a primary, eg testpmd. Run testpmd first and then proc-info:
testpmd: ./testpmd -- -i
proc-info: ./dpdk-procinfo -- --xstats
Before patch:
Cannot get xstat names
Cannot get xstat names
After patch:
<correct xstats output>
I suggest we use Ferruh's fix, and apply ASAP unless @Ivan has a better solution/suggestion?
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index 0b1e92894..1145539ee 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -1631,6 +1631,7 @@ rte_eth_xstats_get_names_by_id(uint16_t port_id,
> {
> struct rte_eth_xstat_name *xstats_names_copy;
> unsigned int expected_entries;
> + unsigned int all_ids_from_pmd = 1;
> struct rte_eth_dev *dev;
> unsigned int i;
>
> @@ -1649,9 +1650,28 @@ rte_eth_xstats_get_names_by_id(uint16_t port_id,
> if (ids && !xstats_names)
> return -EINVAL;
>
> - if (dev->dev_ops->xstats_get_names_by_id != NULL)
> - return (*dev->dev_ops->xstats_get_names_by_id)(
> - dev, xstats_names, ids, size);
> + if (ids && dev->dev_ops->xstats_get_names_by_id != NULL && size >
> 0) {
> + uint64_t ids_copy[size];
> + unsigned int pmd_count;
> + unsigned int count;
> +
> + pmd_count = (*dev->dev_ops->xstats_get_names_by_id)(dev,
> NULL,
> + NULL, 0);
> + count = expected_entries - pmd_count;
> +
> + for (i = 0; i < size; i++) {
> + if (ids[i] < count) {
> + all_ids_from_pmd = 0;
> + break;
> + }
> +
> + ids_copy[i] = ids[i] - count;
> + }
> +
> + if (all_ids_from_pmd)
> + return (*dev->dev_ops-
> >xstats_get_names_by_id)(dev,
> + xstats_names, ids_copy, size);
> + }
>
> /* Retrieve all stats */
> if (!ids) {
More information about the dev
mailing list