diff options
author | Palik, Imre <imrep@amazon.de> | 2015-06-19 14:21:51 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-06-23 12:34:02 +0200 |
commit | 12b322ac85208de564ecf23aa754d796a91de21f (patch) | |
tree | 27923ea28478e5becfc6a226beddee2b9b71cc31 | |
parent | bridge: multicast: restore router configuration on port link down/up (diff) | |
download | linux-12b322ac85208de564ecf23aa754d796a91de21f.tar.xz linux-12b322ac85208de564ecf23aa754d796a91de21f.zip |
xen-netback: fix a BUG() during initialization
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>
-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) char *node; unsigned maxlen = strlen(dev->nodename) + sizeof("/rate"); + if (vif->credit_watch.node) + return -EADDRINUSE; + node = kmalloc(maxlen, GFP_KERNEL); if (!node) return -ENOMEM; @@ -770,6 +773,7 @@ static void connect(struct backend_info *be) } xen_net_read_rate(dev, &credit_bytes, &credit_usec); + xen_unregister_watchers(be->vif); xen_register_watchers(dev, be->vif); read_xenbus_vif_flags(be); |