mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:04:41 +01:00
This was done entirely with mindless brute force, using
git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'
to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.
Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.
For the same reason the 'flex' versions will be done as a separate
conversion.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
419 lines
11 KiB
C
419 lines
11 KiB
C
// 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;
|
|
}
|