Skip to content

Commit

Permalink
tools/biolatpcts: Support measuring overall latencies between two events
Browse files Browse the repository at this point in the history
* Interpret negative interval as infinite and output once as soon as init is
  complete to indicate readiness.

* Output on SIGUSR1.

* When exit is requested through SIGINT, TERM or HUP, output the latency
  distribution one more time before exiting.

Combined, this allows using biolatpcts to measure the overall latency
distribution between two events.
  • Loading branch information
htejun authored and yonghong-song committed Nov 13, 2020
1 parent ca2d412 commit b2d3632
Showing 1 changed file with 34 additions and 4 deletions.
38 changes: 34 additions & 4 deletions tools/biolatpcts.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,31 @@
from __future__ import print_function
from bcc import BPF
from time import sleep
from threading import Event
import argparse
import json
import sys
import os
import signal

description = """
Monitor IO latency distribution of a block device
"""

parser = argparse.ArgumentParser(description = description,
epilog = """
When interval is infinite, biolatpcts will print out result once the
initialization is complete to indicate readiness. Once initialized,
biolatpcts will output whenever it receives SIGUSR1 and before exiting on
SIGINT, SIGTERM or SIGHUP. This can be used to obtain latency distribution
between two events.
"""

parser = argparse.ArgumentParser(description = description, epilog = epilog,
formatter_class = argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('dev', metavar='DEV', type=str,
help='Target block device (/dev/DEVNAME, DEVNAME or MAJ:MIN)')
parser.add_argument('-i', '--interval', type=int, default=3,
help='Report interval')
help='Report interval (0: exit after startup, -1: infinite)')
parser.add_argument('-w', '--which', choices=['from-rq-alloc', 'after-rq-alloc', 'on-device'],
default='on-device', help='Which latency to measure')
parser.add_argument('-p', '--pcts', metavar='PCT,...', type=str,
Expand Down Expand Up @@ -206,8 +216,28 @@ def format_usec(lat):
if args.interval == 0:
sys.exit(0)

while True:
sleep(args.interval)
# Set up signal handling so that we print the result on USR1 and before
# exiting on a signal. Combined with infinite interval, this can be used to
# obtain overall latency distribution between two events.
keep_running = True
result_req = Event()
def sig_handler(sig, frame):
global keep_running, result_req
if sig != signal.SIGUSR1:
keep_running = False
result_req.set()

for sig in (signal.SIGUSR1, signal.SIGINT, signal.SIGTERM, signal.SIGHUP):
signal.signal(sig, sig_handler)

# If infinite interval, always trigger the first output so that the caller
# can tell when initialization is complete.
if args.interval < 0:
result_req.set();

while keep_running:
result_req.wait(args.interval if args.interval > 0 else None)
result_req.clear()

rwdf_total = [0] * 4;

Expand Down

0 comments on commit b2d3632

Please sign in to comment.