Why kernl miss __blk_account_io_start kprobe

Posted rtoax

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Why kernl miss __blk_account_io_start kprobe相关的知识,希望对你有一定的参考价值。

Why kernl miss __blk_account_io_start kprobe

ENV

  • os: fedora37 x86_64
  • kernel: 6.1.10-200.fc37.x86_64
  • LLVM/Clang version 15.0.7
  • gcc (GCC) 12.2.1 20221121
  • Python 3.11.1

Error

biosnoop.py

$ sudo ./biosnoop.py
cannot attach kprobe, probe entry may not exist
Traceback (most recent call last):
  File "/home/sdb/Git/bcc/tools/./biosnoop.py", line 258, in <module>
    b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start")
  File "/usr/lib/python3.11/site-packages/bcc/__init__.py", line 840, in attach_kprobe
    raise Exception("Failed to attach BPF program %s to kprobe %s" %
Exception: Failed to attach BPF program b'trace_pid_start' to kprobe b'blk_account_io_start'

biotop.py

$ sudo ./biotop.py
cannot attach kprobe, probe entry may not exist
Traceback (most recent call last):
  File "/home/sdb/Git/bcc/tools/./biotop.py", line 211, in <module>
    b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start")
  File "/usr/lib/python3.11/site-packages/bcc/__init__.py", line 840, in attach_kprobe
    raise Exception("Failed to attach BPF program %s to kprobe %s" %
Exception: Failed to attach BPF program b'trace_pid_start' to kprobe b'blk_account_io_start'

objdump -d blk-mq.o

$ git remote get-url origin
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ git describe HEAD
v6.2-rc7-199-g420b2d431d18
$ pwd
/home/rongtao/Git/linux/block
$ objdump -d blk-mq.o | grep __blk_account_io_
0000000000000630 <__pfx___blk_account_io_done>:
0000000000000640 <__blk_account_io_done>:
     640:	e8 00 00 00 00       	call   645 <__blk_account_io_done+0x5>
     656:	0f 84 fc 00 00 00    	je     758 <__blk_account_io_done+0x118>
     674:	e8 00 00 00 00       	call   679 <__blk_account_io_done+0x39>
     679:	48 8b 35 00 00 00 00 	mov    0x0(%rip),%rsi        # 680 <__blk_account_io_done+0x40>
     689:	e8 00 00 00 00       	call   68e <__blk_account_io_done+0x4e>
     695:	e8 00 00 00 00       	call   69a <__blk_account_io_done+0x5a>
     6b4:	75 52                	jne    708 <__blk_account_io_done+0xc8>
     6bd:	e8 00 00 00 00       	call   6c2 <__blk_account_io_done+0x82>
     6e6:	75 46                	jne    72e <__blk_account_io_done+0xee>
     6ed:	e8 00 00 00 00       	call   6f2 <__blk_account_io_done+0xb2>
     6f2:	65 8b 05 00 00 00 00 	mov    %gs:0x0(%rip),%eax        # 6f9 <__blk_account_io_done+0xb9>
     6fb:	74 6c                	je     769 <__blk_account_io_done+0x129>
     703:	e9 00 00 00 00       	jmp    708 <__blk_account_io_done+0xc8>
     70f:	e8 00 00 00 00       	call   714 <__blk_account_io_done+0xd4>
     72c:	eb 88                	jmp    6b6 <__blk_account_io_done+0x76>
     735:	e8 00 00 00 00       	call   73a <__blk_account_io_done+0xfa>
     756:	eb 90                	jmp    6e8 <__blk_account_io_done+0xa8>
     764:	e9 06 ff ff ff       	jmp    66f <__blk_account_io_done+0x2f>
     769:	e8 00 00 00 00       	call   76e <__blk_account_io_done+0x12e>
     774:	e9 00 00 00 00       	jmp    779 <__blk_account_io_done+0x139>
    2afe:	e8 3d db ff ff       	call   640 <__blk_account_io_done>
    3788:	e8 b3 ce ff ff       	call   640 <__blk_account_io_done>
    5045:	e8 f6 b5 ff ff       	call   640 <__blk_account_io_done>

There is no __blk_account_io_start, Why?

kernel block/blk-mq.c

static void __blk_account_io_done(struct request *req, u64 now)

    const int sgrp = op_stat_group(req_op(req));

    part_stat_lock();
    update_io_ticks(req->part, jiffies, true);
    part_stat_inc(req->part, ios[sgrp]);
    part_stat_add(req->part, nsecs[sgrp], now - req->start_time_ns);
    part_stat_unlock();


static inline void blk_account_io_done(struct request *req, u64 now)

    /*
     * Account IO completion.  flush_rq isn't accounted as a
     * normal IO on queueing nor completion.  Accounting the
     * containing request is enough.
     */
    if (blk_do_io_stat(req) && req->part &&
        !(req->rq_flags & RQF_FLUSH_SEQ))
        __blk_account_io_done(req, now);


static void __blk_account_io_start(struct request *rq)

    /*
     * All non-passthrough requests are created from a bio with one
     * exception: when a flush command that is part of a flush sequence
     * generated by the state machine in blk-flush.c is cloned onto the
     * lower device by dm-multipath we can get here without a bio.
     */
    if (rq->bio)
        rq->part = rq->bio->bi_bdev;
    else
        rq->part = rq->q->disk->part0;

    part_stat_lock();
    update_io_ticks(rq->part, jiffies, false);
    part_stat_unlock();


static inline void blk_account_io_start(struct request *req)

    if (blk_do_io_stat(req))
        __blk_account_io_start(req);

The code above show us __blk_account_io_done and __blk_account_io_start has totally exact same function definition and usage method, why only __blk_account_io_done exists, and __blk_account_io_start is optimized by the compiler?

$ sudo bpftrace -l | grep __blk_account_io
kfunc:vmlinux:__blk_account_io_done
kprobe:__blk_account_io_done

以上是关于Why kernl miss __blk_account_io_start kprobe的主要内容,如果未能解决你的问题,请参考以下文章

Why IPv6 gateway missing

解决TypeError: __init__() missing 1 required positio

执行python manage.py makemigrations时报错TypeError: __init__() missing 1 required positional argument: &#

TypeError: __init__() missing 1 required positional argument: 'on_delete'

Django :执行 python manage.py makemigrations 时报错 TypeError: __init__() missing 1 required positional a

TypeError: __init__() missing 1 required positional argument: 'on_delete'