cpu: Add a basic progress check to the TrafficGen
authorAndreas Hansson <andreas.hansson@arm.com>
Thu, 26 May 2016 10:56:24 +0000 (11:56 +0100)
committerAndreas Hansson <andreas.hansson@arm.com>
Thu, 26 May 2016 10:56:24 +0000 (11:56 +0100)
This patch adds a progress check to the TrafficGen so that it is
easier to detect deadlock scenarios where the generator gets stuck
waiting for a retry, and makes no further progress.

Change-Id: Ifb8779ad0939f52c0518d0e867bac73f99b82e2b
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Radhika Jagtap <radhika.jagtap@arm.com>
src/cpu/testers/traffic_gen/TrafficGen.py
src/cpu/testers/traffic_gen/traffic_gen.cc
src/cpu/testers/traffic_gen/traffic_gen.hh

index f29cedb3afd72b4a2044ade5d4f681dbf20e7a23..1a6a6359c1b6f486be980ce6b7e4b2d740b76de5 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 ARM Limited
+# Copyright (c) 2012, 2016 ARM Limited
 # All rights reserved.
 #
 # The license below extends only to copyright in the software and shall
@@ -77,3 +77,9 @@ class TrafficGen(MemObject):
     # are not immediately accepted
     elastic_req = Param.Bool(False,
                              "Slow down requests in case of backpressure")
+
+    # Let the user know if we have waited for a retry and not made any
+    # progress for a long period of time. The default value is
+    # somewhat arbitrary and may well have to be tuned.
+    progress_check = Param.Latency('1ms', "Time before exiting " \
+                                   "due to lack of progress")
index a405351edabbb9124b85872a9ed3997b4e4c5cef..fbb26baa8891ce3e175b168c44a58210064c4dee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -57,6 +57,8 @@ TrafficGen::TrafficGen(const TrafficGenParams* p)
       masterID(system->getMasterId(name())),
       configFile(p->config_file),
       elasticReq(p->elastic_req),
+      progressCheck(p->progress_check),
+      noProgressEvent(this),
       nextTransitionTick(0),
       nextPacketTick(0),
       currState(0),
@@ -179,6 +181,9 @@ TrafficGen::unserialize(CheckpointIn &cp)
 void
 TrafficGen::update()
 {
+    // shift our progress-tracking event forward
+    reschedule(noProgressEvent, curTick() + progressCheck, true);
+
     // if we have reached the time for the next state transition, then
     // perform the transition
     if (curTick() >= nextTransitionTick) {
@@ -511,6 +516,13 @@ TrafficGen::recvReqRetry()
     }
 }
 
+void
+TrafficGen::noProgress()
+{
+    fatal("TrafficGen %s spent %llu ticks without making progress",
+          name(), progressCheck);
+}
+
 void
 TrafficGen::regStats()
 {
index 914b4ac09fabeb0aaed4cc07de880ad01d638902..0715c59658f9dd47821d9bcbebd8a387784482cd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -94,6 +94,11 @@ class TrafficGen : public MemObject
      */
     void recvReqRetry();
 
+    /**
+     * Method to inform the user we have made no progress.
+     */
+    void noProgress();
+
     /** Struct to represent a probabilistic transition during parsing. */
     struct Transition {
         uint32_t from;
@@ -123,6 +128,17 @@ class TrafficGen : public MemObject
      */
     const bool elasticReq;
 
+    /**
+     * Time to tolerate waiting for retries (not making progress),
+     * until we declare things broken.
+     */
+    const Tick progressCheck;
+
+    /**
+     * Event to keep track of our progress, or lack thereof.
+     */
+    EventWrapper<TrafficGen, &TrafficGen::noProgress> noProgressEvent;
+
     /** Time of next transition */
     Tick nextTransitionTick;