diff options
author | Palik, Imre <imrep@amazon.de> | 2015-06-19 08:21:51 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-07-10 12:49:30 -0400 |
commit | 6fc8b947b364ceb6d91e5b6f3e3d22cd9a013ac0 (patch) | |
tree | 12c5ae56e68ed797941d0db2383fcc8b6be73a65 /drivers/net | |
parent | c31967d447989b85b631dda39487a319df21e03a (diff) |
xen-netback: fix a BUG() during initialization
[ Upstream commit 12b322ac85208de564ecf23aa754d796a91de21f ]
Commit edafc132baac ("xen-netback: making the bandwidth limiter runtime settable")
introduced the capability to change the bandwidth rate limit at runtime.
But it also introduced a possible crashing bug.
If netback receives two XenbusStateConnected without getting the
hotplug-status watch firing in between, then it will try to register the
watches for the rate limiter again. But this triggers a BUG() in the watch
registration code.
The fix modifies connect() to remove the possibly existing packet-rate
watches before trying to install those watches. This behaviour is in line
with how connect() deals with the hotplug-status watch.
Signed-off-by: Imre Palik <imrep@amazon.de>
Cc: Matt Wilson <msw@amazon.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/xen-netback/xenbus.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index 968787abf78d..ec383b0f5443 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c | |||
@@ -681,6 +681,9 @@ static int xen_register_watchers(struct xenbus_device *dev, struct xenvif *vif) | |||
681 | char *node; | 681 | char *node; |
682 | unsigned maxlen = strlen(dev->nodename) + sizeof("/rate"); | 682 | unsigned maxlen = strlen(dev->nodename) + sizeof("/rate"); |
683 | 683 | ||
684 | if (vif->credit_watch.node) | ||
685 | return -EADDRINUSE; | ||
686 | |||
684 | node = kmalloc(maxlen, GFP_KERNEL); | 687 | node = kmalloc(maxlen, GFP_KERNEL); |
685 | if (!node) | 688 | if (!node) |
686 | return -ENOMEM; | 689 | return -ENOMEM; |
@@ -770,6 +773,7 @@ static void connect(struct backend_info *be) | |||
770 | } | 773 | } |
771 | 774 | ||
772 | xen_net_read_rate(dev, &credit_bytes, &credit_usec); | 775 | xen_net_read_rate(dev, &credit_bytes, &credit_usec); |
776 | xen_unregister_watchers(be->vif); | ||
773 | xen_register_watchers(dev, be->vif); | 777 | xen_register_watchers(dev, be->vif); |
774 | read_xenbus_vif_flags(be); | 778 | read_xenbus_vif_flags(be); |
775 | 779 | ||