atomic_t outstanding_operations;
/* Per connection stats */
- struct timeval ts;
struct gb_loopback_stats latency;
struct gb_loopback_stats throughput;
struct gb_loopback_stats requests_per_second;
gb_loopback_push_latency_ts(gb, &op_async->ts, &te);
gb->elapsed_nsecs = gb_loopback_calc_latency(&op_async->ts,
&te);
+ gb_loopback_calculate_stats(gb);
}
if (op_async->pending) {
del_timer_sync(&op_async->timer);
gb_loopback_async_operation_put(op_async);
}
- gb_loopback_calculate_stats(gb);
mutex_unlock(&gb->mutex);
dev_dbg(&gb->connection->bundle->dev, "complete operation %d\n",
/* Should be initialized at least once per transaction set */
gb->apbridge_latency_ts = 0;
gb->gpbridge_latency_ts = 0;
- memset(&gb->ts, 0, sizeof(struct timeval));
}
static void gb_loopback_update_stats(struct gb_loopback_stats *stats, u32 val)
static void gb_loopback_requests_update(struct gb_loopback *gb, u32 latency)
{
- u64 req = gb->requests_completed * USEC_PER_SEC;
+ u32 req = USEC_PER_SEC;
do_div(req, latency);
- gb_loopback_update_stats(&gb->requests_per_second, (u32)req);
+ gb_loopback_update_stats(&gb->requests_per_second, req);
}
static void gb_loopback_throughput_update(struct gb_loopback *gb, u32 latency)
{
- u64 throughput;
+ u32 throughput;
u32 aggregate_size = sizeof(struct gb_operation_msg_hdr) * 2;
switch (gb->type) {
return;
}
- aggregate_size *= gb->requests_completed;
- throughput = aggregate_size * USEC_PER_SEC;
+ /* Calculate bytes per second */
+ throughput = USEC_PER_SEC;
do_div(throughput, latency);
- gb_loopback_update_stats(&gb->throughput, (u32)throughput);
+ throughput *= aggregate_size;
+ gb_loopback_update_stats(&gb->throughput, throughput);
}
-static void gb_loopback_calculate_latency_stats(struct gb_loopback *gb)
+static void gb_loopback_calculate_stats(struct gb_loopback *gb)
{
u32 lat;
/* Raw latency log on a per thread basis */
kfifo_in(&gb->kfifo_lat, (unsigned char *)&lat, sizeof(lat));
+ /* Log throughput and requests using latency as benchmark */
+ gb_loopback_throughput_update(gb, lat);
+ gb_loopback_requests_update(gb, lat);
+
/* Log the firmware supplied latency values */
gb_loopback_update_stats(&gb->apbridge_unipro_latency,
gb->apbridge_latency_ts);
gb->gpbridge_latency_ts);
}
-static void gb_loopback_calculate_stats(struct gb_loopback *gb)
-{
- u64 nlat;
- u32 lat;
- struct timeval te;
-
- gb_loopback_calculate_latency_stats(gb);
-
- if (gb->iteration_count == gb->iteration_max) {
- do_gettimeofday(&te);
- nlat = gb_loopback_calc_latency(&gb->ts, &te);
- lat = gb_loopback_nsec_to_usec_latency(nlat);
-
- gb_loopback_throughput_update(gb, lat);
- gb_loopback_requests_update(gb, lat);
-
- memset(&gb->ts, 0, sizeof(struct timeval));
- gb->type = 0;
- }
-}
-
static void gb_loopback_async_wait_to_send(struct gb_loopback *gb)
{
if (!(gb->async && gb->outstanding_operations_max))
/* Optionally terminate */
if (send_count == gb->iteration_max) {
- if (!gb->async)
- send_count = 0;
- else if (gb->iteration_count == gb->iteration_max)
- send_count = 0;
+ gb->type = 0;
+ send_count = 0;
mutex_unlock(&gb->mutex);
continue;
}
type = gb->type;
mutex_unlock(&gb->mutex);
- if (gb->ts.tv_usec == 0 && gb->ts.tv_sec == 0)
- do_gettimeofday(&gb->ts);
-
/* Else operations to perform */
if (gb->async) {
if (type == GB_LOOPBACK_TYPE_PING) {
error = gb_loopback_async_ping(gb);
- if (!error)
- gb->requests_completed++;
gb_loopback_calculate_stats(gb);
} else if (type == GB_LOOPBACK_TYPE_TRANSFER) {
error = gb_loopback_async_transfer(gb, size);
if (error)
gb->error++;
- else
- gb->requests_completed++;
gb->iteration_count++;
gb_loopback_calculate_stats(gb);
}