Merge "metric: Add net_rx action statistic to network performance metric"
diff --git a/protos/perfetto/metrics/android/network_metric.proto b/protos/perfetto/metrics/android/network_metric.proto
index 61fac5c..5205aca 100644
--- a/protos/perfetto/metrics/android/network_metric.proto
+++ b/protos/perfetto/metrics/android/network_metric.proto
@@ -20,22 +20,22 @@
 
 message AndroidNetworkMetric {
   message PacketStatistic {
-    // Packet count
+    // Packet count.
     optional int64 packets = 1;
 
-    // Packet Bytes
+    // Packet Bytes.
     optional int64 bytes = 2;
 
-    // Timestamp when first packet received or transmitted
+    // Timestamp when first packet received or transmitted.
     optional int64 first_packet_timestamp_ns = 3;
 
-    // Timestamp when last packet received or transmitted
+    // Timestamp when last packet received or transmitted.
     optional int64 last_packet_timestamp_ns = 4;
 
     // Interval between first & last packet. The minimum interval is 10ms.
     optional int64 interval_ns = 5;
 
-    // Data Speed
+    // Data Speed.
     optional double data_rate_kbps = 6;
   }
 
@@ -45,20 +45,50 @@
   }
 
   message Rx {
-    // Total packets statistic
+    // Total packets statistic.
     optional PacketStatistic total = 1;
-    // Per core packets statistic
+    // Per core packets statistic.
     repeated CorePacketStatistic core = 2;
   }
 
   message NetDevice {
-    // Network device name
+    // Network device name.
     optional string name = 1;
 
-    // Ingress traffic statistic
+    // Ingress traffic statistic.
     optional Rx rx = 2;
   }
 
-  // Network device metrics
+  message NetRxActionStatistic {
+    // SoftIrq NET_RX action count.
+    optional int64 count = 1;
+
+    // SoftIrq NET_RX action was running in millisecond.
+    optional double runtime_ms = 2;
+
+    // SoftIrq NET_RX action average running time.
+    optional double avg_runtime_ms = 3;
+  }
+
+  message CoreNetRxActionStatistic {
+    optional uint32 id = 1;
+    optional NetRxActionStatistic net_rx_action_statistic = 2;
+  }
+
+  message NetRxAction {
+    // Total NET_RX action statistics.
+    optional NetRxActionStatistic total = 1;
+
+    // Per core NET_RX action statistics.
+    repeated CoreNetRxActionStatistic core = 2;
+
+    // The average packet time moves through the kernel stack.
+    optional double avg_interstack_latency_ms = 3;
+  }
+
+  // Network device metrics.
   repeated NetDevice net_devices = 1;
+
+  // SoftIrq NET_RX action metrics.
+  optional NetRxAction net_rx_action = 2;
 }
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index 9bd0298..08173c9 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -800,22 +800,22 @@
 
 message AndroidNetworkMetric {
   message PacketStatistic {
-    // Packet count
+    // Packet count.
     optional int64 packets = 1;
 
-    // Packet Bytes
+    // Packet Bytes.
     optional int64 bytes = 2;
 
-    // Timestamp when first packet received or transmitted
+    // Timestamp when first packet received or transmitted.
     optional int64 first_packet_timestamp_ns = 3;
 
-    // Timestamp when last packet received or transmitted
+    // Timestamp when last packet received or transmitted.
     optional int64 last_packet_timestamp_ns = 4;
 
     // Interval between first & last packet. The minimum interval is 10ms.
     optional int64 interval_ns = 5;
 
-    // Data Speed
+    // Data Speed.
     optional double data_rate_kbps = 6;
   }
 
@@ -825,22 +825,52 @@
   }
 
   message Rx {
-    // Total packets statistic
+    // Total packets statistic.
     optional PacketStatistic total = 1;
-    // Per core packets statistic
+    // Per core packets statistic.
     repeated CorePacketStatistic core = 2;
   }
 
   message NetDevice {
-    // Network device name
+    // Network device name.
     optional string name = 1;
 
-    // Ingress traffic statistic
+    // Ingress traffic statistic.
     optional Rx rx = 2;
   }
 
-  // Network device metrics
+  message NetRxActionStatistic {
+    // SoftIrq NET_RX action count.
+    optional int64 count = 1;
+
+    // SoftIrq NET_RX action was running in millisecond.
+    optional double runtime_ms = 2;
+
+    // SoftIrq NET_RX action average running time.
+    optional double avg_runtime_ms = 3;
+  }
+
+  message CoreNetRxActionStatistic {
+    optional uint32 id = 1;
+    optional NetRxActionStatistic net_rx_action_statistic = 2;
+  }
+
+  message NetRxAction {
+    // Total NET_RX action statistics.
+    optional NetRxActionStatistic total = 1;
+
+    // Per core NET_RX action statistics.
+    repeated CoreNetRxActionStatistic core = 2;
+
+    // The average packet time moves through the kernel stack.
+    optional double avg_interstack_latency_ms = 3;
+  }
+
+  // Network device metrics.
   repeated NetDevice net_devices = 1;
+
+  // SoftIrq NET_RX action metrics.
+  optional NetRxAction net_rx_action = 2;
 }
 
 // End of protos/perfetto/metrics/android/network_metric.proto
diff --git a/src/trace_processor/metrics/sql/android/android_netperf.sql b/src/trace_processor/metrics/sql/android/android_netperf.sql
index f7d8ae5..900322f 100644
--- a/src/trace_processor/metrics/sql/android/android_netperf.sql
+++ b/src/trace_processor/metrics/sql/android/android_netperf.sql
@@ -33,7 +33,7 @@
     MIN(ts) AS start_ts,
     MAX(ts) AS end_ts,
     IIF((MAX(ts) - MIN(ts)) > 10000000, MAX(ts)-MIN(ts), 10000000) AS interval,
-    count(1) AS packets,
+    COUNT(1) AS packets,
     SUM(len) AS bytes
   FROM rx_packets
   GROUP BY dev;
@@ -45,7 +45,7 @@
     AndroidNetworkMetric_CorePacketStatistic(
       'id', cpu,
       'packet_statistic', AndroidNetworkMetric_PacketStatistic(
-        'packets', count(1),
+        'packets', COUNT(1),
         'bytes', SUM(len),
         'first_packet_timestamp_ns', MIN(ts),
         'last_packet_timestamp_ns', MAX(ts),
@@ -81,6 +81,40 @@
   FROM device_total_ingress_traffic
   ORDER BY dev;
 
+DROP VIEW IF EXISTS net_rx_actions;
+CREATE VIEW net_rx_actions AS
+  SELECT
+    s.ts,
+    s.dur,
+    CAST(SUBSTR(t.name, 13, 1) AS int) AS cpu
+  FROM slice s
+  LEFT JOIN track t
+    ON s.track_id = t.id
+  WHERE s.name = "NET_RX";
+
+DROP VIEW IF EXISTS total_net_rx_action_statistic;
+CREATE VIEW total_net_rx_action_statistic AS
+  SELECT
+    COUNT(1) AS times,
+    SUM(dur) AS runtime,
+    AVG(dur) AS avg_runtime,
+    (SELECT COUNT(1) FROM rx_packets) AS total_packet
+  FROM net_rx_actions;
+
+DROP VIEW IF EXISTS per_core_net_rx_action_statistic;
+CREATE VIEW per_core_net_rx_action_statistic AS
+  SELECT
+    AndroidNetworkMetric_CoreNetRxActionStatistic(
+      'id', cpu,
+      'net_rx_action_statistic', AndroidNetworkMetric_NetRxActionStatistic(
+        'count', COUNT(1),
+        'runtime_ms', SUM(dur)/1e6,
+        'avg_runtime_ms', AVG(dur)/1e6
+      )
+    ) AS proto
+  FROM net_rx_actions
+  GROUP BY cpu;
+
 DROP VIEW IF EXISTS android_netperf_output;
 CREATE VIEW android_netperf_output AS
   SELECT AndroidNetworkMetric(
@@ -88,6 +122,23 @@
       SELECT
         RepeatedField(proto)
       FROM device_ingress_traffic_statistic
+    ),
+    'net_rx_action', AndroidNetworkMetric_NetRxAction(
+       'total', AndroidNetworkMetric_NetRxActionStatistic(
+         'count', (SELECT times FROM total_net_rx_action_statistic),
+         'runtime_ms', (SELECT runtime/1e6 FROM total_net_rx_action_statistic),
+         'avg_runtime_ms', (SELECT avg_runtime/1e6 FROM total_net_rx_action_statistic)
+       ),
+       'core', (
+         SELECT
+           RepeatedField(proto)
+         FROM per_core_net_rx_action_statistic
+       ),
+       'avg_interstack_latency_ms', (
+         SELECT
+           runtime/total_packet/1e6
+         FROM total_net_rx_action_statistic
+       )
     )
   );
 
diff --git a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
index 9ade464..11ce57d 100644
--- a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
+++ b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
Binary files differ
diff --git a/test/trace_processor/network/netperf_metric.out b/test/trace_processor/network/netperf_metric.out
index 89ca722..62e7507 100644
--- a/test/trace_processor/network/netperf_metric.out
+++ b/test/trace_processor/network/netperf_metric.out
@@ -58,4 +58,28 @@
       }
     }
   }
+  net_rx_action {
+    total {
+      count: 4
+      runtime_ms: 0.4
+      avg_runtime_ms: 0.1
+    }
+    core {
+      id: 0
+      net_rx_action_statistic {
+        count: 2
+        runtime_ms: 0.2
+        avg_runtime_ms: 0.1
+      }
+    }
+    core {
+      id: 1
+      net_rx_action_statistic {
+        count: 2
+        runtime_ms: 0.2
+        avg_runtime_ms: 0.1
+      }
+    }
+    avg_interstack_latency_ms: 0.08
+  }
 }
diff --git a/test/trace_processor/network/netperf_metric.textproto b/test/trace_processor/network/netperf_metric.textproto
index ffa3ad1..589d222 100644
--- a/test/trace_processor/network/netperf_metric.textproto
+++ b/test/trace_processor/network/netperf_metric.textproto
@@ -1,7 +1,14 @@
- packet {
+packet {
   ftrace_events {
     cpu: 0
     event {
+     timestamp: 100000000
+     pid: 200
+     softirq_entry {
+       vec: 3
+     }
+    }
+    event {
       timestamp: 100000000
       pid: 200
       netif_receive_skb {
@@ -9,12 +16,27 @@
         len: 1024
       }
     }
+    event {
+     timestamp: 100100000
+     pid: 200
+     softirq_exit {
+       vec: 3
+     }
+    }
   }
 }
-packet {
+
+packet {  
   ftrace_events {
     cpu: 1
     event {
+     timestamp: 120000000
+     pid: 300
+     softirq_entry {
+       vec: 3
+     }
+    }
+    event {
       timestamp: 120000000
       pid: 300
       netif_receive_skb {
@@ -22,12 +44,27 @@
         len: 1024
       }
     }
+    event {
+     timestamp: 120100000
+     pid: 300
+     softirq_exit {
+       vec: 3
+     }
+    }
   }
 }
+
 packet {
   ftrace_events {
     cpu: 0
     event {
+     timestamp: 140000000
+     pid: 400
+     softirq_entry {
+       vec: 3
+     }
+    }
+    event {
       timestamp: 140000000
       pid: 400
       netif_receive_skb {
@@ -35,12 +72,27 @@
         len: 1024
       }
     }
+    event {
+     timestamp: 140100000
+     pid: 400
+     softirq_exit {
+       vec: 3
+     }
+    }
   }
 }
+
 packet {
   ftrace_events {
     cpu: 1
     event {
+     timestamp: 140000000
+     pid: 500
+     softirq_entry {
+       vec: 3
+     }
+    }
+    event {
       timestamp: 140000000
       pid: 500
       netif_receive_skb {
@@ -48,8 +100,16 @@
         len: 1024
       }
     }
+    event {
+     timestamp: 140100000
+     pid: 500
+     softirq_exit {
+       vec: 3
+     }
+    }
   }
 }
+
 packet {
   ftrace_events {
     cpu: 4