diff options
author | Filipe Manco <filipe.manco@neclab.eu> | 2016-09-15 11:10:46 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-09-17 09:56:02 -0400 |
commit | cce94483e47e8e3d74cf4475dea33f9fd4b6ad9f (patch) | |
tree | 319883b04cf525b1ab41a6dd6d3f1f5df97443ec /drivers/net/xen-netback | |
parent | 4253ef8f6f81405e65304eef5a5b182c32dec915 (diff) |
xen-netback: fix error handling on netback_probe()
In case of error during netback_probe() (e.g. an entry missing on the
xenstore) netback_remove() is called on the new device, which will set
the device backend state to XenbusStateClosed by calling
set_backend_state(). However, the backend state wasn't initialized by
netback_probe() at this point, which will cause and invalid transaction
and set_backend_state() to BUG().
Initialize the backend state at the beginning of netback_probe() to
XenbusStateInitialising, and create two new valid state transitions on
set_backend_state(), from XenbusStateInitialising to XenbusStateClosed,
and from XenbusStateInitialising to XenbusStateInitWait.
Signed-off-by: Filipe Manco <filipe.manco@neclab.eu>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/xen-netback')
-rw-r--r-- | drivers/net/xen-netback/xenbus.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index 6a31f2610c23..daf4c7867102 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c | |||
@@ -271,6 +271,11 @@ static int netback_probe(struct xenbus_device *dev, | |||
271 | be->dev = dev; | 271 | be->dev = dev; |
272 | dev_set_drvdata(&dev->dev, be); | 272 | dev_set_drvdata(&dev->dev, be); |
273 | 273 | ||
274 | be->state = XenbusStateInitialising; | ||
275 | err = xenbus_switch_state(dev, XenbusStateInitialising); | ||
276 | if (err) | ||
277 | goto fail; | ||
278 | |||
274 | sg = 1; | 279 | sg = 1; |
275 | 280 | ||
276 | do { | 281 | do { |
@@ -383,11 +388,6 @@ static int netback_probe(struct xenbus_device *dev, | |||
383 | 388 | ||
384 | be->hotplug_script = script; | 389 | be->hotplug_script = script; |
385 | 390 | ||
386 | err = xenbus_switch_state(dev, XenbusStateInitWait); | ||
387 | if (err) | ||
388 | goto fail; | ||
389 | |||
390 | be->state = XenbusStateInitWait; | ||
391 | 391 | ||
392 | /* This kicks hotplug scripts, so do it immediately. */ | 392 | /* This kicks hotplug scripts, so do it immediately. */ |
393 | err = backend_create_xenvif(be); | 393 | err = backend_create_xenvif(be); |
@@ -492,20 +492,20 @@ static inline void backend_switch_state(struct backend_info *be, | |||
492 | 492 | ||
493 | /* Handle backend state transitions: | 493 | /* Handle backend state transitions: |
494 | * | 494 | * |
495 | * The backend state starts in InitWait and the following transitions are | 495 | * The backend state starts in Initialising and the following transitions are |
496 | * allowed. | 496 | * allowed. |
497 | * | 497 | * |
498 | * InitWait -> Connected | 498 | * Initialising -> InitWait -> Connected |
499 | * | 499 | * \ |
500 | * ^ \ | | 500 | * \ ^ \ | |
501 | * | \ | | 501 | * \ | \ | |
502 | * | \ | | 502 | * \ | \ | |
503 | * | \ | | 503 | * \ | \ | |
504 | * | \ | | 504 | * \ | \ | |
505 | * | \ | | 505 | * \ | \ | |
506 | * | V V | 506 | * V | V V |
507 | * | 507 | * |
508 | * Closed <-> Closing | 508 | * Closed <-> Closing |
509 | * | 509 | * |
510 | * The state argument specifies the eventual state of the backend and the | 510 | * The state argument specifies the eventual state of the backend and the |
511 | * function transitions to that state via the shortest path. | 511 | * function transitions to that state via the shortest path. |
@@ -515,6 +515,20 @@ static void set_backend_state(struct backend_info *be, | |||
515 | { | 515 | { |
516 | while (be->state != state) { | 516 | while (be->state != state) { |
517 | switch (be->state) { | 517 | switch (be->state) { |
518 | case XenbusStateInitialising: | ||
519 | switch (state) { | ||
520 | case XenbusStateInitWait: | ||
521 | case XenbusStateConnected: | ||
522 | case XenbusStateClosing: | ||
523 | backend_switch_state(be, XenbusStateInitWait); | ||
524 | break; | ||
525 | case XenbusStateClosed: | ||
526 | backend_switch_state(be, XenbusStateClosed); | ||
527 | break; | ||
528 | default: | ||
529 | BUG(); | ||
530 | } | ||
531 | break; | ||
518 | case XenbusStateClosed: | 532 | case XenbusStateClosed: |
519 | switch (state) { | 533 | switch (state) { |
520 | case XenbusStateInitWait: | 534 | case XenbusStateInitWait: |