189dd4c3bSJack Wang // SPDX-License-Identifier: GPL-2.0-or-later
289dd4c3bSJack Wang /*
389dd4c3bSJack Wang * RDMA Transport Layer
489dd4c3bSJack Wang *
589dd4c3bSJack Wang * Copyright (c) 2014 - 2018 ProfitBricks GmbH. All rights reserved.
689dd4c3bSJack Wang * Copyright (c) 2018 - 2019 1&1 IONOS Cloud GmbH. All rights reserved.
789dd4c3bSJack Wang * Copyright (c) 2019 - 2020 1&1 IONOS SE. All rights reserved.
889dd4c3bSJack Wang */
989dd4c3bSJack Wang #undef pr_fmt
1089dd4c3bSJack Wang #define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt
1189dd4c3bSJack Wang
1289dd4c3bSJack Wang #include "rtrs-clt.h"
1389dd4c3bSJack Wang
rtrs_clt_update_wc_stats(struct rtrs_clt_con * con)1489dd4c3bSJack Wang void rtrs_clt_update_wc_stats(struct rtrs_clt_con *con)
1589dd4c3bSJack Wang {
16caa84d95SVaishali Thakkar struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
17caa84d95SVaishali Thakkar struct rtrs_clt_stats *stats = clt_path->stats;
1889dd4c3bSJack Wang struct rtrs_clt_stats_pcpu *s;
1989dd4c3bSJack Wang int cpu;
2089dd4c3bSJack Wang
2189dd4c3bSJack Wang cpu = raw_smp_processor_id();
22db6169b5SGuoqing Jiang s = get_cpu_ptr(stats->pcpu_stats);
234693d6b7SGioh Kim if (con->cpu != cpu) {
2489dd4c3bSJack Wang s->cpu_migr.to++;
2589dd4c3bSJack Wang
2689dd4c3bSJack Wang /* Careful here, override s pointer */
2789dd4c3bSJack Wang s = per_cpu_ptr(stats->pcpu_stats, con->cpu);
2889dd4c3bSJack Wang atomic_inc(&s->cpu_migr.from);
2989dd4c3bSJack Wang }
30db6169b5SGuoqing Jiang put_cpu_ptr(stats->pcpu_stats);
3189dd4c3bSJack Wang }
3289dd4c3bSJack Wang
rtrs_clt_inc_failover_cnt(struct rtrs_clt_stats * stats)3389dd4c3bSJack Wang void rtrs_clt_inc_failover_cnt(struct rtrs_clt_stats *stats)
3489dd4c3bSJack Wang {
35*861703b4SSantosh Kumar Pradhan this_cpu_inc(stats->pcpu_stats->rdma.failover_cnt);
3689dd4c3bSJack Wang }
3789dd4c3bSJack Wang
rtrs_clt_stats_migration_from_cnt_to_str(struct rtrs_clt_stats * stats,char * buf)383f3fe682SMd Haris Iqbal int rtrs_clt_stats_migration_from_cnt_to_str(struct rtrs_clt_stats *stats, char *buf)
3989dd4c3bSJack Wang {
4089dd4c3bSJack Wang struct rtrs_clt_stats_pcpu *s;
4189dd4c3bSJack Wang
4289dd4c3bSJack Wang size_t used;
4389dd4c3bSJack Wang int cpu;
4489dd4c3bSJack Wang
453f3fe682SMd Haris Iqbal used = 0;
4689dd4c3bSJack Wang for_each_possible_cpu(cpu) {
4789dd4c3bSJack Wang s = per_cpu_ptr(stats->pcpu_stats, cpu);
482f232912SMd Haris Iqbal used += sysfs_emit_at(buf, used, "%d ",
4989dd4c3bSJack Wang atomic_read(&s->cpu_migr.from));
5089dd4c3bSJack Wang }
5189dd4c3bSJack Wang
523f3fe682SMd Haris Iqbal used += sysfs_emit_at(buf, used, "\n");
533f3fe682SMd Haris Iqbal
543f3fe682SMd Haris Iqbal return used;
553f3fe682SMd Haris Iqbal }
563f3fe682SMd Haris Iqbal
rtrs_clt_stats_migration_to_cnt_to_str(struct rtrs_clt_stats * stats,char * buf)573f3fe682SMd Haris Iqbal int rtrs_clt_stats_migration_to_cnt_to_str(struct rtrs_clt_stats *stats, char *buf)
583f3fe682SMd Haris Iqbal {
593f3fe682SMd Haris Iqbal struct rtrs_clt_stats_pcpu *s;
603f3fe682SMd Haris Iqbal
613f3fe682SMd Haris Iqbal size_t used;
623f3fe682SMd Haris Iqbal int cpu;
633f3fe682SMd Haris Iqbal
643f3fe682SMd Haris Iqbal used = 0;
6589dd4c3bSJack Wang for_each_possible_cpu(cpu) {
6689dd4c3bSJack Wang s = per_cpu_ptr(stats->pcpu_stats, cpu);
672f232912SMd Haris Iqbal used += sysfs_emit_at(buf, used, "%d ", s->cpu_migr.to);
6889dd4c3bSJack Wang }
693f3fe682SMd Haris Iqbal
702f232912SMd Haris Iqbal used += sysfs_emit_at(buf, used, "\n");
7189dd4c3bSJack Wang
7289dd4c3bSJack Wang return used;
7389dd4c3bSJack Wang }
7489dd4c3bSJack Wang
rtrs_clt_stats_reconnects_to_str(struct rtrs_clt_stats * stats,char * buf)7580ad07f7SMd Haris Iqbal int rtrs_clt_stats_reconnects_to_str(struct rtrs_clt_stats *stats, char *buf)
7689dd4c3bSJack Wang {
772f232912SMd Haris Iqbal return sysfs_emit(buf, "%d %d\n", stats->reconnects.successful_cnt,
7889dd4c3bSJack Wang stats->reconnects.fail_cnt);
7989dd4c3bSJack Wang }
8089dd4c3bSJack Wang
rtrs_clt_stats_rdma_to_str(struct rtrs_clt_stats * stats,char * page)8180ad07f7SMd Haris Iqbal ssize_t rtrs_clt_stats_rdma_to_str(struct rtrs_clt_stats *stats, char *page)
8289dd4c3bSJack Wang {
8389dd4c3bSJack Wang struct rtrs_clt_stats_rdma sum;
8489dd4c3bSJack Wang struct rtrs_clt_stats_rdma *r;
8589dd4c3bSJack Wang int cpu;
8689dd4c3bSJack Wang
8789dd4c3bSJack Wang memset(&sum, 0, sizeof(sum));
8889dd4c3bSJack Wang
8989dd4c3bSJack Wang for_each_possible_cpu(cpu) {
9089dd4c3bSJack Wang r = &per_cpu_ptr(stats->pcpu_stats, cpu)->rdma;
9189dd4c3bSJack Wang
9289dd4c3bSJack Wang sum.dir[READ].cnt += r->dir[READ].cnt;
9389dd4c3bSJack Wang sum.dir[READ].size_total += r->dir[READ].size_total;
9489dd4c3bSJack Wang sum.dir[WRITE].cnt += r->dir[WRITE].cnt;
9589dd4c3bSJack Wang sum.dir[WRITE].size_total += r->dir[WRITE].size_total;
9689dd4c3bSJack Wang sum.failover_cnt += r->failover_cnt;
9789dd4c3bSJack Wang }
9889dd4c3bSJack Wang
992f232912SMd Haris Iqbal return sysfs_emit(page, "%llu %llu %llu %llu %u %llu\n",
10089dd4c3bSJack Wang sum.dir[READ].cnt, sum.dir[READ].size_total,
10189dd4c3bSJack Wang sum.dir[WRITE].cnt, sum.dir[WRITE].size_total,
10289dd4c3bSJack Wang atomic_read(&stats->inflight), sum.failover_cnt);
10389dd4c3bSJack Wang }
10489dd4c3bSJack Wang
rtrs_clt_reset_all_help(struct rtrs_clt_stats * s,char * page)10580ad07f7SMd Haris Iqbal ssize_t rtrs_clt_reset_all_help(struct rtrs_clt_stats *s, char *page)
10689dd4c3bSJack Wang {
1072f232912SMd Haris Iqbal return sysfs_emit(page, "echo 1 to reset all statistics\n");
10889dd4c3bSJack Wang }
10989dd4c3bSJack Wang
rtrs_clt_reset_rdma_stats(struct rtrs_clt_stats * stats,bool enable)11089dd4c3bSJack Wang int rtrs_clt_reset_rdma_stats(struct rtrs_clt_stats *stats, bool enable)
11189dd4c3bSJack Wang {
11289dd4c3bSJack Wang struct rtrs_clt_stats_pcpu *s;
11389dd4c3bSJack Wang int cpu;
11489dd4c3bSJack Wang
11589dd4c3bSJack Wang if (!enable)
11689dd4c3bSJack Wang return -EINVAL;
11789dd4c3bSJack Wang
11889dd4c3bSJack Wang for_each_possible_cpu(cpu) {
11989dd4c3bSJack Wang s = per_cpu_ptr(stats->pcpu_stats, cpu);
12089dd4c3bSJack Wang memset(&s->rdma, 0, sizeof(s->rdma));
12189dd4c3bSJack Wang }
12289dd4c3bSJack Wang
12389dd4c3bSJack Wang return 0;
12489dd4c3bSJack Wang }
12589dd4c3bSJack Wang
rtrs_clt_reset_cpu_migr_stats(struct rtrs_clt_stats * stats,bool enable)12689dd4c3bSJack Wang int rtrs_clt_reset_cpu_migr_stats(struct rtrs_clt_stats *stats, bool enable)
12789dd4c3bSJack Wang {
12889dd4c3bSJack Wang struct rtrs_clt_stats_pcpu *s;
12989dd4c3bSJack Wang int cpu;
13089dd4c3bSJack Wang
13189dd4c3bSJack Wang if (!enable)
13289dd4c3bSJack Wang return -EINVAL;
13389dd4c3bSJack Wang
13489dd4c3bSJack Wang for_each_possible_cpu(cpu) {
13589dd4c3bSJack Wang s = per_cpu_ptr(stats->pcpu_stats, cpu);
13689dd4c3bSJack Wang memset(&s->cpu_migr, 0, sizeof(s->cpu_migr));
13789dd4c3bSJack Wang }
13889dd4c3bSJack Wang
13989dd4c3bSJack Wang return 0;
14089dd4c3bSJack Wang }
14189dd4c3bSJack Wang
rtrs_clt_reset_reconnects_stat(struct rtrs_clt_stats * stats,bool enable)14289dd4c3bSJack Wang int rtrs_clt_reset_reconnects_stat(struct rtrs_clt_stats *stats, bool enable)
14389dd4c3bSJack Wang {
14489dd4c3bSJack Wang if (!enable)
14589dd4c3bSJack Wang return -EINVAL;
14689dd4c3bSJack Wang
14789dd4c3bSJack Wang memset(&stats->reconnects, 0, sizeof(stats->reconnects));
14889dd4c3bSJack Wang
14989dd4c3bSJack Wang return 0;
15089dd4c3bSJack Wang }
15189dd4c3bSJack Wang
rtrs_clt_reset_all_stats(struct rtrs_clt_stats * s,bool enable)15289dd4c3bSJack Wang int rtrs_clt_reset_all_stats(struct rtrs_clt_stats *s, bool enable)
15389dd4c3bSJack Wang {
15489dd4c3bSJack Wang if (enable) {
15589dd4c3bSJack Wang rtrs_clt_reset_rdma_stats(s, enable);
15689dd4c3bSJack Wang rtrs_clt_reset_cpu_migr_stats(s, enable);
15789dd4c3bSJack Wang rtrs_clt_reset_reconnects_stat(s, enable);
15889dd4c3bSJack Wang atomic_set(&s->inflight, 0);
15989dd4c3bSJack Wang return 0;
16089dd4c3bSJack Wang }
16189dd4c3bSJack Wang
16289dd4c3bSJack Wang return -EINVAL;
16389dd4c3bSJack Wang }
16489dd4c3bSJack Wang
rtrs_clt_update_rdma_stats(struct rtrs_clt_stats * stats,size_t size,int d)16589dd4c3bSJack Wang static inline void rtrs_clt_update_rdma_stats(struct rtrs_clt_stats *stats,
16689dd4c3bSJack Wang size_t size, int d)
16789dd4c3bSJack Wang {
168*861703b4SSantosh Kumar Pradhan this_cpu_inc(stats->pcpu_stats->rdma.dir[d].cnt);
169*861703b4SSantosh Kumar Pradhan this_cpu_add(stats->pcpu_stats->rdma.dir[d].size_total, size);
17089dd4c3bSJack Wang }
17189dd4c3bSJack Wang
rtrs_clt_update_all_stats(struct rtrs_clt_io_req * req,int dir)17289dd4c3bSJack Wang void rtrs_clt_update_all_stats(struct rtrs_clt_io_req *req, int dir)
17389dd4c3bSJack Wang {
17489dd4c3bSJack Wang struct rtrs_clt_con *con = req->con;
175caa84d95SVaishali Thakkar struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
176caa84d95SVaishali Thakkar struct rtrs_clt_stats *stats = clt_path->stats;
17789dd4c3bSJack Wang unsigned int len;
17889dd4c3bSJack Wang
17989dd4c3bSJack Wang len = req->usr_len + req->data_len;
18089dd4c3bSJack Wang rtrs_clt_update_rdma_stats(stats, len, dir);
1810d8f2cfaSGioh Kim if (req->mp_policy == MP_POLICY_MIN_INFLIGHT)
18289dd4c3bSJack Wang atomic_inc(&stats->inflight);
18389dd4c3bSJack Wang }
18489dd4c3bSJack Wang
rtrs_clt_init_stats(struct rtrs_clt_stats * stats)18589dd4c3bSJack Wang int rtrs_clt_init_stats(struct rtrs_clt_stats *stats)
18689dd4c3bSJack Wang {
18789dd4c3bSJack Wang stats->pcpu_stats = alloc_percpu(typeof(*stats->pcpu_stats));
18889dd4c3bSJack Wang if (!stats->pcpu_stats)
18989dd4c3bSJack Wang return -ENOMEM;
19089dd4c3bSJack Wang
19189dd4c3bSJack Wang /*
19289dd4c3bSJack Wang * successful_cnt will be set to 0 after session
19389dd4c3bSJack Wang * is established for the first time
19489dd4c3bSJack Wang */
19589dd4c3bSJack Wang stats->reconnects.successful_cnt = -1;
19689dd4c3bSJack Wang
19789dd4c3bSJack Wang return 0;
19889dd4c3bSJack Wang }
199