[dpdk-dev] [PATCH 5/5] rte_sched: allow reading without clearing
Dumitrescu, Cristian
cristian.dumitrescu at intel.com
Thu Jun 4 19:48:21 CEST 2015
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen at networkplumber.org]
> Sent: Wednesday, May 27, 2015 7:10 PM
> To: Dumitrescu, Cristian
> Cc: dev at dpdk.org; Stephen Hemminger
> Subject: [PATCH 5/5] rte_sched: allow reading without clearing
>
> The rte_sched statistics API should allow reading statistics without
> clearing. Make auto-clear optional. In this version, this is handled
> by deprecating the old API and adding a new one.
>
> Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>
> ---
> app/test/test_sched.c | 4 +--
> lib/librte_sched/rte_sched.c | 65 +++++++++++++++++++++-------------
> lib/librte_sched/rte_sched.h | 37 ++++++++++++++-----
> lib/librte_sched/rte_sched_version.map | 2 ++
> 4 files changed, 74 insertions(+), 34 deletions(-)
>
> diff --git a/app/test/test_sched.c b/app/test/test_sched.c
> index c7239f8..03f89b4 100644
> --- a/app/test/test_sched.c
> +++ b/app/test/test_sched.c
> @@ -198,13 +198,13 @@ test_sched(void)
>
> struct rte_sched_subport_stats subport_stats;
> uint32_t tc_ov;
> - rte_sched_subport_read_stats(port, SUBPORT, &subport_stats,
> &tc_ov);
> + rte_sched_subport_stats(port, SUBPORT, &subport_stats, &tc_ov,
> 1);
> #if 0
> TEST_ASSERT_EQUAL(subport_stats.n_pkts_tc[TC-1], 10, "Wrong
> subport stats\n");
> #endif
> struct rte_sched_queue_stats queue_stats;
> uint16_t qlen;
> - rte_sched_queue_read_stats(port, QUEUE, &queue_stats, &qlen);
> + rte_sched_queue_stats(port, QUEUE, &queue_stats, &qlen, 1);
> #if 0
> TEST_ASSERT_EQUAL(queue_stats.n_pkts, 10, "Wrong queue
> stats\n");
> #endif
> diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
> index 9c9419d..b4d7edd 100644
> --- a/lib/librte_sched/rte_sched.c
> +++ b/lib/librte_sched/rte_sched.c
> @@ -965,61 +965,78 @@ rte_sched_port_pkt_read_color(const struct
> rte_mbuf *pkt)
> }
>
> int
> -rte_sched_subport_read_stats(struct rte_sched_port *port,
> - uint32_t subport_id,
> - struct rte_sched_subport_stats *stats,
> - uint32_t *tc_ov)
> +rte_sched_subport_stats(struct rte_sched_port *port, uint32_t
> subport_id,
> + struct rte_sched_subport_stats *stats,
> + uint32_t *tc_ov, int clear)
> {
> struct rte_sched_subport *s;
>
> /* Check user parameters */
> - if ((port == NULL) ||
> - (subport_id >= port->n_subports_per_port) ||
> - (stats == NULL) ||
> - (tc_ov == NULL)) {
> + if (port == NULL || subport_id >= port->n_subports_per_port)
> return -1;
> - }
> +
> s = port->subport + subport_id;
>
> /* Copy subport stats and clear */
> - memcpy(stats, &s->stats, sizeof(struct rte_sched_subport_stats));
> - memset(&s->stats, 0, sizeof(struct rte_sched_subport_stats));
> + if (stats)
> + *stats = s->stats;
> + if (clear)
> + memset(&s->stats, 0, sizeof(struct
> rte_sched_subport_stats));
>
> /* Subport TC ovesubscription status */
> - *tc_ov = s->tc_ov;
> + if (tc_ov)
> + *tc_ov = s->tc_ov;
>
> return 0;
> }
>
> +/* Deprecated API, always clears */
> int
> -rte_sched_queue_read_stats(struct rte_sched_port *port,
> - uint32_t queue_id,
> - struct rte_sched_queue_stats *stats,
> - uint16_t *qlen)
> +rte_sched_subport_read_stats(struct rte_sched_port *port, uint32_t
> subport_id,
> + struct rte_sched_subport_stats *stats,
> + uint32_t *tc_ov)
> +{
> + return rte_sched_subport_stats(port, subport_id, stats, tc_ov, 1);
> +}
> +
> +int
> +rte_sched_queue_stats(struct rte_sched_port *port, uint32_t queue_id,
> + struct rte_sched_queue_stats *stats,
> + uint16_t *qlen, int clear)
> {
> struct rte_sched_queue *q;
> struct rte_sched_queue_extra *qe;
>
> /* Check user parameters */
> - if ((port == NULL) ||
> - (queue_id >= rte_sched_port_queues_per_port(port)) ||
> - (stats == NULL) ||
> - (qlen == NULL)) {
> + if (port == NULL || queue_id >=
> rte_sched_port_queues_per_port(port))
> return -1;
> - }
> +
> q = port->queue + queue_id;
> qe = port->queue_extra + queue_id;
>
> /* Copy queue stats and clear */
> - memcpy(stats, &qe->stats, sizeof(struct rte_sched_queue_stats));
> - memset(&qe->stats, 0, sizeof(struct rte_sched_queue_stats));
> + if (stats)
> + *stats = qe->stats;
> + if (clear)
> + memset(&qe->stats, 0, sizeof(struct
> rte_sched_queue_stats));
>
> /* Queue length */
> - *qlen = q->qw - q->qr;
> + if (qlen)
> + *qlen = q->qw - q->qr;
>
> return 0;
> }
>
> +/* Deprecated API, always clears */
> +int
> +rte_sched_queue_read_stats(struct rte_sched_port *port,
> + uint32_t queue_id,
> + struct rte_sched_queue_stats *stats,
> + uint16_t *qlen)
> +{
> + return rte_sched_queue_stats(port, queue_id, stats, qlen, 1);
> +}
> +
> static inline uint32_t
> rte_sched_port_qindex(struct rte_sched_port *port, uint32_t subport,
> uint32_t pipe, uint32_t traffic_class, uint32_t queue)
> {
> diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h
> index f7c0b8e..053454c 100644
> --- a/lib/librte_sched/rte_sched.h
> +++ b/lib/librte_sched/rte_sched.h
> @@ -300,14 +300,24 @@ rte_sched_port_get_memory_footprint(struct
> rte_sched_port_params *params);
> * @param tc_ov
> * Pointer to pre-allocated 4-entry array where the oversubscription status
> for
> * each of the 4 subport traffic classes should be stored.
> + * @parm clear
> + * Reset statistics after read
> + *
> * @return
> * 0 upon success, error code otherwise
> */
> int
> -rte_sched_subport_read_stats(struct rte_sched_port *port,
> - uint32_t subport_id,
> - struct rte_sched_subport_stats *stats,
> - uint32_t *tc_ov);
> +rte_sched_subport_stats(struct rte_sched_port *port, uint32_t
> subport_id,
> + struct rte_sched_subport_stats *stats,
> + uint32_t *tc_ov, int clear);
> +
> +/* Note: use rte_sched_subport_stats() instead,
> + * which allows separate read and clear.
> + */
> +int
> +rte_sched_subport_read_stats(struct rte_sched_port *port, uint32_t
> subport_id,
> + struct rte_sched_subport_stats *stats,
> + uint32_t *tc_ov) __attribute__((deprecated));
>
> /**
> * Hierarchical scheduler queue statistics read
> @@ -321,14 +331,25 @@ rte_sched_subport_read_stats(struct
> rte_sched_port *port,
> * counters should be stored
> * @param qlen
> * Pointer to pre-allocated variable where the current queue length should
> be stored.
> + * @parm clear
> + * Reset statistics after read
> * @return
> * 0 upon success, error code otherwise
> */
> int
> -rte_sched_queue_read_stats(struct rte_sched_port *port,
> - uint32_t queue_id,
> - struct rte_sched_queue_stats *stats,
> - uint16_t *qlen);
> +rte_sched_queue_stats(struct rte_sched_port *port,
> + uint32_t queue_id,
> + struct rte_sched_queue_stats *stats,
> + uint16_t *qlen, int clear);
> +
> +
> +/* Note: use rte_sched_queue_stats() instead
> + * which allows separate read and clear.
> + */
> +int
> +rte_sched_queue_read_stats(struct rte_sched_port *port, uint32_t
> queue_id,
> + struct rte_sched_queue_stats *stats,
> + uint16_t *qlen) __attribute__((deprecated));
>
> /**
> * Scheduler hierarchy path write to packet descriptor. Typically called by the
> diff --git a/lib/librte_sched/rte_sched_version.map
> b/lib/librte_sched/rte_sched_version.map
> index 6626a74..cdbaeb7 100644
> --- a/lib/librte_sched/rte_sched_version.map
> +++ b/lib/librte_sched/rte_sched_version.map
> @@ -14,8 +14,10 @@ DPDK_2.0 {
> rte_sched_port_enqueue;
> rte_sched_port_free;
> rte_sched_port_get_memory_footprint;
> + rte_sched_queue_stats;
> rte_sched_queue_read_stats;
> rte_sched_subport_config;
> + rte_sched_subport_stats;
> rte_sched_subport_read_stats;
> rte_sched_port_pkt_write;
> rte_sched_port_pkt_read_tree_path;
> --
> 2.1.4
If we plan to obsolete API function rte_sched_queue_read_stats() and have people use the new API function rte_sched_queue_stats(), we should replace every usage of the obsolete function with call to new function. We need to do this in examples/qos_sched and app/test.
More information about the dev
mailing list