summaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus
diff options
context:
space:
mode:
authorBryan O'Donoghue <bryan.odonoghue@linaro.org>2015-08-11 13:50:51 +0100
committerGreg Kroah-Hartman <gregkh@google.com>2015-08-11 20:00:40 -0700
commita1a4a29cb9e9593a1f47d549af212f35f131e6cc (patch)
treed42e9178ebe2453f9aa998fbd8bc7a553725ed32 /drivers/staging/greybus
parent8ebc998f5fb146b7304fb7ac4e4d80059b6197fe (diff)
downloadlinux-stable-a1a4a29cb9e9593a1f47d549af212f35f131e6cc.tar.gz
linux-stable-a1a4a29cb9e9593a1f47d549af212f35f131e6cc.tar.bz2
linux-stable-a1a4a29cb9e9593a1f47d549af212f35f131e6cc.zip
greybus: connection: add a timestamp kfifo to track connection handoff
For the ES2 test activity it may be beneficial to have a performance metric that doesn't include any of the greybus stack malloc, workqueues etc. In order to faciltate, this patch adds a simple kfifo structure to hold two timestamp values. One timestamp will represent the last reasonable point a greybus outbound timestamp can be taken, the other timestamp will represent the first reasonable point an inbound timestamp can be taken. In order to facilitate this model, tracking the timestamps in the connection structure appears to be the best place to keep store of this data. Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus')
-rw-r--r--drivers/staging/greybus/connection.c36
-rw-r--r--drivers/staging/greybus/connection.h5
2 files changed, 40 insertions, 1 deletions
diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c
index 3765aa87ef2d..0ec5b0dcc145 100644
--- a/drivers/staging/greybus/connection.c
+++ b/drivers/staging/greybus/connection.c
@@ -11,6 +11,10 @@
#include "greybus.h"
+#define GB_CONNECTION_TS_KFIFO_ELEMENTS 2
+#define GB_CONNECTION_TS_KFIFO_LEN \
+ (GB_CONNECTION_TS_KFIFO_ELEMENTS * sizeof(struct timeval))
+
static DEFINE_SPINLOCK(gb_connections_lock);
/* This is only used at initialization time; no locking is required. */
@@ -63,6 +67,29 @@ void greybus_data_rcvd(struct greybus_host_device *hd, u16 cport_id,
}
EXPORT_SYMBOL_GPL(greybus_data_rcvd);
+void gb_connection_push_timestamp(struct gb_connection *connection)
+{
+ struct timeval tv;
+
+ do_gettimeofday(&tv);
+ kfifo_in_locked(&connection->ts_kfifo, (void *)&tv,
+ sizeof(struct timeval), &connection->lock);
+}
+EXPORT_SYMBOL_GPL(gb_connection_push_timestamp);
+
+int gb_connection_pop_timestamp(struct gb_connection *connection,
+ struct timeval *tv)
+{
+ int retval;
+
+ if (!kfifo_len(&connection->ts_kfifo))
+ return -ENOMEM;
+ retval = kfifo_out_locked(&connection->ts_kfifo, (void *)tv,
+ sizeof(*tv), &connection->lock);
+ return retval;
+}
+EXPORT_SYMBOL_GPL(gb_connection_pop_timestamp);
+
static ssize_t state_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -102,6 +129,7 @@ static void gb_connection_release(struct device *dev)
struct gb_connection *connection = to_gb_connection(dev);
destroy_workqueue(connection->wq);
+ kfifo_free(&connection->ts_kfifo);
kfree(connection);
}
@@ -222,6 +250,10 @@ gb_connection_create_range(struct greybus_host_device *hd,
if (!connection->wq)
goto err_free_connection;
+ if (kfifo_alloc(&connection->ts_kfifo, GB_CONNECTION_TS_KFIFO_LEN,
+ GFP_KERNEL))
+ goto err_free_connection;
+
connection->dev.parent = parent;
connection->dev.bus = &greybus_bus_type;
connection->dev.type = &greybus_connection_type;
@@ -238,7 +270,7 @@ gb_connection_create_range(struct greybus_host_device *hd,
pr_err("failed to add connection device for cport 0x%04hx\n",
cport_id);
- goto err_free_connection;
+ goto err_free_kfifo;
}
spin_lock_irq(&gb_connections_lock);
@@ -259,6 +291,8 @@ gb_connection_create_range(struct greybus_host_device *hd,
return connection;
+err_free_kfifo:
+ kfifo_free(&connection->ts_kfifo);
err_free_connection:
kfree(connection);
err_remove_ida:
diff --git a/drivers/staging/greybus/connection.h b/drivers/staging/greybus/connection.h
index 0dbbc202e953..a26a48033fc6 100644
--- a/drivers/staging/greybus/connection.h
+++ b/drivers/staging/greybus/connection.h
@@ -11,6 +11,7 @@
#define __CONNECTION_H
#include <linux/list.h>
+#include <linux/kfifo.h>
enum gb_connection_state {
GB_CONNECTION_STATE_INVALID = 0,
@@ -42,6 +43,7 @@ struct gb_connection {
struct list_head operations;
struct workqueue_struct *wq;
+ struct kfifo ts_kfifo;
atomic_t op_cycle;
@@ -65,6 +67,9 @@ void gb_hd_connections_exit(struct greybus_host_device *hd);
void greybus_data_rcvd(struct greybus_host_device *hd, u16 cport_id,
u8 *data, size_t length);
+void gb_connection_push_timestamp(struct gb_connection *connection);
+int gb_connection_pop_timestamp(struct gb_connection *connection,
+ struct timeval *tv);
void gb_connection_bind_protocol(struct gb_connection *connection);