Hi Ilya,
Thanks for the quick review.
Please find comments inline.

> -----Original Message-----
> From: Ilya Maximets <[email protected]>
> Sent: Wednesday, January 16, 2019 5:42 PM
> To: Ophir Munk <[email protected]>; [email protected]; Ian
> Stokes <[email protected]>
> Cc: Asaf Penso <[email protected]>; Shahaf Shuler
> <[email protected]>; Thomas Monjalon <[email protected]>; Olga
> Shern <[email protected]>; Kevin Traynor <[email protected]>; Aaron
> Conole <[email protected]>
> Subject: Re: [PATCH v5] netdev-dpdk: support port representors
> 
> Not a full review.
> Comments inline.
> 
> Best regards, Ilya Maximets.
> 
> >
> > @@ -1361,12 +1382,32 @@ netdev_dpdk_destruct(struct netdev *netdev)
> >      dev->started = false;
> >
> >      if (dev->attached) {
> > +        /* Retrieve eth device data before closing it.
> > +         * FIXME: avoid direct access to DPDK internal array 
> > rte_eth_devices.
> > +         */
> > +        eth_dev = &rte_eth_devices[dev->port_id];
> > +        uint32_t remove_on_close =
> > +            eth_dev->data->dev_flags & RTE_ETH_DEV_CLOSE_REMOVE;
> 
> All other variables declared at the start of this function.
> Please, be consistent.
> 

In v6

> > +        rte_dev = eth_dev->device;
> > +
> > +        /* Remove the eth device. */
> >          rte_eth_dev_close(dev->port_id);
> > -        rte_eth_dev_info_get(dev->port_id, &dev_info);
> > -        if (dev_info.device && !rte_dev_remove(dev_info.device)) {
> > -            VLOG_INFO("Device '%s' has been detached", dev->devargs);
> > +
> > +        /* Remove this rte device and all its eth devices if flag
> > +         * RTE_ETH_DEV_CLOSE_REMOVE is not supported (which means
> representors
> > +         * are not supported), or if all the eth devices belonging to the 
> > rte
> > +         * device are closed.
> > +         */
> > +        if (!remove_on_close || !netdev_dpdk_get_num_ports(rte_dev)) {
> > +            if (rte_dev_remove(rte_dev) < 0) {
> > +                VLOG_ERR("Device '%s' can not be detached", dev->devargs);
> > +            } else {
> > +                /* Device was closed and detached. */
> > +                VLOG_INFO("Device '%s' has been detached", dev->devargs);
> > +            }
> >          } else {
> > -            VLOG_ERR("Device '%s' can not be detached", dev->devargs);
> > +            /* Device was only closed. rte_dev_remove() was not called. */
> > +            VLOG_INFO("Device '%s' has been removed", dev->devargs);
> 
> IMHO, this should be printed regardless of detaching. (Before it)
> 

As I suggested to Kevin in a recent review - "Device has been detached" was 
changed to "Device has been removed and detached".
This will accurately reflect the operations on the device.

> > +
> > +static int
> > +netdev_dpdk_check_dup_dev(dpdk_port_t port_id, struct netdev *netdev,
> > +                          const char *devargs, char **errp) {
> 
> OVS_REQUIRES(dpdk_mutex)
> 
> Also, the '{' should be on a new line in function definitions.
> 

This function is removed in v6

> > +    struct netdev_dpdk *dup_dev;
> > +
> > +    dup_dev = netdev_dpdk_lookup_by_port_id(port_id);
> > +    if (dup_dev) {
> > +        VLOG_WARN_BUF(errp, "'%s' is trying to use device '%s' "
> > +                            "which is already in use by '%s'",
> > +                            netdev_get_name(netdev), devargs,
> > +                            netdev_get_name(&dup_dev->up));
> > +      return EADDRINUSE;
> > +   }
> > +   return 0;
> 
> Indents are off in the previous 3 lines.
> 

In v6

> > +}
> > +
> >  /*
> > - * Normally, a PCI id is enough for identifying a specific DPDK port.
> > + * Normally, a PCI id (optionally followed by a representor number)
> > + * is enough for identifying a specific DPDK port.
> >   * However, for some NICs having multiple ports sharing the same PCI
> >   * id, using PCI id won't work then.
> >   *
> > @@ -1641,32 +1728,35 @@ netdev_dpdk_get_port_by_mac(const char
> *mac_str)
> >   *
> >   * Note that the compatibility is fully kept: user can still use the
> >   * PCI id for adding ports (when it's enough for them).
> > + *
> > + * In order to avoid clang errors add OVS_REQUIRES(dpdk_mutex) to
> > + this function
> > + * since it is required by netdev_dpdk_lookup_by_port_id() while the
> > + dpdk_mutex
> > + * is taken outside of this function.
> 
> Agree with Aaron that the comment is not needed.
> 

Comment removed in v6

> >   */
> >  static dpdk_port_t
> >  netdev_dpdk_process_devargs(struct netdev_dpdk *dev,
> >                              const char *devargs, char **errp)
> > +    OVS_REQUIRES(dpdk_mutex)
> >  {
> > -    char *name;
> >      dpdk_port_t new_port_id = DPDK_ETH_PORT_ID_INVALID;
> >
> >      if (strncmp(devargs, "class=eth,mac=", 14) == 0) {
> >          new_port_id = netdev_dpdk_get_port_by_mac(&devargs[14]);
> >      } else {
> > -        name = xmemdup0(devargs, strcspn(devargs, ","));
> > -        if (rte_eth_dev_get_port_by_name(name, &new_port_id)
> > -                || !rte_eth_dev_is_valid_port(new_port_id)) {
> > -            /* Device not found in DPDK, attempt to attach it */
> > -            if (!rte_dev_probe(devargs)
> > -                && !rte_eth_dev_get_port_by_name(name, &new_port_id)) {
> > -                /* Attach successful */
> > -                dev->attached = true;
> > -                VLOG_INFO("Device '%s' attached to DPDK", devargs);
> > +        new_port_id = netdev_dpdk_probe_port_by_devargs(devargs);
> > +        if (!rte_eth_dev_is_valid_port(new_port_id)) {
> > +            new_port_id = DPDK_ETH_PORT_ID_INVALID;
> > +        } else {
> > +            if (netdev_dpdk_check_dup_dev(new_port_id, &dev->up,
> > +                    devargs, errp)) {
> > +                    new_port_id = DPDK_ETH_PORT_ID_INVALID;
> 
> Still don't understand why you need to check duplicated ports twice.
> Upper layer should handle this case.
> Also, indents are off.

Duplicate check is removed in v6

> > +1846,9 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct
> smap *args,
> >                  /* Already configured, do not reconfigure again */
> >                  err = 0;
> >              } else {
> > -                struct netdev_dpdk *dup_dev;
> > -
> > -                dup_dev = netdev_dpdk_lookup_by_port_id(new_port_id);
> > -                if (dup_dev) {
> > -                    VLOG_WARN_BUF(errp, "'%s' is trying to use device '%s' 
> > "
> > -                                        "which is already in use by '%s'",
> > -                                  netdev_get_name(netdev), new_devargs,
> > -                                  netdev_get_name(&dup_dev->up));
> > -                    err = EADDRINUSE;
> > -                } else {
> > +                err = netdev_dpdk_check_dup_dev(new_port_id, netdev,
> > +                          new_devargs, errp);
> 
> Indents off.
> It's better to be:
> 
>                 err = netdev_dpdk_check_dup_dev(new_port_id, netdev,
>                                                 new_devargs, errp);
> 

In v6 this function call is replaced by the function contents.

> > @@ -3253,15 +3342,26 @@ netdev_dpdk_detach(struct unixctl_conn *conn,
> int argc OVS_UNUSED,
> >          goto error;
> >      }
> >
> > -    rte_eth_dev_close(port_id);
> > +    /* FIXME: avoid direct access to DPDK internal array rte_eth_devices. 
> > */
> > +    eth_dev = &rte_eth_devices[port_id];
> > +    rte_dev = eth_dev->device;
> > +
> > +    if ((eth_dev->data->dev_flags & RTE_ETH_DEV_CLOSE_REMOVE) &&
> > +            (netdev_dpdk_get_num_ports(rte_dev) > 1)) {

This line requires a fix. It should be ">=1" instead of ">1".
The two lines above are rewritten in v6.

> 
> We still need to close the port here because if you'll have 2 sibling ports 
> you'll
> not be able do detach any of them because another one still open.
> 
> Anyway, Logic seems wrong here.
> 

I will try to explain the logic

> The function intended to detach pci devices. And the usecase is detaching
> devices that was added by the whitelist and not attached in
> 'netdev_dpdk_process_devargs', i.e. has 'dev->attached = false'.
> 

Correct

> The workflow should be:
> 
>   * Iterate over all the siblings of the desired device.
>       * if port_id still used by OVS (netdev_dpdk_lookup_by_port_id(port_id) 
> !=
> NULL)
>            print "Device '%s' is being used by interface '%s'. Remove it 
> before
> detaching"
> 

For PMDs not supporting representors the code is backward compatible with 
previous versions.
For PMDs supporting representors and in cases we have dozens of multi-ports 
(representors/interfaces) - is it desirable to print dozens of such messages?
The current patch suggests one message for all cases:
"Device '%s' is being shared with other interfaces. Remove them before 
detaching.",
IMHO, I would leave it this way for this patch. If you still think it is useful 
to have a message per interface - I suggest adding it in a follow up patch.
What do you think?

>   * If some ports are still used by OVS
>       return
> 
>   * If none of the ports still used by OVS
>       Iterate over all the siblings and close them. 
> (rte_eth_dev_close(port_id))
>       Try to remove the device. (rte_dev_remove(rte_dev))

The responsibility for closing all eth devices before detaching the rte device 
should be embedded in the rte_dev_remove() call itself. 
In other words, when calling rte_dev_remove() - all opened eth devices should 
be automatically closed and then the rte device should be unplugged/detached.
It requires a PMD supporting representors to implement the remove() callback as 
part of struct rte_pci_driver. 
Hence, if none of the sibling ports is used by OVS - it is sufficient to call 
rte_dev_remove(rte_dev) and there is no need to iterate over all the siblings 
and close them.

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to