]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/block/drbd/drbd_proc.c
UBUNTU: Ubuntu-5.15.0-39.42
[mirror_ubuntu-jammy-kernel.git] / drivers / block / drbd / drbd_proc.c
CommitLineData
c6ae4c04 1// SPDX-License-Identifier: GPL-2.0-or-later
b411b363
PR
2/*
3 drbd_proc.c
4
5 This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
6
7 Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
8 Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
9 Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
10
b411b363
PR
11
12 */
13
b411b363
PR
14#include <linux/module.h>
15
7e5fec31 16#include <linux/uaccess.h>
b411b363
PR
17#include <linux/fs.h>
18#include <linux/file.h>
b411b363
PR
19#include <linux/proc_fs.h>
20#include <linux/seq_file.h>
21#include <linux/drbd.h>
22#include "drbd_int.h"
23
b411b363 24struct proc_dir_entry *drbd_proc;
b411b363 25
fbe0d91c 26static void seq_printf_with_thousands_grouping(struct seq_file *seq, long v)
439d5953
LE
27{
28 /* v is in kB/sec. We don't expect TiByte/sec yet. */
29 if (unlikely(v >= 1000000)) {
30 /* cool: > GiByte/s */
31 seq_printf(seq, "%ld,", v / 1000000);
fc251d5c 32 v %= 1000000;
439d5953
LE
33 seq_printf(seq, "%03ld,%03ld", v/1000, v % 1000);
34 } else if (likely(v >= 1000))
35 seq_printf(seq, "%ld,%03ld", v/1000, v % 1000);
36 else
37 seq_printf(seq, "%ld", v);
38}
b411b363 39
a5655dac
LE
40static void drbd_get_syncer_progress(struct drbd_device *device,
41 union drbd_dev_state state, unsigned long *rs_total,
42 unsigned long *bits_left, unsigned int *per_mil_done)
43{
44 /* this is to break it at compile time when we change that, in case we
45 * want to support more than (1<<32) bits on a 32bit arch. */
46 typecheck(unsigned long, device->rs_total);
47 *rs_total = device->rs_total;
48
49 /* note: both rs_total and rs_left are in bits, i.e. in
50 * units of BM_BLOCK_SIZE.
51 * for the percentage, we don't care. */
52
53 if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
54 *bits_left = device->ov_left;
55 else
56 *bits_left = drbd_bm_total_weight(device) - device->rs_failed;
57 /* >> 10 to prevent overflow,
58 * +1 to prevent division by zero */
59 if (*bits_left > *rs_total) {
60 /* D'oh. Maybe a logic bug somewhere. More likely just a race
61 * between state change and reset of rs_total.
62 */
63 *bits_left = *rs_total;
64 *per_mil_done = *rs_total ? 0 : 1000;
65 } else {
66 /* Make sure the division happens in long context.
67 * We allow up to one petabyte storage right now,
68 * at a granularity of 4k per bit that is 2**38 bits.
69 * After shift right and multiplication by 1000,
70 * this should still fit easily into a 32bit long,
71 * so we don't need a 64bit division on 32bit arch.
72 * Note: currently we don't support such large bitmaps on 32bit
73 * arch anyways, but no harm done to be prepared for it here.
74 */
75 unsigned int shift = *rs_total > UINT_MAX ? 16 : 10;
76 unsigned long left = *bits_left >> shift;
77 unsigned long total = 1UL + (*rs_total >> shift);
78 unsigned long tmp = 1000UL - left * 1000UL/total;
79 *per_mil_done = tmp;
80 }
81}
82
83
b411b363
PR
84/*lge
85 * progress bars shamelessly adapted from driver/md/md.c
86 * output looks like
87 * [=====>..............] 33.5% (23456/123456)
88 * finish: 2:20:20 speed: 6,345 (6,456) K/sec
89 */
a5655dac
LE
90static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *seq,
91 union drbd_dev_state state)
b411b363 92{
a5655dac 93 unsigned long db, dt, dbdt, rt, rs_total, rs_left;
b411b363
PR
94 unsigned int res;
95 int i, x, y;
1d7734a0 96 int stalled = 0;
b411b363 97
a5655dac 98 drbd_get_syncer_progress(device, state, &rs_total, &rs_left, &res);
b411b363
PR
99
100 x = res/50;
101 y = 20-x;
7e5fec31 102 seq_puts(seq, "\t[");
b411b363 103 for (i = 1; i < x; i++)
7e5fec31
FF
104 seq_putc(seq, '=');
105 seq_putc(seq, '>');
b411b363 106 for (i = 0; i < y; i++)
427fd2be 107 seq_putc(seq, '.');
7e5fec31 108 seq_puts(seq, "] ");
b411b363 109
a5655dac 110 if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
7e5fec31 111 seq_puts(seq, "verified:");
5f9915bb 112 else
7e5fec31 113 seq_puts(seq, "sync'ed:");
5f9915bb
LE
114 seq_printf(seq, "%3u.%u%% ", res / 10, res % 10);
115
4b0715f0 116 /* if more than a few GB, display in MB */
a5655dac 117 if (rs_total > (4UL << (30 - BM_BLOCK_SHIFT)))
4b0715f0 118 seq_printf(seq, "(%lu/%lu)M",
b411b363 119 (unsigned long) Bit2KB(rs_left >> 10),
a5655dac 120 (unsigned long) Bit2KB(rs_total >> 10));
b411b363 121 else
590001c2 122 seq_printf(seq, "(%lu/%lu)K",
b411b363 123 (unsigned long) Bit2KB(rs_left),
a5655dac 124 (unsigned long) Bit2KB(rs_total));
b411b363 125
7e5fec31 126 seq_puts(seq, "\n\t");
590001c2 127
b411b363
PR
128 /* see drivers/md/md.c
129 * We do not want to overflow, so the order of operands and
130 * the * 100 / 100 trick are important. We do a +1 to be
131 * safe against division by zero. We only estimate anyway.
132 *
133 * dt: time from mark until now
134 * db: blocks written from mark until now
135 * rt: remaining time
136 */
1d7734a0
LE
137 /* Rolling marks. last_mark+1 may just now be modified. last_mark+2 is
138 * at least (DRBD_SYNC_MARKS-2)*DRBD_SYNC_MARK_STEP old, and has at
139 * least DRBD_SYNC_MARK_STEP time before it will be modified. */
439d5953 140 /* ------------------------ ~18s average ------------------------ */
b30ab791
AG
141 i = (device->rs_last_mark + 2) % DRBD_SYNC_MARKS;
142 dt = (jiffies - device->rs_mark_time[i]) / HZ;
9ae47260 143 if (dt > 180)
1d7734a0 144 stalled = 1;
b411b363
PR
145
146 if (!dt)
147 dt++;
b30ab791 148 db = device->rs_mark_left[i] - rs_left;
b411b363
PR
149 rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */
150
151 seq_printf(seq, "finish: %lu:%02lu:%02lu",
152 rt / 3600, (rt % 3600) / 60, rt % 60);
153
b411b363 154 dbdt = Bit2KB(db/dt);
7e5fec31 155 seq_puts(seq, " speed: ");
439d5953 156 seq_printf_with_thousands_grouping(seq, dbdt);
7e5fec31 157 seq_puts(seq, " (");
439d5953 158 /* ------------------------- ~3s average ------------------------ */
183ece30 159 if (drbd_proc_details >= 1) {
439d5953 160 /* this is what drbd_rs_should_slow_down() uses */
b30ab791
AG
161 i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
162 dt = (jiffies - device->rs_mark_time[i]) / HZ;
439d5953
LE
163 if (!dt)
164 dt++;
b30ab791 165 db = device->rs_mark_left[i] - rs_left;
439d5953
LE
166 dbdt = Bit2KB(db/dt);
167 seq_printf_with_thousands_grouping(seq, dbdt);
7e5fec31 168 seq_puts(seq, " -- ");
439d5953 169 }
b411b363 170
439d5953 171 /* --------------------- long term average ---------------------- */
b411b363
PR
172 /* mean speed since syncer started
173 * we do account for PausedSync periods */
b30ab791 174 dt = (jiffies - device->rs_start - device->rs_paused) / HZ;
22657695 175 if (dt == 0)
b411b363 176 dt = 1;
a5655dac 177 db = rs_total - rs_left;
b411b363 178 dbdt = Bit2KB(db/dt);
439d5953 179 seq_printf_with_thousands_grouping(seq, dbdt);
7e5fec31 180 seq_putc(seq, ')');
b411b363 181
a5655dac
LE
182 if (state.conn == C_SYNC_TARGET ||
183 state.conn == C_VERIFY_S) {
7e5fec31 184 seq_puts(seq, " want: ");
b30ab791 185 seq_printf_with_thousands_grouping(seq, device->c_sync_rate);
1d7734a0
LE
186 }
187 seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : "");
5f9915bb 188
183ece30 189 if (drbd_proc_details >= 1) {
5f9915bb
LE
190 /* 64 bit:
191 * we convert to sectors in the display below. */
b30ab791 192 unsigned long bm_bits = drbd_bm_bits(device);
4896e8c1 193 unsigned long bit_pos;
58ffa580 194 unsigned long long stop_sector = 0;
a5655dac
LE
195 if (state.conn == C_VERIFY_S ||
196 state.conn == C_VERIFY_T) {
b30ab791
AG
197 bit_pos = bm_bits - device->ov_left;
198 if (verify_can_do_stop_sector(device))
199 stop_sector = device->ov_stop_sector;
58ffa580 200 } else
b30ab791 201 bit_pos = device->bm_resync_fo;
5f9915bb
LE
202 /* Total sectors may be slightly off for oddly
203 * sized devices. So what. */
204 seq_printf(seq,
58ffa580 205 "\t%3d%% sector pos: %llu/%llu",
5f9915bb 206 (int)(bit_pos / (bm_bits/100+1)),
4896e8c1
LE
207 (unsigned long long)bit_pos * BM_SECT_PER_BIT,
208 (unsigned long long)bm_bits * BM_SECT_PER_BIT);
58ffa580
LE
209 if (stop_sector != 0 && stop_sector != ULLONG_MAX)
210 seq_printf(seq, " stop sector: %llu", stop_sector);
7e5fec31 211 seq_putc(seq, '\n');
5f9915bb 212 }
b411b363
PR
213}
214
004fd11d 215int drbd_seq_show(struct seq_file *seq, void *v)
b411b363 216{
81a5d60e 217 int i, prev_i = -1;
b411b363 218 const char *sn;
b30ab791 219 struct drbd_device *device;
44ed167d 220 struct net_conf *nc;
a5655dac 221 union drbd_dev_state state;
44ed167d 222 char wp;
b411b363
PR
223
224 static char write_ordering_chars[] = {
f6ba8636
AG
225 [WO_NONE] = 'n',
226 [WO_DRAIN_IO] = 'd',
227 [WO_BDEV_FLUSH] = 'f',
b411b363
PR
228 };
229
230 seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n",
231 API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag());
232
233 /*
234 cs .. connection state
235 ro .. node role (local/remote)
236 ds .. disk state (local/remote)
237 protocol
238 various flags
239 ns .. network send
240 nr .. network receive
241 dw .. disk write
242 dr .. disk read
243 al .. activity log write count
244 bm .. bitmap update write count
245 pe .. pending (waiting for ack or data reply)
246 ua .. unack'd (still need to send ack or data reply)
247 ap .. application requests accepted, but not yet completed
248 ep .. number of epochs currently "on the fly", P_BARRIER_ACK pending
249 wo .. write ordering mode currently in use
250 oos .. known out-of-sync kB
251 */
252
c141ebda 253 rcu_read_lock();
05a10ec7 254 idr_for_each_entry(&drbd_devices, device, i) {
81a5d60e 255 if (prev_i != i - 1)
7e5fec31 256 seq_putc(seq, '\n');
81a5d60e 257 prev_i = i;
b411b363 258
a5655dac
LE
259 state = device->state;
260 sn = drbd_conn_str(state.conn);
b411b363 261
a5655dac
LE
262 if (state.conn == C_STANDALONE &&
263 state.disk == D_DISKLESS &&
264 state.role == R_SECONDARY) {
b411b363
PR
265 seq_printf(seq, "%2d: cs:Unconfigured\n", i);
266 } else {
b30ab791 267 /* reset device->congestion_reason */
8a943170 268
a6b32bc3 269 nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
44ed167d 270 wp = nc ? nc->wire_protocol - DRBD_PROT_A + 'A' : ' ';
b411b363 271 seq_printf(seq,
0778286a 272 "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c%c\n"
b411b363
PR
273 " ns:%u nr:%u dw:%u dr:%u al:%u bm:%u "
274 "lo:%d pe:%d ua:%d ap:%d ep:%d wo:%c",
275 i, sn,
a5655dac
LE
276 drbd_role_str(state.role),
277 drbd_role_str(state.peer),
278 drbd_disk_str(state.disk),
279 drbd_disk_str(state.pdsk),
44ed167d 280 wp,
b30ab791 281 drbd_suspended(device) ? 's' : 'r',
a5655dac
LE
282 state.aftr_isp ? 'a' : '-',
283 state.peer_isp ? 'p' : '-',
284 state.user_isp ? 'u' : '-',
b30ab791
AG
285 device->congestion_reason ?: '-',
286 test_bit(AL_SUSPENDED, &device->flags) ? 's' : '-',
287 device->send_cnt/2,
288 device->recv_cnt/2,
289 device->writ_cnt/2,
290 device->read_cnt/2,
291 device->al_writ_cnt,
292 device->bm_writ_cnt,
293 atomic_read(&device->local_cnt),
294 atomic_read(&device->ap_pending_cnt) +
295 atomic_read(&device->rs_pending_cnt),
296 atomic_read(&device->unacked_cnt),
297 atomic_read(&device->ap_bio_cnt),
a6b32bc3 298 first_peer_device(device)->connection->epochs,
e9526580 299 write_ordering_chars[device->resource->write_ordering]
b411b363 300 );
18edc0b9
LE
301 seq_printf(seq, " oos:%llu\n",
302 Bit2KB((unsigned long long)
b30ab791 303 drbd_bm_total_weight(device)));
b411b363 304 }
a5655dac
LE
305 if (state.conn == C_SYNC_SOURCE ||
306 state.conn == C_SYNC_TARGET ||
307 state.conn == C_VERIFY_S ||
308 state.conn == C_VERIFY_T)
309 drbd_syncer_progress(device, seq, state);
b30ab791 310
183ece30 311 if (drbd_proc_details >= 1 && get_ldev_if_state(device, D_FAILED)) {
b30ab791
AG
312 lc_seq_printf_stats(seq, device->resync);
313 lc_seq_printf_stats(seq, device->act_log);
314 put_ldev(device);
b411b363 315 }
ad3fee79 316
183ece30 317 if (drbd_proc_details >= 2)
ad3fee79 318 seq_printf(seq, "\tblocked on activity log: %d\n", atomic_read(&device->ap_actlog_cnt));
b411b363 319 }
c141ebda 320 rcu_read_unlock();
b411b363
PR
321
322 return 0;
323}