Hello, ISTR giving the same feedback before. On Wed, Jul 25, 2018 at 10:38:28AM -0700, Bart Van Assche wrote: > +struct remove_dev_work { > + struct callback_head head; > + struct scsi_device *sdev; > +}; > + > +static void delete_sdev(struct callback_head *head) > +{ > + struct remove_dev_work *work = container_of(head, typeof(*work), head); > + struct scsi_device *sdev = work->sdev; > + > + scsi_remove_device(sdev); > + kfree(work); > + scsi_device_put(sdev); > +} > + > 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; > -}; > + struct scsi_device *sdev = to_scsi_device(dev); > + struct remove_dev_work *work; > + int ret; > + > + ret = scsi_device_get(sdev); > + if (ret < 0) > + goto out; > + ret = -ENOMEM; > + work = kmalloc(sizeof(*work), GFP_KERNEL); > + if (!work) > + goto put; > + work->head.func = delete_sdev; > + work->sdev = sdev; > + ret = task_work_add(current, &work->head, false); > + if (ret < 0) > + goto free; > + ret = count; > + > +out: > + return ret; > + > +free: > + kfree(work); > + > +put: > + scsi_device_put(sdev); > + goto out; > +} 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? Thanks. -- tejun