#!/usr/bin/env drgn
#
# Copyright (C) 2019 Tejun Heo <tj@kernel.org>
# Copyright (C) 2019 Facebook

desc = """
This is a drgn script to monitor the blk-iocost cgroup controller.
See the comment at the top of block/blk-iocost.c for more details.
For drgn, visit https://github.com/osandov/drgn.
"""

import sys
import re
import time
import json
import math

import drgn
from drgn import container_of
from drgn.helpers.linux.list import list_for_each_entry,list_empty
from drgn.helpers.linux.radixtree import radix_tree_for_each,radix_tree_lookup

import argparse
parser = argparse.ArgumentParser(description=desc,
                                 formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('devname', metavar='DEV',
                    help='Target block device name (e.g. sda)')
parser.add_argument('--cgroup', action='append', metavar='REGEX',
                    help='Regex for target cgroups, ')
parser.add_argument('--interval', '-i', metavar='SECONDS', type=float, default=1,
                    help='Monitoring interval in seconds (0 exits immediately '
                    'after checking requirements)')
parser.add_argument('--json', action='store_true',
                    help='Output in json')
args = parser.parse_args()

def err(s):
    print(s, file=sys.stderr, flush=True)
    sys.exit(1)

try:
    blkcg_root = prog['blkcg_root']
    plid = prog['blkcg_policy_iocost'].plid.value_()
except:
    err('The kernel does not have iocost enabled')

IOC_RUNNING     = prog['IOC_RUNNING'].value_()
NR_USAGE_SLOTS  = prog['NR_USAGE_SLOTS'].value_()
HWEIGHT_WHOLE   = prog['HWEIGHT_WHOLE'].value_()
VTIME_PER_SEC   = prog['VTIME_PER_SEC'].value_()
VTIME_PER_USEC  = prog['VTIME_PER_USEC'].value_()
AUTOP_SSD_FAST  = prog['AUTOP_SSD_FAST'].value_()
AUTOP_SSD_DFL   = prog['AUTOP_SSD_DFL'].value_()
AUTOP_SSD_QD1   = prog['AUTOP_SSD_QD1'].value_()
AUTOP_HDD       = prog['AUTOP_HDD'].value_()

autop_names = {
    AUTOP_SSD_FAST:        'ssd_fast',
    AUTOP_SSD_DFL:         'ssd_dfl',
    AUTOP_SSD_QD1:         'ssd_qd1',
    AUTOP_HDD:             'hdd',
}

class BlkgIterator:
    def blkcg_name(blkcg):
        return blkcg.css.cgroup.kn.name.string_().decode('utf-8')

    def walk(self, blkcg, q_id, parent_path):
        if not self.include_dying and \
           not (blkcg.css.flags.value_() & prog['CSS_ONLINE'].value_()):
            return

        name = BlkgIterator.blkcg_name(blkcg)
        path = parent_path + '/' + name if parent_path else name
        blkg = drgn.Object(prog, 'struct blkcg_gq',
                           address=radix_tree_lookup(blkcg.blkg_tree.address_of_(), q_id))
        if not blkg.address_:
            return

        self.blkgs.append((path if path else '/', blkg))

        for c in list_for_each_entry('struct blkcg',
                                     blkcg.css.children.address_of_(), 'css.sibling'):
            self.walk(c, q_id, path)

    def __init__(self, root_blkcg, q_id, include_dying=False):
        self.include_dying = include_dying
        self.blkgs = []
        self.walk(root_blkcg, q_id, '')

    def __iter__(self):
        return iter(self.blkgs)

class IocStat:
    def __init__(self, ioc):
        global autop_names

        self.enabled = ioc.enabled.value_()
        self.running = ioc.running.value_() == IOC_RUNNING
        self.period_ms = ioc.period_us.value_() / 1_000
        self.period_at = ioc.period_at.value_() / 1_000_000
        self.vperiod_at = ioc.period_at_vtime.value_() / VTIME_PER_SEC
        self.vrate_pct = ioc.vtime_rate.counter.value_() * 100 / VTIME_PER_USEC
        self.busy_level = ioc.busy_level.value_()
        self.autop_idx = ioc.autop_idx.value_()
        self.user_cost_model = ioc.user_cost_model.value_()
        self.user_qos_params = ioc.user_qos_params.value_()

        if self.autop_idx in autop_names:
            self.autop_name = autop_names[self.autop_idx]
        else:
            self.autop_name = '?'

    def dict(self, now):
        return { 'device'               : devname,
                 'timestamp'            : now,
                 'enabled'              : self.enabled,
                 'running'              : self.running,
                 'period_ms'            : self.period_ms,
                 'period_at'            : self.period_at,
                 'period_vtime_at'      : self.vperiod_at,
                 'busy_level'           : self.busy_level,
                 'vrate_pct'            : self.vrate_pct, }

    def table_preamble_str(self):
        state = ('RUN' if self.running else 'IDLE') if self.enabled else 'OFF'
        output = f'{devname} {state:4} ' \
                 f'per={self.period_ms}ms ' \
                 f'cur_per={self.period_at:.3f}:v{self.vperiod_at:.3f} ' \
                 f'busy={self.busy_level:+3} ' \
                 f'vrate={self.vrate_pct:6.2f}% ' \
                 f'params={self.autop_name}'
        if self.user_cost_model or self.user_qos_params:
            output += f'({"C" if self.user_cost_model else ""}{"Q" if self.user_qos_params else ""})'
        return output

    def table_header_str(self):
        return f'{"":25} active {"weight":>9} {"hweight%":>13} {"inflt%":>6} ' \
               f'{"dbt":>3} {"delay":>6} {"usages%"}'

class IocgStat:
    def __init__(self, iocg):
        ioc = iocg.ioc
        blkg = iocg.pd.blkg

        self.is_active = not list_empty(iocg.active_list.address_of_())
        self.weight = iocg.weight.value_()
        self.active = iocg.active.value_()
        self.inuse = iocg.inuse.value_()
        self.hwa_pct = iocg.hweight_active.value_() * 100 / HWEIGHT_WHOLE
        self.hwi_pct = iocg.hweight_inuse.value_() * 100 / HWEIGHT_WHOLE
        self.address = iocg.value_()

        vdone = iocg.done_vtime.counter.value_()
        vtime = iocg.vtime.counter.value_()
        vrate = ioc.vtime_rate.counter.value_()
        period_vtime = ioc.period_us.value_() * vrate
        if period_vtime:
            self.inflight_pct = (vtime - vdone) * 100 / period_vtime
        else:
            self.inflight_pct = 0

        # vdebt used to be an atomic64_t and is now u64, support both
        try:
            self.debt_ms = iocg.abs_vdebt.counter.value_() / VTIME_PER_USEC / 1000
        except:
            self.debt_ms = iocg.abs_vdebt.value_() / VTIME_PER_USEC / 1000

        self.use_delay = blkg.use_delay.counter.value_()
        self.delay_ms = blkg.delay_nsec.counter.value_() / 1_000_000

        usage_idx = iocg.usage_idx.value_()
        self.usages = []
        self.usage = 0
        for i in range(NR_USAGE_SLOTS):
            usage = iocg.usages[(usage_idx + 1 + i) % NR_USAGE_SLOTS].value_()
            upct = usage * 100 / HWEIGHT_WHOLE
            self.usages.append(upct)
            self.usage = max(self.usage, upct)

    def dict(self, now, path):
        out = { 'cgroup'                : path,
                'timestamp'             : now,
                'is_active'             : self.is_active,
                'weight'                : self.weight,
                'weight_active'         : self.active,
                'weight_inuse'          : self.inuse,
                'hweight_active_pct'    : self.hwa_pct,
                'hweight_inuse_pct'     : self.hwi_pct,
                'inflight_pct'          : self.inflight_pct,
                'debt_ms'               : self.debt_ms,
                'use_delay'             : self.use_delay,
                'delay_ms'              : self.delay_ms,
                'usage_pct'             : self.usage,
                'address'               : self.address }
        for i in range(len(self.usages)):
            out[f'usage_pct_{i}'] = str(self.usages[i])
        return out

    def table_row_str(self, path):
        out = f'{path[-28:]:28} ' \
              f'{"*" if self.is_active else " "} ' \
              f'{self.inuse:5}/{self.active:5} ' \
              f'{self.hwi_pct:6.2f}/{self.hwa_pct:6.2f} ' \
              f'{self.inflight_pct:6.2f} ' \
              f'{min(math.ceil(self.debt_ms), 999):3} ' \
              f'{min(self.use_delay, 99):2}*'\
              f'{min(math.ceil(self.delay_ms), 999):03} '
        for u in self.usages:
            out += f'{min(round(u), 999):03d}:'
        out = out.rstrip(':')
        return out

# handle args
table_fmt = not args.json
interval = args.interval
devname = args.devname

if args.json:
    table_fmt = False

re_str = None
if args.cgroup:
    for r in args.cgroup:
        if re_str is None:
            re_str = r
        else:
            re_str += '|' + r

filter_re = re.compile(re_str) if re_str else None

# Locate the roots
q_id = None
root_iocg = None
ioc = None

for i, ptr in radix_tree_for_each(blkcg_root.blkg_tree.address_of_()):
    blkg = drgn.Object(prog, 'struct blkcg_gq', address=ptr)
    try:
        if devname == blkg.q.kobj.parent.name.string_().decode('utf-8'):
            q_id = blkg.q.id.value_()
            if blkg.pd[plid]:
                root_iocg = container_of(blkg.pd[plid], 'struct ioc_gq', 'pd')
                ioc = root_iocg.ioc
            break
    except:
        pass

if ioc is None:
    err(f'Could not find ioc for {devname}');

if interval == 0:
    sys.exit(0)

# Keep printing
while True:
    now = time.time()
    iocstat = IocStat(ioc)
    output = ''

    if table_fmt:
        output += '\n' + iocstat.table_preamble_str()
        output += '\n' + iocstat.table_header_str()
    else:
        output += json.dumps(iocstat.dict(now))

    for path, blkg in BlkgIterator(blkcg_root, q_id):
        if filter_re and not filter_re.match(path):
            continue
        if not blkg.pd[plid]:
            continue

        iocg = container_of(blkg.pd[plid], 'struct ioc_gq', 'pd')
        iocg_stat = IocgStat(iocg)

        if not filter_re and not iocg_stat.is_active:
            continue

        if table_fmt:
            output += '\n' + iocg_stat.table_row_str(path)
        else:
            output += '\n' + json.dumps(iocg_stat.dict(now, path))

    print(output)
    sys.stdout.flush()
    time.sleep(interval)
