}
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)
{
struct gb_connection *connection = to_gb_connection(dev);
destroy_workqueue(connection->wq);
- kfifo_free(&connection->ts_kfifo);
kfree(connection);
}
if (!connection->wq)
goto err_free_connection;
- if (kfifo_alloc(&connection->ts_kfifo, GB_CONNECTION_TS_KFIFO_LEN,
- GFP_KERNEL))
- goto err_destroy_wq;
-
connection->dev.parent = parent;
connection->dev.bus = &greybus_bus_type;
connection->dev.type = &greybus_connection_type;
return connection;
-err_destroy_wq:
- destroy_workqueue(connection->wq);
err_free_connection:
kfree(connection);
err_remove_ida:
/* Overall stats */
struct gb_loopback_stats latency;
- struct gb_loopback_stats latency_gb;
struct gb_loopback_stats throughput;
struct gb_loopback_stats requests_per_second;
};
/* Per connection stats */
struct gb_loopback_stats latency;
- struct gb_loopback_stats latency_gb;
struct gb_loopback_stats throughput;
struct gb_loopback_stats requests_per_second;
u32 lbid;
u32 iteration_count;
u64 elapsed_nsecs;
- u64 elapsed_nsecs_gb;
u32 error;
};
/* Time to send and receive one message */
gb_loopback_stats_attrs(latency, dev, false);
gb_loopback_stats_attrs(latency, con, true);
-/* Time to send and receive one message not including greybus */
-gb_loopback_stats_attrs(latency_gb, dev, false);
-gb_loopback_stats_attrs(latency_gb, con, true);
/* Number of requests sent per second on this cport */
gb_loopback_stats_attrs(requests_per_second, dev, false);
gb_loopback_stats_attrs(requests_per_second, con, true);
&dev_attr_latency_min_dev.attr,
&dev_attr_latency_max_dev.attr,
&dev_attr_latency_avg_dev.attr,
- &dev_attr_latency_gb_min_dev.attr,
- &dev_attr_latency_gb_max_dev.attr,
- &dev_attr_latency_gb_avg_dev.attr,
&dev_attr_requests_per_second_min_dev.attr,
&dev_attr_requests_per_second_max_dev.attr,
&dev_attr_requests_per_second_avg_dev.attr,
&dev_attr_latency_min_con.attr,
&dev_attr_latency_max_con.attr,
&dev_attr_latency_avg_con.attr,
- &dev_attr_latency_gb_min_con.attr,
- &dev_attr_latency_gb_max_con.attr,
- &dev_attr_latency_gb_avg_con.attr,
&dev_attr_requests_per_second_min_con.attr,
&dev_attr_requests_per_second_max_con.attr,
&dev_attr_requests_per_second_avg_con.attr,
gb_loopback_push_latency_ts(gb, &ts, &te);
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 ret;
}
mutex_lock(&gb->mutex);
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,
memset(&gb_dev->start, 0, sizeof(struct timeval));
memset(&gb_dev->end, 0, sizeof(struct timeval));
memcpy(&gb_dev->latency, &reset, sizeof(struct gb_loopback_stats));
- memcpy(&gb_dev->latency_gb, &reset, sizeof(struct gb_loopback_stats));
memcpy(&gb_dev->throughput, &reset, sizeof(struct gb_loopback_stats));
memcpy(&gb_dev->requests_per_second, &reset,
sizeof(struct gb_loopback_stats));
static void gb_loopback_calculate_stats(struct gb_loopback *gb)
{
u32 lat;
- u64 tmp;
/* Express latency in terms of microseconds */
lat = gb_loopback_nsec_to_usec_latency(gb->elapsed_nsecs);
/* 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_dev.latency_gb, lat);
- gb_loopback_update_stats(&gb->latency_gb, lat);
}
static int gb_loopback_fn(void *data)