Bug 1277275 - Cache I/O queue length telemetry, r=michal
authorHonza Bambas <honzab.moz@firemni.cz>
Mon, 27 Jun 2016 05:43:00 +0200
changeset 345160 4070b1ce5332d1c7926f6223d189da38c856231f
parent 345159 ed713102408e02b6162cf0bb7c4bc83c7ea6bd12
child 345161 259215eef842ec7d2e7266e0052ede53c07a853a
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal
bugs1277275
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1277275 - Cache I/O queue length telemetry, r=michal
netwerk/cache2/CacheIOThread.cpp
netwerk/cache2/CacheIOThread.h
toolkit/components/telemetry/Histograms.json
toolkit/components/telemetry/histogram-whitelists.json
--- a/netwerk/cache2/CacheIOThread.cpp
+++ b/netwerk/cache2/CacheIOThread.cpp
@@ -9,16 +9,65 @@
 #include "nsISupportsImpl.h"
 #include "nsPrintfCString.h"
 #include "nsThreadUtils.h"
 #include "mozilla/IOInterposer.h"
 
 namespace mozilla {
 namespace net {
 
+namespace { // anon
+
+class CacheIOTelemetry
+{
+public:
+  typedef CacheIOThread::EventQueue::size_type size_type;
+  static size_type mMinLengthToReport[CacheIOThread::LAST_LEVEL];
+  static void Report(uint32_t aLevel, size_type aLength);
+};
+
+static CacheIOTelemetry::size_type const kGranularity = 30;
+
+CacheIOTelemetry::size_type 
+CacheIOTelemetry::mMinLengthToReport[CacheIOThread::LAST_LEVEL] = {
+  kGranularity, kGranularity, kGranularity, kGranularity,
+  kGranularity, kGranularity, kGranularity, kGranularity
+};
+
+// static
+void CacheIOTelemetry::Report(uint32_t aLevel, CacheIOTelemetry::size_type aLength)
+{
+  if (mMinLengthToReport[aLevel] > aLength) {
+    return;
+  }
+
+  static Telemetry::ID telemetryID[] = {
+    Telemetry::HTTP_CACHE_IO_QUEUE_OPEN_PRIORITY,
+    Telemetry::HTTP_CACHE_IO_QUEUE_READ_PRIORITY,
+    Telemetry::HTTP_CACHE_IO_QUEUE_OPEN,
+    Telemetry::HTTP_CACHE_IO_QUEUE_READ,
+    Telemetry::HTTP_CACHE_IO_QUEUE_MANAGEMENT,
+    Telemetry::HTTP_CACHE_IO_QUEUE_WRITE,
+    Telemetry::HTTP_CACHE_IO_QUEUE_INDEX,
+    Telemetry::HTTP_CACHE_IO_QUEUE_EVICT
+  };
+
+  // Each bucket is a multiply of kGranularity (30, 60, 90..., 300+)
+  aLength = (aLength / kGranularity);
+  // Next time report only when over the current length + kGranularity
+  mMinLengthToReport[aLevel] = (aLength + 1) * kGranularity;
+
+  // 10 is number of buckets we have in each probe
+  aLength = std::min<size_type>(aLength, 10);
+
+  Telemetry::Accumulate(telemetryID[aLevel], aLength - 1); // counted from 0
+}
+
+} // anon
+
 CacheIOThread* CacheIOThread::sSelf = nullptr;
 
 NS_IMPL_ISUPPORTS(CacheIOThread, nsIThreadObserver)
 
 CacheIOThread::CacheIOThread()
 : mMonitor("CacheIOThread")
 , mThread(nullptr)
 , mXPCOMThread(nullptr)
@@ -261,53 +310,44 @@ loopStart:
     mInsideLoop = false;
 #endif
   } // lock
 
   if (threadInternal)
     threadInternal->SetObserver(nullptr);
 }
 
-static const char* const sLevelTraceName[] = {
-  "net::cache::io::level(0)",
-  "net::cache::io::level(1)",
-  "net::cache::io::level(2)",
-  "net::cache::io::level(3)",
-  "net::cache::io::level(4)",
-  "net::cache::io::level(5)",
-  "net::cache::io::level(6)",
-  "net::cache::io::level(7)",
-  "net::cache::io::level(8)",
-  "net::cache::io::level(9)",
-  "net::cache::io::level(10)",
-  "net::cache::io::level(11)",
-  "net::cache::io::level(12)"
-};
-
 void CacheIOThread::LoopOneLevel(uint32_t aLevel)
 {
-  nsTArray<nsCOMPtr<nsIRunnable> > events;
+  EventQueue events;
   events.SwapElements(mEventQueue[aLevel]);
-  uint32_t length = events.Length();
+  EventQueue::size_type length = events.Length();
 
   mCurrentlyExecutingLevel = aLevel;
 
   bool returnEvents = false;
-  uint32_t index;
+  bool reportTelementry = true;
+
+  EventQueue::size_type index;
   {
     MonitorAutoUnlock unlock(mMonitor);
 
     for (index = 0; index < length; ++index) {
       if (EventsPending(aLevel)) {
         // Somebody scheduled a new event on a lower level, break and harry
         // to execute it!  Don't forget to return what we haven't exec.
         returnEvents = true;
         break;
       }
 
+      if (reportTelementry) {
+        reportTelementry = false;
+        CacheIOTelemetry::Report(aLevel, length);
+      }
+
       // Drop any previous flagging, only an event on the current level may set
       // this flag.
       mRerunCurrentEvent = false;
 
       events[index]->Run();
 
       if (mRerunCurrentEvent) {
         // The event handler yields to higher priority events and wants to rerun.
--- a/netwerk/cache2/CacheIOThread.h
+++ b/netwerk/cache2/CacheIOThread.h
@@ -24,17 +24,19 @@ class CacheIOThread : public nsIThreadOb
   virtual ~CacheIOThread();
 
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSITHREADOBSERVER
 
   CacheIOThread();
 
-  enum ELevel {
+  typedef nsTArray<nsCOMPtr<nsIRunnable>> EventQueue;
+
+  enum ELevel : uint32_t {
     OPEN_PRIORITY,
     READ_PRIORITY,
     OPEN,
     READ,
     MANAGEMENT,
     WRITE,
     CLOSE = WRITE,
     INDEX,
@@ -87,17 +89,18 @@ private:
 
   static CacheIOThread* sSelf;
 
   mozilla::Monitor mMonitor;
   PRThread* mThread;
   Atomic<nsIThread *> mXPCOMThread;
   Atomic<uint32_t, Relaxed> mLowestLevelWaiting;
   uint32_t mCurrentlyExecutingLevel;
-  nsTArray<nsCOMPtr<nsIRunnable> > mEventQueue[LAST_LEVEL];
+
+  EventQueue mEventQueue[LAST_LEVEL];
 
   Atomic<bool, Relaxed> mHasXPCOMEvents;
   bool mRerunCurrentEvent;
   bool mShutdown;
 #ifdef DEBUG
   bool mInsideLoop;
 #endif
 };
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -1729,16 +1729,64 @@
     "n_values": 5,
     "description": "HTTP Offline Cache Hit, Reval, Failed-Reval, Miss"
   },
   "HTTP_OFFLINE_CACHE_DOCUMENT_LOAD": {
     "expires_in_version": "never",
     "kind": "boolean",
     "description": "Rate of page load from offline cache"
   },
+  "HTTP_CACHE_IO_QUEUE_OPEN_PRIORITY": {
+    "expires_in_version": "54",
+    "kind": "enumerated",
+    "n_values": 10,
+    "description": "HTTP Cache IO queue length"
+  },
+  "HTTP_CACHE_IO_QUEUE_READ_PRIORITY": {
+    "expires_in_version": "54",
+    "kind": "enumerated",
+    "n_values": 10,
+    "description": "HTTP Cache IO queue length"
+  },
+  "HTTP_CACHE_IO_QUEUE_OPEN": {
+    "expires_in_version": "54",
+    "kind": "enumerated",
+    "n_values": 10,
+    "description": "HTTP Cache IO queue length"
+  },
+  "HTTP_CACHE_IO_QUEUE_READ": {
+    "expires_in_version": "54",
+    "kind": "enumerated",
+    "n_values": 10,
+    "description": "HTTP Cache IO queue length"
+  },
+  "HTTP_CACHE_IO_QUEUE_MANAGEMENT": {
+    "expires_in_version": "54",
+    "kind": "enumerated",
+    "n_values": 10,
+    "description": "HTTP Cache IO queue length"
+  },
+  "HTTP_CACHE_IO_QUEUE_WRITE": {
+    "expires_in_version": "54",
+    "kind": "enumerated",
+    "n_values": 10,
+    "description": "HTTP Cache IO queue length"
+  },
+  "HTTP_CACHE_IO_QUEUE_INDEX": {
+    "expires_in_version": "54",
+    "kind": "enumerated",
+    "n_values": 10,
+    "description": "HTTP Cache IO queue length"
+  },
+  "HTTP_CACHE_IO_QUEUE_EVICT": {
+    "expires_in_version": "54",
+    "kind": "enumerated",
+    "n_values": 10,
+    "description": "HTTP Cache IO queue length"
+  },
   "CACHE_DEVICE_SEARCH_2": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": 10000,
     "n_buckets": 50,
     "description": "Time to search cache (ms)"
   },
   "CACHE_MEMORY_SEARCH_2": {
--- a/toolkit/components/telemetry/histogram-whitelists.json
+++ b/toolkit/components/telemetry/histogram-whitelists.json
@@ -493,16 +493,24 @@
     "HTTP_CONNECTION_ENTRY_CACHE_HIT_1",
     "HTTP_CONTENT_ENCODING",
     "HTTP_DISK_CACHE_DISPOSITION_2",
     "HTTP_DISK_CACHE_OVERHEAD",
     "HTTP_KBREAD_PER_CONN",
     "HTTP_MEMORY_CACHE_DISPOSITION_2",
     "HTTP_OFFLINE_CACHE_DISPOSITION_2",
     "HTTP_OFFLINE_CACHE_DOCUMENT_LOAD",
+    "HTTP_CACHE_IO_QUEUE_OPEN_PRIORITY",
+    "HTTP_CACHE_IO_QUEUE_READ_PRIORITY",
+    "HTTP_CACHE_IO_QUEUE_OPEN",
+    "HTTP_CACHE_IO_QUEUE_READ",
+    "HTTP_CACHE_IO_QUEUE_MANAGEMENT",
+    "HTTP_CACHE_IO_QUEUE_WRITE",
+    "HTTP_CACHE_IO_QUEUE_INDEX",
+    "HTTP_CACHE_IO_QUEUE_EVICT",
     "HTTP_PAGELOAD_IS_SSL",
     "HTTP_PAGE_CACHE_READ_TIME",
     "HTTP_PAGE_CACHE_READ_TIME_V2",
     "HTTP_PAGE_COMPLETE_LOAD",
     "HTTP_PAGE_COMPLETE_LOAD_CACHED",
     "HTTP_PAGE_COMPLETE_LOAD_CACHED_V2",
     "HTTP_PAGE_COMPLETE_LOAD_NET",
     "HTTP_PAGE_COMPLETE_LOAD_NET_V2",
@@ -1609,16 +1617,24 @@
     "HTTP_CONNECTION_ENTRY_CACHE_HIT_1",
     "HTTP_CONTENT_ENCODING",
     "HTTP_DISK_CACHE_DISPOSITION_2",
     "HTTP_DISK_CACHE_OVERHEAD",
     "HTTP_KBREAD_PER_CONN",
     "HTTP_MEMORY_CACHE_DISPOSITION_2",
     "HTTP_OFFLINE_CACHE_DISPOSITION_2",
     "HTTP_OFFLINE_CACHE_DOCUMENT_LOAD",
+    "HTTP_CACHE_IO_QUEUE_OPEN_PRIORITY",
+    "HTTP_CACHE_IO_QUEUE_READ_PRIORITY",
+    "HTTP_CACHE_IO_QUEUE_OPEN",
+    "HTTP_CACHE_IO_QUEUE_READ",
+    "HTTP_CACHE_IO_QUEUE_MANAGEMENT",
+    "HTTP_CACHE_IO_QUEUE_WRITE",
+    "HTTP_CACHE_IO_QUEUE_INDEX",
+    "HTTP_CACHE_IO_QUEUE_EVICT",
     "HTTP_PAGELOAD_IS_SSL",
     "HTTP_PAGE_CACHE_READ_TIME",
     "HTTP_PAGE_CACHE_READ_TIME_V2",
     "HTTP_PAGE_COMPLETE_LOAD",
     "HTTP_PAGE_COMPLETE_LOAD_CACHED",
     "HTTP_PAGE_COMPLETE_LOAD_CACHED_V2",
     "HTTP_PAGE_COMPLETE_LOAD_NET",
     "HTTP_PAGE_COMPLETE_LOAD_NET_V2",