Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/net/smc/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 11 kB image not shown  

Quelle  smc_stats.c   Sprache: 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(sizeof(*net->smc.fback_rsn), GFP_KERNEL);
 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(sizeof(*stats), GFP_KERNEL);
 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;
}

Messung V0.5
C=100 H=46 G=77

¤ Dauer der Verarbeitung: 0.8 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.