kobject: '(null)' (00000000bbe09fa2): is not initialized, yet kobject_put() is being called.
阿新 • • 發佈:2022-01-07
1. 問題說明
在學習宋寶華老師第六章 "字元裝置驅動" 示例時,解除安裝globalmem
模組會報告下述異常:
[ 4039.481628] ------------[ cut here ]------------ [ 4039.482450] kobject: '(null)' (00000000bbe09fa2): is not initialized, yet kobject_put() is being called. [ 4039.483446] WARNING: CPU: 5 PID: 7475 at lib/kobject.c:750 kobject_put+0x74/0x90 [ 4039.484247] Modules linked in: globalmem(O-) [last unloaded: globalmem] [ 4039.484700] CPU: 5 PID: 7475 Comm: rmmod Tainted: G B W O 5.10.74.3-microsoft-standard-WSL2 #5 [ 4039.485330] RIP: 0010:kobject_put+0x74/0x90 [ 4039.485604] Code: 85 c0 7e 2b 5b 5d 41 5c 41 5d 41 5e 41 5f c3 48 89 ef e8 6f 7a 73 ff 48 8b 75 00 48 89 ea 48 c7 c7 c0 4e ea 9f e8 c5 1c 92 00 <0f> 0b eb b1 c3 5b 4c 89 e7 be 03 00 00 00 5d 41 5c 41 5d 41 5e 41 [ 4039.486863] RSP: 0018:ffff88813f7e7e18 EFLAGS: 00010282 [ 4039.487235] RAX: 0000000000000000 RBX: 00000000ffffffff RCX: 0000000000000000 [ 4039.487774] RDX: dffffc0000000000 RSI: 0000000000000008 RDI: ffffed1027efcfb5 [ 4039.488321] RBP: ffff8881343d4000 R08: 0000000000000000 R09: ffffed1027efcf54 [ 4039.488883] R10: ffff88813f7e7a9f R11: ffffed1027efcf53 R12: 0000000000000000 [ 4039.489501] R13: ffff8881343d403c R14: 0000000000000800 R15: 0000000000000000 [ 4039.490175] FS: 00007fb3dfaf5540(0000) GS:ffff888366b40000(0000) knlGS:0000000000000000 [ 4039.490874] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 4039.491391] CR2: 00007fb3dfcbe421 CR3: 000000017206e000 CR4: 0000000000350ea0 [ 4039.491994] Call Trace: [ 4039.492193] globalmem_exit+0x18/0x50 [globalmem] [ 4039.492560] __x64_sys_delete_module+0x22a/0x300 [ 4039.492955] ? __ia32_sys_delete_module+0x300/0x300 [ 4039.493360] ? mem_cgroup_handle_over_high+0x2b/0x360 [ 4039.493762] ? exit_to_user_mode_prepare+0xc1/0xe0 [ 4039.494240] do_syscall_64+0x33/0x80 [ 4039.494575] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 4039.494955] RIP: 0033:0x7fb3dfc41bcb [ 4039.495233] Code: 73 01 c3 48 8b 0d c5 82 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 b0 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 95 82 0c 00 f7 d8 64 89 01 48 [ 4039.496755] RSP: 002b:00007ffc444400b8 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0 [ 4039.497470] RAX: ffffffffffffffda RBX: 00005591f7a3d790 RCX: 00007fb3dfc41bcb [ 4039.498129] RDX: 000000000000000a RSI: 0000000000000800 RDI: 00005591f7a3d7f8 [ 4039.498714] RBP: 00007ffc44440118 R08: 0000000000000000 R09: 0000000000000000 [ 4039.499272] R10: 00007fb3dfcbdac0 R11: 0000000000000206 R12: 00007ffc444402f0 [ 4039.499818] R13: 00007ffc444418da R14: 00005591f7a3c2a0 R15: 00005591f7a3d790 [ 4039.500364] ---[ end trace 526b84e5b448dd54 ]---
2. 問題分析
檢視對應版本的核心程式碼,發現問題出在通過cdev_del
介面刪除字元裝置時,核心對未初始化就釋放的物件報告了一個warning。
// fs/char_dev.c void cdev_del(struct cdev *p) { cdev_unmap(p->dev, p->count); kobject_put(&p->kobj); } // lib/kobject.c void kobject_put(struct kobject *kobj) { if (kobj) { if (!kobj->state_initialized) WARN(1, KERN_WARNING "kobject: '%s' (%p): is not initialized, yet kobject_put() is being called.\n", kobject_name(kobj), kobj); kref_put(&kobj->kref, kobject_release); } } EXPORT_SYMBOL(kobject_put);
3. 解決辦法
既然是未初始化導致的warning
,那麼我們將其初始化即可。
// globalmem.c static int __init globalmem_init(void) { int ret; dev_t devno = MKDEV(globalmem_major, 0); if (globalmem_major) ret = register_chrdev_region(devno, 1, "globalmem"); else { ret = alloc_chrdev_region(&devno, 0, 1, "globalmem"); globalmem_major = MAJOR(devno); } if (ret < 0) return ret; globalmem_devp = kzalloc(sizeof(struct globalmem_dev), GFP_KERNEL); if (!globalmem_devp) { printk(KERN_ERR "kzalloc failed!\n"); ret = -ENOMEM; goto fail_malloc; } // 這裡對cdev物件進行初始化即可 cdev_init(&globalmem_devp->cdev, &globalmem_fops); globalmem_setup_cdev(globalmem_devp, 0); return 0; fail_malloc: unregister_chrdev_region(devno, 1); return ret; }
4. 測試驗證
➜ ch06 sudo dmesg -c
➜ ch06 make
make -C /lib/modules/5.10.74.3-microsoft-standard-WSL2/build M=/home/dw/src/drivers/study/globalmem/ch06 modules
make[1]: Entering directory '/home/dw/src/kernel/WSL2-Linux-Kernel'
make[1]: Leaving directory '/home/dw/src/kernel/WSL2-Linux-Kernel'
➜ ch06 sudo insmod ./globalmem.ko
➜ ch06 sudo rmmod globalmem
➜ ch06 dmesg
[ 4464.318048] kobject: 'globalmem' (00000000481400b3): kobject_add_internal: parent: 'module', set: 'module'
[ 4464.319001] kobject: 'holders' (0000000061e89e87): kobject_add_internal: parent: 'globalmem', set: '<NULL>'
[ 4464.319864] kobject: 'notes' (000000001486d8de): kobject_add_internal: parent: 'globalmem', set: '<NULL>'
[ 4464.320518] kobject: 'globalmem' (00000000481400b3): kobject_uevent_env
[ 4464.320965] kobject: 'globalmem' (00000000481400b3): fill_kobj_path: path = '/module/globalmem'
[ 4473.702248] try to del cdev
[ 4473.702258] kobject: '(null)' (00000000e357b512): kobject_cleanup, parent 0000000000000000
[ 4473.703282] kobject: '(null)' (00000000e357b512): calling ktype release
[ 4473.703858] try to free globalmem_devp
[ 4473.703862] try to unregister_chrdev_region
[ 4473.704335] kobject: 'holders' (0000000061e89e87): kobject_cleanup, parent 00000000481400b3
[ 4473.705287] kobject: 'holders' (0000000061e89e87): auto cleanup kobject_del
[ 4473.705756] kobject: 'holders' (0000000061e89e87): calling ktype release
[ 4473.706250] kobject: (0000000061e89e87): dynamic_kobj_release
[ 4473.706703] kobject: 'holders': free name
[ 4473.706984] kobject: 'notes' (000000001486d8de): kobject_cleanup, parent 00000000481400b3
[ 4473.707543] kobject: 'notes' (000000001486d8de): auto cleanup kobject_del
[ 4473.708034] kobject: 'notes' (000000001486d8de): calling ktype release
[ 4473.708514] kobject: (000000001486d8de): dynamic_kobj_release
[ 4473.709012] kobject: 'notes': free name
[ 4473.709495] kobject: 'globalmem' (00000000481400b3): kobject_cleanup, parent 000000000152e7cb
[ 4473.710273] kobject: 'globalmem' (00000000481400b3): auto cleanup kobject_del
[ 4473.710862] kobject: 'globalmem' (00000000481400b3): auto cleanup 'remove' event
[ 4473.711393] kobject: 'globalmem' (00000000481400b3): kobject_uevent_env
[ 4473.711862] kobject: 'globalmem' (00000000481400b3): fill_kobj_path: path = '/module/globalmem'
[ 4473.712499] kobject: 'globalmem' (00000000481400b3): calling ktype release
[ 4473.712937] kobject: 'globalmem': free name