Re: [PATCH v1 1/2] vdpa: Add support for querying vendor statistics

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Mar 19, 2022 at 1:18 PM Si-Wei Liu <si-wei.liu@xxxxxxxxxx> wrote:
>
>
>
> On 3/17/2022 7:27 PM, Jason Wang wrote:
> > On Fri, Mar 18, 2022 at 8:59 AM Si-Wei Liu <si-wei.liu@xxxxxxxxxx> wrote:
> >>
> >>
> >> On 3/16/2022 7:32 PM, Jason Wang wrote:
> >>> On Thu, Mar 17, 2022 at 6:00 AM Si-Wei Liu <si-wei.liu@xxxxxxxxxx> wrote:
> >>>>
> >>>> On 3/16/2022 12:10 AM, Eli Cohen wrote:
> >>>>>> From: Si-Wei Liu <si-wei.liu@xxxxxxxxxx>
> >>>>>> Sent: Wednesday, March 16, 2022 8:52 AM
> >>>>>> To: Eli Cohen <elic@xxxxxxxxxx>
> >>>>>> Cc: mst@xxxxxxxxxx; jasowang@xxxxxxxxxx; virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx; eperezma@xxxxxxxxxx; amorenoz@xxxxxxxxxx;
> >>>>>> lvivier@xxxxxxxxxx; sgarzare@xxxxxxxxxx; Parav Pandit <parav@xxxxxxxxxx>
> >>>>>> Subject: Re: [PATCH v1 1/2] vdpa: Add support for querying vendor statistics
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On 3/15/2022 2:10 AM, Eli Cohen wrote:
> >>>>>>
> >>>>>> <...snip...>
> >>>>>>
> >>>>>>>> Say you got a vdpa net device created with 4 data queue pairs and a
> >>>>>>>> control vq. On boot some guest firmware may support just F_CTRL_VQ but
> >>>>>>>> not F_MQ, then the index for the control vq in guest ends up with 2, as
> >>>>>>>> in this case there's only a single queue pair enabled for rx (index 0)
> >>>>>>>> and tx (index 1). From the host driver (e.g. mlx5_vdpa) perspective, the
> >>>>>>>> control vq is the last vq following 8
> >>>>>>> If the host sees F_MQ was not negotiated but F_CTRL_VQ was, then it knows
> >>>>>>> that control VQ index is 2
> >>>>>> Right, but I don't see this feature negotiation info getting returned
> >>>>>> from your vdpa_dev_vendor_stats_fill(), or did I miss something? How do
> >>>>>> you plan for host user to get this info? If you meant another "vdpa dev
> >>>>>> show" command to query negotiated features ahead, this won't get the
> >>>>>> same lock protected as the time you run the stat query. It's very easy
> >>>>>> to miss that ephemeral queue index.
> >>>>> Right, so I suggested to include the negotiated features in the netlink message
> >>>>> for the statistics. That would save us from using two system calls to get the
> >>>>> information required and it answers your concern with respect to locking.
> >>>>> I think Jason was reluctant to adding this attribute to the message but can't
> >>>>> find where he explained the reasoning.
> >>>> Maybe Jason can clarify and correct me, but I just did not get the same
> >>>> impression as what you said? I just skimmed through all of the emails in
> >>>> the thread, only finding that he didn't want device specific attribute
> >>>> such as queue type to get returned by the vdpa core, which I agree. I'm
> >>>> not sure if he's explicitly against piggyback negotiated features to aid
> >>>> userspace parsing the index.
> >>> I think we need piggyback the negotiated features, otherwise as you
> >>> mentioned, we will probably get in-consistency.
> >> Great. Thanks for confirming it.
> >>
> >>> But a question for the "host queue index", as mentioned before. It's
> >>> something that is not defined in the spec, so technically, vendor can
> >>> do any mappings between it and the index what guest can see. I feel
> >>> like we need to clarify it in the spec first.
> >> I have been thinking about this for some while today. Actually I am not
> >> against exposing the host queue index to the spec, as we know it's
> >> somewhat implicitly defined in the QEMU device model for multiqueue. The
> >> thing is, I'm not sure if there's extra benefit than this minor
> >> requirement (*) given that all of the other vDPA kAPI are taking the
> >> guest queue index rather than the host queue index.
> > Rethink of this, consider currently we do this via vendor stats, so
> > it's probably fine. Maybe we can have a better netlink API like
> > "vendor_queue_index" etc then everything should be fine.
> True. Or if there's netlink API that simply dumps the stats for all of
> the available queues in one shot, that would serve our cloud use case
> quite well. :)

This might be another option.

>
> >
> >> It works for
> >> mlx5_vdpa as the control vq is implemented in the software, so it can
> >> map to whatever guest qindex it wishes to. But would it cause extra
> >> trouble for some other emulated vDPA device or other vendor's vDPA such
> >> as ifcvf to fabricate a fake mapping between the host queue index and
> >> the one guest can see? I would have to send a heads-up ahead that the
> >> current vhost-vdpa mq implementation in upstream QEMU has some issue in
> >> mapping the host qindex to the guest one. This would become a problem
> >> with MQ enabled vdpa device and a non-MQ supporting guest e.g. OVMF, for
> >> which I'm about to share some RFC patches shortly to demonstrate the
> >> issue.
> > Sure.
> Please see the RFC patch just sent with the subject "vhost_net: should
> not use max_queue_pairs for non-mq guest", option #3 is to leverage host
> queue index.

Right. If we take Qemu as a kind of vDPA implementation, it's a good
example that something like "vendor queue index" or "host queue index"
is not even implemented.

>
> >
> >> If exposing the host queue index to the spec turns is essential
> >> to resolving this issue and maybe help with software virtio QEMU
> >> implementation too, I won't hesitate to expose this important
> >> implementation detail to the spec.
> >>
> >> (*) another means that may somehow address my use case is to use some
> >> magic keyword e.g. "ctrlvq" to identify the control vq. Implementation
> >> wise, we can extensively pass -1 to indicate the last guest qindex to
> >> the get_vq_vstat() API given that we know for sure the ctrlvq is the
> >> last queue in the array when the relevant features are present. Since
> >> the negotiated features are piggybacked, it's not hard for the vdpa tool
> >> to tell apart whether the last queue is a control vq or not.
> > For virtqueue index (guest index) defined in the spec, I'd let
> > userspace to deduce it.
> OK, that'll be fine. Although I thought by extending
> get_vendor_vq_vstat() a bit, the virtqueue index is still guest based,
> from which the userspace can deduce control vq for its own.

Yes.

>
> > But for the host or vendor index, we probably can do this.
> Does vendor index means it's optional and vendor specific, host index
> means it is mandated and universal to all vendors?

It's probably too late to mandate this consider we've already have 3
or 4 vDPA vendors.

>I hope we can define
> some generic indexing scheme for virtio stats defined in the spec across
> all vendor's devices, while limiting vendor's flexibility to define its
> own index mapping to only those vendor stats.

Right.

Thanks

>
> > (Btw, I feel like we need to separate the features, if we agree to go
> > with host/vendor index, we can let guest index part in first).
> OK. Sounds like a plan. Thanks Jason.
>
> Thanks,
> -Siwei
>
> >
> > Thanks
> >
> >> I'd also welcome other ideas that can make virtqueue identification
> >> easier and predictable from the CLI.
> >>
> >> Thanks,
> >> -Siwei
> >>
> >>> Thanks
> >>>
> >>>> Another way around, vdpa tool may pass down -1 to get_vq_vstat() to
> >>>> represent the queue index for the control queue - but that's less
> >>>> favorable as the vdpa core needs to maintain device specific knowledge.
> >>>>
> >>>>
> >>>>
> >>>>>>>> data vqs of all 4 pairs, hence got
> >>>>>>>> the 8th index in the rank. Since F_MQ is not negotiated and only 1 data
> >>>>>>>> queue pair enabled, in such event only host qindex 0,1 and 8 have vendor
> >>>>>>>> stats available, and the rest of qindex would get invalid/empty stat.
> >>>>>>>>
> >>>>>>>> Later on say boot continues towards loading the Linux virtio driver,
> >>>>>>>> then guest could successfully negotiate both F_CTRL_VQ and F_MQ
> >>>>>>>> features. In this case, all 8 data virtqueues are fully enabled, the
> >>>>>>>> index for the control vq ends up as 8, following tightly after all the 4
> >>>>>>>> data queue pairs. Only until both features are negotiated, the guest and
> >>>>>>>> host are able to see consistent view in identifying the control vq.
> >>>>>>>> Since F_MQ is negotiated, all host queues, indexed from 0 through 8,
> >>>>>>>> should have vendor stats available.
> >>>>>>>>
> >>>>>>>> That's why I said the guest qindex is ephemeral and hard to predict
> >>>>>>>> subjected to negotiated features, but host qindex is reliable and more
> >>>>>>>> eligible for command line identification purpose.
> >>>>>>>>
> >>>>>> <...snip...>
> >>>>>>>>> So what are you actually proposing? Display received and completed descriptors
> >>>>>>>>> per queue index without further interpretation?
> >>>>>>>> I'd suggest using a more stable queue id i.e. the host queue index to
> >>>>>>>> represent the qidx (which seems to be what you're doing now?), and
> >>>>>>>> displaying both the host qindex (queue_index_device in the example
> >>>>>>>> below), as well as the guest's (queue_index_driver as below) in the output:
> >>>>>>>>
> >>>>>>> Given that per vdpa device you can display statistics only after features have
> >>>>>>> been negotiated, you can always know the correct queue index for the control
> >>>>>>> VQ.
> >>>>>> The stats can be displayed only after features are negotiated, and only
> >>>>>> when the corresponding queue is enabled. If you know it from "vdpa dev
> >>>>>> show" on day 1 that the control vq and mq features are negotiated, but
> >>>>>> then on day2 you got nothing for the predicted control vq index, what
> >>>>>> would you recommend the host admin to do to get the right qindex again?
> >>>>>> Re-run the stat query on the same queue index, or check the "vdpa dev
> >>>>>> show" output again on day 3? This CLI design makes cloud administrator
> >>>>>> really challenging to follow the dynamics of guest activities were to
> >>>>>> manage hundreds or thousands of virtual machines...
> >>>>>>
> >>>>>> It would be easier, in my opinion, to grasp some well-defined handle
> >>>>>> that is easily predictable or fixed across the board, for looking up the
> >>>>>> control virtqueue. This could be a constant host queue index, or a
> >>>>>> special magic keyword like "qidx ctrlvq". If cloud admin runs vstat
> >>>>>> query on the control vq using a determined handle but get nothing back,
> >>>>>> then s/he knows *for sure* the control vq was not available for some
> >>>>>> reason at the point when the stat was being collected. S/he doesn't even
> >>>>>> need to care negotiated status via "vdpa dev show" at all. Why bother?
> >>>>> So, per my suggestion above, passing the negotiated attribute in the netlink
> >>>>> message would satisfy the requirements for atomicity, right?
> >>>> Yes, it satisfied the atomicity requirement, though not sure how you
> >>>> want to represent the queue index for control vq? Basically if cloud
> >>>> admin wants to dump control queue stats explicitly with a fixed handle
> >>>> or identifier, how that can be done with the negotiated attribute?
> >>>>
> >>>> Thanks,
> >>>> -Siwei
> >>>>>>> Do you still hold see your proposal required?
> >>>>>> Yes, this is essential to any cloud admin that runs stat query on all of
> >>>>>> the queues on periodic basis. You'd get some deterministic without
> >>>>>> blindly guessing or bothering other irrelevant command.
> >>>>>>
> >>>>>>
> >>>>>> Thanks,
> >>>>>> -Siwei
> >>>>>>>> $ vdpa -jp dev vstats show vdpa-a qidx 8
> >>>>>>>> {
> >>>>>>>>          "vstats": {
> >>>>>>>>              "vdpa-a": {
> >>>>>>>>                  "queue_stats": [{
> >>>>>>>>                      "queue_index_device": 8,
> >>>>>>>>                      "queue_index_driver": 2,
> >>>>>>>>                      "queue_type": "control_vq",
> >>>>>>>>                      "stat_name": [ "received_desc","completed_desc" ],
> >>>>>>>>                      "stat_value": [ 417776,417775 ],
> >>>>>>>>                  }]
> >>>>>>>>              }
> >>>>>>>>          }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> Optionally, user may use guest queue index gqidx, which is kind of an
> >>>>>>>> ephemeral ID and F_MQ negotiation depended, to query the stat on a
> >>>>>>>> specific guest queue:
> >>>>>>>>
> >>>>>>>> $ vdpa -jp dev vstats show vdpa-a gqidx 2
> >>>>>>>> {
> >>>>>>>>          "vstats": {
> >>>>>>>>              "vdpa-a": {
> >>>>>>>>                  "queue_stats": [{
> >>>>>>>>                      "queue_index_device": 8,
> >>>>>>>>                      "queue_index_driver": 2,
> >>>>>>>>                      "queue_type": "control_vq",
> >>>>>>>>                      "stat_name": [ "received_desc","completed_desc" ],
> >>>>>>>>                      "stat_value": [ 417776,417775 ],
> >>>>>>>>                  }]
> >>>>>>>>              }
> >>>>>>>>          }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> Thanks,
> >>>>>>>> -Siwei
> >>>>>>>>
> >>>>>>>>>> Thanks,
> >>>>>>>>>> -Siwei
> >>>>>>>>>>
> >>>>>>>>>>>> Regards,
> >>>>>>>>>>>> -Siwei
> >>>>>>>>>>>>
> >>>>>>>>>>>>>>>> Looks to me there are still some loose end I don't quite yet
> >>>>>>>>>>>>>>>> understand.
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>>                       "queue_index": 0,
> >>>>>>>>>>>>>>> I think this can be removed since the command is for a specific index.
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>>                       "name": "received_desc",
> >>>>>>>>>>>>>>>>>>>                       "value": 417776,
> >>>>>>>>>>>>>>>>>>>                       "name": "completed_desc",
> >>>>>>>>>>>>>>>>>>>                       "value": 417548
> >>>>>>>>>>>>>>>>>> Not for this kernel patch, but IMHO it's the best to put the name
> >>>>>>>>>>>>>>>>>> & value pairs in an array instead of flat entries in json's
> >>>>>>>>>>>>>>>>>> hash/dictionary. The hash entries can be re-ordered deliberately
> >>>>>>>>>>>>>>>>>> by external json parsing tool, ending up with inconsistent stat values.
> >>>>>>>>>>>>>>>> This comment is missed for some reason. Please change the example
> >>>>>>>>>>>>>>>> in the log if you agree to address it in vdpa tool. Or justify why
> >>>>>>>>>>>>>>>> keeping the order for json hash/dictionary is fine.
> >>>>>>>>>>>>>>> Sorry for skipping this comment.
> >>>>>>>>>>>>>>> Do you mean to present the information like:
> >>>>>>>>>>>>>>> "received_desc": 417776,
> >>>>>>>>>>>>>>> "completed_desc": 417548,
> >>>>>>>>>>>>>> I mean the following presentation:
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> $ vdpa -jp dev vstats show vdpa-a qidx 0 {
> >>>>>>>>>>>>>>             "vstats": {
> >>>>>>>>>>>>>>                 "vdpa-a": {
> >>>>>>>>>>>>>>                     "queue_stats": [{
> >>>>>>>>>>>>>>                         "queue_index": 0,
> >>>>>>>>>>>>>>                         "queue_type": "rx",
> >>>>>>>>>>>>>>                         "stat_name": [ "received_desc","completed_desc" ],
> >>>>>>>>>>>>>>                         "stat_value": [ 417776,417548 ],
> >>>>>>>>>>>>>>                     }]
> >>>>>>>>>>>>>>                 }
> >>>>>>>>>>>>>>             }
> >>>>>>>>>>>>>> }
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> I think Parav had similar suggestion, too.
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Thanks,
> >>>>>>>>>>>>>> -Siwei
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> Thanks,
> >>>>>>>>>>>>>>>> -Siwei
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> Thanks,
> >>>>>>>>>>>>>>>>>> -Siwei
> >>>>>>>>>>>>>>>>>>>                   }
> >>>>>>>>>>>>>>>>>>>               }
> >>>>>>>>>>>>>>>>>>> }
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> Signed-off-by: Eli Cohen <elic@xxxxxxxxxx>
> >>>>>>>>>>>>>>>>>>> ---
> >>>>>>>>>>>>>>>>>>>            drivers/vdpa/vdpa.c       | 129
> >>>>>>>>>>>>>>>> ++++++++++++++++++++++++++++++++++++++
> >>>>>>>>>>>>>>>>>>>            include/linux/vdpa.h      |   5 ++
> >>>>>>>>>>>>>>>>>>>            include/uapi/linux/vdpa.h |   7 +++
> >>>>>>>>>>>>>>>>>>>            3 files changed, 141 insertions(+)
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c index
> >>>>>>>>>>>>>>>>>>> 9846c9de4bfa..d0ff671baf88 100644
> >>>>>>>>>>>>>>>>>>> --- a/drivers/vdpa/vdpa.c
> >>>>>>>>>>>>>>>>>>> +++ b/drivers/vdpa/vdpa.c
> >>>>>>>>>>>>>>>>>>> @@ -909,6 +909,74 @@ vdpa_dev_config_fill(struct vdpa_device
> >>>>>>>>>>>>>>>>>>> *vdev,
> >>>>>>>>>>>>>>>> struct sk_buff *msg, u32 portid,
> >>>>>>>>>>>>>>>>>>>                   return err;
> >>>>>>>>>>>>>>>>>>>            }
> >>>>>>>>>>>>>>>>>>> +static int vdpa_fill_stats_rec(struct vdpa_device *vdev, struct
> >>>>>>>>>>>>>>>>>>> +sk_buff
> >>>>>>>>>>>>>>>> *msg,
> >>>>>>>>>>>>>>>>>>> +                              struct genl_info *info, u32 index) {
> >>>>>>>>>>>>>>>>>>> +       int err;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       if (nla_put_u32(msg, VDPA_ATTR_DEV_QUEUE_INDEX, index))
> >>>>>>>>>>>>>>>>>>> +               return -EMSGSIZE;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       err = vdev->config->get_vendor_vq_stats(vdev, index, msg,
> >>>>>>>>>>>>>>>>>>> +info-
> >>>>>>>>>>>>>>>>> extack);
> >>>>>>>>>>>>>>>>>>> +       if (err)
> >>>>>>>>>>>>>>>>>>> +               return err;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       return 0;
> >>>>>>>>>>>>>>>>>>> +}
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +static int vendor_stats_fill(struct vdpa_device *vdev, struct
> >>>>>>>>>>>>>>>>>>> +sk_buff
> >>>>>>>>>>>>>> *msg,
> >>>>>>>>>>>>>>>>>>> +                            struct genl_info *info, u32 index) {
> >>>>>>>>>>>>>>>>>>> +       int err;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       if (!vdev->config->get_vendor_vq_stats)
> >>>>>>>>>>>>>>>>>>> +               return -EOPNOTSUPP;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       err = vdpa_fill_stats_rec(vdev, msg, info, index);
> >>>>>>>>>>>>>>>>>>> +       if (err)
> >>>>>>>>>>>>>>>>>>> +               return err;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       return 0;
> >>>>>>>>>>>>>>>>>>> +}
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +static int vdpa_dev_vendor_stats_fill(struct vdpa_device *vdev,
> >>>>>>>>>>>>>>>>>>> +                                     struct sk_buff *msg,
> >>>>>>>>>>>>>>>>>>> +                                     struct genl_info *info, u32 index) {
> >>>>>>>>>>>>>>>>>>> +       u32 device_id;
> >>>>>>>>>>>>>>>>>>> +       void *hdr;
> >>>>>>>>>>>>>>>>>>> +       int err;
> >>>>>>>>>>>>>>>>>>> +       u32 portid = info->snd_portid;
> >>>>>>>>>>>>>>>>>>> +       u32 seq = info->snd_seq;
> >>>>>>>>>>>>>>>>>>> +       u32 flags = 0;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       hdr = genlmsg_put(msg, portid, seq, &vdpa_nl_family, flags,
> >>>>>>>>>>>>>>>>>>> +                         VDPA_CMD_DEV_VSTATS_GET);
> >>>>>>>>>>>>>>>>>>> +       if (!hdr)
> >>>>>>>>>>>>>>>>>>> +               return -EMSGSIZE;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       if (nla_put_string(msg, VDPA_ATTR_DEV_NAME,
> >>>>>>>>>>>> dev_name(&vdev-
> >>>>>>>>>>>>>>>>> dev))) {
> >>>>>>>>>>>>>>>>>>> +               err = -EMSGSIZE;
> >>>>>>>>>>>>>>>>>>> +               goto undo_msg;
> >>>>>>>>>>>>>>>>>>> +       }
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       device_id = vdev->config->get_device_id(vdev);
> >>>>>>>>>>>>>>>>>>> +       if (nla_put_u32(msg, VDPA_ATTR_DEV_ID, device_id)) {
> >>>>>>>>>>>>>>>>>>> +               err = -EMSGSIZE;
> >>>>>>>>>>>>>>>>>>> +               goto undo_msg;
> >>>>>>>>>>>>>>>>>>> +       }
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       err = vendor_stats_fill(vdev, msg, info, index);
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       genlmsg_end(msg, hdr);
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       return err;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +undo_msg:
> >>>>>>>>>>>>>>>>>>> +       genlmsg_cancel(msg, hdr);
> >>>>>>>>>>>>>>>>>>> +       return err;
> >>>>>>>>>>>>>>>>>>> +}
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>>            static int vdpa_nl_cmd_dev_config_get_doit(struct sk_buff
> >>>>>>>>>>>>>>>>>>> *skb, struct
> >>>>>>>>>>>>>>>> genl_info *info)
> >>>>>>>>>>>>>>>>>>>            {
> >>>>>>>>>>>>>>>>>>>                   struct vdpa_device *vdev;
> >>>>>>>>>>>>>>>>>>> @@ -990,6 +1058,60 @@
> >>>>>>>>>>>> vdpa_nl_cmd_dev_config_get_dumpit(struct
> >>>>>>>>>>>>>>>> sk_buff *msg, struct netlink_callback *
> >>>>>>>>>>>>>>>>>>>                   return msg->len;
> >>>>>>>>>>>>>>>>>>>            }
> >>>>>>>>>>>>>>>>>>> +static int vdpa_nl_cmd_dev_stats_get_doit(struct sk_buff *skb,
> >>>>>>>>>>>>>>>>>>> +                                         struct genl_info *info)
> >>>>>>>>>>>>>>>>>>> +{
> >>>>>>>>>>>>>>>>>>> +       struct vdpa_device *vdev;
> >>>>>>>>>>>>>>>>>>> +       struct sk_buff *msg;
> >>>>>>>>>>>>>>>>>>> +       const char *devname;
> >>>>>>>>>>>>>>>>>>> +       struct device *dev;
> >>>>>>>>>>>>>>>>>>> +       u32 index;
> >>>>>>>>>>>>>>>>>>> +       int err;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       if (!info->attrs[VDPA_ATTR_DEV_NAME])
> >>>>>>>>>>>>>>>>>>> +               return -EINVAL;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       if (!info->attrs[VDPA_ATTR_DEV_QUEUE_INDEX])
> >>>>>>>>>>>>>>>>>>> +               return -EINVAL;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       devname = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
> >>>>>>>>>>>>>>>>>>> +       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
> >>>>>>>>>>>>>>>>>>> +       if (!msg)
> >>>>>>>>>>>>>>>>>>> +               return -ENOMEM;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       index = nla_get_u32(info-
> >>>>>>>>>>>>> attrs[VDPA_ATTR_DEV_QUEUE_INDEX]);
> >>>>>>>>>>>>>>>>>>> +       mutex_lock(&vdpa_dev_mutex);
> >>>>>>>>>>>>>>>>>>> +       dev = bus_find_device(&vdpa_bus, NULL, devname,
> >>>>>>>>>>>>>>>> vdpa_name_match);
> >>>>>>>>>>>>>>>>>>> +       if (!dev) {
> >>>>>>>>>>>>>>>>>>> +               NL_SET_ERR_MSG_MOD(info->extack, "device not
> >>>>>>>>>>>> found");
> >>>>>>>>>>>>>>>>>>> +               err = -ENODEV;
> >>>>>>>>>>>>>>>>>>> +               goto dev_err;
> >>>>>>>>>>>>>>>>>>> +       }
> >>>>>>>>>>>>>>>>>>> +       vdev = container_of(dev, struct vdpa_device, dev);
> >>>>>>>>>>>>>>>>>>> +       if (!vdev->mdev) {
> >>>>>>>>>>>>>>>>>>> +               NL_SET_ERR_MSG_MOD(info->extack, "unmanaged
> >>>>>>>>>>>> vdpa
> >>>>>>>>>>>>>>>> device");
> >>>>>>>>>>>>>>>>>>> +               err = -EINVAL;
> >>>>>>>>>>>>>>>>>>> +               goto mdev_err;
> >>>>>>>>>>>>>>>>>>> +       }
> >>>>>>>>>>>>>>>>>>> +       err = vdpa_dev_vendor_stats_fill(vdev, msg, info, index);
> >>>>>>>>>>>>>>>>>>> +       if (!err)
> >>>>>>>>>>>>>>>>>>> +               err = genlmsg_reply(msg, info);
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       put_device(dev);
> >>>>>>>>>>>>>>>>>>> +       mutex_unlock(&vdpa_dev_mutex);
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       if (err)
> >>>>>>>>>>>>>>>>>>> +               nlmsg_free(msg);
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       return err;
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +mdev_err:
> >>>>>>>>>>>>>>>>>>> +       put_device(dev);
> >>>>>>>>>>>>>>>>>>> +dev_err:
> >>>>>>>>>>>>>>>>>>> +       mutex_unlock(&vdpa_dev_mutex);
> >>>>>>>>>>>>>>>>>>> +       return err;
> >>>>>>>>>>>>>>>>>>> +}
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>>            static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX + 1]
> >>>>>>>>>>>> = {
> >>>>>>>>>>>>>>>>>>>                   [VDPA_ATTR_MGMTDEV_BUS_NAME] = { .type =
> >>>>>>>>>>>>>> NLA_NUL_STRING },
> >>>>>>>>>>>>>>>>>>>                   [VDPA_ATTR_MGMTDEV_DEV_NAME] = { .type = NLA_STRING
> >>>>>>>>>>>>>> }, @@ -
> >>>>>>>>>>>>>>>> 997,6
> >>>>>>>>>>>>>>>>>>> +1119,7 @@ static const struct nla_policy
> >>>>>>>>>>>>>>>> vdpa_nl_policy[VDPA_ATTR_MAX + 1] = {
> >>>>>>>>>>>>>>>>>>>                   [VDPA_ATTR_DEV_NET_CFG_MACADDR] =
> >>>>>>>>>>>>>> NLA_POLICY_ETH_ADDR,
> >>>>>>>>>>>>>>>>>>>                   /* virtio spec 1.1 section 5.1.4.1 for valid MTU range */
> >>>>>>>>>>>>>>>>>>>                   [VDPA_ATTR_DEV_NET_CFG_MTU] =
> >>>>>>>>>>>>>> NLA_POLICY_MIN(NLA_U16, 68),
> >>>>>>>>>>>>>>>>>>> +       [VDPA_ATTR_DEV_QUEUE_INDEX] =
> >>>>>>>>>>>> NLA_POLICY_RANGE(NLA_U32, 0,
> >>>>>>>>>>>>>>>> 65535),
> >>>>>>>>>>>>>>>>>>>            };
> >>>>>>>>>>>>>>>>>>>            static const struct genl_ops vdpa_nl_ops[] = { @@ -1030,6
> >>>>>>>>>>>>>>>>>>> +1153,12 @@ static const struct genl_ops vdpa_nl_ops[] = {
> >>>>>>>>>>>>>>>>>>>                           .doit = vdpa_nl_cmd_dev_config_get_doit,
> >>>>>>>>>>>>>>>>>>>                           .dumpit = vdpa_nl_cmd_dev_config_get_dumpit,
> >>>>>>>>>>>>>>>>>>>                   },
> >>>>>>>>>>>>>>>>>>> +       {
> >>>>>>>>>>>>>>>>>>> +               .cmd = VDPA_CMD_DEV_VSTATS_GET,
> >>>>>>>>>>>>>>>>>>> +               .validate = GENL_DONT_VALIDATE_STRICT |
> >>>>>>>>>>>>>>>> GENL_DONT_VALIDATE_DUMP,
> >>>>>>>>>>>>>>>>>>> +               .doit = vdpa_nl_cmd_dev_stats_get_doit,
> >>>>>>>>>>>>>>>>>>> +               .flags = GENL_ADMIN_PERM,
> >>>>>>>>>>>>>>>>>>> +       },
> >>>>>>>>>>>>>>>>>>>            };
> >>>>>>>>>>>>>>>>>>>            static struct genl_family vdpa_nl_family __ro_after_init =
> >>>>>>>>>>>>>>>>>>> { diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h index
> >>>>>>>>>>>>>>>>>>> 2de442ececae..274203845cfc 100644
> >>>>>>>>>>>>>>>>>>> --- a/include/linux/vdpa.h
> >>>>>>>>>>>>>>>>>>> +++ b/include/linux/vdpa.h
> >>>>>>>>>>>>>>>>>>> @@ -275,6 +275,9 @@ struct vdpa_config_ops {
> >>>>>>>>>>>>>>>>>>>                                       const struct vdpa_vq_state *state);
> >>>>>>>>>>>>>>>>>>>                   int (*get_vq_state)(struct vdpa_device *vdev, u16 idx,
> >>>>>>>>>>>>>>>>>>>                                       struct vdpa_vq_state *state);
> >>>>>>>>>>>>>>>>>>> +       int (*get_vendor_vq_stats)(struct vdpa_device *vdev, u16 idx,
> >>>>>>>>>>>>>>>>>>> +                                  struct sk_buff *msg,
> >>>>>>>>>>>>>>>>>>> +                                  struct netlink_ext_ack *extack);
> >>>>>>>>>>>>>>>>>>>                   struct vdpa_notification_area
> >>>>>>>>>>>>>>>>>>>                   (*get_vq_notification)(struct vdpa_device *vdev, u16 idx);
> >>>>>>>>>>>>>>>>>>>                   /* vq irq is not expected to be changed once DRIVER_OK is
> >>>>>>>>>>>>>>>>>>> set */ @@ -466,4 +469,6 @@ struct vdpa_mgmt_dev {
> >>>>>>>>>>>>>>>>>>>            int vdpa_mgmtdev_register(struct vdpa_mgmt_dev *mdev);
> >>>>>>>>>>>>>>>>>>>            void vdpa_mgmtdev_unregister(struct vdpa_mgmt_dev *mdev);
> >>>>>>>>>>>>>>>>>>> +#define VDPA_INVAL_QUEUE_INDEX 0xffff
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>>            #endif /* _LINUX_VDPA_H */
> >>>>>>>>>>>>>>>>>>> diff --git a/include/uapi/linux/vdpa.h
> >>>>>>>>>>>>>>>>>>> b/include/uapi/linux/vdpa.h index 1061d8d2d09d..c5f229a41dc2
> >>>>>>>>>>>>>>>>>>> 100644
> >>>>>>>>>>>>>>>>>>> --- a/include/uapi/linux/vdpa.h
> >>>>>>>>>>>>>>>>>>> +++ b/include/uapi/linux/vdpa.h
> >>>>>>>>>>>>>>>>>>> @@ -18,6 +18,7 @@ enum vdpa_command {
> >>>>>>>>>>>>>>>>>>>                   VDPA_CMD_DEV_DEL,
> >>>>>>>>>>>>>>>>>>>                   VDPA_CMD_DEV_GET,               /* can dump */
> >>>>>>>>>>>>>>>>>>>                   VDPA_CMD_DEV_CONFIG_GET,        /* can dump */
> >>>>>>>>>>>>>>>>>>> +       VDPA_CMD_DEV_VSTATS_GET,
> >>>>>>>>>>>>>>>>>>>            };
> >>>>>>>>>>>>>>>>>>>            enum vdpa_attr {
> >>>>>>>>>>>>>>>>>>> @@ -46,6 +47,12 @@ enum vdpa_attr {
> >>>>>>>>>>>>>>>>>>>                   VDPA_ATTR_DEV_NEGOTIATED_FEATURES,      /* u64 */
> >>>>>>>>>>>>>>>>>>>                   VDPA_ATTR_DEV_MGMTDEV_MAX_VQS,          /*
> >>>>>>>>>>>>>> u32 */
> >>>>>>>>>>>>>>>>>>>                   VDPA_ATTR_DEV_SUPPORTED_FEATURES,       /* u64 */
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>> +       VDPA_ATTR_DEV_QUEUE_INDEX,              /* u16 */
> >>>>>>>>>>>>>>>>>>> +       VDPA_ATTR_DEV_QUEUE_TYPE,               /* string */
> >>>>>>>>>>>>>>>>>>> +       VDPA_ATTR_DEV_VENDOR_ATTR_NAME,         /*
> >>>>>>>>>>>> string */
> >>>>>>>>>>>>>>>>>>> +       VDPA_ATTR_DEV_VENDOR_ATTR_VALUE,        /* u64 */
> >>>>>>>>>>>>>>>>>>> +
> >>>>>>>>>>>>>>>>>>>                   /* new attributes must be added above here */
> >>>>>>>>>>>>>>>>>>>                   VDPA_ATTR_MAX,
> >>>>>>>>>>>>>>>>>>>            };
>

_______________________________________________
Virtualization mailing list
Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linuxfoundation.org/mailman/listinfo/virtualization



[Index of Archives]     [KVM Development]     [Libvirt Development]     [Libvirt Users]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux