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
478 return err;478 return err;
479}479}
480 480
481static int
482vdpa_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
518msg_err:
519 genlmsg_cancel(msg, hdr);
520 return err;
521}
522
523static 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);
553mdev_err:
554 put_device(dev);
555err:
556 mutex_unlock(&vdpa_dev_mutex);
557 if (err)
558 nlmsg_free(msg);
559 return err;
560}
561
562struct vdpa_dev_dump_info {
563 struct sk_buff *msg;
564 struct netlink_callback *cb;
565 int start_idx;
566 int idx;
567};
568
569static 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
590static 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
481static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX + 1] = {606static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX + 1] = {
482 [VDPA_ATTR_MGMTDEV_BUS_NAME] = { .type = NLA_NUL_STRING },607 [VDPA_ATTR_MGMTDEV_BUS_NAME] = { .type = NLA_NUL_STRING },
483 [VDPA_ATTR_MGMTDEV_DEV_NAME] = { .type = NLA_STRING },608 [VDPA_ATTR_MGMTDEV_DEV_NAME] = { .type = NLA_STRING },
@@ -503,6 +628,12 @@ static const struct genl_ops vdpa_nl_ops[] = { · 19 unmodified lines
503 .doit = vdpa_nl_cmd_dev_del_set_doit,628 .doit = vdpa_nl_cmd_dev_del_set_doit,
504 .flags = GENL_ADMIN_PERM,629 .flags = GENL_ADMIN_PERM,
505 },630 },
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 },
506};637};
507 638
508static struct genl_family vdpa_nl_family __ro_after_init = {639static 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
16 VDPA_CMD_MGMTDEV_GET, /* can dump */16 VDPA_CMD_MGMTDEV_GET, /* can dump */
17 VDPA_CMD_DEV_NEW,17 VDPA_CMD_DEV_NEW,
18 VDPA_CMD_DEV_DEL,18 VDPA_CMD_DEV_DEL,
19 VDPA_CMD_DEV_GET, /* can dump */
19};20};
20 21
21enum vdpa_attr {22enum vdpa_attr {
@@ -27,6 +28,10 @@ enum vdpa_attr { · 5 unmodified lines
27 VDPA_ATTR_MGMTDEV_SUPPORTED_CLASSES, /* u64 */28 VDPA_ATTR_MGMTDEV_SUPPORTED_CLASSES, /* u64 */
28 29
29 VDPA_ATTR_DEV_NAME, /* string */30 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 */
30 35
31 /* new attributes must be added above here */36 /* new attributes must be added above here */
32 VDPA_ATTR_MAX,37 VDPA_ATTR_MAX,