On Thu, 2018-07-26 at 07:14 -0700, tj@kernel.org wrote:
Hello,
On Thu, Jul 26, 2018 at 02:09:41PM +0000, Bart Van Assche wrote:
On Thu, 2018-07-26 at 06:35 -0700, Tejun Heo wrote:
Making removal asynchronous this way sometimes causes issues because whether the user sees the device released or not is racy. kernfs/sysfs have mechanisms to deal with these cases - remove_self and kernfs_break_active_protection(). Have you looked at those?
Hello Tejun,
The call stack in the patch description shows that sdev_store_delete() is involved in the deadlock. The implementation of that function is as follows:
static ssize_t sdev_store_delete(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { if (device_remove_file_self(dev, attr)) scsi_remove_device(to_scsi_device(dev)); return count; };
device_remove_file_self() calls sysfs_remove_file_self() and that last function calls kernfs_remove_self(). In other words, kernfs_remove_self() is already being used. Please let me know if I misunderstood your comment.
So, here, because scsi_remove_device() is the one involved in the circular dependency, just breaking the dependency chain on the file itself (self removal) isn't enough. You can wrap the whole operation with kernfs_break_active_protection() to also move scsi_remove_device() invocation outside the kernfs synchronization. This will need to be piped through sysfs but shouldn't be too complex.
Hello Tejun,
I have tried to implement the above but my implementation triggered a kernel warning. Can you have a look at the attached patches and see what I did wrong?
Thanks,
Bart.
The kernel warning I ran into is as follows:
kernfs_put: 6:0:0:0/delete: released with incorrect active_ref 2147483647 WARNING: CPU: 6 PID: 1014 at fs/kernfs/dir.c:527 kernfs_put+0x136/0x180 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014 RIP: 0010:kernfs_put+0x136/0x180 Call Trace: evict+0xc1/0x190 __dentry_kill+0xc4/0x150 shrink_dentry_list+0x9e/0x1c0 shrink_dcache_parent+0x63/0x70 d_invalidate+0x42/0xb0 lookup_fast+0x278/0x2a0 walk_component+0x38/0x450 link_path_walk+0x2a8/0x4f0 path_openat+0x89/0x13a0 do_filp_open+0x8c/0xf0 do_sys_open+0x1a6/0x230 do_syscall_64+0x4f/0x110 entry_SYSCALL_64_after_hwframe+0x44/0xa9