Before send this patch, I had run the xfstets. No new kmemleak/KASAN report.
Test on linux-next commit: 5b6a4bf680d61b1dd26629840f848d0df8983c62
Add some debug info in cifs_free_inode:
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -412,6 +412,11 @@ cifs_alloc_inode(struct super_block *sb)
static void
cifs_free_inode(struct inode *inode)
{
+ struct cifs_deferred_close *dclose;
+ list_for_each_entry(dclose, &CIFS_I(inode)->deferred_closes, dlist) {
+ printk("maybe leak %px\n", dclose);
+ }
+
kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
}
Step:
1. while true; do echo scan > /sys/kernel/debug/kmemleak; cat /sys/kernel/debug/kmemleak; sleep 10; done
2. run xfstest generic/029
dmesg:
[ 158.744333] maybe leak ffff88810f8b4380
[ 158.751709] maybe leak ffff8881774f7100
kmemleak report:
unreferenced object 0xffff88810f8b4380 (size 64):
comm "xfs_io", pid 1205, jiffies 4294824392 (age 54.681s)
hex dump (first 32 bytes):
00 71 4f 77 81 88 ff ff 58 af 64 7e 81 88 ff ff .qOw....X.d~....
00 4d 8b 0f 81 88 ff ff 00 00 28 77 81 88 ff ff .M........(w....
backtrace:
[<00000000f205d29f>] cifs_close+0x87/0x2d0
[<00000000bb6a0f7d>] __fput+0x111/0x440
[<0000000052732f3c>] task_work_run+0x85/0xc0
[<0000000050df65ac>] do_exit+0x5e5/0x1240
[<00000000579f0599>] do_group_exit+0x58/0xe0
[<00000000150b6679>] __x64_sys_exit_group+0x28/0x30
[<0000000040aba183>] do_syscall_64+0x35/0x80
[<000000007427e315>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
unreferenced object 0xffff8881774f7100 (size 64):
comm "hexdump", pid 1227, jiffies 4294824547 (age 54.527s)
hex dump (first 32 bytes):
58 af 64 7e 81 88 ff ff 80 43 8b 0f 81 88 ff ff X.d~.....C......
00 4d 8b 0f 81 88 ff ff 00 00 4f 77 81 88 ff ff .M........Ow....
backtrace:
[<00000000f205d29f>] cifs_close+0x87/0x2d0
[<00000000bb6a0f7d>] __fput+0x111/0x440
[<0000000052732f3c>] task_work_run+0x85/0xc0
[<0000000050df65ac>] do_exit+0x5e5/0x1240
[<00000000579f0599>] do_group_exit+0x58/0xe0
[<00000000150b6679>] __x64_sys_exit_group+0x28/0x30
[<0000000040aba183>] do_syscall_64+0x35/0x80
[<000000007427e315>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
Some more debug info point to when cancel the defered close, no free the cifs_deferred_close.
在 2022/8/19 10:53, Steve French 写道:
Don't see any problems with this - but would like to run some more tests on it
On Thu, Aug 18, 2022 at 8:24 PM zhangxiaoxu (A) <zhangxiaoxu5@xxxxxxxxxx> wrote:
running generic/029 and scan kmemleak on backend report this issue.
在 2022/8/19 0:28, Steve French 写道:
looks promising - am reviewing this now. Which xfstest did you see
this when runnign?
On Thu, Aug 18, 2022 at 8:01 AM Zhang Xiaoxu <zhangxiaoxu5@xxxxxxxxxx> wrote:
xfstests on smb21 report kmemleak as below:
unreferenced object 0xffff8881767d6200 (size 64):
comm "xfs_io", pid 1284, jiffies 4294777434 (age 20.789s)
hex dump (first 32 bytes):
80 5a d0 11 81 88 ff ff 78 8a aa 63 81 88 ff ff .Z......x..c....
00 71 99 76 81 88 ff ff 00 00 00 00 00 00 00 00 .q.v............
backtrace:
[<00000000ad04e6ea>] cifs_close+0x92/0x2c0
[<0000000028b93c82>] __fput+0xff/0x3f0
[<00000000d8116851>] task_work_run+0x85/0xc0
[<0000000027e14f9e>] do_exit+0x5e5/0x1240
[<00000000fb492b95>] do_group_exit+0x58/0xe0
[<00000000129a32d9>] __x64_sys_exit_group+0x28/0x30
[<00000000e3f7d8e9>] do_syscall_64+0x35/0x80
[<00000000102e8a0b>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
When cancel the deferred close work, we should also cleanup the struct
cifs_deferred_close.
Fixes: 9e992755be8f2 ("cifs: Call close synchronously during unlink/rename/lease break.")
Fixes: e3fc065682ebb ("cifs: Deferred close performance improvements")
Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@xxxxxxxxxx>
---
fs/cifs/misc.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 1f2628ffe9d7..87f60f736731 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -737,6 +737,8 @@ cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode)
list_for_each_entry(cfile, &cifs_inode->openFileList, flist) {
if (delayed_work_pending(&cfile->deferred)) {
if (cancel_delayed_work(&cfile->deferred)) {
+ cifs_del_deferred_close(cfile);
+
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
if (tmp_list == NULL)
break;
@@ -766,6 +768,8 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
list_for_each_entry(cfile, &tcon->openFileList, tlist) {
if (delayed_work_pending(&cfile->deferred)) {
if (cancel_delayed_work(&cfile->deferred)) {
+ cifs_del_deferred_close(cfile);
+
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
if (tmp_list == NULL)
break;
@@ -799,6 +803,8 @@ cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
if (strstr(full_path, path)) {
if (delayed_work_pending(&cfile->deferred)) {
if (cancel_delayed_work(&cfile->deferred)) {
+ cifs_del_deferred_close(cfile);
+
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
if (tmp_list == NULL)
break;
--
2.31.1