0

I've been looking and looking and everybody explains the /proc/diskstats file, but nobody seems to explain where that data comes from.

I found this comment:

Just remember that /proc/diskstats is tracking the kernel’s read requests–not yours.

on this page:

https://kevinclosson.net/2018/10/09/no-proc-diskstats-does-not-track-your-physical-i-o-requests/

But basically my problem is that I've got a kernel module that creates a block device, and handles requests via a request handler set via blk_queue_make_request not blk_init_queue, just like dm, I don't want the kernel to queue requests for me.

Everything works fine, but nothing shows up in /proc/diskstats What bit of magic am I missing to get my stats in there so it will show up in iostat? I assumed the kernel would be tallying this information since it's handling the requests to the kernel module, but apparently not. or I'm missing a flag somewhere or something.

Any ideas?

2 Answers 2

1

The stats file is named diskstats, instead of blkdevstats or similar. This is a clue. The statistics are output by diskstats_show() in block/genhd.c, and it uses the struct gendisk structures as its information source.

You have created a block device, but for regular disks that is just the first step. After that there is usually alloc_disk() to allocate struct gendisks for all minor numbers presented by the device driver, and add_disk() after specifying the basic properties of each disk the device driver handles.

But you said you don't want queuing, so you've probably skipped that part to just get a basic block device. Well, you got exactly what you asked for - in fact, the basic block device is so lean and mean, it does not even take the time to tally statistics unless you make your module do so.

It looks like your driver will get its disks in /proc/diskstats only if it participates in the gendisk/genhd framework. If you don't want to use that, it looks like you'll have to collect your own statistics.

For more details, this might be helpful: https://olegkutkov.me/2020/02/10/linux-block-device-driver/

1
  • sorry, I wasn't trying to skip over information, I was only trying to point out that I call blk_queue_make_request() instead of blk_init_queue() to not have the kernel do queueing. I do call register_blkdev() then get a gendisk from alloc_disk() set all the gendisk params, and finally call add_disk() to create it. The block device functions perfectly I get read and write requests via the callback I passed to blk_queue_make_request(). So I am using the gendisk framework, but at least I have something else to look into now, thanks. I'll check out that blog post as well. Other tidbits welcome :-) Commented Sep 29, 2020 at 13:06
0

So I found it... it seems the kernel supplies helper functions for you....

you need the request_queue, the bio and the gendisk, call these before and after you process the io...

unsigned long start_time;
start_time = jiffies;
generic_start_io_acct(q, bio_op(bio), bio_sectors(bio), &gd->part0);

generic_end_io_acct(q, bio_op(bio), &gd->part0, start_time);

and voila, the stats and your block device start showing up in iostat.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.