Si-Wei Liu
2022-May-11 17:34 UTC
[PATCH] net/vdpa: Use reader/writers semaphore instead of mutex
On 5/11/2022 5:58 AM, Eli Cohen wrote:> Use rw_semaphore instead of mutex to control access to vdpa devices. > This can be especially beneficial in case process poll on statistics > information. > > Suggested-by: Si-Wei Liu <si-wei.liu at oracle.com> > Signed-off-by: Eli Cohen <elic at nvidia.com>LGTM. It might be good to pack this patch into the vendor stat series such that the newly added vdpa_dev_vendor_stats_fill() may use rw_semaphore on top. Reviewed-by: Si-Wei Liu <si-wei.liu at oracle.com>> --- > drivers/vdpa/vdpa.c | 64 ++++++++++++++++++++++----------------------- > 1 file changed, 32 insertions(+), 32 deletions(-) > > diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c > index 0fb4a615f267..ced634f94f76 100644 > --- a/drivers/vdpa/vdpa.c > +++ b/drivers/vdpa/vdpa.c > @@ -18,7 +18,7 @@ > > static LIST_HEAD(mdev_head); > /* A global mutex that protects vdpa management device and device level operations. */ > -static DEFINE_MUTEX(vdpa_dev_mutex); > +static DECLARE_RWSEM(vdpa_dev_lock); > static DEFINE_IDA(vdpa_index_ida); > > void vdpa_set_status(struct vdpa_device *vdev, u8 status) > @@ -238,7 +238,7 @@ static int __vdpa_register_device(struct vdpa_device *vdev, u32 nvqs) > > vdev->nvqs = nvqs; > > - lockdep_assert_held(&vdpa_dev_mutex); > + lockdep_assert_held(&vdpa_dev_lock); > dev = bus_find_device(&vdpa_bus, NULL, dev_name(&vdev->dev), vdpa_name_match); > if (dev) { > put_device(dev); > @@ -278,9 +278,9 @@ int vdpa_register_device(struct vdpa_device *vdev, u32 nvqs) > { > int err; > > - mutex_lock(&vdpa_dev_mutex); > + down_write(&vdpa_dev_lock); > err = __vdpa_register_device(vdev, nvqs); > - mutex_unlock(&vdpa_dev_mutex); > + up_write(&vdpa_dev_lock); > return err; > } > EXPORT_SYMBOL_GPL(vdpa_register_device); > @@ -293,7 +293,7 @@ EXPORT_SYMBOL_GPL(vdpa_register_device); > */ > void _vdpa_unregister_device(struct vdpa_device *vdev) > { > - lockdep_assert_held(&vdpa_dev_mutex); > + lockdep_assert_held(&vdpa_dev_lock); > WARN_ON(!vdev->mdev); > device_unregister(&vdev->dev); > } > @@ -305,9 +305,9 @@ EXPORT_SYMBOL_GPL(_vdpa_unregister_device); > */ > void vdpa_unregister_device(struct vdpa_device *vdev) > { > - mutex_lock(&vdpa_dev_mutex); > + down_write(&vdpa_dev_lock); > device_unregister(&vdev->dev); > - mutex_unlock(&vdpa_dev_mutex); > + up_write(&vdpa_dev_lock); > } > EXPORT_SYMBOL_GPL(vdpa_unregister_device); > > @@ -352,9 +352,9 @@ int vdpa_mgmtdev_register(struct vdpa_mgmt_dev *mdev) > return -EINVAL; > > INIT_LIST_HEAD(&mdev->list); > - mutex_lock(&vdpa_dev_mutex); > + down_write(&vdpa_dev_lock); > list_add_tail(&mdev->list, &mdev_head); > - mutex_unlock(&vdpa_dev_mutex); > + up_write(&vdpa_dev_lock); > return 0; > } > EXPORT_SYMBOL_GPL(vdpa_mgmtdev_register); > @@ -371,14 +371,14 @@ static int vdpa_match_remove(struct device *dev, void *data) > > void vdpa_mgmtdev_unregister(struct vdpa_mgmt_dev *mdev) > { > - mutex_lock(&vdpa_dev_mutex); > + down_write(&vdpa_dev_lock); > > list_del(&mdev->list); > > /* Filter out all the entries belong to this management device and delete it. */ > bus_for_each_dev(&vdpa_bus, NULL, mdev, vdpa_match_remove); > > - mutex_unlock(&vdpa_dev_mutex); > + up_write(&vdpa_dev_lock); > } > EXPORT_SYMBOL_GPL(vdpa_mgmtdev_unregister); > > @@ -532,17 +532,17 @@ static int vdpa_nl_cmd_mgmtdev_get_doit(struct sk_buff *skb, struct genl_info *i > if (!msg) > return -ENOMEM; > > - mutex_lock(&vdpa_dev_mutex); > + down_read(&vdpa_dev_lock); > mdev = vdpa_mgmtdev_get_from_attr(info->attrs); > if (IS_ERR(mdev)) { > - mutex_unlock(&vdpa_dev_mutex); > + up_read(&vdpa_dev_lock); > NL_SET_ERR_MSG_MOD(info->extack, "Fail to find the specified mgmt device"); > err = PTR_ERR(mdev); > goto out; > } > > err = vdpa_mgmtdev_fill(mdev, msg, info->snd_portid, info->snd_seq, 0); > - mutex_unlock(&vdpa_dev_mutex); > + up_read(&vdpa_dev_lock); > if (err) > goto out; > err = genlmsg_reply(msg, info); > @@ -561,7 +561,7 @@ vdpa_nl_cmd_mgmtdev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) > int idx = 0; > int err; > > - mutex_lock(&vdpa_dev_mutex); > + down_read(&vdpa_dev_lock); > list_for_each_entry(mdev, &mdev_head, list) { > if (idx < start) { > idx++; > @@ -574,7 +574,7 @@ vdpa_nl_cmd_mgmtdev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) > idx++; > } > out: > - mutex_unlock(&vdpa_dev_mutex); > + up_read(&vdpa_dev_lock); > cb->args[0] = idx; > return msg->len; > } > @@ -630,7 +630,7 @@ static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *i > !netlink_capable(skb, CAP_NET_ADMIN)) > return -EPERM; > > - mutex_lock(&vdpa_dev_mutex); > + down_write(&vdpa_dev_lock); > mdev = vdpa_mgmtdev_get_from_attr(info->attrs); > if (IS_ERR(mdev)) { > NL_SET_ERR_MSG_MOD(info->extack, "Fail to find the specified management device"); > @@ -650,7 +650,7 @@ static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *i > > err = mdev->ops->dev_add(mdev, name, &config); > err: > - mutex_unlock(&vdpa_dev_mutex); > + up_write(&vdpa_dev_lock); > return err; > } > > @@ -666,7 +666,7 @@ static int vdpa_nl_cmd_dev_del_set_doit(struct sk_buff *skb, struct genl_info *i > return -EINVAL; > name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]); > > - mutex_lock(&vdpa_dev_mutex); > + down_write(&vdpa_dev_lock); > dev = bus_find_device(&vdpa_bus, NULL, name, vdpa_name_match); > if (!dev) { > NL_SET_ERR_MSG_MOD(info->extack, "device not found"); > @@ -684,7 +684,7 @@ static int vdpa_nl_cmd_dev_del_set_doit(struct sk_buff *skb, struct genl_info *i > mdev_err: > put_device(dev); > dev_err: > - mutex_unlock(&vdpa_dev_mutex); > + up_write(&vdpa_dev_lock); > return err; > } > > @@ -750,7 +750,7 @@ static int vdpa_nl_cmd_dev_get_doit(struct sk_buff *skb, struct genl_info *info) > if (!msg) > return -ENOMEM; > > - mutex_lock(&vdpa_dev_mutex); > + down_read(&vdpa_dev_lock); > dev = bus_find_device(&vdpa_bus, NULL, devname, vdpa_name_match); > if (!dev) { > NL_SET_ERR_MSG_MOD(info->extack, "device not found"); > @@ -768,13 +768,13 @@ static int vdpa_nl_cmd_dev_get_doit(struct sk_buff *skb, struct genl_info *info) > > err = genlmsg_reply(msg, info); > put_device(dev); > - mutex_unlock(&vdpa_dev_mutex); > + up_read(&vdpa_dev_lock); > return err; > > mdev_err: > put_device(dev); > err: > - mutex_unlock(&vdpa_dev_mutex); > + up_read(&vdpa_dev_lock); > nlmsg_free(msg); > return err; > } > @@ -816,9 +816,9 @@ static int vdpa_nl_cmd_dev_get_dumpit(struct sk_buff *msg, struct netlink_callba > info.start_idx = cb->args[0]; > info.idx = 0; > > - mutex_lock(&vdpa_dev_mutex); > + down_read(&vdpa_dev_lock); > bus_for_each_dev(&vdpa_bus, NULL, &info, vdpa_dev_dump); > - mutex_unlock(&vdpa_dev_mutex); > + up_read(&vdpa_dev_lock); > cb->args[0] = info.idx; > return msg->len; > } > @@ -1016,7 +1016,7 @@ static int vdpa_nl_cmd_dev_config_get_doit(struct sk_buff *skb, struct genl_info > if (!msg) > return -ENOMEM; > > - mutex_lock(&vdpa_dev_mutex); > + down_read(&vdpa_dev_lock); > dev = bus_find_device(&vdpa_bus, NULL, devname, vdpa_name_match); > if (!dev) { > NL_SET_ERR_MSG_MOD(info->extack, "device not found"); > @@ -1037,7 +1037,7 @@ static int vdpa_nl_cmd_dev_config_get_doit(struct sk_buff *skb, struct genl_info > mdev_err: > put_device(dev); > dev_err: > - mutex_unlock(&vdpa_dev_mutex); > + up_read(&vdpa_dev_lock); > if (err) > nlmsg_free(msg); > return err; > @@ -1075,9 +1075,9 @@ vdpa_nl_cmd_dev_config_get_dumpit(struct sk_buff *msg, struct netlink_callback * > info.start_idx = cb->args[0]; > info.idx = 0; > > - mutex_lock(&vdpa_dev_mutex); > + down_read(&vdpa_dev_lock); > bus_for_each_dev(&vdpa_bus, NULL, &info, vdpa_dev_config_dump); > - mutex_unlock(&vdpa_dev_mutex); > + up_read(&vdpa_dev_lock); > cb->args[0] = info.idx; > return msg->len; > } > @@ -1104,7 +1104,7 @@ static int vdpa_nl_cmd_dev_stats_get_doit(struct sk_buff *skb, > return -ENOMEM; > > index = nla_get_u32(info->attrs[VDPA_ATTR_DEV_QUEUE_INDEX]); > - mutex_lock(&vdpa_dev_mutex); > + down_read(&vdpa_dev_lock); > dev = bus_find_device(&vdpa_bus, NULL, devname, vdpa_name_match); > if (!dev) { > NL_SET_ERR_MSG_MOD(info->extack, "device not found"); > @@ -1124,7 +1124,7 @@ static int vdpa_nl_cmd_dev_stats_get_doit(struct sk_buff *skb, > err = genlmsg_reply(msg, info); > > put_device(dev); > - mutex_unlock(&vdpa_dev_mutex); > + up_read(&vdpa_dev_lock); > > return err; > > @@ -1132,7 +1132,7 @@ static int vdpa_nl_cmd_dev_stats_get_doit(struct sk_buff *skb, > put_device(dev); > dev_err: > nlmsg_free(msg); > - mutex_unlock(&vdpa_dev_mutex); > + up_read(&vdpa_dev_lock); > return err; > } >