History

vdpa: Enable user to query vdpa device info

Enable user to query vdpa device information. $ vdpa dev add mgmtdev vdpasim_net name foo2 Show the newly created vdpa device by its name: $ vdpa dev show foo2 foo2: type network mgmtdev vdpasim_net vendor_id 0 max_vqs 2 max_vq_size 256 $ vdpa dev show foo2 -jp { "dev": { "foo2": { "type": "network", "mgmtdev": "vdpasim_net", "vendor_id": 0, "max_vqs": 2, "max_vq_size": 256 } } } Signed-off-by: Parav Pandit <parav@nvidia.com> Reviewed-by: Eli Cohen <elic@nvidia.com> Reviewed-by: Jason Wang <jasowang@redhat.com> Link: https://lore.kernel.org/r/20210105103203.82508-6-parav@nvidia.com Including a memory leak fix:

Parav Pandit committed 5 years ago

Commit bc0d90e1 parent 903f7bc2 files · +136 −0Browse files

Unified · Split

2 files
  1. drivers/vdpa/vdpa.c +131 −0
  2. include/uapi/linux/vdpa.h +5 −0
drivers/vdpa/vdpa.c+131−0
@@ -478,6 +478,131 @@ dev_err: · 477 unmodified lines
478478 return err;
479479 }
480480
481+static int
482+vdpa_dev_fill(struct vdpa_device *vdev, struct sk_buff *msg, u32 portid, u32 seq,
483+ int flags, struct netlink_ext_ack *extack)
484+{
485+ u16 max_vq_size;
486+ u32 device_id;
487+ u32 vendor_id;
488+ void *hdr;
489+ int err;
490+
491+ hdr = genlmsg_put(msg, portid, seq, &vdpa_nl_family, flags, VDPA_CMD_DEV_NEW);
492+ if (!hdr)
493+ return -EMSGSIZE;
494+
495+ err = vdpa_nl_mgmtdev_handle_fill(msg, vdev->mdev);
496+ if (err)
497+ goto msg_err;
498+
499+ device_id = vdev->config->get_device_id(vdev);
500+ vendor_id = vdev->config->get_vendor_id(vdev);
501+ max_vq_size = vdev->config->get_vq_num_max(vdev);
502+
503+ err = -EMSGSIZE;
504+ if (nla_put_string(msg, VDPA_ATTR_DEV_NAME, dev_name(&vdev->dev)))
505+ goto msg_err;
506+ if (nla_put_u32(msg, VDPA_ATTR_DEV_ID, device_id))
507+ goto msg_err;
508+ if (nla_put_u32(msg, VDPA_ATTR_DEV_VENDOR_ID, vendor_id))
509+ goto msg_err;
510+ if (nla_put_u32(msg, VDPA_ATTR_DEV_MAX_VQS, vdev->nvqs))
511+ goto msg_err;
512+ if (nla_put_u16(msg, VDPA_ATTR_DEV_MAX_VQ_SIZE, max_vq_size))
513+ goto msg_err;
514+
515+ genlmsg_end(msg, hdr);
516+ return 0;
517+
518+msg_err:
519+ genlmsg_cancel(msg, hdr);
520+ return err;
521+}
522+
523+static int vdpa_nl_cmd_dev_get_doit(struct sk_buff *skb, struct genl_info *info)
524+{
525+ struct vdpa_device *vdev;
526+ struct sk_buff *msg;
527+ const char *devname;
528+ struct device *dev;
529+ int err;
530+
531+ if (!info->attrs[VDPA_ATTR_DEV_NAME])
532+ return -EINVAL;
533+ devname = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
534+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
535+ if (!msg)
536+ return -ENOMEM;
537+
538+ mutex_lock(&vdpa_dev_mutex);
539+ dev = bus_find_device(&vdpa_bus, NULL, devname, vdpa_name_match);
540+ if (!dev) {
541+ NL_SET_ERR_MSG_MOD(info->extack, "device not found");
542+ err = -ENODEV;
543+ goto err;
544+ }
545+ vdev = container_of(dev, struct vdpa_device, dev);
546+ if (!vdev->mdev) {
547+ err = -EINVAL;
548+ goto mdev_err;
549+ }
550+ err = vdpa_dev_fill(vdev, msg, info->snd_portid, info->snd_seq, 0, info->extack);
551+ if (!err)
552+ err = genlmsg_reply(msg, info);
553+mdev_err:
554+ put_device(dev);
555+err:
556+ mutex_unlock(&vdpa_dev_mutex);
557+ if (err)
558+ nlmsg_free(msg);
559+ return err;
560+}
561+
562+struct vdpa_dev_dump_info {
563+ struct sk_buff *msg;
564+ struct netlink_callback *cb;
565+ int start_idx;
566+ int idx;
567+};
568+
569+static int vdpa_dev_dump(struct device *dev, void *data)
570+{
571+ struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev);
572+ struct vdpa_dev_dump_info *info = data;
573+ int err;
574+
575+ if (!vdev->mdev)
576+ return 0;
577+ if (info->idx < info->start_idx) {
578+ info->idx++;
579+ return 0;
580+ }
581+ err = vdpa_dev_fill(vdev, info->msg, NETLINK_CB(info->cb->skb).portid,
582+ info->cb->nlh->nlmsg_seq, NLM_F_MULTI, info->cb->extack);
583+ if (err)
584+ return err;
585+
586+ info->idx++;
587+ return 0;
588+}
589+
590+static int vdpa_nl_cmd_dev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
591+{
592+ struct vdpa_dev_dump_info info;
593+
594+ info.msg = msg;
595+ info.cb = cb;
596+ info.start_idx = cb->args[0];
597+ info.idx = 0;
598+
599+ mutex_lock(&vdpa_dev_mutex);
600+ bus_for_each_dev(&vdpa_bus, NULL, &info, vdpa_dev_dump);
601+ mutex_unlock(&vdpa_dev_mutex);
602+ cb->args[0] = info.idx;
603+ return msg->len;
604+}
605+
481606 static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX + 1] = {
482607 [VDPA_ATTR_MGMTDEV_BUS_NAME] = { .type = NLA_NUL_STRING },
483608 [VDPA_ATTR_MGMTDEV_DEV_NAME] = { .type = NLA_STRING },
@@ -503,6 +628,12 @@ static const struct genl_ops vdpa_nl_ops[] = { · 19 unmodified lines
503628 .doit = vdpa_nl_cmd_dev_del_set_doit,
504629 .flags = GENL_ADMIN_PERM,
505630 },
631+ {
632+ .cmd = VDPA_CMD_DEV_GET,
633+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
634+ .doit = vdpa_nl_cmd_dev_get_doit,
635+ .dumpit = vdpa_nl_cmd_dev_get_dumpit,
636+ },
506637 };
507638
508639 static struct genl_family vdpa_nl_family __ro_after_init = {
include/uapi/linux/vdpa.h+5−0
@@ -16,6 +16,7 @@ enum vdpa_command { · 15 unmodified lines
1616 VDPA_CMD_MGMTDEV_GET, /* can dump */
1717 VDPA_CMD_DEV_NEW,
1818 VDPA_CMD_DEV_DEL,
19+ VDPA_CMD_DEV_GET, /* can dump */
1920 };
2021
2122 enum vdpa_attr {
@@ -27,6 +28,10 @@ enum vdpa_attr { · 5 unmodified lines
2728 VDPA_ATTR_MGMTDEV_SUPPORTED_CLASSES, /* u64 */
2829
2930 VDPA_ATTR_DEV_NAME, /* string */
31+ VDPA_ATTR_DEV_ID, /* u32 */
32+ VDPA_ATTR_DEV_VENDOR_ID, /* u32 */
33+ VDPA_ATTR_DEV_MAX_VQS, /* u32 */
34+ VDPA_ATTR_DEV_MAX_VQ_SIZE, /* u16 */
3035
3136 /* new attributes must be added above here */
3237 VDPA_ATTR_MAX,