// SPDX-License-Identifier: GPL-2.0-only
/*
 * Shared Memory Communications over RDMA (SMC-R) and RoCE
 *
 * SMC statistics netlink routines
 *
 * Copyright IBM Corp. 2021
 *
 * Author(s):  Guvenc Gulce
 */
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/percpu.h>
#include <linux/ctype.h>
#include <linux/smc.h>
#include <net/genetlink.h>
#include <net/sock.h>
#include "smc_netlink.h"
#include "smc_stats.h"

int smc_stats_init(struct net *net)
{
	net->smc.fback_rsn = kzalloc_obj(*net->smc.fback_rsn);
	if (!net->smc.fback_rsn)
		goto err_fback;
	net->smc.smc_stats = alloc_percpu(struct smc_stats);
	if (!net->smc.smc_stats)
		goto err_stats;
	mutex_init(&net->smc.mutex_fback_rsn);
	return 0;

err_stats:
	kfree(net->smc.fback_rsn);
err_fback:
	return -ENOMEM;
}

void smc_stats_exit(struct net *net)
{
	kfree(net->smc.fback_rsn);
	if (net->smc.smc_stats)
		free_percpu(net->smc.smc_stats);
}

static int smc_nl_fill_stats_rmb_data(struct sk_buff *skb,
				      struct smc_stats *stats, int tech,
				      int type)
{
	struct smc_stats_rmbcnt *stats_rmb_cnt;
	struct nlattr *attrs;

	if (type == SMC_NLA_STATS_T_TX_RMB_STATS)
		stats_rmb_cnt = &stats->smc[tech].rmb_tx;
	else
		stats_rmb_cnt = &stats->smc[tech].rmb_rx;

	attrs = nla_nest_start(skb, type);
	if (!attrs)
		goto errout;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_RMB_REUSE_CNT,
			      stats_rmb_cnt->reuse_cnt,
			      SMC_NLA_STATS_RMB_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_RMB_SIZE_SM_PEER_CNT,
			      stats_rmb_cnt->buf_size_small_peer_cnt,
			      SMC_NLA_STATS_RMB_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_RMB_SIZE_SM_CNT,
			      stats_rmb_cnt->buf_size_small_cnt,
			      SMC_NLA_STATS_RMB_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_RMB_FULL_PEER_CNT,
			      stats_rmb_cnt->buf_full_peer_cnt,
			      SMC_NLA_STATS_RMB_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_RMB_FULL_CNT,
			      stats_rmb_cnt->buf_full_cnt,
			      SMC_NLA_STATS_RMB_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_RMB_ALLOC_CNT,
			      stats_rmb_cnt->alloc_cnt,
			      SMC_NLA_STATS_RMB_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_RMB_DGRADE_CNT,
			      stats_rmb_cnt->dgrade_cnt,
			      SMC_NLA_STATS_RMB_PAD))
		goto errattr;

	nla_nest_end(skb, attrs);
	return 0;

errattr:
	nla_nest_cancel(skb, attrs);
errout:
	return -EMSGSIZE;
}

static int smc_nl_fill_stats_bufsize_data(struct sk_buff *skb,
					  struct smc_stats *stats, int tech,
					  int type)
{
	struct smc_stats_memsize *stats_pload;
	struct nlattr *attrs;

	if (type == SMC_NLA_STATS_T_TXPLOAD_SIZE)
		stats_pload = &stats->smc[tech].tx_pd;
	else if (type == SMC_NLA_STATS_T_RXPLOAD_SIZE)
		stats_pload = &stats->smc[tech].rx_pd;
	else if (type == SMC_NLA_STATS_T_TX_RMB_SIZE)
		stats_pload = &stats->smc[tech].tx_rmbsize;
	else if (type == SMC_NLA_STATS_T_RX_RMB_SIZE)
		stats_pload = &stats->smc[tech].rx_rmbsize;
	else
		goto errout;

	attrs = nla_nest_start(skb, type);
	if (!attrs)
		goto errout;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_PLOAD_8K,
			      stats_pload->buf[SMC_BUF_8K],
			      SMC_NLA_STATS_PLOAD_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_PLOAD_16K,
			      stats_pload->buf[SMC_BUF_16K],
			      SMC_NLA_STATS_PLOAD_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_PLOAD_32K,
			      stats_pload->buf[SMC_BUF_32K],
			      SMC_NLA_STATS_PLOAD_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_PLOAD_64K,
			      stats_pload->buf[SMC_BUF_64K],
			      SMC_NLA_STATS_PLOAD_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_PLOAD_128K,
			      stats_pload->buf[SMC_BUF_128K],
			      SMC_NLA_STATS_PLOAD_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_PLOAD_256K,
			      stats_pload->buf[SMC_BUF_256K],
			      SMC_NLA_STATS_PLOAD_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_PLOAD_512K,
			      stats_pload->buf[SMC_BUF_512K],
			      SMC_NLA_STATS_PLOAD_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_PLOAD_1024K,
			      stats_pload->buf[SMC_BUF_1024K],
			      SMC_NLA_STATS_PLOAD_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_PLOAD_G_1024K,
			      stats_pload->buf[SMC_BUF_G_1024K],
			      SMC_NLA_STATS_PLOAD_PAD))
		goto errattr;

	nla_nest_end(skb, attrs);
	return 0;

errattr:
	nla_nest_cancel(skb, attrs);
errout:
	return -EMSGSIZE;
}

static int smc_nl_fill_stats_tech_data(struct sk_buff *skb,
				       struct smc_stats *stats, int tech)
{
	struct smc_stats_tech *smc_tech;
	struct nlattr *attrs;

	smc_tech = &stats->smc[tech];
	if (tech == SMC_TYPE_D)
		attrs = nla_nest_start(skb, SMC_NLA_STATS_SMCD_TECH);
	else
		attrs = nla_nest_start(skb, SMC_NLA_STATS_SMCR_TECH);

	if (!attrs)
		goto errout;
	if (smc_nl_fill_stats_rmb_data(skb, stats, tech,
				       SMC_NLA_STATS_T_TX_RMB_STATS))
		goto errattr;
	if (smc_nl_fill_stats_rmb_data(skb, stats, tech,
				       SMC_NLA_STATS_T_RX_RMB_STATS))
		goto errattr;
	if (smc_nl_fill_stats_bufsize_data(skb, stats, tech,
					   SMC_NLA_STATS_T_TXPLOAD_SIZE))
		goto errattr;
	if (smc_nl_fill_stats_bufsize_data(skb, stats, tech,
					   SMC_NLA_STATS_T_RXPLOAD_SIZE))
		goto errattr;
	if (smc_nl_fill_stats_bufsize_data(skb, stats, tech,
					   SMC_NLA_STATS_T_TX_RMB_SIZE))
		goto errattr;
	if (smc_nl_fill_stats_bufsize_data(skb, stats, tech,
					   SMC_NLA_STATS_T_RX_RMB_SIZE))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_CLNT_V1_SUCC,
			      smc_tech->clnt_v1_succ_cnt,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_CLNT_V2_SUCC,
			      smc_tech->clnt_v2_succ_cnt,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_SRV_V1_SUCC,
			      smc_tech->srv_v1_succ_cnt,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_SRV_V2_SUCC,
			      smc_tech->srv_v2_succ_cnt,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_RX_BYTES,
			      smc_tech->rx_bytes,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_TX_BYTES,
			      smc_tech->tx_bytes,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_uint(skb, SMC_NLA_STATS_T_RX_RMB_USAGE,
			 smc_tech->rx_rmbuse))
		goto errattr;
	if (nla_put_uint(skb, SMC_NLA_STATS_T_TX_RMB_USAGE,
			 smc_tech->tx_rmbuse))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_RX_CNT,
			      smc_tech->rx_cnt,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_TX_CNT,
			      smc_tech->tx_cnt,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_SENDPAGE_CNT,
			      0,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_CORK_CNT,
			      smc_tech->cork_cnt,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_NDLY_CNT,
			      smc_tech->ndly_cnt,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_SPLICE_CNT,
			      smc_tech->splice_cnt,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_URG_DATA_CNT,
			      smc_tech->urg_data_cnt,
			      SMC_NLA_STATS_PAD))
		goto errattr;

	nla_nest_end(skb, attrs);
	return 0;

errattr:
	nla_nest_cancel(skb, attrs);
errout:
	return -EMSGSIZE;
}

int smc_nl_get_stats(struct sk_buff *skb,
		     struct netlink_callback *cb)
{
	struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb);
	struct net *net = sock_net(skb->sk);
	struct smc_stats *stats;
	struct nlattr *attrs;
	int cpu, i, size;
	void *nlh;
	u64 *src;
	u64 *sum;

	if (cb_ctx->pos[0])
		goto errmsg;
	nlh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
			  &smc_gen_nl_family, NLM_F_MULTI,
			  SMC_NETLINK_GET_STATS);
	if (!nlh)
		goto errmsg;

	attrs = nla_nest_start(skb, SMC_GEN_STATS);
	if (!attrs)
		goto errnest;
	stats = kzalloc_obj(*stats);
	if (!stats)
		goto erralloc;
	size = sizeof(*stats) / sizeof(u64);
	for_each_possible_cpu(cpu) {
		src = (u64 *)per_cpu_ptr(net->smc.smc_stats, cpu);
		sum = (u64 *)stats;
		for (i = 0; i < size; i++)
			*(sum++) += *(src++);
	}
	if (smc_nl_fill_stats_tech_data(skb, stats, SMC_TYPE_D))
		goto errattr;
	if (smc_nl_fill_stats_tech_data(skb, stats, SMC_TYPE_R))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_CLNT_HS_ERR_CNT,
			      stats->clnt_hshake_err_cnt,
			      SMC_NLA_STATS_PAD))
		goto errattr;
	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_SRV_HS_ERR_CNT,
			      stats->srv_hshake_err_cnt,
			      SMC_NLA_STATS_PAD))
		goto errattr;

	nla_nest_end(skb, attrs);
	genlmsg_end(skb, nlh);
	cb_ctx->pos[0] = 1;
	kfree(stats);
	return skb->len;

errattr:
	kfree(stats);
erralloc:
	nla_nest_cancel(skb, attrs);
errnest:
	genlmsg_cancel(skb, nlh);
errmsg:
	return skb->len;
}

static int smc_nl_get_fback_details(struct sk_buff *skb,
				    struct netlink_callback *cb, int pos,
				    bool is_srv)
{
	struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb);
	struct net *net = sock_net(skb->sk);
	int cnt_reported = cb_ctx->pos[2];
	struct smc_stats_fback *trgt_arr;
	struct nlattr *attrs;
	int rc = 0;
	void *nlh;

	if (is_srv)
		trgt_arr = &net->smc.fback_rsn->srv[0];
	else
		trgt_arr = &net->smc.fback_rsn->clnt[0];
	if (!trgt_arr[pos].fback_code)
		return -ENODATA;
	nlh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
			  &smc_gen_nl_family, NLM_F_MULTI,
			  SMC_NETLINK_GET_FBACK_STATS);
	if (!nlh)
		goto errmsg;
	attrs = nla_nest_start(skb, SMC_GEN_FBACK_STATS);
	if (!attrs)
		goto errout;
	if (nla_put_u8(skb, SMC_NLA_FBACK_STATS_TYPE, is_srv))
		goto errattr;
	if (!cnt_reported) {
		if (nla_put_u64_64bit(skb, SMC_NLA_FBACK_STATS_SRV_CNT,
				      net->smc.fback_rsn->srv_fback_cnt,
				      SMC_NLA_FBACK_STATS_PAD))
			goto errattr;
		if (nla_put_u64_64bit(skb, SMC_NLA_FBACK_STATS_CLNT_CNT,
				      net->smc.fback_rsn->clnt_fback_cnt,
				      SMC_NLA_FBACK_STATS_PAD))
			goto errattr;
		cnt_reported = 1;
	}

	if (nla_put_u32(skb, SMC_NLA_FBACK_STATS_RSN_CODE,
			trgt_arr[pos].fback_code))
		goto errattr;
	if (nla_put_u16(skb, SMC_NLA_FBACK_STATS_RSN_CNT,
			trgt_arr[pos].count))
		goto errattr;

	cb_ctx->pos[2] = cnt_reported;
	nla_nest_end(skb, attrs);
	genlmsg_end(skb, nlh);
	return rc;

errattr:
	nla_nest_cancel(skb, attrs);
errout:
	genlmsg_cancel(skb, nlh);
errmsg:
	return -EMSGSIZE;
}

int smc_nl_get_fback_stats(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb);
	struct net *net = sock_net(skb->sk);
	int rc_srv = 0, rc_clnt = 0, k;
	int skip_serv = cb_ctx->pos[1];
	int snum = cb_ctx->pos[0];
	bool is_srv = true;

	mutex_lock(&net->smc.mutex_fback_rsn);
	for (k = 0; k < SMC_MAX_FBACK_RSN_CNT; k++) {
		if (k < snum)
			continue;
		if (!skip_serv) {
			rc_srv = smc_nl_get_fback_details(skb, cb, k, is_srv);
			if (rc_srv && rc_srv != -ENODATA)
				break;
		} else {
			skip_serv = 0;
		}
		rc_clnt = smc_nl_get_fback_details(skb, cb, k, !is_srv);
		if (rc_clnt && rc_clnt != -ENODATA) {
			skip_serv = 1;
			break;
		}
		if (rc_clnt == -ENODATA && rc_srv == -ENODATA)
			break;
	}
	mutex_unlock(&net->smc.mutex_fback_rsn);
	cb_ctx->pos[1] = skip_serv;
	cb_ctx->pos[0] = k;
	return skb->len;
}
