Hi Alex, > -----Original Message----- > From: Alex Williamson <alex.williamson@xxxxxxxxxx> > Sent: Wednesday, May 29, 2019 8:27 PM [..] > > > > diff --git a/drivers/vfio/mdev/mdev_core.c > > b/drivers/vfio/mdev/mdev_core.c index 0bef0cae1d4b..c5401a8c6843 > > 100644 > > --- a/drivers/vfio/mdev/mdev_core.c > > +++ b/drivers/vfio/mdev/mdev_core.c > > @@ -102,11 +102,36 @@ static void mdev_put_parent(struct mdev_parent > *parent) > > kref_put(&parent->ref, mdev_release_parent); } > > > > Some sort of locking semantics comment would be useful here, ex: > > /* Caller holds parent unreg_sem read or write lock */ > Added. > > + > > static int mdev_device_remove_cb(struct device *dev, void *data) { > > - if (dev_is_mdev(dev)) > > - mdev_device_remove(dev); > > + struct mdev_parent *parent; > > + struct mdev_device *mdev; > > > > + if (!dev_is_mdev(dev)) > > + return 0; > > + > > + mdev = to_mdev_device(dev); > > + parent = mdev->parent; > > + mdev_device_remove_common(mdev); > > 'parent' is unused here and we only use mdev once, so we probably don't need > to put it in a local variable. > Right left out from previous code. Removed and refactored the code now. > > return 0; > > } > > > > @@ -148,6 +173,7 @@ int mdev_register_device(struct device *dev, const > struct mdev_parent_ops *ops) > > } > > > > kref_init(&parent->ref); > > + init_rwsem(&parent->unreg_sem); > > > > parent->dev = dev; > > parent->ops = ops; > > @@ -206,13 +232,17 @@ void mdev_unregister_device(struct device *dev) > > dev_info(dev, "MDEV: Unregistering\n"); > > > > list_del(&parent->next); > > + mutex_unlock(&parent_list_lock); > > + > > + down_write(&parent->unreg_sem); > > + > > class_compat_remove_link(mdev_bus_compat_class, dev, NULL); > > > > device_for_each_child(dev, NULL, mdev_device_remove_cb); > > > > parent_remove_sysfs_files(parent); > > + up_write(&parent->unreg_sem); > > > > - mutex_unlock(&parent_list_lock); > > mdev_put_parent(parent); > > } > > EXPORT_SYMBOL(mdev_unregister_device); > > @@ -265,6 +295,12 @@ int mdev_device_create(struct kobject *kobj, > > > > mdev->parent = parent; > > > > + ret = down_read_trylock(&parent->unreg_sem); > > + if (!ret) { > > + ret = -ENODEV; > > I would have expected -EAGAIN or -EBUSY here, but I guess that since we > consider the lock-out to deterministically be the parent going away that - > ENODEV makes sense. Ok. > Yeah, I agree that ENODEV is more accurate error code as we don't want to tell user to retry so EAGAIN is less appropriate. Sending v5.