I want to draw latency information for each struct bio that passes through the block layer. I have a module that overrides make_request_fn. I would want to find out how long did that bio took from there to reach request queue and from there to driver and so on.
I tried to attach a custom struct to the bio I receive at make_request_fn but since I did not create those, I cant use the bi_private field. Is there any way to work around this?
One option I have is to make a bio wrapper structure and copy bio structs into it before passing it to the lower functions so that I could use container_of to record times.
I have read about tools like blktrace and btt but I need that information inside my module. Is there any way to achieve this?
Thank you.
The solution I used seemed like a common workaround once I found something similar in the source of drbd block driver. The bi_private field can be used only by the function that allocates it. So I used bio_clone in the following way
bio_copy = bio_clone(bio_source, GFP_NOIO);
struct something *instance = kmalloc(sizeof(struct something), GFP_KERNEL);
instance->bio_original = bio_source;
//update timestamps for latency inside this struct instance
bio_copy->bi_private = instance;
bio_copy->bi_end_io = my_end_io_function;
bio_copy->bi_dev = bio_source->bi_dev;
...
...
make_request_fn(queue, bio_copy);
You'll have to write a bi_end_io function. Do remember to call bio_endio for original bio inside this function. You might need to copy bi_error field into bio_source's bi_error before calling bio_endio(bio_source).
Hope this helps someone.