From 860b8fc1299fc3fe143fa1e7bf8fa35384ca81f5 Mon Sep 17 00:00:00 2001
From: Florian Pose <fp@igh-essen.com>
Date: Wed, 12 Sep 2007 14:06:35 +0000
Subject: [PATCH] Store skipped information in datagrams; name datagrams for
 statistics output.

---
 master/datagram.c | 26 ++++++++++++++++++++++++++
 master/datagram.h | 11 ++++++++++-
 master/domain.c   |  3 +++
 master/ethernet.c | 11 ++++++++---
 master/master.c   | 12 ++++--------
 master/master.h   |  2 --
 6 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/master/datagram.c b/master/datagram.c
index 59d2376a..007cc5ea 100644
--- a/master/datagram.c
+++ b/master/datagram.c
@@ -82,6 +82,9 @@ void ec_datagram_init(ec_datagram_t *datagram /**< EtherCAT datagram */)
     datagram->jiffies_sent = 0;
     datagram->cycles_received = 0;
     datagram->jiffies_received = 0;
+    datagram->skip_count = 0;
+    datagram->stats_output_jiffies = 0;
+    datagram->name[0] = 0x00;
 }
 
 /*****************************************************************************/
@@ -319,3 +322,26 @@ void ec_datagram_print_wc_error(
 }
 
 /*****************************************************************************/
+
+/**
+ * Outputs datagram statistics at most every second.
+ */
+
+void ec_datagram_output_stats(
+        ec_datagram_t *datagram
+        )
+{
+    if (jiffies - datagram->stats_output_jiffies < HZ) {
+        datagram->stats_output_jiffies = jiffies;
+    
+        if (unlikely(datagram->skip_count)) {
+            EC_WARN("Datagram %x (%s) was SKIPPED %u time%s.\n",
+                    (unsigned int) datagram, datagram->name,
+                    datagram->skip_count,
+                    datagram->skip_count == 1 ? "" : "s");
+            datagram->skip_count = 0;
+        }
+    }
+}
+
+/*****************************************************************************/
diff --git a/master/datagram.h b/master/datagram.h
index a35af77f..eeb0dd22 100644
--- a/master/datagram.h
+++ b/master/datagram.h
@@ -49,6 +49,11 @@
 
 /*****************************************************************************/
 
+/** size of the datagram description string */
+#define EC_DATAGRAM_NAME_SIZE 20
+
+/*****************************************************************************/
+
 /**
    EtherCAT datagram type.
 */
@@ -103,7 +108,10 @@ typedef struct
     cycles_t cycles_sent; /**< time, the datagram was sent */
     unsigned long jiffies_sent; /**< jiffies, when the datagram was sent */
     cycles_t cycles_received; /**< time, when the datagram was received */
-    unsigned long jiffies_received; /**< jiffies, when the datagram was rec. */
+    unsigned long jiffies_received; /**< jiffies the datagram was received */
+    unsigned int skip_count; /**< number of requeues when not yet received */
+    unsigned long stats_output_jiffies; /**< last statistics output */
+    char name[EC_DATAGRAM_NAME_SIZE]; /**< description of the datagram */
 }
 ec_datagram_t;
 
@@ -122,6 +130,7 @@ int ec_datagram_bwr(ec_datagram_t *, uint16_t, size_t);
 int ec_datagram_lrw(ec_datagram_t *, uint32_t, size_t);
 
 void ec_datagram_print_wc_error(const ec_datagram_t *);
+void ec_datagram_output_stats(ec_datagram_t *datagram);
 
 /*****************************************************************************/
 
diff --git a/master/domain.c b/master/domain.c
index 2ca65c65..0a7525a5 100644
--- a/master/domain.c
+++ b/master/domain.c
@@ -269,6 +269,8 @@ int ec_domain_add_datagram(ec_domain_t *domain, /**< EtherCAT domain */
     }
 
     ec_datagram_init(datagram);
+    snprintf(datagram->name, EC_DATAGRAM_NAME_SIZE,
+            "domain%u-%u", domain->index, offset);
 
     if (ec_datagram_lrw(datagram, offset, data_size)) {
         kfree(datagram);
@@ -547,6 +549,7 @@ void ecrt_domain_process(ec_domain_t *domain /**< EtherCAT domain */)
     working_counter_sum = 0;
     domain->state = 0;
     list_for_each_entry(datagram, &domain->datagrams, list) {
+        ec_datagram_output_stats(datagram);
         if (datagram->state == EC_DATAGRAM_RECEIVED) {
             working_counter_sum += datagram->working_counter;
         }
diff --git a/master/ethernet.c b/master/ethernet.c
index 436b75c1..f8f31927 100644
--- a/master/ethernet.c
+++ b/master/ethernet.c
@@ -94,7 +94,7 @@ int ec_eoe_init(
 {
     ec_eoe_t **priv;
     int result, i;
-    char name[20];
+    char name[EC_DATAGRAM_NAME_SIZE];
 
     eoe->slave = slave;
 
@@ -120,11 +120,15 @@ int ec_eoe_init(
     /* device name eoe<MASTER>[as]<SLAVE>, because networking scripts don't
      * like hyphens etc. in interface names. */
     if (slave->sii_alias) {
-        sprintf(name, "eoe%ua%u", slave->master->index, slave->sii_alias);
+        snprintf(name, EC_DATAGRAM_NAME_SIZE,
+                "eoe%ua%u", slave->master->index, slave->sii_alias);
     } else {
-        sprintf(name, "eoe%us%u", slave->master->index, slave->ring_position);
+        snprintf(name, EC_DATAGRAM_NAME_SIZE,
+                "eoe%us%u", slave->master->index, slave->ring_position);
     }
 
+    snprintf(eoe->datagram.name, EC_DATAGRAM_NAME_SIZE, name);
+
     if (!(eoe->dev = alloc_netdev(sizeof(ec_eoe_t *), name, ether_setup))) {
         EC_ERR("Unable to allocate net_device %s for EoE handler!\n", name);
         goto out_return;
@@ -307,6 +311,7 @@ void ec_eoe_run(ec_eoe_t *eoe /**< EoE handler */)
         eoe->tx_counter = 0;
         eoe->rate_jiffies = jiffies;
     }
+    ec_datagram_output_stats(&eoe->datagram);
 }
 
 /*****************************************************************************/
diff --git a/master/master.c b/master/master.c
index 690340bd..91cc3a2f 100644
--- a/master/master.c
+++ b/master/master.c
@@ -143,7 +143,6 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
 
     master->stats.timeouts = 0;
     master->stats.corrupted = 0;
-    master->stats.skipped = 0;
     master->stats.unmatched = 0;
     master->stats.output_jiffies = 0;
 
@@ -186,6 +185,7 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
 
     // init state machine datagram
     ec_datagram_init(&master->fsm_datagram);
+    snprintf(master->fsm_datagram.name, EC_DATAGRAM_NAME_SIZE, "master-fsm");
     if (ec_datagram_prealloc(&master->fsm_datagram, EC_MAX_DATA_SIZE)) {
         EC_ERR("Failed to allocate FSM datagram.\n");
         goto out_clear_backup;
@@ -548,10 +548,9 @@ void ec_master_queue_datagram(ec_master_t *master, /**< EtherCAT master */
     // check, if the datagram is already queued
     list_for_each_entry(queued_datagram, &master->datagram_queue, queue) {
         if (queued_datagram == datagram) {
-            master->stats.skipped++;
+            datagram->skip_count++;
             if (master->debug_level)
                 EC_DBG("skipping datagram %x.\n", (unsigned int) datagram);
-            ec_master_output_stats(master);
             datagram->state = EC_DATAGRAM_QUEUED;
             return;
         }
@@ -798,11 +797,6 @@ void ec_master_output_stats(ec_master_t *master /**< EtherCAT master */)
                     master->stats.corrupted == 1 ? "" : "s");
             master->stats.corrupted = 0;
         }
-        if (master->stats.skipped) {
-            EC_WARN("%i datagram%s SKIPPED!\n", master->stats.skipped,
-                    master->stats.skipped == 1 ? "" : "s");
-            master->stats.skipped = 0;
-        }
         if (master->stats.unmatched) {
             EC_WARN("%i datagram%s UNMATCHED!\n", master->stats.unmatched,
                     master->stats.unmatched == 1 ? "" : "s");
@@ -826,6 +820,7 @@ static int ec_master_idle_thread(ec_master_t *master)
 
     while (!signal_pending(current)) {
         cycles_start = get_cycles();
+        ec_datagram_output_stats(&master->fsm_datagram);
 
         if (ec_fsm_master_running(&master->fsm)) { // datagram on the way
             // receive
@@ -882,6 +877,7 @@ static int ec_master_operation_thread(ec_master_t *master)
     allow_signal(SIGTERM);
 
     while (!signal_pending(current)) {
+        ec_datagram_output_stats(&master->fsm_datagram);
         if (master->injection_seq_rt != master->injection_seq_fsm ||
                 master->fsm_datagram.state == EC_DATAGRAM_SENT ||
                 master->fsm_datagram.state == EC_DATAGRAM_QUEUED)
diff --git a/master/master.h b/master/master.h
index 31c31f51..f11f8588 100644
--- a/master/master.h
+++ b/master/master.h
@@ -75,8 +75,6 @@ typedef struct
 {
     unsigned int timeouts; /**< datagram timeouts */
     unsigned int corrupted; /**< corrupted frames */
-    unsigned int skipped; /**< skipped datagrams (the ones that were
-                             requeued when not yet received) */
     unsigned int unmatched; /**< unmatched datagrams (received, but not
                                queued any longer) */
     unsigned long output_jiffies; /**< time of last output */
-- 
GitLab