From: Bryan O'Donoghue Date: Tue, 11 Aug 2015 12:50:51 +0000 (+0100) Subject: greybus: connection: add a timestamp kfifo to track connection handoff X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=a1a4a29cb9e9593a1f47d549af212f35f131e6cc;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git 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 Signed-off-by: Greg Kroah-Hartman --- 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 +#include 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);