cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

drbd_proc.c (10043B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      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
     11
     12 */
     13
     14#include <linux/module.h>
     15
     16#include <linux/uaccess.h>
     17#include <linux/fs.h>
     18#include <linux/file.h>
     19#include <linux/proc_fs.h>
     20#include <linux/seq_file.h>
     21#include <linux/drbd.h>
     22#include "drbd_int.h"
     23
     24struct proc_dir_entry *drbd_proc;
     25
     26static void seq_printf_with_thousands_grouping(struct seq_file *seq, long v)
     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);
     32		v %= 1000000;
     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}
     39
     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
     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 */
     90static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *seq,
     91		union drbd_dev_state state)
     92{
     93	unsigned long db, dt, dbdt, rt, rs_total, rs_left;
     94	unsigned int res;
     95	int i, x, y;
     96	int stalled = 0;
     97
     98	drbd_get_syncer_progress(device, state, &rs_total, &rs_left, &res);
     99
    100	x = res/50;
    101	y = 20-x;
    102	seq_puts(seq, "\t[");
    103	for (i = 1; i < x; i++)
    104		seq_putc(seq, '=');
    105	seq_putc(seq, '>');
    106	for (i = 0; i < y; i++)
    107		seq_putc(seq, '.');
    108	seq_puts(seq, "] ");
    109
    110	if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
    111		seq_puts(seq, "verified:");
    112	else
    113		seq_puts(seq, "sync'ed:");
    114	seq_printf(seq, "%3u.%u%% ", res / 10, res % 10);
    115
    116	/* if more than a few GB, display in MB */
    117	if (rs_total > (4UL << (30 - BM_BLOCK_SHIFT)))
    118		seq_printf(seq, "(%lu/%lu)M",
    119			    (unsigned long) Bit2KB(rs_left >> 10),
    120			    (unsigned long) Bit2KB(rs_total >> 10));
    121	else
    122		seq_printf(seq, "(%lu/%lu)K",
    123			    (unsigned long) Bit2KB(rs_left),
    124			    (unsigned long) Bit2KB(rs_total));
    125
    126	seq_puts(seq, "\n\t");
    127
    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	 */
    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. */
    140	/* ------------------------ ~18s average ------------------------ */
    141	i = (device->rs_last_mark + 2) % DRBD_SYNC_MARKS;
    142	dt = (jiffies - device->rs_mark_time[i]) / HZ;
    143	if (dt > 180)
    144		stalled = 1;
    145
    146	if (!dt)
    147		dt++;
    148	db = device->rs_mark_left[i] - rs_left;
    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
    154	dbdt = Bit2KB(db/dt);
    155	seq_puts(seq, " speed: ");
    156	seq_printf_with_thousands_grouping(seq, dbdt);
    157	seq_puts(seq, " (");
    158	/* ------------------------- ~3s average ------------------------ */
    159	if (drbd_proc_details >= 1) {
    160		/* this is what drbd_rs_should_slow_down() uses */
    161		i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
    162		dt = (jiffies - device->rs_mark_time[i]) / HZ;
    163		if (!dt)
    164			dt++;
    165		db = device->rs_mark_left[i] - rs_left;
    166		dbdt = Bit2KB(db/dt);
    167		seq_printf_with_thousands_grouping(seq, dbdt);
    168		seq_puts(seq, " -- ");
    169	}
    170
    171	/* --------------------- long term average ---------------------- */
    172	/* mean speed since syncer started
    173	 * we do account for PausedSync periods */
    174	dt = (jiffies - device->rs_start - device->rs_paused) / HZ;
    175	if (dt == 0)
    176		dt = 1;
    177	db = rs_total - rs_left;
    178	dbdt = Bit2KB(db/dt);
    179	seq_printf_with_thousands_grouping(seq, dbdt);
    180	seq_putc(seq, ')');
    181
    182	if (state.conn == C_SYNC_TARGET ||
    183	    state.conn == C_VERIFY_S) {
    184		seq_puts(seq, " want: ");
    185		seq_printf_with_thousands_grouping(seq, device->c_sync_rate);
    186	}
    187	seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : "");
    188
    189	if (drbd_proc_details >= 1) {
    190		/* 64 bit:
    191		 * we convert to sectors in the display below. */
    192		unsigned long bm_bits = drbd_bm_bits(device);
    193		unsigned long bit_pos;
    194		unsigned long long stop_sector = 0;
    195		if (state.conn == C_VERIFY_S ||
    196		    state.conn == C_VERIFY_T) {
    197			bit_pos = bm_bits - device->ov_left;
    198			if (verify_can_do_stop_sector(device))
    199				stop_sector = device->ov_stop_sector;
    200		} else
    201			bit_pos = device->bm_resync_fo;
    202		/* Total sectors may be slightly off for oddly
    203		 * sized devices. So what. */
    204		seq_printf(seq,
    205			"\t%3d%% sector pos: %llu/%llu",
    206			(int)(bit_pos / (bm_bits/100+1)),
    207			(unsigned long long)bit_pos * BM_SECT_PER_BIT,
    208			(unsigned long long)bm_bits * BM_SECT_PER_BIT);
    209		if (stop_sector != 0 && stop_sector != ULLONG_MAX)
    210			seq_printf(seq, " stop sector: %llu", stop_sector);
    211		seq_putc(seq, '\n');
    212	}
    213}
    214
    215int drbd_seq_show(struct seq_file *seq, void *v)
    216{
    217	int i, prev_i = -1;
    218	const char *sn;
    219	struct drbd_device *device;
    220	struct net_conf *nc;
    221	union drbd_dev_state state;
    222	char wp;
    223
    224	static char write_ordering_chars[] = {
    225		[WO_NONE] = 'n',
    226		[WO_DRAIN_IO] = 'd',
    227		[WO_BDEV_FLUSH] = 'f',
    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
    253	rcu_read_lock();
    254	idr_for_each_entry(&drbd_devices, device, i) {
    255		if (prev_i != i - 1)
    256			seq_putc(seq, '\n');
    257		prev_i = i;
    258
    259		state = device->state;
    260		sn = drbd_conn_str(state.conn);
    261
    262		if (state.conn == C_STANDALONE &&
    263		    state.disk == D_DISKLESS &&
    264		    state.role == R_SECONDARY) {
    265			seq_printf(seq, "%2d: cs:Unconfigured\n", i);
    266		} else {
    267			/* reset device->congestion_reason */
    268
    269			nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
    270			wp = nc ? nc->wire_protocol - DRBD_PROT_A + 'A' : ' ';
    271			seq_printf(seq,
    272			   "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c%c\n"
    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,
    276			   drbd_role_str(state.role),
    277			   drbd_role_str(state.peer),
    278			   drbd_disk_str(state.disk),
    279			   drbd_disk_str(state.pdsk),
    280			   wp,
    281			   drbd_suspended(device) ? 's' : 'r',
    282			   state.aftr_isp ? 'a' : '-',
    283			   state.peer_isp ? 'p' : '-',
    284			   state.user_isp ? 'u' : '-',
    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),
    298			   first_peer_device(device)->connection->epochs,
    299			   write_ordering_chars[device->resource->write_ordering]
    300			);
    301			seq_printf(seq, " oos:%llu\n",
    302				   Bit2KB((unsigned long long)
    303					   drbd_bm_total_weight(device)));
    304		}
    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);
    310
    311		if (drbd_proc_details >= 1 && get_ldev_if_state(device, D_FAILED)) {
    312			lc_seq_printf_stats(seq, device->resync);
    313			lc_seq_printf_stats(seq, device->act_log);
    314			put_ldev(device);
    315		}
    316
    317		if (drbd_proc_details >= 2)
    318			seq_printf(seq, "\tblocked on activity log: %d\n", atomic_read(&device->ap_actlog_cnt));
    319	}
    320	rcu_read_unlock();
    321
    322	return 0;
    323}