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

Reply via email to