Commit a1a4a29c authored by Bryan O'Donoghue's avatar Bryan O'Donoghue Committed by Greg Kroah-Hartman

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: default avatarBryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 8ebc998f
......@@ -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:
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment