I am not so sure about __mt76_tx_complete_skb
. Initially I thought so too but the offset doesn't make any sense. I can disassemble the kernel module just fine in gdb. The interleaving with source code (disas/m
/disas/s
) seems a bit broken - at least where it actually counts - but that simply might be because it's in an inline function from list.h
.
The interesting part is that the address of __mt76_tx_complete_skb+0x56c
is actually outside of that function, which ends at +632 (NB: gdb prints it as decimal, that's 0x278).
p/x __mt76_tx_complete_skb+0x56c
0x8c6c
disas/s 0x8c6c
then gives us...
568 static inline void list_splice_init(struct list_head *list,
569 struct list_head *head)
570 {
571 if (!list_empty(list)) {
0x0000000000008c5c <+124>: ldr x3, [sp, #104]
0x0000000000008c60 <+128>: cmp x3, x0
0x0000000000008c64 <+132>: b.eq 0x8c88 <mt76_txq_schedule_pending+168> // b.none
572 __list_splice(list, head, head->next);
0x0000000000008c68 <+136>: ldp x2, x1, [x22, #48]
530 first->prev = prev;
0x0000000000008c6c <+140>: str x28, [x2, #8]
When I compare this to the output of disas/m 0x8c6c
....
disas/m 0x8c6c
Dump of assembler code for function mt76_txq_schedule_pending:
646
0x0000000000008be0 <+0>: stp x29, x30, [sp, #-128]!
0x0000000000008be4 <+4>: mov x29, sp
0x0000000000008be8 <+8>: stp x21, x22, [sp, #32]
0x0000000000008bec <+12>: mov x22, x0
0x0000000000008bf4 <+20>: stp x27, x28, [sp, #80]
647 spin_unlock(&phy->tx_lock);
0x0000000000008bfc <+28>: add x28, sp, #0x70
0x0000000000008c00 <+32>: stp x0, x28, [sp, #104]
0x0000000000008c08 <+40>: str x28, [sp, #120]
648 ret = mt76_txq_schedule_pending_wcid(phy, wcid);
649 spin_lock(&phy->tx_lock);
0x0000000000008bf0 <+16>: add x0, x0, #0x30
0x0000000000008bf8 <+24>: mov x1, x0
650
651 if (ret) {
652 if (list_empty(&wcid->tx_list))
653 list_add_tail(&wcid->tx_list, &phy->tx_list);
654 break;
655 }
656 }
657 spin_unlock(&phy->tx_lock);
0x0000000000008c94 <+180>: cmp x0, x28
0x0000000000008c98 <+184>: b.eq 0x8d40 <mt76_txq_schedule_pending+352> // b.none
one would guess that list_add_tail()
(or list_empty()
) somehow call list_splice_init()
. However, I don't see how that would be... list_splice_init()
is actually called directly in mac.c though. That's all more puzzling than helping.
The above was produced via...
./build_dir/target-aarch64_cortex-a53_musl/openwrt-sdk-24.10-SNAPSHOT-mediatek-filogic_gcc-13.3.0_musl.Linux-x86_64/staging_dir/toolchain-aarch64_cortex-a53_gcc-13.3.0_musl/bin/aarch64-openwrt-linux-gdb ./staging_dir/target-aarch64_cortex-a53_musl/root-mediatek/lib/modules/6.6.73/mt76.ko
[…]
(gdb) dir ./build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/linux-6.6.73/drivers/net/wireless/mediatek/mt76
(gdb) dir ./build_dir/target-aarch64_cortex-a53_musl/openwrt-sdk-24.10-SNAPSHOT-mediatek-filogic_gcc-13.3.0_musl.Linux-x86_64/build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/linux-6.6.73
(gdb) set substitute-path ../mt76-2025.02.14~e5fef138 .
on top of current openwrt-24.10
(b7b6ae7424
) and a minor ccache patch of mine.
I would like to add dump_stack()
and printk()
but I don't know how to do that correctly. Is there a practical way to do this somewhat structured (i.e. with git support)? I don't fancy editing inside build_dir
a lot because I haven't grasped the openwrt build system.