Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1538332 > unrolled thread
| Started by | kys@exchange.microsoft.com |
|---|---|
| First post | 2016-12-08 07:40 +0100 |
| Last post | 2016-12-09 23:50 +0100 |
| Articles | 20 on this page of 21 — 5 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers kys@exchange.microsoft.com - 2016-12-08 07:40 +0100
Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Greg KH <gregkh@linuxfoundation.org> - 2016-12-08 17:00 +0100
RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers KY Srinivasan <kys@microsoft.com> - 2016-12-09 01:30 +0100
Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Greg KH <gregkh@linuxfoundation.org> - 2016-12-09 08:40 +0100
Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Stephen Hemminger <stephen@networkplumber.org> - 2016-12-09 19:30 +0100
Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Stephen Hemminger <stephen@networkplumber.org> - 2016-12-09 21:30 +0100
Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Stephen Hemminger <stephen@networkplumber.org> - 2016-12-09 22:50 +0100
RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Haiyang Zhang <haiyangz@microsoft.com> - 2016-12-09 23:10 +0100
Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Stephen Hemminger <stephen@networkplumber.org> - 2016-12-09 23:10 +0100
RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Haiyang Zhang <haiyangz@microsoft.com> - 2016-12-10 00:00 +0100
Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Stephen Hemminger <stephen@networkplumber.org> - 2016-12-10 01:30 +0100
Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Greg KH <gregkh@linuxfoundation.org> - 2016-12-10 13:30 +0100
Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Greg KH <gregkh@linuxfoundation.org> - 2016-12-15 00:30 +0100
Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Stephen Hemminger <stephen@networkplumber.org> - 2016-12-15 01:00 +0100
RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers KY Srinivasan <kys@microsoft.com> - 2016-12-16 02:20 +0100
RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Haiyang Zhang <haiyangz@microsoft.com> - 2016-12-16 17:00 +0100
RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers KY Srinivasan <kys@microsoft.com> - 2016-12-16 20:00 +0100
Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Greg KH <gregkh@linuxfoundation.org> - 2016-12-16 17:50 +0100
RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Haiyang Zhang <haiyangz@microsoft.com> - 2016-12-15 04:00 +0100
RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Haiyang Zhang <haiyangz@microsoft.com> - 2016-12-09 22:50 +0100
RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers Haiyang Zhang <haiyangz@microsoft.com> - 2016-12-09 23:50 +0100
Page 1 of 2 [1] 2 Next page →
| From | kys@exchange.microsoft.com |
|---|---|
| Date | 2016-12-08 07:40 +0100 |
| Subject | [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sM0x3-2Ck-7@gated-at.bofh.it> |
From: Haiyang Zhang <haiyangz@microsoft.com>
We currently use MAC address to match VF and synthetic NICs. Hyper-V
provides a serial number to both devices for this purpose. This patch
implements the matching based on VF serial numbers. This is the way
specified by the protocol and more reliable.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/net/hyperv/netvsc_drv.c | 55 ++++++++++++++++++++++++++++++++++++---
1 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 9522763..c5778cf 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1165,9 +1165,10 @@ static void netvsc_free_netdev(struct net_device *netdev)
free_netdev(netdev);
}
-static struct net_device *get_netvsc_bymac(const u8 *mac)
+static struct net_device *get_netvsc_byvfser(u32 vfser)
{
struct net_device *dev;
+ struct net_device_context *ndev_ctx;
ASSERT_RTNL();
@@ -1175,7 +1176,8 @@ static void netvsc_free_netdev(struct net_device *netdev)
if (dev->netdev_ops != &device_ops)
continue; /* not a netvsc device */
- if (ether_addr_equal(mac, dev->perm_addr))
+ ndev_ctx = netdev_priv(dev);
+ if (ndev_ctx->vf_serial == vfser)
return dev;
}
@@ -1205,21 +1207,66 @@ static void netvsc_free_netdev(struct net_device *netdev)
return NULL;
}
+static u32 netvsc_get_vfser(struct net_device *vf_netdev)
+{
+ struct device *dev;
+ struct hv_device *hdev;
+ struct hv_pcibus_device *hbus = NULL;
+ struct list_head *iter;
+ struct hv_pci_dev *hpdev;
+ unsigned long flags;
+ u32 vfser = 0;
+ u32 count = 0;
+
+ for (dev = &vf_netdev->dev; dev; dev = dev->parent) {
+ if (!dev_is_vmbus(dev))
+ continue;
+
+ hdev = device_to_hv_device(dev);
+ if (hdev->device_id != HV_PCIE)
+ continue;
+
+ hbus = hv_get_drvdata(hdev);
+ break;
+ }
+
+ if (!hbus)
+ return 0;
+
+ spin_lock_irqsave(&hbus->device_list_lock, flags);
+ list_for_each(iter, &hbus->children) {
+ hpdev = container_of(iter, struct hv_pci_dev, list_entry);
+ vfser = hpdev->desc.ser;
+ count++;
+ }
+ spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+
+ if (count == 1)
+ return vfser;
+
+ return 0;
+}
+
static int netvsc_register_vf(struct net_device *vf_netdev)
{
struct net_device *ndev;
struct net_device_context *net_device_ctx;
struct netvsc_device *netvsc_dev;
+ u32 vfser;
if (vf_netdev->addr_len != ETH_ALEN)
return NOTIFY_DONE;
+ vfser = netvsc_get_vfser(vf_netdev);
+ if (!vfser)
+ return NOTIFY_DONE;
+
/*
- * We will use the MAC address to locate the synthetic interface to
+ * We will use the VF serial to locate the synthetic interface to
* associate with the VF interface. If we don't find a matching
* synthetic interface, move on.
*/
- ndev = get_netvsc_bymac(vf_netdev->perm_addr);
+ ndev = get_netvsc_byvfser(vfser);
if (!ndev)
return NOTIFY_DONE;
--
1.7.4.1
[toc] | [next] | [standalone]
| From | Greg KH <gregkh@linuxfoundation.org> |
|---|---|
| Date | 2016-12-08 17:00 +0100 |
| Subject | Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sM9h5-7Vv-35@gated-at.bofh.it> |
| In reply to | #1538332 |
On Thu, Dec 08, 2016 at 12:33:43AM -0800, kys@exchange.microsoft.com wrote:
> From: Haiyang Zhang <haiyangz@microsoft.com>
>
> We currently use MAC address to match VF and synthetic NICs. Hyper-V
> provides a serial number to both devices for this purpose. This patch
> implements the matching based on VF serial numbers. This is the way
> specified by the protocol and more reliable.
>
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> ---
> drivers/net/hyperv/netvsc_drv.c | 55 ++++++++++++++++++++++++++++++++++++---
> 1 files changed, 51 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
> index 9522763..c5778cf 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -1165,9 +1165,10 @@ static void netvsc_free_netdev(struct net_device *netdev)
> free_netdev(netdev);
> }
>
> -static struct net_device *get_netvsc_bymac(const u8 *mac)
> +static struct net_device *get_netvsc_byvfser(u32 vfser)
> {
> struct net_device *dev;
> + struct net_device_context *ndev_ctx;
>
> ASSERT_RTNL();
>
> @@ -1175,7 +1176,8 @@ static void netvsc_free_netdev(struct net_device *netdev)
> if (dev->netdev_ops != &device_ops)
> continue; /* not a netvsc device */
>
> - if (ether_addr_equal(mac, dev->perm_addr))
> + ndev_ctx = netdev_priv(dev);
> + if (ndev_ctx->vf_serial == vfser)
> return dev;
> }
>
> @@ -1205,21 +1207,66 @@ static void netvsc_free_netdev(struct net_device *netdev)
> return NULL;
> }
>
> +static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> +{
> + struct device *dev;
> + struct hv_device *hdev;
> + struct hv_pcibus_device *hbus = NULL;
> + struct list_head *iter;
> + struct hv_pci_dev *hpdev;
> + unsigned long flags;
> + u32 vfser = 0;
> + u32 count = 0;
> +
> + for (dev = &vf_netdev->dev; dev; dev = dev->parent) {
You are going to walk the whole device tree backwards? That's crazy.
And foolish. And racy and broken (what happens if the tree changes
while you do this?) Where is the lock being grabbed while this happens?
What about reference counts? Do you see other drivers ever doing this
(if you do, point them out and I'll go yell at them too...)
> + if (!dev_is_vmbus(dev))
> + continue;
Ick.
Why isn't your parent pointer a vmbus device all the time? How could
you get burried down in the device hierarchy when you are the driver for
a specific bus type in the first place? How could this function ever be
called for a device that is NOT of this type?
thanks,
greg k-h
[toc] | [prev] | [next] | [standalone]
| From | KY Srinivasan <kys@microsoft.com> |
|---|---|
| Date | 2016-12-09 01:30 +0100 |
| Subject | RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sMhex-4yz-5@gated-at.bofh.it> |
| In reply to | #1538657 |
> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: Thursday, December 8, 2016 7:56 AM
> To: KY Srinivasan <kys@microsoft.com>
> Cc: linux-kernel@vger.kernel.org; devel@linuxdriverproject.org;
> olaf@aepfle.de; apw@canonical.com; vkuznets@redhat.com;
> jasowang@redhat.com; leann.ogasawara@canonical.com;
> bjorn.helgaas@gmail.com; Haiyang Zhang <haiyangz@microsoft.com>
> Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial
> numbers
>
> On Thu, Dec 08, 2016 at 12:33:43AM -0800, kys@exchange.microsoft.com
> wrote:
> > From: Haiyang Zhang <haiyangz@microsoft.com>
> >
> > We currently use MAC address to match VF and synthetic NICs. Hyper-V
> > provides a serial number to both devices for this purpose. This patch
> > implements the matching based on VF serial numbers. This is the way
> > specified by the protocol and more reliable.
> >
> > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > ---
> > drivers/net/hyperv/netvsc_drv.c | 55
> ++++++++++++++++++++++++++++++++++++---
> > 1 files changed, 51 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/net/hyperv/netvsc_drv.c
> b/drivers/net/hyperv/netvsc_drv.c
> > index 9522763..c5778cf 100644
> > --- a/drivers/net/hyperv/netvsc_drv.c
> > +++ b/drivers/net/hyperv/netvsc_drv.c
> > @@ -1165,9 +1165,10 @@ static void netvsc_free_netdev(struct
> net_device *netdev)
> > free_netdev(netdev);
> > }
> >
> > -static struct net_device *get_netvsc_bymac(const u8 *mac)
> > +static struct net_device *get_netvsc_byvfser(u32 vfser)
> > {
> > struct net_device *dev;
> > + struct net_device_context *ndev_ctx;
> >
> > ASSERT_RTNL();
> >
> > @@ -1175,7 +1176,8 @@ static void netvsc_free_netdev(struct net_device
> *netdev)
> > if (dev->netdev_ops != &device_ops)
> > continue; /* not a netvsc device */
> >
> > - if (ether_addr_equal(mac, dev->perm_addr))
> > + ndev_ctx = netdev_priv(dev);
> > + if (ndev_ctx->vf_serial == vfser)
> > return dev;
> > }
> >
> > @@ -1205,21 +1207,66 @@ static void netvsc_free_netdev(struct
> net_device *netdev)
> > return NULL;
> > }
> >
> > +static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> > +{
> > + struct device *dev;
> > + struct hv_device *hdev;
> > + struct hv_pcibus_device *hbus = NULL;
> > + struct list_head *iter;
> > + struct hv_pci_dev *hpdev;
> > + unsigned long flags;
> > + u32 vfser = 0;
> > + u32 count = 0;
> > +
> > + for (dev = &vf_netdev->dev; dev; dev = dev->parent) {
>
> You are going to walk the whole device tree backwards? That's crazy.
> And foolish. And racy and broken (what happens if the tree changes
> while you do this?) Where is the lock being grabbed while this happens?
> What about reference counts? Do you see other drivers ever doing this
> (if you do, point them out and I'll go yell at them too...)
Greg,
We are registering for netdev events. Coming into this function, the caller
guarantees that the list of netdevs does not change - we assert this on entry:
ASSERT_RTNL(). We are only walking up the device tree for the netdevs whose
state change is being notified to us - the device tree being walked here is limited to
netdevs under question.
We have a reference to the device and we know the device is not going away. Is it not
safe to dereference the parent pointer - after all the child has taken a reference on
the parent as part of device_add() call.
>
> > + if (!dev_is_vmbus(dev))
> > + continue;
>
> Ick.
>
> Why isn't your parent pointer a vmbus device all the time? How could
> you get burried down in the device hierarchy when you are the driver for
> a specific bus type in the first place? How could this function ever be
> called for a device that is NOT of this type?
We get notified when state changes on any of the netdev devices in the system.
Not all netdevs in the system belong to vmbus. Consider for instance the
emulated NIC that can be configured. This is an emulated PCI NIC. We are only
interested in netdevs that correspond to the VF instance that we are interested in.
Regards,
K. Y
[toc] | [prev] | [next] | [standalone]
| From | Greg KH <gregkh@linuxfoundation.org> |
|---|---|
| Date | 2016-12-09 08:40 +0100 |
| Subject | Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sMnWG-qT-13@gated-at.bofh.it> |
| In reply to | #1538977 |
On Fri, Dec 09, 2016 at 12:05:53AM +0000, KY Srinivasan wrote:
>
>
> > -----Original Message-----
> > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > Sent: Thursday, December 8, 2016 7:56 AM
> > To: KY Srinivasan <kys@microsoft.com>
> > Cc: linux-kernel@vger.kernel.org; devel@linuxdriverproject.org;
> > olaf@aepfle.de; apw@canonical.com; vkuznets@redhat.com;
> > jasowang@redhat.com; leann.ogasawara@canonical.com;
> > bjorn.helgaas@gmail.com; Haiyang Zhang <haiyangz@microsoft.com>
> > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial
> > numbers
> >
> > On Thu, Dec 08, 2016 at 12:33:43AM -0800, kys@exchange.microsoft.com
> > wrote:
> > > From: Haiyang Zhang <haiyangz@microsoft.com>
> > >
> > > We currently use MAC address to match VF and synthetic NICs. Hyper-V
> > > provides a serial number to both devices for this purpose. This patch
> > > implements the matching based on VF serial numbers. This is the way
> > > specified by the protocol and more reliable.
> > >
> > > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > > ---
> > > drivers/net/hyperv/netvsc_drv.c | 55
> > ++++++++++++++++++++++++++++++++++++---
> > > 1 files changed, 51 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/net/hyperv/netvsc_drv.c
> > b/drivers/net/hyperv/netvsc_drv.c
> > > index 9522763..c5778cf 100644
> > > --- a/drivers/net/hyperv/netvsc_drv.c
> > > +++ b/drivers/net/hyperv/netvsc_drv.c
> > > @@ -1165,9 +1165,10 @@ static void netvsc_free_netdev(struct
> > net_device *netdev)
> > > free_netdev(netdev);
> > > }
> > >
> > > -static struct net_device *get_netvsc_bymac(const u8 *mac)
> > > +static struct net_device *get_netvsc_byvfser(u32 vfser)
> > > {
> > > struct net_device *dev;
> > > + struct net_device_context *ndev_ctx;
> > >
> > > ASSERT_RTNL();
> > >
> > > @@ -1175,7 +1176,8 @@ static void netvsc_free_netdev(struct net_device
> > *netdev)
> > > if (dev->netdev_ops != &device_ops)
> > > continue; /* not a netvsc device */
> > >
> > > - if (ether_addr_equal(mac, dev->perm_addr))
> > > + ndev_ctx = netdev_priv(dev);
> > > + if (ndev_ctx->vf_serial == vfser)
> > > return dev;
> > > }
> > >
> > > @@ -1205,21 +1207,66 @@ static void netvsc_free_netdev(struct
> > net_device *netdev)
> > > return NULL;
> > > }
> > >
> > > +static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> > > +{
> > > + struct device *dev;
> > > + struct hv_device *hdev;
> > > + struct hv_pcibus_device *hbus = NULL;
> > > + struct list_head *iter;
> > > + struct hv_pci_dev *hpdev;
> > > + unsigned long flags;
> > > + u32 vfser = 0;
> > > + u32 count = 0;
> > > +
> > > + for (dev = &vf_netdev->dev; dev; dev = dev->parent) {
> >
> > You are going to walk the whole device tree backwards? That's crazy.
> > And foolish. And racy and broken (what happens if the tree changes
> > while you do this?) Where is the lock being grabbed while this happens?
> > What about reference counts? Do you see other drivers ever doing this
> > (if you do, point them out and I'll go yell at them too...)
>
> Greg,
>
> We are registering for netdev events. Coming into this function, the caller
> guarantees that the list of netdevs does not change - we assert this on entry:
> ASSERT_RTNL(). We are only walking up the device tree for the netdevs whose
> state change is being notified to us - the device tree being walked here is limited to
> netdevs under question.
But a netdev is a child of some type of "real" device, and you are now
walking the tree of all devices up to the "root" parent device, which
means you will hit PCI bridges, USB controllers, and all sorts of fun
things if you are a child of those types of devices.
And can't you tell if the netdev for this event, really is "your"
netdev? Or are you getting called this for "all" netdevs? Sorry, I
don't know this api, any pointers to it would be appreciated.
> We have a reference to the device and we know the device is not going away. Is it not
> safe to dereference the parent pointer - after all the child has taken a reference on
> the parent as part of device_add() call.
It might be, and might not be. There's a reason you don't see this
pattern anywhere in the kernel because of this...
> > > + if (!dev_is_vmbus(dev))
> > > + continue;
> >
> > Ick.
> >
> > Why isn't your parent pointer a vmbus device all the time? How could
> > you get burried down in the device hierarchy when you are the driver for
> > a specific bus type in the first place? How could this function ever be
> > called for a device that is NOT of this type?
>
> We get notified when state changes on any of the netdev devices in the system.
> Not all netdevs in the system belong to vmbus. Consider for instance the
> emulated NIC that can be configured. This is an emulated PCI NIC. We are only
> interested in netdevs that correspond to the VF instance that we are interested in.
Can you "know" this is your netdev by some other way than having to walk
the device tree? Name? local device type? Something else? This seems
like an odd api in that everyone would have to do gyrations like this in
order to determine if the netdev is "theirs" or not...
thanks,
greg k-h
[toc] | [prev] | [next] | [standalone]
| From | Stephen Hemminger <stephen@networkplumber.org> |
|---|---|
| Date | 2016-12-09 19:30 +0100 |
| Subject | Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sMy5I-6DX-45@gated-at.bofh.it> |
| In reply to | #1539156 |
On Fri, 9 Dec 2016 08:31:22 +0100
Greg KH <gregkh@linuxfoundation.org> wrote:
> On Fri, Dec 09, 2016 at 12:05:53AM +0000, KY Srinivasan wrote:
> >
> >
> > > -----Original Message-----
> > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > Sent: Thursday, December 8, 2016 7:56 AM
> > > To: KY Srinivasan <kys@microsoft.com>
> > > Cc: linux-kernel@vger.kernel.org; devel@linuxdriverproject.org;
> > > olaf@aepfle.de; apw@canonical.com; vkuznets@redhat.com;
> > > jasowang@redhat.com; leann.ogasawara@canonical.com;
> > > bjorn.helgaas@gmail.com; Haiyang Zhang <haiyangz@microsoft.com>
> > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial
> > > numbers
> > >
> > > On Thu, Dec 08, 2016 at 12:33:43AM -0800, kys@exchange.microsoft.com
> > > wrote:
> > > > From: Haiyang Zhang <haiyangz@microsoft.com>
> > > >
> > > > We currently use MAC address to match VF and synthetic NICs. Hyper-V
> > > > provides a serial number to both devices for this purpose. This patch
> > > > implements the matching based on VF serial numbers. This is the way
> > > > specified by the protocol and more reliable.
> > > >
> > > > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > > > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > > > ---
> > > > drivers/net/hyperv/netvsc_drv.c | 55
> > > ++++++++++++++++++++++++++++++++++++---
> > > > 1 files changed, 51 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/drivers/net/hyperv/netvsc_drv.c
> > > b/drivers/net/hyperv/netvsc_drv.c
> > > > index 9522763..c5778cf 100644
> > > > --- a/drivers/net/hyperv/netvsc_drv.c
> > > > +++ b/drivers/net/hyperv/netvsc_drv.c
> > > > @@ -1165,9 +1165,10 @@ static void netvsc_free_netdev(struct
> > > net_device *netdev)
> > > > free_netdev(netdev);
> > > > }
> > > >
> > > > -static struct net_device *get_netvsc_bymac(const u8 *mac)
> > > > +static struct net_device *get_netvsc_byvfser(u32 vfser)
> > > > {
> > > > struct net_device *dev;
> > > > + struct net_device_context *ndev_ctx;
> > > >
> > > > ASSERT_RTNL();
> > > >
> > > > @@ -1175,7 +1176,8 @@ static void netvsc_free_netdev(struct net_device
> > > *netdev)
> > > > if (dev->netdev_ops != &device_ops)
> > > > continue; /* not a netvsc device */
> > > >
> > > > - if (ether_addr_equal(mac, dev->perm_addr))
> > > > + ndev_ctx = netdev_priv(dev);
> > > > + if (ndev_ctx->vf_serial == vfser)
> > > > return dev;
> > > > }
> > > >
> > > > @@ -1205,21 +1207,66 @@ static void netvsc_free_netdev(struct
> > > net_device *netdev)
> > > > return NULL;
> > > > }
> > > >
> > > > +static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> > > > +{
> > > > + struct device *dev;
> > > > + struct hv_device *hdev;
> > > > + struct hv_pcibus_device *hbus = NULL;
> > > > + struct list_head *iter;
> > > > + struct hv_pci_dev *hpdev;
> > > > + unsigned long flags;
> > > > + u32 vfser = 0;
> > > > + u32 count = 0;
> > > > +
> > > > + for (dev = &vf_netdev->dev; dev; dev = dev->parent) {
> > >
> > > You are going to walk the whole device tree backwards? That's crazy.
> > > And foolish. And racy and broken (what happens if the tree changes
> > > while you do this?) Where is the lock being grabbed while this happens?
> > > What about reference counts? Do you see other drivers ever doing this
> > > (if you do, point them out and I'll go yell at them too...)
> >
> > Greg,
> >
> > We are registering for netdev events. Coming into this function, the caller
> > guarantees that the list of netdevs does not change - we assert this on entry:
> > ASSERT_RTNL(). We are only walking up the device tree for the netdevs whose
> > state change is being notified to us - the device tree being walked here is limited to
> > netdevs under question.
>
> But a netdev is a child of some type of "real" device, and you are now
> walking the tree of all devices up to the "root" parent device, which
> means you will hit PCI bridges, USB controllers, and all sorts of fun
> things if you are a child of those types of devices.
>
> And can't you tell if the netdev for this event, really is "your"
> netdev? Or are you getting called this for "all" netdevs? Sorry, I
> don't know this api, any pointers to it would be appreciated.
>
> > We have a reference to the device and we know the device is not going away. Is it not
> > safe to dereference the parent pointer - after all the child has taken a reference on
> > the parent as part of device_add() call.
>
> It might be, and might not be. There's a reason you don't see this
> pattern anywhere in the kernel because of this...
>
> > > > + if (!dev_is_vmbus(dev))
> > > > + continue;
> > >
> > > Ick.
> > >
> > > Why isn't your parent pointer a vmbus device all the time? How could
> > > you get burried down in the device hierarchy when you are the driver for
> > > a specific bus type in the first place? How could this function ever be
> > > called for a device that is NOT of this type?
> >
> > We get notified when state changes on any of the netdev devices in the system.
> > Not all netdevs in the system belong to vmbus. Consider for instance the
> > emulated NIC that can be configured. This is an emulated PCI NIC. We are only
> > interested in netdevs that correspond to the VF instance that we are interested in.
>
> Can you "know" this is your netdev by some other way than having to walk
> the device tree? Name? local device type? Something else? This seems
> like an odd api in that everyone would have to do gyrations like this in
> order to determine if the netdev is "theirs" or not...
The scenario is SR-IOV on Hyper-V. In the case of VF device, the host hands the
guest OS a PCI device for the virtual function device. The VF device is placed
on a special synthetic PCI bus (ie not part of the other buses on the system).
The VF device also has a synthetic network interface (netvsc) which lives
on VMBUS. This code is about managing the interaction between the two.
The association between VF and synthetic NIC is done in response to the
VF network device being registered. Initial version was based on MAC address
which is the same. Later refinement used permanent MAC address to
avoid bugs if MAC address changed. This version is to use serial number
instead which is safer than MAC address.
The code to walk up/down maybe not be needed to find serial number.
Perhaps a more direct single set of conditions is possible?
Something like:
In pci-hyperv.c
u32 hv_pcifront_get_serial(struct pci_bus *bus, unsigned int devfn)
{
struct hv_pcibus_device *hbus
= container_of(bus->sysdata,
struct hv_pcibus_device, sysdata);
struct hf_pci_dev *hpdev;
u32 serial;
hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn));
if (!hpdev)
return 0;
serial = hpdev->devs.ser;
put_pcichild(hpdev, hv_pcidev_ref_by_slot);
return serial;
}
In netvsc_drv.c
static u32 netvsc_get_vfser(struct net_device *vf_netdev)
{
struct device *dev = vf_netdev->dev.parent;
struct pci_dev *pdev;
u32 wslot;
if (!dev || !dev_is_pci(dev))
return 0;
pdev = container_of(dev, struct pci_device, dev);
return hv_pcifront_get_serial(pdev->bus, pdev->devfn);
}
P.S: it would be good to be able to get win_slot out through sysfs as
well for systemd/udev.
[toc] | [prev] | [next] | [standalone]
| From | Stephen Hemminger <stephen@networkplumber.org> |
|---|---|
| Date | 2016-12-09 21:30 +0100 |
| Subject | Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sMzXP-7Mo-13@gated-at.bofh.it> |
| In reply to | #1539611 |
On Fri, 9 Dec 2016 20:09:49 +0000
Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > -----Original Message-----
> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Friday, December 9, 2016 1:21 PM
> > To: Greg KH <gregkh@linuxfoundation.org>
> > Cc: KY Srinivasan <kys@microsoft.com>; olaf@aepfle.de; Haiyang Zhang
> > <haiyangz@microsoft.com>; linux-kernel@vger.kernel.org;
> > bjorn.helgaas@gmail.com; apw@canonical.com; devel@linuxdriverproject.org;
> > leann.ogasawara@canonical.com; jasowang@redhat.com
> > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > serial numbers
> >
> > On Fri, 9 Dec 2016 08:31:22 +0100
> > Greg KH <gregkh@linuxfoundation.org> wrote:
> >
> > > On Fri, Dec 09, 2016 at 12:05:53AM +0000, KY Srinivasan wrote:
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > > > Sent: Thursday, December 8, 2016 7:56 AM
> > > > > To: KY Srinivasan <kys@microsoft.com>
> > > > > Cc: linux-kernel@vger.kernel.org; devel@linuxdriverproject.org;
> > > > > olaf@aepfle.de; apw@canonical.com; vkuznets@redhat.com;
> > > > > jasowang@redhat.com; leann.ogasawara@canonical.com;
> > > > > bjorn.helgaas@gmail.com; Haiyang Zhang <haiyangz@microsoft.com>
> > > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > serial
> > > > > numbers
> > > > >
> > > > > On Thu, Dec 08, 2016 at 12:33:43AM -0800,
> > kys@exchange.microsoft.com
> > > > > wrote:
> > > > > > From: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > >
> > > > > > We currently use MAC address to match VF and synthetic NICs.
> > Hyper-V
> > > > > > provides a serial number to both devices for this purpose. This
> > patch
> > > > > > implements the matching based on VF serial numbers. This is the
> > way
> > > > > > specified by the protocol and more reliable.
> > > > > >
> > > > > > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > > > > > ---
> > > > > > drivers/net/hyperv/netvsc_drv.c | 55
> > > > > ++++++++++++++++++++++++++++++++++++---
> > > > > > 1 files changed, 51 insertions(+), 4 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/net/hyperv/netvsc_drv.c
> > > > > b/drivers/net/hyperv/netvsc_drv.c
> > > > > > index 9522763..c5778cf 100644
> > > > > > --- a/drivers/net/hyperv/netvsc_drv.c
> > > > > > +++ b/drivers/net/hyperv/netvsc_drv.c
> > > > > > @@ -1165,9 +1165,10 @@ static void netvsc_free_netdev(struct
> > > > > net_device *netdev)
> > > > > > free_netdev(netdev);
> > > > > > }
> > > > > >
> > > > > > -static struct net_device *get_netvsc_bymac(const u8 *mac)
> > > > > > +static struct net_device *get_netvsc_byvfser(u32 vfser)
> > > > > > {
> > > > > > struct net_device *dev;
> > > > > > + struct net_device_context *ndev_ctx;
> > > > > >
> > > > > > ASSERT_RTNL();
> > > > > >
> > > > > > @@ -1175,7 +1176,8 @@ static void netvsc_free_netdev(struct
> > net_device
> > > > > *netdev)
> > > > > > if (dev->netdev_ops != &device_ops)
> > > > > > continue; /* not a netvsc device */
> > > > > >
> > > > > > - if (ether_addr_equal(mac, dev->perm_addr))
> > > > > > + ndev_ctx = netdev_priv(dev);
> > > > > > + if (ndev_ctx->vf_serial == vfser)
> > > > > > return dev;
> > > > > > }
> > > > > >
> > > > > > @@ -1205,21 +1207,66 @@ static void netvsc_free_netdev(struct
> > > > > net_device *netdev)
> > > > > > return NULL;
> > > > > > }
> > > > > >
> > > > > > +static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> > > > > > +{
> > > > > > + struct device *dev;
> > > > > > + struct hv_device *hdev;
> > > > > > + struct hv_pcibus_device *hbus = NULL;
> > > > > > + struct list_head *iter;
> > > > > > + struct hv_pci_dev *hpdev;
> > > > > > + unsigned long flags;
> > > > > > + u32 vfser = 0;
> > > > > > + u32 count = 0;
> > > > > > +
> > > > > > + for (dev = &vf_netdev->dev; dev; dev = dev->parent) {
> > > > >
> > > > > You are going to walk the whole device tree backwards? That's
> > crazy.
> > > > > And foolish. And racy and broken (what happens if the tree
> > changes
> > > > > while you do this?) Where is the lock being grabbed while this
> > happens?
> > > > > What about reference counts? Do you see other drivers ever doing
> > this
> > > > > (if you do, point them out and I'll go yell at them too...)
> > > >
> > > > Greg,
> > > >
> > > > We are registering for netdev events. Coming into this function, the
> > caller
> > > > guarantees that the list of netdevs does not change - we assert this
> > on entry:
> > > > ASSERT_RTNL(). We are only walking up the device tree for the
> > netdevs whose
> > > > state change is being notified to us - the device tree being walked
> > here is limited to
> > > > netdevs under question.
> > >
> > > But a netdev is a child of some type of "real" device, and you are now
> > > walking the tree of all devices up to the "root" parent device, which
> > > means you will hit PCI bridges, USB controllers, and all sorts of fun
> > > things if you are a child of those types of devices.
> > >
> > > And can't you tell if the netdev for this event, really is "your"
> > > netdev? Or are you getting called this for "all" netdevs? Sorry, I
> > > don't know this api, any pointers to it would be appreciated.
> > >
> > > > We have a reference to the device and we know the device is not
> > going away. Is it not
> > > > safe to dereference the parent pointer - after all the child has
> > taken a reference on
> > > > the parent as part of device_add() call.
> > >
> > > It might be, and might not be. There's a reason you don't see this
> > > pattern anywhere in the kernel because of this...
> > >
> > > > > > + if (!dev_is_vmbus(dev))
> > > > > > + continue;
> > > > >
> > > > > Ick.
> > > > >
> > > > > Why isn't your parent pointer a vmbus device all the time? How
> > could
> > > > > you get burried down in the device hierarchy when you are the
> > driver for
> > > > > a specific bus type in the first place? How could this function
> > ever be
> > > > > called for a device that is NOT of this type?
> > > >
> > > > We get notified when state changes on any of the netdev devices in
> > the system.
> > > > Not all netdevs in the system belong to vmbus. Consider for instance
> > the
> > > > emulated NIC that can be configured. This is an emulated PCI NIC. We
> > are only
> > > > interested in netdevs that correspond to the VF instance that we are
> > interested in.
> > >
> > > Can you "know" this is your netdev by some other way than having to
> > walk
> > > the device tree? Name? local device type? Something else? This
> > seems
> > > like an odd api in that everyone would have to do gyrations like this
> > in
> > > order to determine if the netdev is "theirs" or not...
> >
> > The scenario is SR-IOV on Hyper-V. In the case of VF device, the host
> > hands the
> > guest OS a PCI device for the virtual function device. The VF device is
> > placed
> > on a special synthetic PCI bus (ie not part of the other buses on the
> > system).
> > The VF device also has a synthetic network interface (netvsc) which
> > lives
> > on VMBUS. This code is about managing the interaction between the two.
> >
> > The association between VF and synthetic NIC is done in response to the
> > VF network device being registered. Initial version was based on MAC
> > address
> > which is the same. Later refinement used permanent MAC address to
> > avoid bugs if MAC address changed. This version is to use serial number
> > instead which is safer than MAC address.
> >
> > The code to walk up/down maybe not be needed to find serial number.
> > Perhaps a more direct single set of conditions is possible?
> >
> > Something like:
> >
> > In pci-hyperv.c
> >
> > u32 hv_pcifront_get_serial(struct pci_bus *bus, unsigned int devfn)
> > {
> > struct hv_pcibus_device *hbus
> > = container_of(bus->sysdata,
> > struct hv_pcibus_device, sysdata);
> > struct hf_pci_dev *hpdev;
> > u32 serial;
> >
> > hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn));
> > if (!hpdev)
> > return 0;
> >
> > serial = hpdev->devs.ser;
> > put_pcichild(hpdev, hv_pcidev_ref_by_slot);
> > return serial;
> > }
> >
> > In netvsc_drv.c
> >
> > static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> > {
> > struct device *dev = vf_netdev->dev.parent;
> > struct pci_dev *pdev;
> > u32 wslot;
> >
> > if (!dev || !dev_is_pci(dev))
> > return 0;
> >
> > pdev = container_of(dev, struct pci_device, dev);
> >
> > return hv_pcifront_get_serial(pdev->bus, pdev->devfn);
> > }
> >
> >
> >
> >
> >
> > P.S: it would be good to be able to get win_slot out through sysfs as
> > well for systemd/udev.
>
> Stephen,
>
> Thanks for suggestion. Actually, in my earlier implementation of this
> feature (VF serial based matching), I thought about export a function
> from vPCI driver, then calling it from netvsc. So I don't need to
> move structs between headers... But, it creates a dependency of netvsc
> on vPCI driver's symbol. So, even if on a VM without SRIOV, we have to
> load vPCI driver, which we don't want.
>
> Also, hv_vpci device is 3 parent layers above the vf_netdevice:
> Here is the VF drv hierarchy --
> Should we assume it's always 3 parents above vf_netdevice, or search for it?
>
> [ 368.185259] HZINFO:NETDEV_REGISTER:
> [ 368.185261] HZINFO: dev:ffff88007c10d518, bus: (null), busName:(null), drvName:(null)
> [ 368.185262] HZINFO: dev:ffff88007c10c0a0, bus:ffffffff81ce4b60, busName:pci, drvName:ixgbevf
> [ 368.185263] HZINFO: dev:ffff8800355c0000, bus: (null), busName:(null), drvName:(null)
> [ 368.185264] HZINFO: dev:ffff8800355c5428, bus:ffffffffa0008160, busName:vmbus, drvName:hv_pci
> [ 368.185264] HZINFO: dev:ffff88007c49e268, bus:ffffffff81ce9800, busName:acpi, drvName:vmbus
> [ 368.185265] HZINFO: dev:ffff88007c48ea68, bus:ffffffff81ce9800, busName:acpi, drvName:(null)
> [ 368.185266] HZINFO: dev:ffff88007c48aa68, bus:ffffffff81ce9800, busName:acpi, drvName:(null)
> [ 368.185266] HZINFO: dev:ffff88007c48a268, bus:ffffffff81ce9800, busName:acpi, drvName:(null)
> [ 368.185267] HZINFO: dev:ffff88007c489a68, bus:ffffffff81ce9800, busName:acpi, drvName:(null)
>
> Thanks,
> - Haiyang
Since this is a synthetic bus, the topology should not change unless host side
software changes. The vf_netdev device has to be PCI device, so that is going to
be certain. After that there maybe intermediate up to hv_pci. The code in hyperv-pci
already has similar stuff (ie for read_config).
[toc] | [prev] | [next] | [standalone]
| From | Stephen Hemminger <stephen@networkplumber.org> |
|---|---|
| Date | 2016-12-09 22:50 +0100 |
| Subject | Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sMBdf-8s8-5@gated-at.bofh.it> |
| In reply to | #1539641 |
On Fri, 9 Dec 2016 21:31:25 +0000
Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > -----Original Message-----
> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Friday, December 9, 2016 3:30 PM
> > To: Haiyang Zhang <haiyangz@microsoft.com>
> > Cc: Greg KH <gregkh@linuxfoundation.org>; KY Srinivasan
> > <kys@microsoft.com>; olaf@aepfle.de; linux-kernel@vger.kernel.org;
> > bjorn.helgaas@gmail.com; apw@canonical.com; devel@linuxdriverproject.org;
> > leann.ogasawara@canonical.com; jasowang@redhat.com
> > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > serial numbers
> >
> > On Fri, 9 Dec 2016 20:09:49 +0000
> > Haiyang Zhang <haiyangz@microsoft.com> wrote:
> >
> > > > -----Original Message-----
> > > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > > Sent: Friday, December 9, 2016 1:21 PM
> > > > To: Greg KH <gregkh@linuxfoundation.org>
> > > > Cc: KY Srinivasan <kys@microsoft.com>; olaf@aepfle.de; Haiyang Zhang
> > > > <haiyangz@microsoft.com>; linux-kernel@vger.kernel.org;
> > > > bjorn.helgaas@gmail.com; apw@canonical.com;
> > devel@linuxdriverproject.org;
> > > > leann.ogasawara@canonical.com; jasowang@redhat.com
> > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > > > serial numbers
> > > >
> > > > On Fri, 9 Dec 2016 08:31:22 +0100
> > > > Greg KH <gregkh@linuxfoundation.org> wrote:
> > > >
> > > > > On Fri, Dec 09, 2016 at 12:05:53AM +0000, KY Srinivasan wrote:
> > > > > >
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > > > > > Sent: Thursday, December 8, 2016 7:56 AM
> > > > > > > To: KY Srinivasan <kys@microsoft.com>
> > > > > > > Cc: linux-kernel@vger.kernel.org; devel@linuxdriverproject.org;
> > > > > > > olaf@aepfle.de; apw@canonical.com; vkuznets@redhat.com;
> > > > > > > jasowang@redhat.com; leann.ogasawara@canonical.com;
> > > > > > > bjorn.helgaas@gmail.com; Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching
> > based on
> > > > serial
> > > > > > > numbers
> > > > > > >
> > > > > > > On Thu, Dec 08, 2016 at 12:33:43AM -0800,
> > > > kys@exchange.microsoft.com
> > > > > > > wrote:
> > > > > > > > From: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > > >
> > > > > > > > We currently use MAC address to match VF and synthetic NICs.
> > > > Hyper-V
> > > > > > > > provides a serial number to both devices for this purpose.
> > This
> > > > patch
> > > > > > > > implements the matching based on VF serial numbers. This is
> > the
> > > > way
> > > > > > > > specified by the protocol and more reliable.
> > > > > > > >
> > > > > > > > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > > > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > > > > > > > ---
> > > > > > > > drivers/net/hyperv/netvsc_drv.c | 55
> > > > > > > ++++++++++++++++++++++++++++++++++++---
> > > > > > > > 1 files changed, 51 insertions(+), 4 deletions(-)
> > > > > > > >
> > > > > > > > diff --git a/drivers/net/hyperv/netvsc_drv.c
> > > > > > > b/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > index 9522763..c5778cf 100644
> > > > > > > > --- a/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > +++ b/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > @@ -1165,9 +1165,10 @@ static void netvsc_free_netdev(struct
> > > > > > > net_device *netdev)
> > > > > > > > free_netdev(netdev);
> > > > > > > > }
> > > > > > > >
> > > > > > > > -static struct net_device *get_netvsc_bymac(const u8 *mac)
> > > > > > > > +static struct net_device *get_netvsc_byvfser(u32 vfser)
> > > > > > > > {
> > > > > > > > struct net_device *dev;
> > > > > > > > + struct net_device_context *ndev_ctx;
> > > > > > > >
> > > > > > > > ASSERT_RTNL();
> > > > > > > >
> > > > > > > > @@ -1175,7 +1176,8 @@ static void netvsc_free_netdev(struct
> > > > net_device
> > > > > > > *netdev)
> > > > > > > > if (dev->netdev_ops != &device_ops)
> > > > > > > > continue; /* not a netvsc device */
> > > > > > > >
> > > > > > > > - if (ether_addr_equal(mac, dev->perm_addr))
> > > > > > > > + ndev_ctx = netdev_priv(dev);
> > > > > > > > + if (ndev_ctx->vf_serial == vfser)
> > > > > > > > return dev;
> > > > > > > > }
> > > > > > > >
> > > > > > > > @@ -1205,21 +1207,66 @@ static void
> > netvsc_free_netdev(struct
> > > > > > > net_device *netdev)
> > > > > > > > return NULL;
> > > > > > > > }
> > > > > > > >
> > > > > > > > +static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> > > > > > > > +{
> > > > > > > > + struct device *dev;
> > > > > > > > + struct hv_device *hdev;
> > > > > > > > + struct hv_pcibus_device *hbus = NULL;
> > > > > > > > + struct list_head *iter;
> > > > > > > > + struct hv_pci_dev *hpdev;
> > > > > > > > + unsigned long flags;
> > > > > > > > + u32 vfser = 0;
> > > > > > > > + u32 count = 0;
> > > > > > > > +
> > > > > > > > + for (dev = &vf_netdev->dev; dev; dev = dev->parent) {
> > > > > > >
> > > > > > > You are going to walk the whole device tree backwards? That's
> > > > crazy.
> > > > > > > And foolish. And racy and broken (what happens if the tree
> > > > changes
> > > > > > > while you do this?) Where is the lock being grabbed while
> > this
> > > > happens?
> > > > > > > What about reference counts? Do you see other drivers ever
> > doing
> > > > this
> > > > > > > (if you do, point them out and I'll go yell at them too...)
> > > > > >
> > > > > > Greg,
> > > > > >
> > > > > > We are registering for netdev events. Coming into this function,
> > the
> > > > caller
> > > > > > guarantees that the list of netdevs does not change - we assert
> > this
> > > > on entry:
> > > > > > ASSERT_RTNL(). We are only walking up the device tree for the
> > > > netdevs whose
> > > > > > state change is being notified to us - the device tree being
> > walked
> > > > here is limited to
> > > > > > netdevs under question.
> > > > >
> > > > > But a netdev is a child of some type of "real" device, and you are
> > now
> > > > > walking the tree of all devices up to the "root" parent device,
> > which
> > > > > means you will hit PCI bridges, USB controllers, and all sorts of
> > fun
> > > > > things if you are a child of those types of devices.
> > > > >
> > > > > And can't you tell if the netdev for this event, really is "your"
> > > > > netdev? Or are you getting called this for "all" netdevs? Sorry,
> > I
> > > > > don't know this api, any pointers to it would be appreciated.
> > > > >
> > > > > > We have a reference to the device and we know the device is not
> > > > going away. Is it not
> > > > > > safe to dereference the parent pointer - after all the child has
> > > > taken a reference on
> > > > > > the parent as part of device_add() call.
> > > > >
> > > > > It might be, and might not be. There's a reason you don't see
> > this
> > > > > pattern anywhere in the kernel because of this...
> > > > >
> > > > > > > > + if (!dev_is_vmbus(dev))
> > > > > > > > + continue;
> > > > > > >
> > > > > > > Ick.
> > > > > > >
> > > > > > > Why isn't your parent pointer a vmbus device all the time?
> > How
> > > > could
> > > > > > > you get burried down in the device hierarchy when you are the
> > > > driver for
> > > > > > > a specific bus type in the first place? How could this
> > function
> > > > ever be
> > > > > > > called for a device that is NOT of this type?
> > > > > >
> > > > > > We get notified when state changes on any of the netdev devices
> > in
> > > > the system.
> > > > > > Not all netdevs in the system belong to vmbus. Consider for
> > instance
> > > > the
> > > > > > emulated NIC that can be configured. This is an emulated PCI NIC.
> > We
> > > > are only
> > > > > > interested in netdevs that correspond to the VF instance that we
> > are
> > > > interested in.
> > > > >
> > > > > Can you "know" this is your netdev by some other way than having
> > to
> > > > walk
> > > > > the device tree? Name? local device type? Something else? This
> > > > seems
> > > > > like an odd api in that everyone would have to do gyrations like
> > this
> > > > in
> > > > > order to determine if the netdev is "theirs" or not...
> > > >
> > > > The scenario is SR-IOV on Hyper-V. In the case of VF device, the
> > host
> > > > hands the
> > > > guest OS a PCI device for the virtual function device. The VF device
> > is
> > > > placed
> > > > on a special synthetic PCI bus (ie not part of the other buses on
> > the
> > > > system).
> > > > The VF device also has a synthetic network interface (netvsc) which
> > > > lives
> > > > on VMBUS. This code is about managing the interaction between the
> > two.
> > > >
> > > > The association between VF and synthetic NIC is done in response to
> > the
> > > > VF network device being registered. Initial version was based on MAC
> > > > address
> > > > which is the same. Later refinement used permanent MAC address to
> > > > avoid bugs if MAC address changed. This version is to use serial
> > number
> > > > instead which is safer than MAC address.
> > > >
> > > > The code to walk up/down maybe not be needed to find serial number.
> > > > Perhaps a more direct single set of conditions is possible?
> > > >
> > > > Something like:
> > > >
> > > > In pci-hyperv.c
> > > >
> > > > u32 hv_pcifront_get_serial(struct pci_bus *bus, unsigned int devfn)
> > > > {
> > > > struct hv_pcibus_device *hbus
> > > > = container_of(bus->sysdata,
> > > > struct hv_pcibus_device, sysdata);
> > > > struct hf_pci_dev *hpdev;
> > > > u32 serial;
> > > >
> > > > hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn));
> > > > if (!hpdev)
> > > > return 0;
> > > >
> > > > serial = hpdev->devs.ser;
> > > > put_pcichild(hpdev, hv_pcidev_ref_by_slot);
> > > > return serial;
> > > > }
> > > >
> > > > In netvsc_drv.c
> > > >
> > > > static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> > > > {
> > > > struct device *dev = vf_netdev->dev.parent;
> > > > struct pci_dev *pdev;
> > > > u32 wslot;
> > > >
> > > > if (!dev || !dev_is_pci(dev))
> > > > return 0;
> > > >
> > > > pdev = container_of(dev, struct pci_device, dev);
> > > >
> > > > return hv_pcifront_get_serial(pdev->bus, pdev->devfn);
> > > > }
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > P.S: it would be good to be able to get win_slot out through sysfs
> > as
> > > > well for systemd/udev.
> > >
> > > Stephen,
> > >
> > > Thanks for suggestion. Actually, in my earlier implementation of this
> > > feature (VF serial based matching), I thought about export a function
> > > from vPCI driver, then calling it from netvsc. So I don't need to
> > > move structs between headers... But, it creates a dependency of netvsc
> > > on vPCI driver's symbol. So, even if on a VM without SRIOV, we have to
> > > load vPCI driver, which we don't want.
> > >
> > > Also, hv_vpci device is 3 parent layers above the vf_netdevice:
> > > Here is the VF drv hierarchy --
> > > Should we assume it's always 3 parents above vf_netdevice, or search
> > for it?
> > >
> > > [ 368.185259] HZINFO:NETDEV_REGISTER:
> > > [ 368.185261] HZINFO: dev:ffff88007c10d518, bus: (null),
> > busName:(null), drvName:(null)
> > > [ 368.185262] HZINFO: dev:ffff88007c10c0a0, bus:ffffffff81ce4b60,
> > busName:pci, drvName:ixgbevf
> > > [ 368.185263] HZINFO: dev:ffff8800355c0000, bus: (null),
> > busName:(null), drvName:(null)
> > > [ 368.185264] HZINFO: dev:ffff8800355c5428, bus:ffffffffa0008160,
> > busName:vmbus, drvName:hv_pci
> > > [ 368.185264] HZINFO: dev:ffff88007c49e268, bus:ffffffff81ce9800,
> > busName:acpi, drvName:vmbus
> > > [ 368.185265] HZINFO: dev:ffff88007c48ea68, bus:ffffffff81ce9800,
> > busName:acpi, drvName:(null)
> > > [ 368.185266] HZINFO: dev:ffff88007c48aa68, bus:ffffffff81ce9800,
> > busName:acpi, drvName:(null)
> > > [ 368.185266] HZINFO: dev:ffff88007c48a268, bus:ffffffff81ce9800,
> > busName:acpi, drvName:(null)
> > > [ 368.185267] HZINFO: dev:ffff88007c489a68, bus:ffffffff81ce9800,
> > busName:acpi, drvName:(null)
> > >
> > > Thanks,
> > > - Haiyang
> >
> > Since this is a synthetic bus, the topology should not change unless
> > host side
> > software changes. The vf_netdev device has to be PCI device, so that is
> > going to
> > be certain. After that there maybe intermediate up to hv_pci. The code
> > in hyperv-pci
> > already has similar stuff (ie for read_config).
>
> Other netdevice, like emulated NIC can also trigger this notification.
> They are not vPCI.
>
> Thanks,
> - Haiyang
Emulated NIC is already excluded in start of netvc notifier handler.
static int netvsc_netdev_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
/* Skip our own events */
if (event_dev->netdev_ops == &device_ops)
return NOTIFY_DONE;
[toc] | [prev] | [next] | [standalone]
| From | Haiyang Zhang <haiyangz@microsoft.com> |
|---|---|
| Date | 2016-12-09 23:10 +0100 |
| Subject | RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sMBwB-mk-17@gated-at.bofh.it> |
| In reply to | #1539694 |
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Friday, December 9, 2016 4:45 PM
> To: Haiyang Zhang <haiyangz@microsoft.com>
> Cc: Greg KH <gregkh@linuxfoundation.org>; KY Srinivasan
> <kys@microsoft.com>; olaf@aepfle.de; linux-kernel@vger.kernel.org;
> bjorn.helgaas@gmail.com; apw@canonical.com; devel@linuxdriverproject.org;
> leann.ogasawara@canonical.com; jasowang@redhat.com
> Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> serial numbers
>
> On Fri, 9 Dec 2016 21:31:25 +0000
> Haiyang Zhang <haiyangz@microsoft.com> wrote:
>
> > > -----Original Message-----
> > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > Sent: Friday, December 9, 2016 3:30 PM
> > > To: Haiyang Zhang <haiyangz@microsoft.com>
> > > Cc: Greg KH <gregkh@linuxfoundation.org>; KY Srinivasan
> > > <kys@microsoft.com>; olaf@aepfle.de; linux-kernel@vger.kernel.org;
> > > bjorn.helgaas@gmail.com; apw@canonical.com;
> devel@linuxdriverproject.org;
> > > leann.ogasawara@canonical.com; jasowang@redhat.com
> > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > > serial numbers
> > >
> > > On Fri, 9 Dec 2016 20:09:49 +0000
> > > Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > >
> > > > > -----Original Message-----
> > > > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > > > Sent: Friday, December 9, 2016 1:21 PM
> > > > > To: Greg KH <gregkh@linuxfoundation.org>
> > > > > Cc: KY Srinivasan <kys@microsoft.com>; olaf@aepfle.de; Haiyang
> Zhang
> > > > > <haiyangz@microsoft.com>; linux-kernel@vger.kernel.org;
> > > > > bjorn.helgaas@gmail.com; apw@canonical.com;
> > > devel@linuxdriverproject.org;
> > > > > leann.ogasawara@canonical.com; jasowang@redhat.com
> > > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based
> on
> > > > > serial numbers
> > > > >
> > > > > On Fri, 9 Dec 2016 08:31:22 +0100
> > > > > Greg KH <gregkh@linuxfoundation.org> wrote:
> > > > >
> > > > > > On Fri, Dec 09, 2016 at 12:05:53AM +0000, KY Srinivasan wrote:
> > > > > > >
> > > > > > >
> > > > > > > > -----Original Message-----
> > > > > > > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > > > > > > Sent: Thursday, December 8, 2016 7:56 AM
> > > > > > > > To: KY Srinivasan <kys@microsoft.com>
> > > > > > > > Cc: linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org;
> > > > > > > > olaf@aepfle.de; apw@canonical.com; vkuznets@redhat.com;
> > > > > > > > jasowang@redhat.com; leann.ogasawara@canonical.com;
> > > > > > > > bjorn.helgaas@gmail.com; Haiyang Zhang
> <haiyangz@microsoft.com>
> > > > > > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching
> > > based on
> > > > > serial
> > > > > > > > numbers
> > > > > > > >
> > > > > > > > On Thu, Dec 08, 2016 at 12:33:43AM -0800,
> > > > > kys@exchange.microsoft.com
> > > > > > > > wrote:
> > > > > > > > > From: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > > > >
> > > > > > > > > We currently use MAC address to match VF and synthetic
> NICs.
> > > > > Hyper-V
> > > > > > > > > provides a serial number to both devices for this
> purpose.
> > > This
> > > > > patch
> > > > > > > > > implements the matching based on VF serial numbers. This
> is
> > > the
> > > > > way
> > > > > > > > > specified by the protocol and more reliable.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > > > > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > > > > > > > > ---
> > > > > > > > > drivers/net/hyperv/netvsc_drv.c | 55
> > > > > > > > ++++++++++++++++++++++++++++++++++++---
> > > > > > > > > 1 files changed, 51 insertions(+), 4 deletions(-)
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > b/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > > index 9522763..c5778cf 100644
> > > > > > > > > --- a/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > > +++ b/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > > @@ -1165,9 +1165,10 @@ static void
> netvsc_free_netdev(struct
> > > > > > > > net_device *netdev)
> > > > > > > > > free_netdev(netdev);
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > -static struct net_device *get_netvsc_bymac(const u8
> *mac)
> > > > > > > > > +static struct net_device *get_netvsc_byvfser(u32 vfser)
> > > > > > > > > {
> > > > > > > > > struct net_device *dev;
> > > > > > > > > + struct net_device_context *ndev_ctx;
> > > > > > > > >
> > > > > > > > > ASSERT_RTNL();
> > > > > > > > >
> > > > > > > > > @@ -1175,7 +1176,8 @@ static void
> netvsc_free_netdev(struct
> > > > > net_device
> > > > > > > > *netdev)
> > > > > > > > > if (dev->netdev_ops != &device_ops)
> > > > > > > > > continue; /* not a netvsc device */
> > > > > > > > >
> > > > > > > > > - if (ether_addr_equal(mac, dev->perm_addr))
> > > > > > > > > + ndev_ctx = netdev_priv(dev);
> > > > > > > > > + if (ndev_ctx->vf_serial == vfser)
> > > > > > > > > return dev;
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > @@ -1205,21 +1207,66 @@ static void
> > > netvsc_free_netdev(struct
> > > > > > > > net_device *netdev)
> > > > > > > > > return NULL;
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > +static u32 netvsc_get_vfser(struct net_device
> *vf_netdev)
> > > > > > > > > +{
> > > > > > > > > + struct device *dev;
> > > > > > > > > + struct hv_device *hdev;
> > > > > > > > > + struct hv_pcibus_device *hbus = NULL;
> > > > > > > > > + struct list_head *iter;
> > > > > > > > > + struct hv_pci_dev *hpdev;
> > > > > > > > > + unsigned long flags;
> > > > > > > > > + u32 vfser = 0;
> > > > > > > > > + u32 count = 0;
> > > > > > > > > +
> > > > > > > > > + for (dev = &vf_netdev->dev; dev; dev = dev->parent)
> {
> > > > > > > >
> > > > > > > > You are going to walk the whole device tree backwards?
> That's
> > > > > crazy.
> > > > > > > > And foolish. And racy and broken (what happens if the
> tree
> > > > > changes
> > > > > > > > while you do this?) Where is the lock being grabbed while
> > > this
> > > > > happens?
> > > > > > > > What about reference counts? Do you see other drivers
> ever
> > > doing
> > > > > this
> > > > > > > > (if you do, point them out and I'll go yell at them too...)
> > > > > > >
> > > > > > > Greg,
> > > > > > >
> > > > > > > We are registering for netdev events. Coming into this
> function,
> > > the
> > > > > caller
> > > > > > > guarantees that the list of netdevs does not change - we
> assert
> > > this
> > > > > on entry:
> > > > > > > ASSERT_RTNL(). We are only walking up the device tree for
> the
> > > > > netdevs whose
> > > > > > > state change is being notified to us - the device tree being
> > > walked
> > > > > here is limited to
> > > > > > > netdevs under question.
> > > > > >
> > > > > > But a netdev is a child of some type of "real" device, and you
> are
> > > now
> > > > > > walking the tree of all devices up to the "root" parent device,
> > > which
> > > > > > means you will hit PCI bridges, USB controllers, and all sorts
> of
> > > fun
> > > > > > things if you are a child of those types of devices.
> > > > > >
> > > > > > And can't you tell if the netdev for this event, really is
> "your"
> > > > > > netdev? Or are you getting called this for "all" netdevs?
> Sorry,
> > > I
> > > > > > don't know this api, any pointers to it would be appreciated.
> > > > > >
> > > > > > > We have a reference to the device and we know the device is
> not
> > > > > going away. Is it not
> > > > > > > safe to dereference the parent pointer - after all the child
> has
> > > > > taken a reference on
> > > > > > > the parent as part of device_add() call.
> > > > > >
> > > > > > It might be, and might not be. There's a reason you don't see
> > > this
> > > > > > pattern anywhere in the kernel because of this...
> > > > > >
> > > > > > > > > + if (!dev_is_vmbus(dev))
> > > > > > > > > + continue;
> > > > > > > >
> > > > > > > > Ick.
> > > > > > > >
> > > > > > > > Why isn't your parent pointer a vmbus device all the time?
> > > How
> > > > > could
> > > > > > > > you get burried down in the device hierarchy when you are
> the
> > > > > driver for
> > > > > > > > a specific bus type in the first place? How could this
> > > function
> > > > > ever be
> > > > > > > > called for a device that is NOT of this type?
> > > > > > >
> > > > > > > We get notified when state changes on any of the netdev
> devices
> > > in
> > > > > the system.
> > > > > > > Not all netdevs in the system belong to vmbus. Consider for
> > > instance
> > > > > the
> > > > > > > emulated NIC that can be configured. This is an emulated PCI
> NIC.
> > > We
> > > > > are only
> > > > > > > interested in netdevs that correspond to the VF instance
> that we
> > > are
> > > > > interested in.
> > > > > >
> > > > > > Can you "know" this is your netdev by some other way than
> having
> > > to
> > > > > walk
> > > > > > the device tree? Name? local device type? Something else?
> This
> > > > > seems
> > > > > > like an odd api in that everyone would have to do gyrations
> like
> > > this
> > > > > in
> > > > > > order to determine if the netdev is "theirs" or not...
> > > > >
> > > > > The scenario is SR-IOV on Hyper-V. In the case of VF device, the
> > > host
> > > > > hands the
> > > > > guest OS a PCI device for the virtual function device. The VF
> device
> > > is
> > > > > placed
> > > > > on a special synthetic PCI bus (ie not part of the other buses
> on
> > > the
> > > > > system).
> > > > > The VF device also has a synthetic network interface (netvsc)
> which
> > > > > lives
> > > > > on VMBUS. This code is about managing the interaction between
> the
> > > two.
> > > > >
> > > > > The association between VF and synthetic NIC is done in response
> to
> > > the
> > > > > VF network device being registered. Initial version was based on
> MAC
> > > > > address
> > > > > which is the same. Later refinement used permanent MAC address
> to
> > > > > avoid bugs if MAC address changed. This version is to use
> serial
> > > number
> > > > > instead which is safer than MAC address.
> > > > >
> > > > > The code to walk up/down maybe not be needed to find serial
> number.
> > > > > Perhaps a more direct single set of conditions is possible?
> > > > >
> > > > > Something like:
> > > > >
> > > > > In pci-hyperv.c
> > > > >
> > > > > u32 hv_pcifront_get_serial(struct pci_bus *bus, unsigned int
> devfn)
> > > > > {
> > > > > struct hv_pcibus_device *hbus
> > > > > = container_of(bus->sysdata,
> > > > > struct hv_pcibus_device, sysdata);
> > > > > struct hf_pci_dev *hpdev;
> > > > > u32 serial;
> > > > >
> > > > > hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn));
> > > > > if (!hpdev)
> > > > > return 0;
> > > > >
> > > > > serial = hpdev->devs.ser;
> > > > > put_pcichild(hpdev, hv_pcidev_ref_by_slot);
> > > > > return serial;
> > > > > }
> > > > >
> > > > > In netvsc_drv.c
> > > > >
> > > > > static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> > > > > {
> > > > > struct device *dev = vf_netdev->dev.parent;
> > > > > struct pci_dev *pdev;
> > > > > u32 wslot;
> > > > >
> > > > > if (!dev || !dev_is_pci(dev))
> > > > > return 0;
> > > > >
> > > > > pdev = container_of(dev, struct pci_device, dev);
> > > > >
> > > > > return hv_pcifront_get_serial(pdev->bus, pdev->devfn);
> > > > > }
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > P.S: it would be good to be able to get win_slot out through
> sysfs
> > > as
> > > > > well for systemd/udev.
> > > >
> > > > Stephen,
> > > >
> > > > Thanks for suggestion. Actually, in my earlier implementation of
> this
> > > > feature (VF serial based matching), I thought about export a
> function
> > > > from vPCI driver, then calling it from netvsc. So I don't need to
> > > > move structs between headers... But, it creates a dependency of
> netvsc
> > > > on vPCI driver's symbol. So, even if on a VM without SRIOV, we
> have to
> > > > load vPCI driver, which we don't want.
> > > >
> > > > Also, hv_vpci device is 3 parent layers above the vf_netdevice:
> > > > Here is the VF drv hierarchy --
> > > > Should we assume it's always 3 parents above vf_netdevice, or
> search
> > > for it?
> > > >
> > > > [ 368.185259] HZINFO:NETDEV_REGISTER:
> > > > [ 368.185261] HZINFO: dev:ffff88007c10d518, bus: (null),
> > > busName:(null), drvName:(null)
> > > > [ 368.185262] HZINFO: dev:ffff88007c10c0a0, bus:ffffffff81ce4b60,
> > > busName:pci, drvName:ixgbevf
> > > > [ 368.185263] HZINFO: dev:ffff8800355c0000, bus: (null),
> > > busName:(null), drvName:(null)
> > > > [ 368.185264] HZINFO: dev:ffff8800355c5428, bus:ffffffffa0008160,
> > > busName:vmbus, drvName:hv_pci
> > > > [ 368.185264] HZINFO: dev:ffff88007c49e268, bus:ffffffff81ce9800,
> > > busName:acpi, drvName:vmbus
> > > > [ 368.185265] HZINFO: dev:ffff88007c48ea68, bus:ffffffff81ce9800,
> > > busName:acpi, drvName:(null)
> > > > [ 368.185266] HZINFO: dev:ffff88007c48aa68, bus:ffffffff81ce9800,
> > > busName:acpi, drvName:(null)
> > > > [ 368.185266] HZINFO: dev:ffff88007c48a268, bus:ffffffff81ce9800,
> > > busName:acpi, drvName:(null)
> > > > [ 368.185267] HZINFO: dev:ffff88007c489a68, bus:ffffffff81ce9800,
> > > busName:acpi, drvName:(null)
> > > >
> > > > Thanks,
> > > > - Haiyang
> > >
> > > Since this is a synthetic bus, the topology should not change unless
> > > host side
> > > software changes. The vf_netdev device has to be PCI device, so that
> is
> > > going to
> > > be certain. After that there maybe intermediate up to hv_pci. The
> code
> > > in hyperv-pci
> > > already has similar stuff (ie for read_config).
> >
> > Other netdevice, like emulated NIC can also trigger this notification.
> > They are not vPCI.
> >
> > Thanks,
> > - Haiyang
>
> Emulated NIC is already excluded in start of netvc notifier handler.
>
> static int netvsc_netdev_event(struct notifier_block *this,
> unsigned long event, void *ptr)
> {
> struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
>
> /* Skip our own events */
> if (event_dev->netdev_ops == &device_ops)
> return NOTIFY_DONE;
>
Emulated device is not based on netvsc. It's the native Linux (dec100M?)
Driver. So this line doesn't exclude it. And how about other NIC type
may be added in the future?
Thanks,
- Haiyang
[toc] | [prev] | [next] | [standalone]
| From | Stephen Hemminger <stephen@networkplumber.org> |
|---|---|
| Date | 2016-12-09 23:10 +0100 |
| Subject | Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sMBwC-mk-21@gated-at.bofh.it> |
| In reply to | #1539708 |
On Fri, 9 Dec 2016 21:53:49 +0000
Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > -----Original Message-----
> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Friday, December 9, 2016 4:45 PM
> > To: Haiyang Zhang <haiyangz@microsoft.com>
> > Cc: Greg KH <gregkh@linuxfoundation.org>; KY Srinivasan
> > <kys@microsoft.com>; olaf@aepfle.de; linux-kernel@vger.kernel.org;
> > bjorn.helgaas@gmail.com; apw@canonical.com; devel@linuxdriverproject.org;
> > leann.ogasawara@canonical.com; jasowang@redhat.com
> > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > serial numbers
> >
> > On Fri, 9 Dec 2016 21:31:25 +0000
> > Haiyang Zhang <haiyangz@microsoft.com> wrote:
> >
> > > > -----Original Message-----
> > > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > > Sent: Friday, December 9, 2016 3:30 PM
> > > > To: Haiyang Zhang <haiyangz@microsoft.com>
> > > > Cc: Greg KH <gregkh@linuxfoundation.org>; KY Srinivasan
> > > > <kys@microsoft.com>; olaf@aepfle.de; linux-kernel@vger.kernel.org;
> > > > bjorn.helgaas@gmail.com; apw@canonical.com;
> > devel@linuxdriverproject.org;
> > > > leann.ogasawara@canonical.com; jasowang@redhat.com
> > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > > > serial numbers
> > > >
> > > > On Fri, 9 Dec 2016 20:09:49 +0000
> > > > Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > > >
> > > > > > -----Original Message-----
> > > > > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > > > > Sent: Friday, December 9, 2016 1:21 PM
> > > > > > To: Greg KH <gregkh@linuxfoundation.org>
> > > > > > Cc: KY Srinivasan <kys@microsoft.com>; olaf@aepfle.de; Haiyang
> > Zhang
> > > > > > <haiyangz@microsoft.com>; linux-kernel@vger.kernel.org;
> > > > > > bjorn.helgaas@gmail.com; apw@canonical.com;
> > > > devel@linuxdriverproject.org;
> > > > > > leann.ogasawara@canonical.com; jasowang@redhat.com
> > > > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based
> > on
> > > > > > serial numbers
> > > > > >
> > > > > > On Fri, 9 Dec 2016 08:31:22 +0100
> > > > > > Greg KH <gregkh@linuxfoundation.org> wrote:
> > > > > >
> > > > > > > On Fri, Dec 09, 2016 at 12:05:53AM +0000, KY Srinivasan wrote:
> > > > > > > >
> > > > > > > >
> > > > > > > > > -----Original Message-----
> > > > > > > > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > > > > > > > Sent: Thursday, December 8, 2016 7:56 AM
> > > > > > > > > To: KY Srinivasan <kys@microsoft.com>
> > > > > > > > > Cc: linux-kernel@vger.kernel.org;
> > devel@linuxdriverproject.org;
> > > > > > > > > olaf@aepfle.de; apw@canonical.com; vkuznets@redhat.com;
> > > > > > > > > jasowang@redhat.com; leann.ogasawara@canonical.com;
> > > > > > > > > bjorn.helgaas@gmail.com; Haiyang Zhang
> > <haiyangz@microsoft.com>
> > > > > > > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching
> > > > based on
> > > > > > serial
> > > > > > > > > numbers
> > > > > > > > >
> > > > > > > > > On Thu, Dec 08, 2016 at 12:33:43AM -0800,
> > > > > > kys@exchange.microsoft.com
> > > > > > > > > wrote:
> > > > > > > > > > From: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > > > > >
> > > > > > > > > > We currently use MAC address to match VF and synthetic
> > NICs.
> > > > > > Hyper-V
> > > > > > > > > > provides a serial number to both devices for this
> > purpose.
> > > > This
> > > > > > patch
> > > > > > > > > > implements the matching based on VF serial numbers. This
> > is
> > > > the
> > > > > > way
> > > > > > > > > > specified by the protocol and more reliable.
> > > > > > > > > >
> > > > > > > > > > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > > > > > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > > > > > > > > > ---
> > > > > > > > > > drivers/net/hyperv/netvsc_drv.c | 55
> > > > > > > > > ++++++++++++++++++++++++++++++++++++---
> > > > > > > > > > 1 files changed, 51 insertions(+), 4 deletions(-)
> > > > > > > > > >
> > > > > > > > > > diff --git a/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > > b/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > > > index 9522763..c5778cf 100644
> > > > > > > > > > --- a/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > > > +++ b/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > > > @@ -1165,9 +1165,10 @@ static void
> > netvsc_free_netdev(struct
> > > > > > > > > net_device *netdev)
> > > > > > > > > > free_netdev(netdev);
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > -static struct net_device *get_netvsc_bymac(const u8
> > *mac)
> > > > > > > > > > +static struct net_device *get_netvsc_byvfser(u32 vfser)
> > > > > > > > > > {
> > > > > > > > > > struct net_device *dev;
> > > > > > > > > > + struct net_device_context *ndev_ctx;
> > > > > > > > > >
> > > > > > > > > > ASSERT_RTNL();
> > > > > > > > > >
> > > > > > > > > > @@ -1175,7 +1176,8 @@ static void
> > netvsc_free_netdev(struct
> > > > > > net_device
> > > > > > > > > *netdev)
> > > > > > > > > > if (dev->netdev_ops != &device_ops)
> > > > > > > > > > continue; /* not a netvsc device */
> > > > > > > > > >
> > > > > > > > > > - if (ether_addr_equal(mac, dev->perm_addr))
> > > > > > > > > > + ndev_ctx = netdev_priv(dev);
> > > > > > > > > > + if (ndev_ctx->vf_serial == vfser)
> > > > > > > > > > return dev;
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > @@ -1205,21 +1207,66 @@ static void
> > > > netvsc_free_netdev(struct
> > > > > > > > > net_device *netdev)
> > > > > > > > > > return NULL;
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > +static u32 netvsc_get_vfser(struct net_device
> > *vf_netdev)
> > > > > > > > > > +{
> > > > > > > > > > + struct device *dev;
> > > > > > > > > > + struct hv_device *hdev;
> > > > > > > > > > + struct hv_pcibus_device *hbus = NULL;
> > > > > > > > > > + struct list_head *iter;
> > > > > > > > > > + struct hv_pci_dev *hpdev;
> > > > > > > > > > + unsigned long flags;
> > > > > > > > > > + u32 vfser = 0;
> > > > > > > > > > + u32 count = 0;
> > > > > > > > > > +
> > > > > > > > > > + for (dev = &vf_netdev->dev; dev; dev = dev->parent)
> > {
> > > > > > > > >
> > > > > > > > > You are going to walk the whole device tree backwards?
> > That's
> > > > > > crazy.
> > > > > > > > > And foolish. And racy and broken (what happens if the
> > tree
> > > > > > changes
> > > > > > > > > while you do this?) Where is the lock being grabbed while
> > > > this
> > > > > > happens?
> > > > > > > > > What about reference counts? Do you see other drivers
> > ever
> > > > doing
> > > > > > this
> > > > > > > > > (if you do, point them out and I'll go yell at them too...)
> > > > > > > >
> > > > > > > > Greg,
> > > > > > > >
> > > > > > > > We are registering for netdev events. Coming into this
> > function,
> > > > the
> > > > > > caller
> > > > > > > > guarantees that the list of netdevs does not change - we
> > assert
> > > > this
> > > > > > on entry:
> > > > > > > > ASSERT_RTNL(). We are only walking up the device tree for
> > the
> > > > > > netdevs whose
> > > > > > > > state change is being notified to us - the device tree being
> > > > walked
> > > > > > here is limited to
> > > > > > > > netdevs under question.
> > > > > > >
> > > > > > > But a netdev is a child of some type of "real" device, and you
> > are
> > > > now
> > > > > > > walking the tree of all devices up to the "root" parent device,
> > > > which
> > > > > > > means you will hit PCI bridges, USB controllers, and all sorts
> > of
> > > > fun
> > > > > > > things if you are a child of those types of devices.
> > > > > > >
> > > > > > > And can't you tell if the netdev for this event, really is
> > "your"
> > > > > > > netdev? Or are you getting called this for "all" netdevs?
> > Sorry,
> > > > I
> > > > > > > don't know this api, any pointers to it would be appreciated.
> > > > > > >
> > > > > > > > We have a reference to the device and we know the device is
> > not
> > > > > > going away. Is it not
> > > > > > > > safe to dereference the parent pointer - after all the child
> > has
> > > > > > taken a reference on
> > > > > > > > the parent as part of device_add() call.
> > > > > > >
> > > > > > > It might be, and might not be. There's a reason you don't see
> > > > this
> > > > > > > pattern anywhere in the kernel because of this...
> > > > > > >
> > > > > > > > > > + if (!dev_is_vmbus(dev))
> > > > > > > > > > + continue;
> > > > > > > > >
> > > > > > > > > Ick.
> > > > > > > > >
> > > > > > > > > Why isn't your parent pointer a vmbus device all the time?
> > > > How
> > > > > > could
> > > > > > > > > you get burried down in the device hierarchy when you are
> > the
> > > > > > driver for
> > > > > > > > > a specific bus type in the first place? How could this
> > > > function
> > > > > > ever be
> > > > > > > > > called for a device that is NOT of this type?
> > > > > > > >
> > > > > > > > We get notified when state changes on any of the netdev
> > devices
> > > > in
> > > > > > the system.
> > > > > > > > Not all netdevs in the system belong to vmbus. Consider for
> > > > instance
> > > > > > the
> > > > > > > > emulated NIC that can be configured. This is an emulated PCI
> > NIC.
> > > > We
> > > > > > are only
> > > > > > > > interested in netdevs that correspond to the VF instance
> > that we
> > > > are
> > > > > > interested in.
> > > > > > >
> > > > > > > Can you "know" this is your netdev by some other way than
> > having
> > > > to
> > > > > > walk
> > > > > > > the device tree? Name? local device type? Something else?
> > This
> > > > > > seems
> > > > > > > like an odd api in that everyone would have to do gyrations
> > like
> > > > this
> > > > > > in
> > > > > > > order to determine if the netdev is "theirs" or not...
> > > > > >
> > > > > > The scenario is SR-IOV on Hyper-V. In the case of VF device, the
> > > > host
> > > > > > hands the
> > > > > > guest OS a PCI device for the virtual function device. The VF
> > device
> > > > is
> > > > > > placed
> > > > > > on a special synthetic PCI bus (ie not part of the other buses
> > on
> > > > the
> > > > > > system).
> > > > > > The VF device also has a synthetic network interface (netvsc)
> > which
> > > > > > lives
> > > > > > on VMBUS. This code is about managing the interaction between
> > the
> > > > two.
> > > > > >
> > > > > > The association between VF and synthetic NIC is done in response
> > to
> > > > the
> > > > > > VF network device being registered. Initial version was based on
> > MAC
> > > > > > address
> > > > > > which is the same. Later refinement used permanent MAC address
> > to
> > > > > > avoid bugs if MAC address changed. This version is to use
> > serial
> > > > number
> > > > > > instead which is safer than MAC address.
> > > > > >
> > > > > > The code to walk up/down maybe not be needed to find serial
> > number.
> > > > > > Perhaps a more direct single set of conditions is possible?
> > > > > >
> > > > > > Something like:
> > > > > >
> > > > > > In pci-hyperv.c
> > > > > >
> > > > > > u32 hv_pcifront_get_serial(struct pci_bus *bus, unsigned int
> > devfn)
> > > > > > {
> > > > > > struct hv_pcibus_device *hbus
> > > > > > = container_of(bus->sysdata,
> > > > > > struct hv_pcibus_device, sysdata);
> > > > > > struct hf_pci_dev *hpdev;
> > > > > > u32 serial;
> > > > > >
> > > > > > hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn));
> > > > > > if (!hpdev)
> > > > > > return 0;
> > > > > >
> > > > > > serial = hpdev->devs.ser;
> > > > > > put_pcichild(hpdev, hv_pcidev_ref_by_slot);
> > > > > > return serial;
> > > > > > }
> > > > > >
> > > > > > In netvsc_drv.c
> > > > > >
> > > > > > static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> > > > > > {
> > > > > > struct device *dev = vf_netdev->dev.parent;
> > > > > > struct pci_dev *pdev;
> > > > > > u32 wslot;
> > > > > >
> > > > > > if (!dev || !dev_is_pci(dev))
> > > > > > return 0;
> > > > > >
> > > > > > pdev = container_of(dev, struct pci_device, dev);
> > > > > >
> > > > > > return hv_pcifront_get_serial(pdev->bus, pdev->devfn);
> > > > > > }
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > P.S: it would be good to be able to get win_slot out through
> > sysfs
> > > > as
> > > > > > well for systemd/udev.
> > > > >
> > > > > Stephen,
> > > > >
> > > > > Thanks for suggestion. Actually, in my earlier implementation of
> > this
> > > > > feature (VF serial based matching), I thought about export a
> > function
> > > > > from vPCI driver, then calling it from netvsc. So I don't need to
> > > > > move structs between headers... But, it creates a dependency of
> > netvsc
> > > > > on vPCI driver's symbol. So, even if on a VM without SRIOV, we
> > have to
> > > > > load vPCI driver, which we don't want.
> > > > >
> > > > > Also, hv_vpci device is 3 parent layers above the vf_netdevice:
> > > > > Here is the VF drv hierarchy --
> > > > > Should we assume it's always 3 parents above vf_netdevice, or
> > search
> > > > for it?
> > > > >
> > > > > [ 368.185259] HZINFO:NETDEV_REGISTER:
> > > > > [ 368.185261] HZINFO: dev:ffff88007c10d518, bus: (null),
> > > > busName:(null), drvName:(null)
> > > > > [ 368.185262] HZINFO: dev:ffff88007c10c0a0, bus:ffffffff81ce4b60,
> > > > busName:pci, drvName:ixgbevf
> > > > > [ 368.185263] HZINFO: dev:ffff8800355c0000, bus: (null),
> > > > busName:(null), drvName:(null)
> > > > > [ 368.185264] HZINFO: dev:ffff8800355c5428, bus:ffffffffa0008160,
> > > > busName:vmbus, drvName:hv_pci
> > > > > [ 368.185264] HZINFO: dev:ffff88007c49e268, bus:ffffffff81ce9800,
> > > > busName:acpi, drvName:vmbus
> > > > > [ 368.185265] HZINFO: dev:ffff88007c48ea68, bus:ffffffff81ce9800,
> > > > busName:acpi, drvName:(null)
> > > > > [ 368.185266] HZINFO: dev:ffff88007c48aa68, bus:ffffffff81ce9800,
> > > > busName:acpi, drvName:(null)
> > > > > [ 368.185266] HZINFO: dev:ffff88007c48a268, bus:ffffffff81ce9800,
> > > > busName:acpi, drvName:(null)
> > > > > [ 368.185267] HZINFO: dev:ffff88007c489a68, bus:ffffffff81ce9800,
> > > > busName:acpi, drvName:(null)
> > > > >
> > > > > Thanks,
> > > > > - Haiyang
> > > >
> > > > Since this is a synthetic bus, the topology should not change unless
> > > > host side
> > > > software changes. The vf_netdev device has to be PCI device, so that
> > is
> > > > going to
> > > > be certain. After that there maybe intermediate up to hv_pci. The
> > code
> > > > in hyperv-pci
> > > > already has similar stuff (ie for read_config).
> > >
> > > Other netdevice, like emulated NIC can also trigger this notification.
> > > They are not vPCI.
> > >
> > > Thanks,
> > > - Haiyang
> >
> > Emulated NIC is already excluded in start of netvc notifier handler.
> >
> > static int netvsc_netdev_event(struct notifier_block *this,
> > unsigned long event, void *ptr)
> > {
> > struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
> >
> > /* Skip our own events */
> > if (event_dev->netdev_ops == &device_ops)
> > return NOTIFY_DONE;
> >
>
> Emulated device is not based on netvsc. It's the native Linux (dec100M?)
> Driver. So this line doesn't exclude it. And how about other NIC type
> may be added in the future?
Sorry, forgot about that haven't used emulated device in years.
The emulated device should appear to be on a PCI bus, but the serial
would not match??
[toc] | [prev] | [next] | [standalone]
| From | Haiyang Zhang <haiyangz@microsoft.com> |
|---|---|
| Date | 2016-12-10 00:00 +0100 |
| Subject | RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sMCiZ-Cg-19@gated-at.bofh.it> |
| In reply to | #1539709 |
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Friday, December 9, 2016 5:05 PM
> To: Haiyang Zhang <haiyangz@microsoft.com>
> Cc: Greg KH <gregkh@linuxfoundation.org>; KY Srinivasan
> <kys@microsoft.com>; olaf@aepfle.de; linux-kernel@vger.kernel.org;
> bjorn.helgaas@gmail.com; apw@canonical.com; devel@linuxdriverproject.org;
> leann.ogasawara@canonical.com; jasowang@redhat.com
> Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> serial numbers
>
> On Fri, 9 Dec 2016 21:53:49 +0000
> Haiyang Zhang <haiyangz@microsoft.com> wrote:
>
> > > -----Original Message-----
> > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > Sent: Friday, December 9, 2016 4:45 PM
> > > To: Haiyang Zhang <haiyangz@microsoft.com>
> > > Cc: Greg KH <gregkh@linuxfoundation.org>; KY Srinivasan
> > > <kys@microsoft.com>; olaf@aepfle.de; linux-kernel@vger.kernel.org;
> > > bjorn.helgaas@gmail.com; apw@canonical.com;
> devel@linuxdriverproject.org;
> > > leann.ogasawara@canonical.com; jasowang@redhat.com
> > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > > serial numbers
> > >
> > > On Fri, 9 Dec 2016 21:31:25 +0000
> > > Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > >
> > > > > -----Original Message-----
> > > > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > > > Sent: Friday, December 9, 2016 3:30 PM
> > > > > To: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > Cc: Greg KH <gregkh@linuxfoundation.org>; KY Srinivasan
> > > > > <kys@microsoft.com>; olaf@aepfle.de; linux-
> kernel@vger.kernel.org;
> > > > > bjorn.helgaas@gmail.com; apw@canonical.com;
> > > devel@linuxdriverproject.org;
> > > > > leann.ogasawara@canonical.com; jasowang@redhat.com
> > > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based
> on
> > > > > serial numbers
> > > > >
> > > > > On Fri, 9 Dec 2016 20:09:49 +0000
> > > > > Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > > > > > Sent: Friday, December 9, 2016 1:21 PM
> > > > > > > To: Greg KH <gregkh@linuxfoundation.org>
> > > > > > > Cc: KY Srinivasan <kys@microsoft.com>; olaf@aepfle.de;
> Haiyang
> > > Zhang
> > > > > > > <haiyangz@microsoft.com>; linux-kernel@vger.kernel.org;
> > > > > > > bjorn.helgaas@gmail.com; apw@canonical.com;
> > > > > devel@linuxdriverproject.org;
> > > > > > > leann.ogasawara@canonical.com; jasowang@redhat.com
> > > > > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching
> based
> > > on
> > > > > > > serial numbers
> > > > > > >
> > > > > > > On Fri, 9 Dec 2016 08:31:22 +0100
> > > > > > > Greg KH <gregkh@linuxfoundation.org> wrote:
> > > > > > >
> > > > > > > > On Fri, Dec 09, 2016 at 12:05:53AM +0000, KY Srinivasan
> wrote:
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > > -----Original Message-----
> > > > > > > > > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > > > > > > > > Sent: Thursday, December 8, 2016 7:56 AM
> > > > > > > > > > To: KY Srinivasan <kys@microsoft.com>
> > > > > > > > > > Cc: linux-kernel@vger.kernel.org;
> > > devel@linuxdriverproject.org;
> > > > > > > > > > olaf@aepfle.de; apw@canonical.com; vkuznets@redhat.com;
> > > > > > > > > > jasowang@redhat.com; leann.ogasawara@canonical.com;
> > > > > > > > > > bjorn.helgaas@gmail.com; Haiyang Zhang
> > > <haiyangz@microsoft.com>
> > > > > > > > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF
> matching
> > > > > based on
> > > > > > > serial
> > > > > > > > > > numbers
> > > > > > > > > >
> > > > > > > > > > On Thu, Dec 08, 2016 at 12:33:43AM -0800,
> > > > > > > kys@exchange.microsoft.com
> > > > > > > > > > wrote:
> > > > > > > > > > > From: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > > > > > >
> > > > > > > > > > > We currently use MAC address to match VF and
> synthetic
> > > NICs.
> > > > > > > Hyper-V
> > > > > > > > > > > provides a serial number to both devices for this
> > > purpose.
> > > > > This
> > > > > > > patch
> > > > > > > > > > > implements the matching based on VF serial numbers.
> This
> > > is
> > > > > the
> > > > > > > way
> > > > > > > > > > > specified by the protocol and more reliable.
> > > > > > > > > > >
> > > > > > > > > > > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > > > > > > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > > > > > > > > > > ---
> > > > > > > > > > > drivers/net/hyperv/netvsc_drv.c | 55
> > > > > > > > > > ++++++++++++++++++++++++++++++++++++---
> > > > > > > > > > > 1 files changed, 51 insertions(+), 4 deletions(-)
> > > > > > > > > > >
> > > > > > > > > > > diff --git a/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > > > b/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > > > > index 9522763..c5778cf 100644
> > > > > > > > > > > --- a/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > > > > +++ b/drivers/net/hyperv/netvsc_drv.c
> > > > > > > > > > > @@ -1165,9 +1165,10 @@ static void
> > > netvsc_free_netdev(struct
> > > > > > > > > > net_device *netdev)
> > > > > > > > > > > free_netdev(netdev);
> > > > > > > > > > > }
> > > > > > > > > > >
> > > > > > > > > > > -static struct net_device *get_netvsc_bymac(const u8
> > > *mac)
> > > > > > > > > > > +static struct net_device *get_netvsc_byvfser(u32
> vfser)
> > > > > > > > > > > {
> > > > > > > > > > > struct net_device *dev;
> > > > > > > > > > > + struct net_device_context *ndev_ctx;
> > > > > > > > > > >
> > > > > > > > > > > ASSERT_RTNL();
> > > > > > > > > > >
> > > > > > > > > > > @@ -1175,7 +1176,8 @@ static void
> > > netvsc_free_netdev(struct
> > > > > > > net_device
> > > > > > > > > > *netdev)
> > > > > > > > > > > if (dev->netdev_ops != &device_ops)
> > > > > > > > > > > continue; /* not a netvsc device */
> > > > > > > > > > >
> > > > > > > > > > > - if (ether_addr_equal(mac, dev->perm_addr))
> > > > > > > > > > > + ndev_ctx = netdev_priv(dev);
> > > > > > > > > > > + if (ndev_ctx->vf_serial == vfser)
> > > > > > > > > > > return dev;
> > > > > > > > > > > }
> > > > > > > > > > >
> > > > > > > > > > > @@ -1205,21 +1207,66 @@ static void
> > > > > netvsc_free_netdev(struct
> > > > > > > > > > net_device *netdev)
> > > > > > > > > > > return NULL;
> > > > > > > > > > > }
> > > > > > > > > > >
> > > > > > > > > > > +static u32 netvsc_get_vfser(struct net_device
> > > *vf_netdev)
> > > > > > > > > > > +{
> > > > > > > > > > > + struct device *dev;
> > > > > > > > > > > + struct hv_device *hdev;
> > > > > > > > > > > + struct hv_pcibus_device *hbus = NULL;
> > > > > > > > > > > + struct list_head *iter;
> > > > > > > > > > > + struct hv_pci_dev *hpdev;
> > > > > > > > > > > + unsigned long flags;
> > > > > > > > > > > + u32 vfser = 0;
> > > > > > > > > > > + u32 count = 0;
> > > > > > > > > > > +
> > > > > > > > > > > + for (dev = &vf_netdev->dev; dev; dev = dev->parent)
> > > {
> > > > > > > > > >
> > > > > > > > > > You are going to walk the whole device tree backwards?
> > > That's
> > > > > > > crazy.
> > > > > > > > > > And foolish. And racy and broken (what happens if the
> > > tree
> > > > > > > changes
> > > > > > > > > > while you do this?) Where is the lock being grabbed
> while
> > > > > this
> > > > > > > happens?
> > > > > > > > > > What about reference counts? Do you see other drivers
> > > ever
> > > > > doing
> > > > > > > this
> > > > > > > > > > (if you do, point them out and I'll go yell at them
> too...)
> > > > > > > > >
> > > > > > > > > Greg,
> > > > > > > > >
> > > > > > > > > We are registering for netdev events. Coming into this
> > > function,
> > > > > the
> > > > > > > caller
> > > > > > > > > guarantees that the list of netdevs does not change - we
> > > assert
> > > > > this
> > > > > > > on entry:
> > > > > > > > > ASSERT_RTNL(). We are only walking up the device tree
> for
> > > the
> > > > > > > netdevs whose
> > > > > > > > > state change is being notified to us - the device tree
> being
> > > > > walked
> > > > > > > here is limited to
> > > > > > > > > netdevs under question.
> > > > > > > >
> > > > > > > > But a netdev is a child of some type of "real" device, and
> you
> > > are
> > > > > now
> > > > > > > > walking the tree of all devices up to the "root" parent
> device,
> > > > > which
> > > > > > > > means you will hit PCI bridges, USB controllers, and all
> sorts
> > > of
> > > > > fun
> > > > > > > > things if you are a child of those types of devices.
> > > > > > > >
> > > > > > > > And can't you tell if the netdev for this event, really is
> > > "your"
> > > > > > > > netdev? Or are you getting called this for "all" netdevs?
> > > Sorry,
> > > > > I
> > > > > > > > don't know this api, any pointers to it would be
> appreciated.
> > > > > > > >
> > > > > > > > > We have a reference to the device and we know the device
> is
> > > not
> > > > > > > going away. Is it not
> > > > > > > > > safe to dereference the parent pointer - after all the
> child
> > > has
> > > > > > > taken a reference on
> > > > > > > > > the parent as part of device_add() call.
> > > > > > > >
> > > > > > > > It might be, and might not be. There's a reason you don't
> see
> > > > > this
> > > > > > > > pattern anywhere in the kernel because of this...
> > > > > > > >
> > > > > > > > > > > + if (!dev_is_vmbus(dev))
> > > > > > > > > > > + continue;
> > > > > > > > > >
> > > > > > > > > > Ick.
> > > > > > > > > >
> > > > > > > > > > Why isn't your parent pointer a vmbus device all the
> time?
> > > > > How
> > > > > > > could
> > > > > > > > > > you get burried down in the device hierarchy when you
> are
> > > the
> > > > > > > driver for
> > > > > > > > > > a specific bus type in the first place? How could
> this
> > > > > function
> > > > > > > ever be
> > > > > > > > > > called for a device that is NOT of this type?
> > > > > > > > >
> > > > > > > > > We get notified when state changes on any of the netdev
> > > devices
> > > > > in
> > > > > > > the system.
> > > > > > > > > Not all netdevs in the system belong to vmbus. Consider
> for
> > > > > instance
> > > > > > > the
> > > > > > > > > emulated NIC that can be configured. This is an emulated
> PCI
> > > NIC.
> > > > > We
> > > > > > > are only
> > > > > > > > > interested in netdevs that correspond to the VF instance
> > > that we
> > > > > are
> > > > > > > interested in.
> > > > > > > >
> > > > > > > > Can you "know" this is your netdev by some other way than
> > > having
> > > > > to
> > > > > > > walk
> > > > > > > > the device tree? Name? local device type? Something
> else?
> > > This
> > > > > > > seems
> > > > > > > > like an odd api in that everyone would have to do
> gyrations
> > > like
> > > > > this
> > > > > > > in
> > > > > > > > order to determine if the netdev is "theirs" or not...
> > > > > > >
> > > > > > > The scenario is SR-IOV on Hyper-V. In the case of VF device,
> the
> > > > > host
> > > > > > > hands the
> > > > > > > guest OS a PCI device for the virtual function device. The
> VF
> > > device
> > > > > is
> > > > > > > placed
> > > > > > > on a special synthetic PCI bus (ie not part of the other
> buses
> > > on
> > > > > the
> > > > > > > system).
> > > > > > > The VF device also has a synthetic network interface (netvsc)
> > > which
> > > > > > > lives
> > > > > > > on VMBUS. This code is about managing the interaction
> between
> > > the
> > > > > two.
> > > > > > >
> > > > > > > The association between VF and synthetic NIC is done in
> response
> > > to
> > > > > the
> > > > > > > VF network device being registered. Initial version was
> based on
> > > MAC
> > > > > > > address
> > > > > > > which is the same. Later refinement used permanent MAC
> address
> > > to
> > > > > > > avoid bugs if MAC address changed. This version is to use
> > > serial
> > > > > number
> > > > > > > instead which is safer than MAC address.
> > > > > > >
> > > > > > > The code to walk up/down maybe not be needed to find serial
> > > number.
> > > > > > > Perhaps a more direct single set of conditions is possible?
> > > > > > >
> > > > > > > Something like:
> > > > > > >
> > > > > > > In pci-hyperv.c
> > > > > > >
> > > > > > > u32 hv_pcifront_get_serial(struct pci_bus *bus, unsigned int
> > > devfn)
> > > > > > > {
> > > > > > > struct hv_pcibus_device *hbus
> > > > > > > = container_of(bus->sysdata,
> > > > > > > struct hv_pcibus_device, sysdata);
> > > > > > > struct hf_pci_dev *hpdev;
> > > > > > > u32 serial;
> > > > > > >
> > > > > > > hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev-
> >devfn));
> > > > > > > if (!hpdev)
> > > > > > > return 0;
> > > > > > >
> > > > > > > serial = hpdev->devs.ser;
> > > > > > > put_pcichild(hpdev, hv_pcidev_ref_by_slot);
> > > > > > > return serial;
> > > > > > > }
> > > > > > >
> > > > > > > In netvsc_drv.c
> > > > > > >
> > > > > > > static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> > > > > > > {
> > > > > > > struct device *dev = vf_netdev->dev.parent;
> > > > > > > struct pci_dev *pdev;
> > > > > > > u32 wslot;
> > > > > > >
> > > > > > > if (!dev || !dev_is_pci(dev))
> > > > > > > return 0;
> > > > > > >
> > > > > > > pdev = container_of(dev, struct pci_device, dev);
> > > > > > >
> > > > > > > return hv_pcifront_get_serial(pdev->bus, pdev->devfn);
> > > > > > > }
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > P.S: it would be good to be able to get win_slot out through
> > > sysfs
> > > > > as
> > > > > > > well for systemd/udev.
> > > > > >
> > > > > > Stephen,
> > > > > >
> > > > > > Thanks for suggestion. Actually, in my earlier implementation
> of
> > > this
> > > > > > feature (VF serial based matching), I thought about export a
> > > function
> > > > > > from vPCI driver, then calling it from netvsc. So I don't need
> to
> > > > > > move structs between headers... But, it creates a dependency
> of
> > > netvsc
> > > > > > on vPCI driver's symbol. So, even if on a VM without SRIOV, we
> > > have to
> > > > > > load vPCI driver, which we don't want.
> > > > > >
> > > > > > Also, hv_vpci device is 3 parent layers above the vf_netdevice:
> > > > > > Here is the VF drv hierarchy --
> > > > > > Should we assume it's always 3 parents above vf_netdevice, or
> > > search
> > > > > for it?
> > > > > >
> > > > > > [ 368.185259] HZINFO:NETDEV_REGISTER:
> > > > > > [ 368.185261] HZINFO: dev:ffff88007c10d518, bus:
> (null),
> > > > > busName:(null), drvName:(null)
> > > > > > [ 368.185262] HZINFO: dev:ffff88007c10c0a0,
> bus:ffffffff81ce4b60,
> > > > > busName:pci, drvName:ixgbevf
> > > > > > [ 368.185263] HZINFO: dev:ffff8800355c0000, bus:
> (null),
> > > > > busName:(null), drvName:(null)
> > > > > > [ 368.185264] HZINFO: dev:ffff8800355c5428,
> bus:ffffffffa0008160,
> > > > > busName:vmbus, drvName:hv_pci
> > > > > > [ 368.185264] HZINFO: dev:ffff88007c49e268,
> bus:ffffffff81ce9800,
> > > > > busName:acpi, drvName:vmbus
> > > > > > [ 368.185265] HZINFO: dev:ffff88007c48ea68,
> bus:ffffffff81ce9800,
> > > > > busName:acpi, drvName:(null)
> > > > > > [ 368.185266] HZINFO: dev:ffff88007c48aa68,
> bus:ffffffff81ce9800,
> > > > > busName:acpi, drvName:(null)
> > > > > > [ 368.185266] HZINFO: dev:ffff88007c48a268,
> bus:ffffffff81ce9800,
> > > > > busName:acpi, drvName:(null)
> > > > > > [ 368.185267] HZINFO: dev:ffff88007c489a68,
> bus:ffffffff81ce9800,
> > > > > busName:acpi, drvName:(null)
> > > > > >
> > > > > > Thanks,
> > > > > > - Haiyang
> > > > >
> > > > > Since this is a synthetic bus, the topology should not change
> unless
> > > > > host side
> > > > > software changes. The vf_netdev device has to be PCI device, so
> that
> > > is
> > > > > going to
> > > > > be certain. After that there maybe intermediate up to hv_pci.
> The
> > > code
> > > > > in hyperv-pci
> > > > > already has similar stuff (ie for read_config).
> > > >
> > > > Other netdevice, like emulated NIC can also trigger this
> notification.
> > > > They are not vPCI.
> > > >
> > > > Thanks,
> > > > - Haiyang
> > >
> > > Emulated NIC is already excluded in start of netvc notifier handler.
> > >
> > > static int netvsc_netdev_event(struct notifier_block *this,
> > > unsigned long event, void *ptr)
> > > {
> > > struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
> > >
> > > /* Skip our own events */
> > > if (event_dev->netdev_ops == &device_ops)
> > > return NOTIFY_DONE;
> > >
> >
> > Emulated device is not based on netvsc. It's the native Linux
> (dec100M?)
> > Driver. So this line doesn't exclude it. And how about other NIC type
> > may be added in the future?
>
> Sorry, forgot about that haven't used emulated device in years.
> The emulated device should appear to be on a PCI bus, but the serial
> would not match??
It's not a vmbus device, not a hv_pci device either. Hv_PCI is a subset
of vmbus devices. So emulated NIC won't have hv_pci serial number.
In my patch, the following code ensure, we only try to get serial number
after confirming it's vmbus and hv_pci device:
+ if (!dev_is_vmbus(dev))
+ continue;
+
+ hdev = device_to_hv_device(dev);
+ if (hdev->device_id != HV_PCIE)
+ continue;
Thanks,
- Haiyang
[toc] | [prev] | [next] | [standalone]
| From | Stephen Hemminger <stephen@networkplumber.org> |
|---|---|
| Date | 2016-12-10 01:30 +0100 |
| Subject | Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sMDI5-1Aj-5@gated-at.bofh.it> |
| In reply to | #1539723 |
On Fri, 9 Dec 2016 22:35:05 +0000
Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > > >
> > > > Emulated NIC is already excluded in start of netvc notifier handler.
> > > >
> > > > static int netvsc_netdev_event(struct notifier_block *this,
> > > > unsigned long event, void *ptr)
> > > > {
> > > > struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
> > > >
> > > > /* Skip our own events */
> > > > if (event_dev->netdev_ops == &device_ops)
> > > > return NOTIFY_DONE;
> > > >
> > >
> > > Emulated device is not based on netvsc. It's the native Linux
> > (dec100M?)
> > > Driver. So this line doesn't exclude it. And how about other NIC type
> > > may be added in the future?
> >
> > Sorry, forgot about that haven't used emulated device in years.
> > The emulated device should appear to be on a PCI bus, but the serial
> > would not match??
>
> It's not a vmbus device, not a hv_pci device either. Hv_PCI is a subset
> of vmbus devices. So emulated NIC won't have hv_pci serial number.
>
> In my patch, the following code ensure, we only try to get serial number
> after confirming it's vmbus and hv_pci device:
>
> + if (!dev_is_vmbus(dev))
> + continue;
> +
> + hdev = device_to_hv_device(dev);
> + if (hdev->device_id != HV_PCIE)
> + continue;
Ok, the walk back up the device tree is logically ok, but I don't
know enough about PCI device tree to be assured that it is safe.
Also, you could short circuit away most of the unwanted devices
by making sure the vf_netdev->dev.parent is a PCI device.
Also the loop to look for serial number in the devices on the
hv_pci bus could be made a separate function and have a short circuit
return (although it probably doesn't matter since there will only
be on e PCI VF device per bus there).
[toc] | [prev] | [next] | [standalone]
| From | Greg KH <gregkh@linuxfoundation.org> |
|---|---|
| Date | 2016-12-10 13:30 +0100 |
| Subject | Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sMOWR-2d6-9@gated-at.bofh.it> |
| In reply to | #1539747 |
On Fri, Dec 09, 2016 at 04:21:48PM -0800, Stephen Hemminger wrote:
> On Fri, 9 Dec 2016 22:35:05 +0000
> Haiyang Zhang <haiyangz@microsoft.com> wrote:
>
> > > > >
> > > > > Emulated NIC is already excluded in start of netvc notifier handler.
> > > > >
> > > > > static int netvsc_netdev_event(struct notifier_block *this,
> > > > > unsigned long event, void *ptr)
> > > > > {
> > > > > struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
> > > > >
> > > > > /* Skip our own events */
> > > > > if (event_dev->netdev_ops == &device_ops)
> > > > > return NOTIFY_DONE;
> > > > >
> > > >
> > > > Emulated device is not based on netvsc. It's the native Linux
> > > (dec100M?)
> > > > Driver. So this line doesn't exclude it. And how about other NIC type
> > > > may be added in the future?
> > >
> > > Sorry, forgot about that haven't used emulated device in years.
> > > The emulated device should appear to be on a PCI bus, but the serial
> > > would not match??
> >
> > It's not a vmbus device, not a hv_pci device either. Hv_PCI is a subset
> > of vmbus devices. So emulated NIC won't have hv_pci serial number.
> >
> > In my patch, the following code ensure, we only try to get serial number
> > after confirming it's vmbus and hv_pci device:
> >
> > + if (!dev_is_vmbus(dev))
> > + continue;
> > +
> > + hdev = device_to_hv_device(dev);
> > + if (hdev->device_id != HV_PCIE)
> > + continue;
>
> Ok, the walk back up the device tree is logically ok, but I don't
> know enough about PCI device tree to be assured that it is safe.
> Also, you could short circuit away most of the unwanted devices
> by making sure the vf_netdev->dev.parent is a PCI device.
Ugh, this seems really really messy. Can't we just have the
netdev_event interface pass back a pointer to something that we "know"
what it is? This walking the device tree is a mess, and not good.
I'd even argue that dev_is_pci() needs to be removed from the tree too,
as it shouldn't be needed either. We did a lot of work on the driver
model to prevent the need for having to declare the "type" of 'struct
device' at all, and by doing this type of thing it goes against the
basic design of the model.
Yes, it makes things a bit "tougher" in places, but you don't do crazy
things like walk device trees to try to find random devices and then
think it's safe to actually use them :(
thanks,
greg k-h
[toc] | [prev] | [next] | [standalone]
| From | Greg KH <gregkh@linuxfoundation.org> |
|---|---|
| Date | 2016-12-15 00:30 +0100 |
| Subject | Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sOr9M-6Gb-3@gated-at.bofh.it> |
| In reply to | #1539822 |
On Wed, Dec 14, 2016 at 11:18:59PM +0000, Haiyang Zhang wrote:
>
>
> > -----Original Message-----
> > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > Sent: Saturday, December 10, 2016 7:21 AM
> > To: Stephen Hemminger <stephen@networkplumber.org>
> > Cc: Haiyang Zhang <haiyangz@microsoft.com>; olaf@aepfle.de;
> > jasowang@redhat.com; linux-kernel@vger.kernel.org;
> > bjorn.helgaas@gmail.com; apw@canonical.com; devel@linuxdriverproject.org;
> > leann.ogasawara@canonical.com
> > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > serial numbers
> >
> > On Fri, Dec 09, 2016 at 04:21:48PM -0800, Stephen Hemminger wrote:
> > > On Fri, 9 Dec 2016 22:35:05 +0000
> > > Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > >
> > > > > > >
> > > > > > > Emulated NIC is already excluded in start of netvc notifier
> > handler.
> > > > > > >
> > > > > > > static int netvsc_netdev_event(struct notifier_block *this,
> > > > > > > unsigned long event, void *ptr)
> > > > > > > {
> > > > > > > struct net_device *event_dev =
> > netdev_notifier_info_to_dev(ptr);
> > > > > > >
> > > > > > > /* Skip our own events */
> > > > > > > if (event_dev->netdev_ops == &device_ops)
> > > > > > > return NOTIFY_DONE;
> > > > > > >
> > > > > >
> > > > > > Emulated device is not based on netvsc. It's the native Linux
> > > > > (dec100M?)
> > > > > > Driver. So this line doesn't exclude it. And how about other NIC
> > type
> > > > > > may be added in the future?
> > > > >
> > > > > Sorry, forgot about that haven't used emulated device in years.
> > > > > The emulated device should appear to be on a PCI bus, but the
> > serial
> > > > > would not match??
> > > >
> > > > It's not a vmbus device, not a hv_pci device either. Hv_PCI is a
> > subset
> > > > of vmbus devices. So emulated NIC won't have hv_pci serial number.
> > > >
> > > > In my patch, the following code ensure, we only try to get serial
> > number
> > > > after confirming it's vmbus and hv_pci device:
> > > >
> > > > + if (!dev_is_vmbus(dev))
> > > > + continue;
> > > > +
> > > > + hdev = device_to_hv_device(dev);
> > > > + if (hdev->device_id != HV_PCIE)
> > > > + continue;
> > >
> > > Ok, the walk back up the device tree is logically ok, but I don't
> > > know enough about PCI device tree to be assured that it is safe.
> > > Also, you could short circuit away most of the unwanted devices
> > > by making sure the vf_netdev->dev.parent is a PCI device.
> >
> > Ugh, this seems really really messy. Can't we just have the
> > netdev_event interface pass back a pointer to something that we "know"
> > what it is? This walking the device tree is a mess, and not good.
> >
> > I'd even argue that dev_is_pci() needs to be removed from the tree too,
> > as it shouldn't be needed either. We did a lot of work on the driver
> > model to prevent the need for having to declare the "type" of 'struct
> > device' at all, and by doing this type of thing it goes against the
> > basic design of the model.
> >
> > Yes, it makes things a bit "tougher" in places, but you don't do crazy
> > things like walk device trees to try to find random devices and then
> > think it's safe to actually use them :(
> >
>
> We register a notifier_block with:
> register_netdevice_notifier(struct notifier_block *nb)
>
> The "struct notifier_block" basically contains a callback function:
> struct notifier_block {
> notifier_fn_t notifier_call;
> struct notifier_block __rcu *next;
> int priority;
> };
>
> It doesn't specify which device we want, so all net devices can trigger
> this event. Seems we can't have this notifier return VF device only.
Ok, I dug in the kernel and it looks like people check the netdev_ops
structure to see if it matches up with their function pointers to "know"
if this is their device or not. Why not do that here? Or compare the
"string" of the driver name? Or any other such trick that the drivers
that call register_netdevice_notifier do?
All of which are more sane than walking the device tree...
And why am I having to do network driver development, ick ick ick :)
Come on, 'git grep' is your friend. Even better yet, use a good tool
like 'vgrep' which makes git grep work really really well.
thanks,
greg k-h
[toc] | [prev] | [next] | [standalone]
| From | Stephen Hemminger <stephen@networkplumber.org> |
|---|---|
| Date | 2016-12-15 01:00 +0100 |
| Subject | Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sOrCO-6Q9-27@gated-at.bofh.it> |
| In reply to | #1542339 |
On Wed, 14 Dec 2016 15:27:58 -0800
Greg KH <gregkh@linuxfoundation.org> wrote:
> On Wed, Dec 14, 2016 at 11:18:59PM +0000, Haiyang Zhang wrote:
> >
> >
> > > -----Original Message-----
> > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > Sent: Saturday, December 10, 2016 7:21 AM
> > > To: Stephen Hemminger <stephen@networkplumber.org>
> > > Cc: Haiyang Zhang <haiyangz@microsoft.com>; olaf@aepfle.de;
> > > jasowang@redhat.com; linux-kernel@vger.kernel.org;
> > > bjorn.helgaas@gmail.com; apw@canonical.com; devel@linuxdriverproject.org;
> > > leann.ogasawara@canonical.com
> > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > > serial numbers
> > >
> > > On Fri, Dec 09, 2016 at 04:21:48PM -0800, Stephen Hemminger wrote:
> > > > On Fri, 9 Dec 2016 22:35:05 +0000
> > > > Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > > >
> > > > > > > >
> > > > > > > > Emulated NIC is already excluded in start of netvc notifier
> > > handler.
> > > > > > > >
> > > > > > > > static int netvsc_netdev_event(struct notifier_block *this,
> > > > > > > > unsigned long event, void *ptr)
> > > > > > > > {
> > > > > > > > struct net_device *event_dev =
> > > netdev_notifier_info_to_dev(ptr);
> > > > > > > >
> > > > > > > > /* Skip our own events */
> > > > > > > > if (event_dev->netdev_ops == &device_ops)
> > > > > > > > return NOTIFY_DONE;
> > > > > > > >
> > > > > > >
> > > > > > > Emulated device is not based on netvsc. It's the native Linux
> > > > > > (dec100M?)
> > > > > > > Driver. So this line doesn't exclude it. And how about other NIC
> > > type
> > > > > > > may be added in the future?
> > > > > >
> > > > > > Sorry, forgot about that haven't used emulated device in years.
> > > > > > The emulated device should appear to be on a PCI bus, but the
> > > serial
> > > > > > would not match??
> > > > >
> > > > > It's not a vmbus device, not a hv_pci device either. Hv_PCI is a
> > > subset
> > > > > of vmbus devices. So emulated NIC won't have hv_pci serial number.
> > > > >
> > > > > In my patch, the following code ensure, we only try to get serial
> > > number
> > > > > after confirming it's vmbus and hv_pci device:
> > > > >
> > > > > + if (!dev_is_vmbus(dev))
> > > > > + continue;
> > > > > +
> > > > > + hdev = device_to_hv_device(dev);
> > > > > + if (hdev->device_id != HV_PCIE)
> > > > > + continue;
> > > >
> > > > Ok, the walk back up the device tree is logically ok, but I don't
> > > > know enough about PCI device tree to be assured that it is safe.
> > > > Also, you could short circuit away most of the unwanted devices
> > > > by making sure the vf_netdev->dev.parent is a PCI device.
> > >
> > > Ugh, this seems really really messy. Can't we just have the
> > > netdev_event interface pass back a pointer to something that we "know"
> > > what it is? This walking the device tree is a mess, and not good.
> > >
> > > I'd even argue that dev_is_pci() needs to be removed from the tree too,
> > > as it shouldn't be needed either. We did a lot of work on the driver
> > > model to prevent the need for having to declare the "type" of 'struct
> > > device' at all, and by doing this type of thing it goes against the
> > > basic design of the model.
> > >
> > > Yes, it makes things a bit "tougher" in places, but you don't do crazy
> > > things like walk device trees to try to find random devices and then
> > > think it's safe to actually use them :(
> > >
> >
> > We register a notifier_block with:
> > register_netdevice_notifier(struct notifier_block *nb)
> >
> > The "struct notifier_block" basically contains a callback function:
> > struct notifier_block {
> > notifier_fn_t notifier_call;
> > struct notifier_block __rcu *next;
> > int priority;
> > };
> >
> > It doesn't specify which device we want, so all net devices can trigger
> > this event. Seems we can't have this notifier return VF device only.
>
> Ok, I dug in the kernel and it looks like people check the netdev_ops
> structure to see if it matches up with their function pointers to "know"
> if this is their device or not. Why not do that here? Or compare the
> "string" of the driver name? Or any other such trick that the drivers
> that call register_netdevice_notifier do?
>
> All of which are more sane than walking the device tree...
>
> And why am I having to do network driver development, ick ick ick :)
>
> Come on, 'git grep' is your friend. Even better yet, use a good tool
> like 'vgrep' which makes git grep work really really well.
Normally, that would work but in this case we have one driver (netvsc)
which is managing another driver which is unaware of Hyper-V or netvsc
drivers existence. The callback is happening in netvsc driver and it
needs to say "hey I know that SR-IOV device, it is associated with my
network device". This problem is how to know that N is associated with
V? The V device has to be a network device, that is easy. But then it
also has to be a PCI device, not to bad. But then the netvsc code
is matching based on hyper-V only PCI bus metadata (the serial #).
The Microsoft developers made the rational decision not to go modifying
all the possible SR-IOV network devices from Intel and Mellanox to add
the functionality there. That would have been much worse.
Maybe, rather than trying to do the management in the kernel it
could have been done better in user space. Unfortunately, this would
only move the problem. The PCI-hyperv host driver could expose serial
value through sysfs (with some pain). But the problem would be how
to make a new API to join the two V and N device. Doing a private
ioctl is worse than the notifier.
[toc] | [prev] | [next] | [standalone]
| From | KY Srinivasan <kys@microsoft.com> |
|---|---|
| Date | 2016-12-16 02:20 +0100 |
| Subject | RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sOPlM-4TI-3@gated-at.bofh.it> |
| In reply to | #1542363 |
> -----Original Message-----
> From: devel [mailto:driverdev-devel-bounces@linuxdriverproject.org] On
> Behalf Of Stephen Hemminger
> Sent: Wednesday, December 14, 2016 3:52 PM
> To: Greg KH <gregkh@linuxfoundation.org>
> Cc: olaf@aepfle.de; jasowang@redhat.com; linux-kernel@vger.kernel.org;
> bjorn.helgaas@gmail.com; apw@canonical.com;
> devel@linuxdriverproject.org; leann.ogasawara@canonical.com; Haiyang
> Zhang <haiyangz@microsoft.com>
> Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial
> numbers
>
> On Wed, 14 Dec 2016 15:27:58 -0800
> Greg KH <gregkh@linuxfoundation.org> wrote:
>
> > On Wed, Dec 14, 2016 at 11:18:59PM +0000, Haiyang Zhang wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > > Sent: Saturday, December 10, 2016 7:21 AM
> > > > To: Stephen Hemminger <stephen@networkplumber.org>
> > > > Cc: Haiyang Zhang <haiyangz@microsoft.com>; olaf@aepfle.de;
> > > > jasowang@redhat.com; linux-kernel@vger.kernel.org;
> > > > bjorn.helgaas@gmail.com; apw@canonical.com;
> devel@linuxdriverproject.org;
> > > > leann.ogasawara@canonical.com
> > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > > > serial numbers
> > > >
> > > > On Fri, Dec 09, 2016 at 04:21:48PM -0800, Stephen Hemminger wrote:
> > > > > On Fri, 9 Dec 2016 22:35:05 +0000
> > > > > Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > > > >
> > > > > > > > >
> > > > > > > > > Emulated NIC is already excluded in start of netvc notifier
> > > > handler.
> > > > > > > > >
> > > > > > > > > static int netvsc_netdev_event(struct notifier_block *this,
> > > > > > > > > unsigned long event, void *ptr)
> > > > > > > > > {
> > > > > > > > > struct net_device *event_dev =
> > > > netdev_notifier_info_to_dev(ptr);
> > > > > > > > >
> > > > > > > > > /* Skip our own events */
> > > > > > > > > if (event_dev->netdev_ops == &device_ops)
> > > > > > > > > return NOTIFY_DONE;
> > > > > > > > >
> > > > > > > >
> > > > > > > > Emulated device is not based on netvsc. It's the native Linux
> > > > > > > (dec100M?)
> > > > > > > > Driver. So this line doesn't exclude it. And how about other NIC
> > > > type
> > > > > > > > may be added in the future?
> > > > > > >
> > > > > > > Sorry, forgot about that haven't used emulated device in years.
> > > > > > > The emulated device should appear to be on a PCI bus, but the
> > > > serial
> > > > > > > would not match??
> > > > > >
> > > > > > It's not a vmbus device, not a hv_pci device either. Hv_PCI is a
> > > > subset
> > > > > > of vmbus devices. So emulated NIC won't have hv_pci serial
> number.
> > > > > >
> > > > > > In my patch, the following code ensure, we only try to get serial
> > > > number
> > > > > > after confirming it's vmbus and hv_pci device:
> > > > > >
> > > > > > + if (!dev_is_vmbus(dev))
> > > > > > + continue;
> > > > > > +
> > > > > > + hdev = device_to_hv_device(dev);
> > > > > > + if (hdev->device_id != HV_PCIE)
> > > > > > + continue;
> > > > >
> > > > > Ok, the walk back up the device tree is logically ok, but I don't
> > > > > know enough about PCI device tree to be assured that it is safe.
> > > > > Also, you could short circuit away most of the unwanted devices
> > > > > by making sure the vf_netdev->dev.parent is a PCI device.
> > > >
> > > > Ugh, this seems really really messy. Can't we just have the
> > > > netdev_event interface pass back a pointer to something that we
> "know"
> > > > what it is? This walking the device tree is a mess, and not good.
> > > >
> > > > I'd even argue that dev_is_pci() needs to be removed from the tree
> too,
> > > > as it shouldn't be needed either. We did a lot of work on the driver
> > > > model to prevent the need for having to declare the "type" of 'struct
> > > > device' at all, and by doing this type of thing it goes against the
> > > > basic design of the model.
> > > >
> > > > Yes, it makes things a bit "tougher" in places, but you don't do crazy
> > > > things like walk device trees to try to find random devices and then
> > > > think it's safe to actually use them :(
> > > >
> > >
> > > We register a notifier_block with:
> > > register_netdevice_notifier(struct notifier_block *nb)
> > >
> > > The "struct notifier_block" basically contains a callback function:
> > > struct notifier_block {
> > > notifier_fn_t notifier_call;
> > > struct notifier_block __rcu *next;
> > > int priority;
> > > };
> > >
> > > It doesn't specify which device we want, so all net devices can trigger
> > > this event. Seems we can't have this notifier return VF device only.
> >
> > Ok, I dug in the kernel and it looks like people check the netdev_ops
> > structure to see if it matches up with their function pointers to "know"
> > if this is their device or not. Why not do that here? Or compare the
> > "string" of the driver name? Or any other such trick that the drivers
> > that call register_netdevice_notifier do?
> >
> > All of which are more sane than walking the device tree...
> >
> > And why am I having to do network driver development, ick ick ick :)
> >
> > Come on, 'git grep' is your friend. Even better yet, use a good tool
> > like 'vgrep' which makes git grep work really really well.
>
> Normally, that would work but in this case we have one driver (netvsc)
> which is managing another driver which is unaware of Hyper-V or netvsc
> drivers existence. The callback is happening in netvsc driver and it
> needs to say "hey I know that SR-IOV device, it is associated with my
> network device". This problem is how to know that N is associated with
> V? The V device has to be a network device, that is easy. But then it
> also has to be a PCI device, not to bad. But then the netvsc code
> is matching based on hyper-V only PCI bus metadata (the serial #).
>
> The Microsoft developers made the rational decision not to go modifying
> all the possible SR-IOV network devices from Intel and Mellanox to add
> the functionality there. That would have been much worse.
>
> Maybe, rather than trying to do the management in the kernel it
> could have been done better in user space. Unfortunately, this would
> only move the problem. The PCI-hyperv host driver could expose serial
> value through sysfs (with some pain). But the problem would be how
> to make a new API to join the two V and N device. Doing a private
> ioctl is worse than the notifier.
All this has been discussed earlier in the thread. I think I have a solution
to the problem:
The only PCI (non-VF) NIC that may be present in the VM is the emulated NIC and
we know exactly the device ID and vendor ID of this NIC. Furthermore,
as a platform we are not going to be emulating additional NICs. So,
if the PCI NIC is not the emulated NIC, it must be a VF and we can extract the
serial number.
Regards,
K. Y
> _______________________________________________
> devel mailing list
> devel@linuxdriverproject.org
> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdriverd
> ev.linuxdriverproject.org%2Fmailman%2Flistinfo%2Fdriverdev-
> devel&data=02%7C01%7Ckys%40microsoft.com%7C77c2c8a38fe2431945e408
> d4247c2c7d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C63617356
> 3122444667&sdata=u5C0v7ixzRu%2Btw51tTzHNpbsNqCDQTpigzUtwahIPvE%
> 3D&reserved=0
[toc] | [prev] | [next] | [standalone]
| From | Haiyang Zhang <haiyangz@microsoft.com> |
|---|---|
| Date | 2016-12-16 17:00 +0100 |
| Subject | RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sP35n-5AA-7@gated-at.bofh.it> |
| In reply to | #1543158 |
> -----Original Message----- > From: KY Srinivasan > Sent: Thursday, December 15, 2016 8:11 PM > To: Stephen Hemminger <stephen@networkplumber.org>; Greg KH > <gregkh@linuxfoundation.org> > Cc: olaf@aepfle.de; jasowang@redhat.com; linux-kernel@vger.kernel.org; > bjorn.helgaas@gmail.com; apw@canonical.com; devel@linuxdriverproject.org; > leann.ogasawara@canonical.com; Haiyang Zhang <haiyangz@microsoft.com> > Subject: RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on > serial numbers > > > > > -----Original Message----- > > From: devel [mailto:driverdev-devel-bounces@linuxdriverproject.org] On > > Behalf Of Stephen Hemminger > > Sent: Wednesday, December 14, 2016 3:52 PM > > To: Greg KH <gregkh@linuxfoundation.org> > > Cc: olaf@aepfle.de; jasowang@redhat.com; linux-kernel@vger.kernel.org; > > bjorn.helgaas@gmail.com; apw@canonical.com; > > devel@linuxdriverproject.org; leann.ogasawara@canonical.com; Haiyang > > Zhang <haiyangz@microsoft.com> > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on > serial > > numbers > > > > Normally, that would work but in this case we have one driver (netvsc) > > which is managing another driver which is unaware of Hyper-V or netvsc > > drivers existence. The callback is happening in netvsc driver and it > > needs to say "hey I know that SR-IOV device, it is associated with my > > network device". This problem is how to know that N is associated with > > V? The V device has to be a network device, that is easy. But then it > > also has to be a PCI device, not to bad. But then the netvsc code > > is matching based on hyper-V only PCI bus metadata (the serial #). > > > > The Microsoft developers made the rational decision not to go > modifying > > all the possible SR-IOV network devices from Intel and Mellanox to add > > the functionality there. That would have been much worse. > > > > Maybe, rather than trying to do the management in the kernel it > > could have been done better in user space. Unfortunately, this would > > only move the problem. The PCI-hyperv host driver could expose serial > > value through sysfs (with some pain). But the problem would be how > > to make a new API to join the two V and N device. Doing a private > > ioctl is worse than the notifier. > > All this has been discussed earlier in the thread. I think I have a > solution > to the problem: > The only PCI (non-VF) NIC that may be present in the VM is the emulated > NIC and > we know exactly the device ID and vendor ID of this NIC. Furthermore, > as a platform we are not going to be emulating additional NICs. So, > if the PCI NIC is not the emulated NIC, it must be a VF and we can > extract the > serial number. How about direct pass-through NIC devices. Do they have vPCI serial number? And, the numbers should be different from VF NIC? Thanks, - Haiyang
[toc] | [prev] | [next] | [standalone]
| From | KY Srinivasan <kys@microsoft.com> |
|---|---|
| Date | 2016-12-16 20:00 +0100 |
| Subject | RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sP5Tz-7mH-21@gated-at.bofh.it> |
| In reply to | #1543547 |
> -----Original Message----- > From: Haiyang Zhang > Sent: Friday, December 16, 2016 7:21 AM > To: KY Srinivasan <kys@microsoft.com>; Stephen Hemminger > <stephen@networkplumber.org>; Greg KH <gregkh@linuxfoundation.org> > Cc: olaf@aepfle.de; jasowang@redhat.com; linux-kernel@vger.kernel.org; > bjorn.helgaas@gmail.com; apw@canonical.com; > devel@linuxdriverproject.org; leann.ogasawara@canonical.com > Subject: RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial > numbers > > > > > -----Original Message----- > > From: KY Srinivasan > > Sent: Thursday, December 15, 2016 8:11 PM > > To: Stephen Hemminger <stephen@networkplumber.org>; Greg KH > > <gregkh@linuxfoundation.org> > > Cc: olaf@aepfle.de; jasowang@redhat.com; linux-kernel@vger.kernel.org; > > bjorn.helgaas@gmail.com; apw@canonical.com; > devel@linuxdriverproject.org; > > leann.ogasawara@canonical.com; Haiyang Zhang > <haiyangz@microsoft.com> > > Subject: RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on > > serial numbers > > > > > > > > > -----Original Message----- > > > From: devel [mailto:driverdev-devel-bounces@linuxdriverproject.org] > On > > > Behalf Of Stephen Hemminger > > > Sent: Wednesday, December 14, 2016 3:52 PM > > > To: Greg KH <gregkh@linuxfoundation.org> > > > Cc: olaf@aepfle.de; jasowang@redhat.com; linux- > kernel@vger.kernel.org; > > > bjorn.helgaas@gmail.com; apw@canonical.com; > > > devel@linuxdriverproject.org; leann.ogasawara@canonical.com; Haiyang > > > Zhang <haiyangz@microsoft.com> > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on > > serial > > > numbers > > > > > > Normally, that would work but in this case we have one driver (netvsc) > > > which is managing another driver which is unaware of Hyper-V or netvsc > > > drivers existence. The callback is happening in netvsc driver and it > > > needs to say "hey I know that SR-IOV device, it is associated with my > > > network device". This problem is how to know that N is associated with > > > V? The V device has to be a network device, that is easy. But then it > > > also has to be a PCI device, not to bad. But then the netvsc code > > > is matching based on hyper-V only PCI bus metadata (the serial #). > > > > > > The Microsoft developers made the rational decision not to go > > modifying > > > all the possible SR-IOV network devices from Intel and Mellanox to add > > > the functionality there. That would have been much worse. > > > > > > Maybe, rather than trying to do the management in the kernel it > > > could have been done better in user space. Unfortunately, this would > > > only move the problem. The PCI-hyperv host driver could expose serial > > > value through sysfs (with some pain). But the problem would be how > > > to make a new API to join the two V and N device. Doing a private > > > ioctl is worse than the notifier. > > > > All this has been discussed earlier in the thread. I think I have a > > solution > > to the problem: > > The only PCI (non-VF) NIC that may be present in the VM is the emulated > > NIC and > > we know exactly the device ID and vendor ID of this NIC. Furthermore, > > as a platform we are not going to be emulating additional NICs. So, > > if the PCI NIC is not the emulated NIC, it must be a VF and we can > > extract the > > serial number. > > How about direct pass-through NIC devices. Do they have vPCI serial > number? > And, the numbers should be different from VF NIC? This may not have a valid serial number; but is still a descendent of vmbus. K. Y > > Thanks, > - Haiyang
[toc] | [prev] | [next] | [standalone]
| From | Greg KH <gregkh@linuxfoundation.org> |
|---|---|
| Date | 2016-12-16 17:50 +0100 |
| Subject | Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sP3RL-69y-1@gated-at.bofh.it> |
| In reply to | #1542363 |
On Wed, Dec 14, 2016 at 03:51:34PM -0800, Stephen Hemminger wrote:
> On Wed, 14 Dec 2016 15:27:58 -0800
> Greg KH <gregkh@linuxfoundation.org> wrote:
>
> > On Wed, Dec 14, 2016 at 11:18:59PM +0000, Haiyang Zhang wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > > Sent: Saturday, December 10, 2016 7:21 AM
> > > > To: Stephen Hemminger <stephen@networkplumber.org>
> > > > Cc: Haiyang Zhang <haiyangz@microsoft.com>; olaf@aepfle.de;
> > > > jasowang@redhat.com; linux-kernel@vger.kernel.org;
> > > > bjorn.helgaas@gmail.com; apw@canonical.com; devel@linuxdriverproject.org;
> > > > leann.ogasawara@canonical.com
> > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > > > serial numbers
> > > >
> > > > On Fri, Dec 09, 2016 at 04:21:48PM -0800, Stephen Hemminger wrote:
> > > > > On Fri, 9 Dec 2016 22:35:05 +0000
> > > > > Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > > > >
> > > > > > > > >
> > > > > > > > > Emulated NIC is already excluded in start of netvc notifier
> > > > handler.
> > > > > > > > >
> > > > > > > > > static int netvsc_netdev_event(struct notifier_block *this,
> > > > > > > > > unsigned long event, void *ptr)
> > > > > > > > > {
> > > > > > > > > struct net_device *event_dev =
> > > > netdev_notifier_info_to_dev(ptr);
> > > > > > > > >
> > > > > > > > > /* Skip our own events */
> > > > > > > > > if (event_dev->netdev_ops == &device_ops)
> > > > > > > > > return NOTIFY_DONE;
> > > > > > > > >
> > > > > > > >
> > > > > > > > Emulated device is not based on netvsc. It's the native Linux
> > > > > > > (dec100M?)
> > > > > > > > Driver. So this line doesn't exclude it. And how about other NIC
> > > > type
> > > > > > > > may be added in the future?
> > > > > > >
> > > > > > > Sorry, forgot about that haven't used emulated device in years.
> > > > > > > The emulated device should appear to be on a PCI bus, but the
> > > > serial
> > > > > > > would not match??
> > > > > >
> > > > > > It's not a vmbus device, not a hv_pci device either. Hv_PCI is a
> > > > subset
> > > > > > of vmbus devices. So emulated NIC won't have hv_pci serial number.
> > > > > >
> > > > > > In my patch, the following code ensure, we only try to get serial
> > > > number
> > > > > > after confirming it's vmbus and hv_pci device:
> > > > > >
> > > > > > + if (!dev_is_vmbus(dev))
> > > > > > + continue;
> > > > > > +
> > > > > > + hdev = device_to_hv_device(dev);
> > > > > > + if (hdev->device_id != HV_PCIE)
> > > > > > + continue;
> > > > >
> > > > > Ok, the walk back up the device tree is logically ok, but I don't
> > > > > know enough about PCI device tree to be assured that it is safe.
> > > > > Also, you could short circuit away most of the unwanted devices
> > > > > by making sure the vf_netdev->dev.parent is a PCI device.
> > > >
> > > > Ugh, this seems really really messy. Can't we just have the
> > > > netdev_event interface pass back a pointer to something that we "know"
> > > > what it is? This walking the device tree is a mess, and not good.
> > > >
> > > > I'd even argue that dev_is_pci() needs to be removed from the tree too,
> > > > as it shouldn't be needed either. We did a lot of work on the driver
> > > > model to prevent the need for having to declare the "type" of 'struct
> > > > device' at all, and by doing this type of thing it goes against the
> > > > basic design of the model.
> > > >
> > > > Yes, it makes things a bit "tougher" in places, but you don't do crazy
> > > > things like walk device trees to try to find random devices and then
> > > > think it's safe to actually use them :(
> > > >
> > >
> > > We register a notifier_block with:
> > > register_netdevice_notifier(struct notifier_block *nb)
> > >
> > > The "struct notifier_block" basically contains a callback function:
> > > struct notifier_block {
> > > notifier_fn_t notifier_call;
> > > struct notifier_block __rcu *next;
> > > int priority;
> > > };
> > >
> > > It doesn't specify which device we want, so all net devices can trigger
> > > this event. Seems we can't have this notifier return VF device only.
> >
> > Ok, I dug in the kernel and it looks like people check the netdev_ops
> > structure to see if it matches up with their function pointers to "know"
> > if this is their device or not. Why not do that here? Or compare the
> > "string" of the driver name? Or any other such trick that the drivers
> > that call register_netdevice_notifier do?
> >
> > All of which are more sane than walking the device tree...
> >
> > And why am I having to do network driver development, ick ick ick :)
> >
> > Come on, 'git grep' is your friend. Even better yet, use a good tool
> > like 'vgrep' which makes git grep work really really well.
>
> Normally, that would work but in this case we have one driver (netvsc)
> which is managing another driver which is unaware of Hyper-V or netvsc
> drivers existence.
That's the root problem here :)
> The callback is happening in netvsc driver and it
> needs to say "hey I know that SR-IOV device, it is associated with my
> network device". This problem is how to know that N is associated with
> V? The V device has to be a network device, that is easy. But then it
> also has to be a PCI device, not to bad.
I'd argue that it is just as bad, as it shouldn't be poking around with
a random 'struct device' like that, but I'll let it slide...
> But then the netvsc code
> is matching based on hyper-V only PCI bus metadata (the serial #).
Which is a mess.
Again, walking the device tree like this is racy, broken, and shouldn't
be done anywhere. You are crossing bus boundries and lots of bad things
could happen if a device was removed at the same time. Just don't do
that.
> The Microsoft developers made the rational decision not to go modifying
> all the possible SR-IOV network devices from Intel and Mellanox to add
> the functionality there. That would have been much worse.
Why is that worse? How many lines of code would that be?
> Maybe, rather than trying to do the management in the kernel it
> could have been done better in user space. Unfortunately, this would
> only move the problem. The PCI-hyperv host driver could expose serial
> value through sysfs (with some pain). But the problem would be how
> to make a new API to join the two V and N device. Doing a private
> ioctl is worse than the notifier.
I still don't really understand the relationship between V and N, but it
feels like it is very tenous and sketchy and you should work to make it
more explicit. We have the source to these drivers, do it correctly,
or, do something in the network bus layer to be able to properly
represent this heirachy so that it is "obvious" what is going on.
thanks,
greg k-h
[toc] | [prev] | [next] | [standalone]
| From | Haiyang Zhang <haiyangz@microsoft.com> |
|---|---|
| Date | 2016-12-15 04:00 +0100 |
| Subject | RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sOr9M-6Gb-5@gated-at.bofh.it> |
| In reply to | #1539822 |
> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: Saturday, December 10, 2016 7:21 AM
> To: Stephen Hemminger <stephen@networkplumber.org>
> Cc: Haiyang Zhang <haiyangz@microsoft.com>; olaf@aepfle.de;
> jasowang@redhat.com; linux-kernel@vger.kernel.org;
> bjorn.helgaas@gmail.com; apw@canonical.com; devel@linuxdriverproject.org;
> leann.ogasawara@canonical.com
> Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> serial numbers
>
> On Fri, Dec 09, 2016 at 04:21:48PM -0800, Stephen Hemminger wrote:
> > On Fri, 9 Dec 2016 22:35:05 +0000
> > Haiyang Zhang <haiyangz@microsoft.com> wrote:
> >
> > > > > >
> > > > > > Emulated NIC is already excluded in start of netvc notifier
> handler.
> > > > > >
> > > > > > static int netvsc_netdev_event(struct notifier_block *this,
> > > > > > unsigned long event, void *ptr)
> > > > > > {
> > > > > > struct net_device *event_dev =
> netdev_notifier_info_to_dev(ptr);
> > > > > >
> > > > > > /* Skip our own events */
> > > > > > if (event_dev->netdev_ops == &device_ops)
> > > > > > return NOTIFY_DONE;
> > > > > >
> > > > >
> > > > > Emulated device is not based on netvsc. It's the native Linux
> > > > (dec100M?)
> > > > > Driver. So this line doesn't exclude it. And how about other NIC
> type
> > > > > may be added in the future?
> > > >
> > > > Sorry, forgot about that haven't used emulated device in years.
> > > > The emulated device should appear to be on a PCI bus, but the
> serial
> > > > would not match??
> > >
> > > It's not a vmbus device, not a hv_pci device either. Hv_PCI is a
> subset
> > > of vmbus devices. So emulated NIC won't have hv_pci serial number.
> > >
> > > In my patch, the following code ensure, we only try to get serial
> number
> > > after confirming it's vmbus and hv_pci device:
> > >
> > > + if (!dev_is_vmbus(dev))
> > > + continue;
> > > +
> > > + hdev = device_to_hv_device(dev);
> > > + if (hdev->device_id != HV_PCIE)
> > > + continue;
> >
> > Ok, the walk back up the device tree is logically ok, but I don't
> > know enough about PCI device tree to be assured that it is safe.
> > Also, you could short circuit away most of the unwanted devices
> > by making sure the vf_netdev->dev.parent is a PCI device.
>
> Ugh, this seems really really messy. Can't we just have the
> netdev_event interface pass back a pointer to something that we "know"
> what it is? This walking the device tree is a mess, and not good.
>
> I'd even argue that dev_is_pci() needs to be removed from the tree too,
> as it shouldn't be needed either. We did a lot of work on the driver
> model to prevent the need for having to declare the "type" of 'struct
> device' at all, and by doing this type of thing it goes against the
> basic design of the model.
>
> Yes, it makes things a bit "tougher" in places, but you don't do crazy
> things like walk device trees to try to find random devices and then
> think it's safe to actually use them :(
>
We register a notifier_block with:
register_netdevice_notifier(struct notifier_block *nb)
The "struct notifier_block" basically contains a callback function:
struct notifier_block {
notifier_fn_t notifier_call;
struct notifier_block __rcu *next;
int priority;
};
It doesn't specify which device we want, so all net devices can trigger
this event. Seems we can't have this notifier return VF device only.
Thanks,
- Haiyang
[toc] | [prev] | [next] | [standalone]
| From | Haiyang Zhang <haiyangz@microsoft.com> |
|---|---|
| Date | 2016-12-09 22:50 +0100 |
| Subject | RE: [PATCH 3/3] hv_netvsc: Implement VF matching based on serial numbers |
| Message-ID | <sMBdf-8s8-7@gated-at.bofh.it> |
| In reply to | #1539641 |
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Friday, December 9, 2016 3:30 PM
> To: Haiyang Zhang <haiyangz@microsoft.com>
> Cc: Greg KH <gregkh@linuxfoundation.org>; KY Srinivasan
> <kys@microsoft.com>; olaf@aepfle.de; linux-kernel@vger.kernel.org;
> bjorn.helgaas@gmail.com; apw@canonical.com; devel@linuxdriverproject.org;
> leann.ogasawara@canonical.com; jasowang@redhat.com
> Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> serial numbers
>
> On Fri, 9 Dec 2016 20:09:49 +0000
> Haiyang Zhang <haiyangz@microsoft.com> wrote:
>
> > > -----Original Message-----
> > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > Sent: Friday, December 9, 2016 1:21 PM
> > > To: Greg KH <gregkh@linuxfoundation.org>
> > > Cc: KY Srinivasan <kys@microsoft.com>; olaf@aepfle.de; Haiyang Zhang
> > > <haiyangz@microsoft.com>; linux-kernel@vger.kernel.org;
> > > bjorn.helgaas@gmail.com; apw@canonical.com;
> devel@linuxdriverproject.org;
> > > leann.ogasawara@canonical.com; jasowang@redhat.com
> > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching based on
> > > serial numbers
> > >
> > > On Fri, 9 Dec 2016 08:31:22 +0100
> > > Greg KH <gregkh@linuxfoundation.org> wrote:
> > >
> > > > On Fri, Dec 09, 2016 at 12:05:53AM +0000, KY Srinivasan wrote:
> > > > >
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > > > > Sent: Thursday, December 8, 2016 7:56 AM
> > > > > > To: KY Srinivasan <kys@microsoft.com>
> > > > > > Cc: linux-kernel@vger.kernel.org; devel@linuxdriverproject.org;
> > > > > > olaf@aepfle.de; apw@canonical.com; vkuznets@redhat.com;
> > > > > > jasowang@redhat.com; leann.ogasawara@canonical.com;
> > > > > > bjorn.helgaas@gmail.com; Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > Subject: Re: [PATCH 3/3] hv_netvsc: Implement VF matching
> based on
> > > serial
> > > > > > numbers
> > > > > >
> > > > > > On Thu, Dec 08, 2016 at 12:33:43AM -0800,
> > > kys@exchange.microsoft.com
> > > > > > wrote:
> > > > > > > From: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > >
> > > > > > > We currently use MAC address to match VF and synthetic NICs.
> > > Hyper-V
> > > > > > > provides a serial number to both devices for this purpose.
> This
> > > patch
> > > > > > > implements the matching based on VF serial numbers. This is
> the
> > > way
> > > > > > > specified by the protocol and more reliable.
> > > > > > >
> > > > > > > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > > > > > > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > > > > > > ---
> > > > > > > drivers/net/hyperv/netvsc_drv.c | 55
> > > > > > ++++++++++++++++++++++++++++++++++++---
> > > > > > > 1 files changed, 51 insertions(+), 4 deletions(-)
> > > > > > >
> > > > > > > diff --git a/drivers/net/hyperv/netvsc_drv.c
> > > > > > b/drivers/net/hyperv/netvsc_drv.c
> > > > > > > index 9522763..c5778cf 100644
> > > > > > > --- a/drivers/net/hyperv/netvsc_drv.c
> > > > > > > +++ b/drivers/net/hyperv/netvsc_drv.c
> > > > > > > @@ -1165,9 +1165,10 @@ static void netvsc_free_netdev(struct
> > > > > > net_device *netdev)
> > > > > > > free_netdev(netdev);
> > > > > > > }
> > > > > > >
> > > > > > > -static struct net_device *get_netvsc_bymac(const u8 *mac)
> > > > > > > +static struct net_device *get_netvsc_byvfser(u32 vfser)
> > > > > > > {
> > > > > > > struct net_device *dev;
> > > > > > > + struct net_device_context *ndev_ctx;
> > > > > > >
> > > > > > > ASSERT_RTNL();
> > > > > > >
> > > > > > > @@ -1175,7 +1176,8 @@ static void netvsc_free_netdev(struct
> > > net_device
> > > > > > *netdev)
> > > > > > > if (dev->netdev_ops != &device_ops)
> > > > > > > continue; /* not a netvsc device */
> > > > > > >
> > > > > > > - if (ether_addr_equal(mac, dev->perm_addr))
> > > > > > > + ndev_ctx = netdev_priv(dev);
> > > > > > > + if (ndev_ctx->vf_serial == vfser)
> > > > > > > return dev;
> > > > > > > }
> > > > > > >
> > > > > > > @@ -1205,21 +1207,66 @@ static void
> netvsc_free_netdev(struct
> > > > > > net_device *netdev)
> > > > > > > return NULL;
> > > > > > > }
> > > > > > >
> > > > > > > +static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> > > > > > > +{
> > > > > > > + struct device *dev;
> > > > > > > + struct hv_device *hdev;
> > > > > > > + struct hv_pcibus_device *hbus = NULL;
> > > > > > > + struct list_head *iter;
> > > > > > > + struct hv_pci_dev *hpdev;
> > > > > > > + unsigned long flags;
> > > > > > > + u32 vfser = 0;
> > > > > > > + u32 count = 0;
> > > > > > > +
> > > > > > > + for (dev = &vf_netdev->dev; dev; dev = dev->parent) {
> > > > > >
> > > > > > You are going to walk the whole device tree backwards? That's
> > > crazy.
> > > > > > And foolish. And racy and broken (what happens if the tree
> > > changes
> > > > > > while you do this?) Where is the lock being grabbed while
> this
> > > happens?
> > > > > > What about reference counts? Do you see other drivers ever
> doing
> > > this
> > > > > > (if you do, point them out and I'll go yell at them too...)
> > > > >
> > > > > Greg,
> > > > >
> > > > > We are registering for netdev events. Coming into this function,
> the
> > > caller
> > > > > guarantees that the list of netdevs does not change - we assert
> this
> > > on entry:
> > > > > ASSERT_RTNL(). We are only walking up the device tree for the
> > > netdevs whose
> > > > > state change is being notified to us - the device tree being
> walked
> > > here is limited to
> > > > > netdevs under question.
> > > >
> > > > But a netdev is a child of some type of "real" device, and you are
> now
> > > > walking the tree of all devices up to the "root" parent device,
> which
> > > > means you will hit PCI bridges, USB controllers, and all sorts of
> fun
> > > > things if you are a child of those types of devices.
> > > >
> > > > And can't you tell if the netdev for this event, really is "your"
> > > > netdev? Or are you getting called this for "all" netdevs? Sorry,
> I
> > > > don't know this api, any pointers to it would be appreciated.
> > > >
> > > > > We have a reference to the device and we know the device is not
> > > going away. Is it not
> > > > > safe to dereference the parent pointer - after all the child has
> > > taken a reference on
> > > > > the parent as part of device_add() call.
> > > >
> > > > It might be, and might not be. There's a reason you don't see
> this
> > > > pattern anywhere in the kernel because of this...
> > > >
> > > > > > > + if (!dev_is_vmbus(dev))
> > > > > > > + continue;
> > > > > >
> > > > > > Ick.
> > > > > >
> > > > > > Why isn't your parent pointer a vmbus device all the time?
> How
> > > could
> > > > > > you get burried down in the device hierarchy when you are the
> > > driver for
> > > > > > a specific bus type in the first place? How could this
> function
> > > ever be
> > > > > > called for a device that is NOT of this type?
> > > > >
> > > > > We get notified when state changes on any of the netdev devices
> in
> > > the system.
> > > > > Not all netdevs in the system belong to vmbus. Consider for
> instance
> > > the
> > > > > emulated NIC that can be configured. This is an emulated PCI NIC.
> We
> > > are only
> > > > > interested in netdevs that correspond to the VF instance that we
> are
> > > interested in.
> > > >
> > > > Can you "know" this is your netdev by some other way than having
> to
> > > walk
> > > > the device tree? Name? local device type? Something else? This
> > > seems
> > > > like an odd api in that everyone would have to do gyrations like
> this
> > > in
> > > > order to determine if the netdev is "theirs" or not...
> > >
> > > The scenario is SR-IOV on Hyper-V. In the case of VF device, the
> host
> > > hands the
> > > guest OS a PCI device for the virtual function device. The VF device
> is
> > > placed
> > > on a special synthetic PCI bus (ie not part of the other buses on
> the
> > > system).
> > > The VF device also has a synthetic network interface (netvsc) which
> > > lives
> > > on VMBUS. This code is about managing the interaction between the
> two.
> > >
> > > The association between VF and synthetic NIC is done in response to
> the
> > > VF network device being registered. Initial version was based on MAC
> > > address
> > > which is the same. Later refinement used permanent MAC address to
> > > avoid bugs if MAC address changed. This version is to use serial
> number
> > > instead which is safer than MAC address.
> > >
> > > The code to walk up/down maybe not be needed to find serial number.
> > > Perhaps a more direct single set of conditions is possible?
> > >
> > > Something like:
> > >
> > > In pci-hyperv.c
> > >
> > > u32 hv_pcifront_get_serial(struct pci_bus *bus, unsigned int devfn)
> > > {
> > > struct hv_pcibus_device *hbus
> > > = container_of(bus->sysdata,
> > > struct hv_pcibus_device, sysdata);
> > > struct hf_pci_dev *hpdev;
> > > u32 serial;
> > >
> > > hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn));
> > > if (!hpdev)
> > > return 0;
> > >
> > > serial = hpdev->devs.ser;
> > > put_pcichild(hpdev, hv_pcidev_ref_by_slot);
> > > return serial;
> > > }
> > >
> > > In netvsc_drv.c
> > >
> > > static u32 netvsc_get_vfser(struct net_device *vf_netdev)
> > > {
> > > struct device *dev = vf_netdev->dev.parent;
> > > struct pci_dev *pdev;
> > > u32 wslot;
> > >
> > > if (!dev || !dev_is_pci(dev))
> > > return 0;
> > >
> > > pdev = container_of(dev, struct pci_device, dev);
> > >
> > > return hv_pcifront_get_serial(pdev->bus, pdev->devfn);
> > > }
> > >
> > >
> > >
> > >
> > >
> > > P.S: it would be good to be able to get win_slot out through sysfs
> as
> > > well for systemd/udev.
> >
> > Stephen,
> >
> > Thanks for suggestion. Actually, in my earlier implementation of this
> > feature (VF serial based matching), I thought about export a function
> > from vPCI driver, then calling it from netvsc. So I don't need to
> > move structs between headers... But, it creates a dependency of netvsc
> > on vPCI driver's symbol. So, even if on a VM without SRIOV, we have to
> > load vPCI driver, which we don't want.
> >
> > Also, hv_vpci device is 3 parent layers above the vf_netdevice:
> > Here is the VF drv hierarchy --
> > Should we assume it's always 3 parents above vf_netdevice, or search
> for it?
> >
> > [ 368.185259] HZINFO:NETDEV_REGISTER:
> > [ 368.185261] HZINFO: dev:ffff88007c10d518, bus: (null),
> busName:(null), drvName:(null)
> > [ 368.185262] HZINFO: dev:ffff88007c10c0a0, bus:ffffffff81ce4b60,
> busName:pci, drvName:ixgbevf
> > [ 368.185263] HZINFO: dev:ffff8800355c0000, bus: (null),
> busName:(null), drvName:(null)
> > [ 368.185264] HZINFO: dev:ffff8800355c5428, bus:ffffffffa0008160,
> busName:vmbus, drvName:hv_pci
> > [ 368.185264] HZINFO: dev:ffff88007c49e268, bus:ffffffff81ce9800,
> busName:acpi, drvName:vmbus
> > [ 368.185265] HZINFO: dev:ffff88007c48ea68, bus:ffffffff81ce9800,
> busName:acpi, drvName:(null)
> > [ 368.185266] HZINFO: dev:ffff88007c48aa68, bus:ffffffff81ce9800,
> busName:acpi, drvName:(null)
> > [ 368.185266] HZINFO: dev:ffff88007c48a268, bus:ffffffff81ce9800,
> busName:acpi, drvName:(null)
> > [ 368.185267] HZINFO: dev:ffff88007c489a68, bus:ffffffff81ce9800,
> busName:acpi, drvName:(null)
> >
> > Thanks,
> > - Haiyang
>
> Since this is a synthetic bus, the topology should not change unless
> host side
> software changes. The vf_netdev device has to be PCI device, so that is
> going to
> be certain. After that there maybe intermediate up to hv_pci. The code
> in hyperv-pci
> already has similar stuff (ie for read_config).
Other netdevice, like emulated NIC can also trigger this notification.
They are not vPCI.
Thanks,
- Haiyang
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.kernel
csiph-web