+ max = obd_get_max_rpcs_in_flight(&dev->u.cli);
+ seq_printf(m, "%u\n", max);
+
+ return 0;
+}
+
+static ssize_t mdc_max_rpcs_in_flight_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
+{
+ struct obd_device *dev;
+ __s64 val;
+ int rc;
+
+ dev = ((struct seq_file *)file->private_data)->private;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+
+ if (val < 0 || val > UINT_MAX)
+ return -ERANGE;
+
+ rc = obd_set_max_rpcs_in_flight(&dev->u.cli, val);
+ if (rc)
+ return rc;
+
+ return count;
+}
+LPROC_SEQ_FOPS(mdc_max_rpcs_in_flight);
+
+static int mdc_max_mod_rpcs_in_flight_seq_show(struct seq_file *m, void *v)
+{
+ struct obd_device *dev = m->private;
+ __u16 max;
+
+ max = obd_get_max_mod_rpcs_in_flight(&dev->u.cli);
+ seq_printf(m, "%hu\n", max);
+
+ return 0;
+}
+
+static ssize_t mdc_max_mod_rpcs_in_flight_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
+{
+ struct obd_device *dev;
+ __s64 val;
+ int rc;
+
+ dev = ((struct seq_file *)file->private_data)->private;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+
+ if (val < 0 || val > USHRT_MAX)
+ return -ERANGE;
+
+ rc = obd_set_max_mod_rpcs_in_flight(&dev->u.cli, val);
+ if (rc)
+ count = rc;
+
+ return count;
+}
+LPROC_SEQ_FOPS(mdc_max_mod_rpcs_in_flight);
+
+static ssize_t mdc_rpc_stats_seq_write(struct file *file,
+ const char __user *buf,
+ size_t len, loff_t *off)
+{
+ struct seq_file *seq = file->private_data;
+ struct obd_device *dev = seq->private;
+ struct client_obd *cli = &dev->u.cli;
+
+ lprocfs_oh_clear(&cli->cl_mod_rpcs_hist);
+
+ lprocfs_oh_clear(&cli->cl_read_rpc_hist);
+ lprocfs_oh_clear(&cli->cl_write_rpc_hist);
+ lprocfs_oh_clear(&cli->cl_read_page_hist);
+ lprocfs_oh_clear(&cli->cl_write_page_hist);
+ lprocfs_oh_clear(&cli->cl_read_offset_hist);
+ lprocfs_oh_clear(&cli->cl_write_offset_hist);
+
+ return len;
+}
+
+#define pct(a, b) (b ? a * 100 / b : 0)
+static int mdc_rpc_stats_seq_show(struct seq_file *seq, void *v)
+{
+ struct obd_device *dev = seq->private;
+ struct client_obd *cli = &dev->u.cli;
+ unsigned long read_tot = 0, write_tot = 0, read_cum, write_cum;
+ int i;
+
+ obd_mod_rpc_stats_seq_show(&dev->u.cli, seq);
+
+ spin_lock(&cli->cl_loi_list_lock);
+
+ seq_printf(seq, "\nread RPCs in flight: %d\n",
+ cli->cl_r_in_flight);
+ seq_printf(seq, "write RPCs in flight: %d\n",
+ cli->cl_w_in_flight);
+ seq_printf(seq, "pending write pages: %d\n",
+ atomic_read(&cli->cl_pending_w_pages));
+ seq_printf(seq, "pending read pages: %d\n",
+ atomic_read(&cli->cl_pending_r_pages));
+
+ seq_printf(seq, "\n\t\t\tread\t\t\twrite\n");
+ seq_printf(seq, "pages per rpc rpcs %% cum %% |");
+ seq_printf(seq, " rpcs %% cum %%\n");
+
+ read_tot = lprocfs_oh_sum(&cli->cl_read_page_hist);
+ write_tot = lprocfs_oh_sum(&cli->cl_write_page_hist);
+
+ read_cum = 0;
+ write_cum = 0;
+ for (i = 0; i < OBD_HIST_MAX; i++) {
+ unsigned long r = cli->cl_read_page_hist.oh_buckets[i];
+ unsigned long w = cli->cl_write_page_hist.oh_buckets[i];
+
+ read_cum += r;
+ write_cum += w;
+ seq_printf(seq, "%d:\t\t%10lu %3lu %3lu | %10lu %3lu %3lu\n",
+ 1 << i, r, pct(r, read_tot),
+ pct(read_cum, read_tot), w,
+ pct(w, write_tot),
+ pct(write_cum, write_tot));
+ if (read_cum == read_tot && write_cum == write_tot)
+ break;
+ }
+
+ seq_printf(seq, "\n\t\t\tread\t\t\twrite\n");
+ seq_printf(seq, "rpcs in flight rpcs %% cum %% |");
+ seq_printf(seq, " rpcs %% cum %%\n");
+
+ read_tot = lprocfs_oh_sum(&cli->cl_read_rpc_hist);
+ write_tot = lprocfs_oh_sum(&cli->cl_write_rpc_hist);
+
+ read_cum = 0;
+ write_cum = 0;
+ for (i = 0; i < OBD_HIST_MAX; i++) {
+ unsigned long r = cli->cl_read_rpc_hist.oh_buckets[i];
+ unsigned long w = cli->cl_write_rpc_hist.oh_buckets[i];
+
+ read_cum += r;
+ write_cum += w;
+ seq_printf(seq, "%d:\t\t%10lu %3lu %3lu | %10lu %3lu %3lu\n",
+ i, r, pct(r, read_tot), pct(read_cum, read_tot), w,
+ pct(w, write_tot), pct(write_cum, write_tot));
+ if (read_cum == read_tot && write_cum == write_tot)
+ break;
+ }
+
+ seq_printf(seq, "\n\t\t\tread\t\t\twrite\n");
+ seq_printf(seq, "offset rpcs %% cum %% |");
+ seq_printf(seq, " rpcs %% cum %%\n");
+
+ read_tot = lprocfs_oh_sum(&cli->cl_read_offset_hist);
+ write_tot = lprocfs_oh_sum(&cli->cl_write_offset_hist);
+
+ read_cum = 0;
+ write_cum = 0;
+ for (i = 0; i < OBD_HIST_MAX; i++) {
+ unsigned long r = cli->cl_read_offset_hist.oh_buckets[i];
+ unsigned long w = cli->cl_write_offset_hist.oh_buckets[i];
+
+ read_cum += r;
+ write_cum += w;
+ seq_printf(seq, "%d:\t\t%10lu %3lu %3lu | %10lu %3lu %3lu\n",
+ (i == 0) ? 0 : 1 << (i - 1),
+ r, pct(r, read_tot), pct(read_cum, read_tot),
+ w, pct(w, write_tot), pct(write_cum, write_tot));
+ if (read_cum == read_tot && write_cum == write_tot)
+ break;
+ }
+ spin_unlock(&cli->cl_loi_list_lock);
+
+ return 0;
+}
+#undef pct
+LPROC_SEQ_FOPS(mdc_rpc_stats);
+
+static int mdc_stats_seq_show(struct seq_file *seq, void *v)
+{
+ struct timespec64 now;
+ struct obd_device *dev = seq->private;
+ struct osc_stats *stats = &obd2osc_dev(dev)->od_stats;
+
+ ktime_get_real_ts64(&now);
+
+ seq_printf(seq, "snapshot_time: %lld.%09lu (secs.nsecs)\n",
+ (s64)now.tv_sec, now.tv_nsec);
+ seq_printf(seq, "lockless_write_bytes\t\t%llu\n",
+ stats->os_lockless_writes);
+ seq_printf(seq, "lockless_read_bytes\t\t%llu\n",
+ stats->os_lockless_reads);
+ seq_printf(seq, "lockless_truncate\t\t%llu\n",
+ stats->os_lockless_truncates);
+ return 0;
+}
+
+static ssize_t mdc_stats_seq_write(struct file *file,
+ const char __user *buf,
+ size_t len, loff_t *off)