]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
greybus: loopback: add ability to graph greybus latency
authorBryan O'Donoghue <bryan.odonoghue@linaro.org>
Sun, 16 Aug 2015 23:55:02 +0000 (00:55 +0100)
committerGreg Kroah-Hartman <gregkh@google.com>
Tue, 18 Aug 2015 16:45:23 +0000 (09:45 -0700)
This patch adds the ability to graph the latency of the overhead introduced
by the greybus stack in the roundtrip time AP->Module->AP.

Since this is a small number it is reported in nanoseconds, not
mircoseconds. This data can also be derived with tracepoints but it's being
provided in this format to export to CSV file more easily than with
tracepoints.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/loopback.c

index 3263d8351aa307fb077e818d10964b816c83f907..74bc2b4eec6338eb5f54bf9b6ee3d367283ffe0b 100644 (file)
@@ -50,9 +50,11 @@ struct gb_loopback {
        int ms_wait;
 
        struct gb_loopback_stats latency;
+       struct gb_loopback_stats latency_gb;
        struct gb_loopback_stats throughput;
        struct gb_loopback_stats requests_per_second;
        u64 elapsed_nsecs;
+       u64 elapsed_nsecs_gb;
        u32 error;
 };
 
@@ -177,6 +179,8 @@ static void gb_loopback_check_attr(struct gb_connection *connection,
 
 /* Time to send and receive one message */
 gb_loopback_stats_attrs(latency);
+/* Time to send and receive one message not including greybus */
+gb_loopback_stats_attrs(latency_gb);
 /* Number of requests sent per second on this cport */
 gb_loopback_stats_attrs(requests_per_second);
 /* Quantity of data sent and received on this cport */
@@ -209,6 +213,7 @@ gb_loopback_attr(iteration_max, u);
 
 static struct attribute *loopback_attrs[] = {
        dev_stats_attrs(latency),
+       dev_stats_attrs(latency_gb),
        dev_stats_attrs(requests_per_second),
        dev_stats_attrs(throughput),
        &dev_attr_type.attr,
@@ -221,17 +226,16 @@ static struct attribute *loopback_attrs[] = {
 };
 ATTRIBUTE_GROUPS(loopback);
 
-static void gb_loopback_calc_latency(struct gb_loopback *gb,
-                                    struct timeval *ts, struct timeval *te)
+static u64 gb_loopback_calc_latency(struct timeval *ts, struct timeval *te)
 {
        u64 t1, t2;
 
        t1 = timeval_to_ns(ts);
        t2 = timeval_to_ns(te);
        if (t2 > t1)
-               gb->elapsed_nsecs = t2 - t1;
+               return t2 - t1;
        else
-               gb->elapsed_nsecs = NSEC_PER_DAY - t2 + t1;
+               return NSEC_PER_DAY - t2 + t1;
 }
 
 static int gb_loopback_sink(struct gb_loopback *gb, u32 len)
@@ -251,7 +255,15 @@ static int gb_loopback_sink(struct gb_loopback *gb, u32 len)
                                   request, len + sizeof(*request), NULL, 0);
 
        do_gettimeofday(&te);
-       gb_loopback_calc_latency(gb, &ts, &te);
+
+       /* Calculate the total time the message took */
+       gb->elapsed_nsecs = gb_loopback_calc_latency(&ts, &te);
+
+       /* Calculate non-greybus related component of the latency */
+       gb_connection_pop_timestamp(gb->connection, &ts);
+       gb_connection_pop_timestamp(gb->connection, &te);
+       gb->elapsed_nsecs_gb = gb_loopback_calc_latency(&ts, &te);
+
 
        kfree(request);
        return retval;
@@ -282,7 +294,14 @@ static int gb_loopback_transfer(struct gb_loopback *gb, u32 len)
                                   request, len + sizeof(*request),
                                   response, len + sizeof(*response));
        do_gettimeofday(&te);
-       gb_loopback_calc_latency(gb, &ts, &te);
+
+       /* Calculate the total time the message took */
+       gb->elapsed_nsecs = gb_loopback_calc_latency(&ts, &te);
+
+       /* Calculate non-greybus related component of the latency */
+       gb_connection_pop_timestamp(gb->connection, &ts);
+       gb_connection_pop_timestamp(gb->connection, &te);
+       gb->elapsed_nsecs_gb = gb_loopback_calc_latency(&ts, &te);
 
        if (retval)
                goto gb_error;
@@ -308,7 +327,14 @@ static int gb_loopback_ping(struct gb_loopback *gb)
        retval = gb_operation_sync(gb->connection, GB_LOOPBACK_TYPE_PING,
                                   NULL, 0, NULL, 0);
        do_gettimeofday(&te);
-       gb_loopback_calc_latency(gb, &ts, &te);
+
+       /* Calculate the total time the message took */
+       gb->elapsed_nsecs = gb_loopback_calc_latency(&ts, &te);
+
+       /* Calculate non-greybus related component of the latency */
+       gb_connection_pop_timestamp(gb->connection, &ts);
+       gb_connection_pop_timestamp(gb->connection, &te);
+       gb->elapsed_nsecs_gb = gb_loopback_calc_latency(&ts, &te);
 
        return retval;
 }
@@ -371,6 +397,7 @@ static void gb_loopback_reset_stats(struct gb_loopback *gb)
                .min = U32_MAX,
        };
        memcpy(&gb->latency, &reset, sizeof(struct gb_loopback_stats));
+       memcpy(&gb->latency_gb, &reset, sizeof(struct gb_loopback_stats));
        memcpy(&gb->throughput, &reset, sizeof(struct gb_loopback_stats));
        memcpy(&gb->requests_per_second, &reset,
               sizeof(struct gb_loopback_stats));
@@ -439,6 +466,11 @@ static void gb_loopback_calculate_stats(struct gb_loopback *gb)
        /* Log throughput and requests using latency as benchmark */
        gb_loopback_throughput_update(gb, lat);
        gb_loopback_requests_update(gb, lat);
+
+       /* Calculate the greybus related latency number in nanoseconds */
+       tmp = gb->elapsed_nsecs - gb->elapsed_nsecs_gb;
+       lat = tmp;
+       gb_loopback_update_stats(&gb->latency_gb, lat);
 }
 
 static int gb_loopback_fn(void *data)