Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org>
---
 platform/linux-generic/Makefile.am                 |  1 +
 .../linux-generic/include/odp_packet_io_internal.h |  9 +++
 platform/linux-generic/odp_packet_io.c             | 53 +++++++++++++++++
 platform/linux-generic/pktio/socket.c              | 59 ++++++++++++++++++
 platform/linux-generic/pktio/socket_mmap.c         |  8 +++
 platform/linux-generic/pktio/stats_sysfs.c         | 69 ++++++++++++++++++++++
 6 files changed, 199 insertions(+)
 create mode 100644 platform/linux-generic/pktio/stats_sysfs.c

diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 610c79c..e3e4954 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -170,6 +170,7 @@ __LIB__libodp_la_SOURCES = \
                           pktio/netmap.c \
                           pktio/socket.c \
                           pktio/socket_mmap.c \
+                          pktio/stats_sysfs.c \
                           odp_pool.c \
                           odp_queue.c \
                           odp_rwlock.c \
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
b/platform/linux-generic/include/odp_packet_io_internal.h
index 1a1118c..ec43e87 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -84,6 +84,7 @@ struct pktio_entry {
                STATE_STOP
        } state;
        classifier_t cls;               /**< classifier linked with this pktio*/
+       odp_pktio_stats_t stats;        /**< statistic counters for pktio */
        char name[PKTIO_NAME_LEN];      /**< name of pktio provided to
                                           pktio_open() */
        odp_pktio_param_t param;
@@ -107,6 +108,8 @@ typedef struct pktio_if_ops {
        int (*close)(pktio_entry_t *pktio_entry);
        int (*start)(pktio_entry_t *pktio_entry);
        int (*stop)(pktio_entry_t *pktio_entry);
+       int (*stats)(pktio_entry_t *pktio_entry, odp_pktio_stats_t *stats);
+       int (*stats_reset)(pktio_entry_t *pktio_entry);
        int (*recv)(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[],
                    unsigned len);
        int (*send)(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[],
@@ -159,6 +162,12 @@ extern const pktio_if_ops_t pcap_pktio_ops;
 #endif
 extern const pktio_if_ops_t * const pktio_if_ops[];
 
+int sysfs_stats(pktio_entry_t *pktio_entry,
+               odp_pktio_stats_t *stats);
+int sock_stats_reset(pktio_entry_t *pktio_entry);
+int sock_stats(pktio_entry_t *pktio_entry,
+              odp_pktio_stats_t *stats);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/linux-generic/odp_packet_io.c 
b/platform/linux-generic/odp_packet_io.c
index 3ef400f..ba97629 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -862,3 +862,56 @@ void odp_pktio_print(odp_pktio_t id)
 
        ODP_PRINT("\n%s\n", str);
 }
+
+int odp_pktio_stats(odp_pktio_t pktio,
+                   odp_pktio_stats_t *stats)
+{
+       pktio_entry_t *entry;
+       int ret = -1;
+
+       entry = get_pktio_entry(pktio);
+       if (entry == NULL) {
+               ODP_DBG("pktio entry %d does not exist\n", pktio);
+               return -1;
+       }
+
+       lock_entry(entry);
+
+       if (odp_unlikely(is_free(entry))) {
+               unlock_entry(entry);
+               ODP_DBG("already freed pktio\n");
+               return -1;
+       }
+
+       if (entry->s.ops->stats)
+               ret = entry->s.ops->stats(entry, stats);
+       unlock_entry(entry);
+
+       return ret;
+}
+
+int odp_pktio_stats_reset(odp_pktio_t pktio)
+{
+       pktio_entry_t *entry;
+       int ret = -1;
+
+       entry = get_pktio_entry(pktio);
+       if (entry == NULL) {
+               ODP_DBG("pktio entry %d does not exist\n", pktio);
+               return -1;
+       }
+
+       lock_entry(entry);
+
+       if (odp_unlikely(is_free(entry))) {
+               unlock_entry(entry);
+               ODP_DBG("already freed pktio\n");
+               return -1;
+       }
+
+       if (entry->s.ops->stats)
+               ret = entry->s.ops->stats_reset(entry);
+       unlock_entry(entry);
+
+       return ret;
+}
diff --git a/platform/linux-generic/pktio/socket.c 
b/platform/linux-generic/pktio/socket.c
index 5f5e0ae..0bda57b 100644
--- a/platform/linux-generic/pktio/socket.c
+++ b/platform/linux-generic/pktio/socket.c
@@ -254,6 +254,12 @@ static int sock_setup_pkt(pktio_entry_t *pktio_entry, 
const char *netdev,
                goto error;
        }
 
+       err = sock_stats_reset(pktio_entry);
+       if (err != 0) {
+               ODP_ERR("reset stats\n");
+               goto error;
+       }
+
        return 0;
 
 error:
@@ -467,6 +473,57 @@ static int sock_promisc_mode_get(pktio_entry_t 
*pktio_entry)
                                   pktio_entry->s.name);
 }
 
+int sock_stats(pktio_entry_t *pktio_entry,
+              odp_pktio_stats_t *stats)
+{
+       odp_pktio_stats_t cur_stats;
+       int ret;
+
+       memset(&cur_stats, 0, sizeof(odp_pktio_stats_t));
+       ret = sysfs_stats(pktio_entry, &cur_stats);
+       if (ret)
+               ODP_ABORT("sysfs stats error\n");
+
+       stats->in_octets = cur_stats.in_octets -
+                               pktio_entry->s.stats.in_octets;
+       stats->in_ucast_pkts = cur_stats.in_ucast_pkts -
+                               pktio_entry->s.stats.in_ucast_pkts;
+       stats->in_discards = cur_stats.in_discards -
+                               pktio_entry->s.stats.in_discards;
+       stats->in_errors = cur_stats.in_errors -
+                               pktio_entry->s.stats.in_errors;
+       stats->in_unknown_protos = cur_stats.in_unknown_protos -
+                               pktio_entry->s.stats.in_unknown_protos;
+
+       stats->out_octets = cur_stats.out_octets -
+                               pktio_entry->s.stats.out_octets;
+       stats->out_ucast_pkts = cur_stats.out_ucast_pkts -
+                               pktio_entry->s.stats.out_ucast_pkts;
+       stats->out_discards = cur_stats.out_discards -
+                               pktio_entry->s.stats.out_discards;
+       stats->out_errors = cur_stats.out_errors -
+                               pktio_entry->s.stats.out_errors;
+
+       return 0;
+}
+
+int sock_stats_reset(pktio_entry_t *pktio_entry)
+{
+       int err = 0;
+       odp_pktio_stats_t cur;
+
+       memset(&cur, 0, sizeof(odp_pktio_stats_t));
+       err = sysfs_stats(pktio_entry, &cur);
+       if (err != 0) {
+               __odp_errno = errno;
+               ODP_ERR("sysfs stats error\n");
+       } else {
+               memcpy(&pktio_entry->s.stats, &cur, sizeof(odp_pktio_stats_t));
+       }
+
+       return err;
+}
+
 const pktio_if_ops_t sock_mmsg_pktio_ops = {
        .init = NULL,
        .term = NULL,
@@ -474,6 +531,8 @@ const pktio_if_ops_t sock_mmsg_pktio_ops = {
        .close = sock_close,
        .start = NULL,
        .stop = NULL,
+       .stats = sock_stats,
+       .stats_reset = sock_stats_reset,
        .recv = sock_mmsg_recv,
        .send = sock_mmsg_send,
        .mtu_get = sock_mtu_get,
diff --git a/platform/linux-generic/pktio/socket_mmap.c 
b/platform/linux-generic/pktio/socket_mmap.c
index 79ff82d..2031485 100644
--- a/platform/linux-generic/pktio/socket_mmap.c
+++ b/platform/linux-generic/pktio/socket_mmap.c
@@ -467,6 +467,12 @@ static int sock_mmap_open(odp_pktio_t id ODP_UNUSED,
                        goto error;
        }
 
+       ret = sock_stats_reset(pktio_entry);
+       if (ret != 0) {
+               ODP_ERR("reset stats\n");
+               goto error;
+       }
+
        return 0;
 
 error:
@@ -525,6 +531,8 @@ const pktio_if_ops_t sock_mmap_pktio_ops = {
        .close = sock_mmap_close,
        .start = NULL,
        .stop = NULL,
+       .stats = sock_stats,
+       .stats_reset = sock_stats_reset,
        .recv = sock_mmap_recv,
        .send = sock_mmap_send,
        .mtu_get = sock_mmap_mtu_get,
diff --git a/platform/linux-generic/pktio/stats_sysfs.c 
b/platform/linux-generic/pktio/stats_sysfs.c
new file mode 100644
index 0000000..5033b7e
--- /dev/null
+++ b/platform/linux-generic/pktio/stats_sysfs.c
@@ -0,0 +1,69 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include <odp.h>
+#include <odp_packet_io_internal.h>
+#include <stdio.h>
+
+static uint64_t sysfs_get_val(const char *fname)
+{
+       FILE  *file;
+       char str[128];
+       uint64_t ret = -1;
+
+       file = fopen(fname, "rt");
+       if (file == NULL) {
+               /* File not found */
+               return 0;
+       }
+
+       if (fgets(str, sizeof(str), file) != NULL) {
+               /* Read cache line size */
+               if (sscanf(str, "%" SCNx64, &ret) != 1) {
+                       ODP_ERR("read %s\n", fname);
+                       ret = 0;
+               }
+       }
+
+       (void)fclose(file);
+       return ret;
+}
+
+int sysfs_stats(pktio_entry_t *pktio_entry,
+               odp_pktio_stats_t *stats)
+{
+       char fname[256];
+       const char *dev = pktio_entry->s.name;
+
+       sprintf(fname, "/sys/class/net/%s/statistics/rx_bytes", dev);
+       stats->in_octets = sysfs_get_val(fname);
+
+       sprintf(fname, "/sys/class/net/%s/statistics/rx_packets", dev);
+       stats->in_ucast_pkts = sysfs_get_val(fname);
+
+       sprintf(fname, "/sys/class/net/%s/statistics/rx_droppped", dev);
+       stats->in_discards = sysfs_get_val(fname);
+
+       sprintf(fname, "/sys/class/net/%s/statistics/rx_errors", dev);
+       stats->in_errors = sysfs_get_val(fname);
+
+       stats->in_unknown_protos = 0;
+
+       sprintf(fname, "/sys/class/net/%s/statistics/tx_bytes", dev);
+       stats->out_octets = sysfs_get_val(fname);
+
+       sprintf(fname, "/sys/class/net/%s/statistics/tx_packets", dev);
+       stats->out_ucast_pkts = sysfs_get_val(fname);
+
+       sprintf(fname, "/sys/class/net/%s/statistics/tx_dropped", dev);
+       stats->out_discards = sysfs_get_val(fname);
+
+       sprintf(fname, "/sys/class/net/%s/statistics/tx_errors", dev);
+       stats->out_errors = sysfs_get_val(fname);
+
+       return 0;
+}
+
-- 
1.9.1

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to