#include <sys/rds.h>
#include <sys/ib/clients/rdsv3/rdsv3.h>
struct rdsv3_statistics *rdsv3_stats = NULL;
uint_t nr_cpus;
static char *rdsv3_stat_names[] = {
"conn_reset",
"recv_drop_bad_checksum",
"recv_drop_old_seq",
"recv_drop_no_sock",
"recv_drop_dead_sock",
"recv_deliver_raced",
"recv_delivered",
"recv_queued",
"recv_immediate_retry",
"recv_delayed_retry",
"recv_ack_required",
"recv_rdma_bytes",
"recv_ping",
"send_queue_empty",
"send_queue_full",
"send_sem_contention",
"send_sem_queue_raced",
"send_immediate_retry",
"send_delayed_retry",
"send_drop_acked",
"send_ack_required",
"send_queued",
"send_rdma",
"send_rdma_bytes",
"send_pong",
"page_remainder_hit",
"page_remainder_miss",
"copy_to_user",
"copy_from_user",
"cong_update_queued",
"cong_update_received",
"cong_send_error",
"cong_send_blocked",
};
void
rdsv3_stats_info_copy(struct rdsv3_info_iterator *iter,
uint64_t *values, char **names, size_t nr)
{
struct rds_info_counter ctr;
size_t i;
for (i = 0; i < nr; i++) {
ASSERT(!(strlen(names[i]) >= sizeof (ctr.name)));
(void) strncpy((char *)ctr.name, names[i],
sizeof (ctr.name) - 1);
ctr.value = values[i];
rdsv3_info_copy(iter, &ctr, sizeof (ctr));
}
}
static void
rdsv3_stats_info(struct rsock *sock, unsigned int len,
struct rdsv3_info_iterator *iter,
struct rdsv3_info_lengths *lens)
{
struct rdsv3_statistics stats;
uint64_t *src;
uint64_t *sum;
size_t i;
int cpu;
unsigned int avail;
avail = len / sizeof (struct rds_info_counter);
if (avail < ARRAY_SIZE(rdsv3_stat_names)) {
avail = 0;
goto trans;
}
bzero(&stats, sizeof (struct rdsv3_statistics));
for (cpu = 0; cpu < nr_cpus; cpu++) {
src = (uint64_t *)&(rdsv3_per_cpu(rdsv3_stats, cpu));
sum = (uint64_t *)&stats;
for (i = 0;
i < sizeof (struct rdsv3_statistics) / sizeof (uint64_t);
i++)
*(sum++) += *(src++);
}
rdsv3_stats_info_copy(iter, (uint64_t *)&stats, rdsv3_stat_names,
ARRAY_SIZE(rdsv3_stat_names));
avail -= ARRAY_SIZE(rdsv3_stat_names);
trans:
lens->each = sizeof (struct rds_info_counter);
lens->nr = rdsv3_trans_stats_info_copy(iter, avail) +
ARRAY_SIZE(rdsv3_stat_names);
}
void
rdsv3_stats_exit(void)
{
rdsv3_info_deregister_func(RDS_INFO_COUNTERS, rdsv3_stats_info);
ASSERT(rdsv3_stats);
kmem_free(rdsv3_stats,
nr_cpus * sizeof (struct rdsv3_statistics));
rdsv3_stats = NULL;
}
int
rdsv3_stats_init(void)
{
nr_cpus = max_ncpus;
ASSERT(rdsv3_stats == NULL);
rdsv3_stats = kmem_zalloc(nr_cpus *
sizeof (struct rdsv3_statistics), KM_SLEEP);
rdsv3_info_register_func(RDS_INFO_COUNTERS, rdsv3_stats_info);
return (0);
}