diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2005-08-31 21:28:59 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-31 22:37:56 -0400 |
commit | abfda4719c61550be4efaf277d4a904a7930d410 (patch) | |
tree | 868c89f3f74f3771a336bca4c9abcbc75e61105c /drivers/net/iseries_veth.c | |
parent | 61a3c6966158dfd9b1279c10ea8eeb3bc7acdef4 (diff) |
[PATCH] iseries_veth: Remove a FIXME WRT deletion of the ack_timer
The iseries_veth driver has a timer which we use to send acks. When the
connection is reset or stopped we need to delete the timer.
Currently we only call del_timer() when resetting a connection, which means
the timer might run again while the connection is being re-setup. As it turns
out that's ok, because the flags the timer consults have been reset.
It's cleaner though to call del_timer_sync() once we've dropped the lock,
although the timer may still run between us dropping the lock and calling
del_timer_sync(), but as above that's ok.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/iseries_veth.c')
-rw-r--r-- | drivers/net/iseries_veth.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index d5b08dc8a9f8..c19b32e0a5ad 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c | |||
@@ -450,13 +450,15 @@ static void veth_statemachine(void *p) | |||
450 | if (cnx->state & VETH_STATE_RESET) { | 450 | if (cnx->state & VETH_STATE_RESET) { |
451 | int i; | 451 | int i; |
452 | 452 | ||
453 | del_timer(&cnx->ack_timer); | ||
454 | |||
455 | if (cnx->state & VETH_STATE_OPEN) | 453 | if (cnx->state & VETH_STATE_OPEN) |
456 | HvCallEvent_closeLpEventPath(cnx->remote_lp, | 454 | HvCallEvent_closeLpEventPath(cnx->remote_lp, |
457 | HvLpEvent_Type_VirtualLan); | 455 | HvLpEvent_Type_VirtualLan); |
458 | 456 | ||
459 | /* reset ack data */ | 457 | /* |
458 | * Reset ack data. This prevents the ack_timer actually | ||
459 | * doing anything, even if it runs one more time when | ||
460 | * we drop the lock below. | ||
461 | */ | ||
460 | memset(&cnx->pending_acks, 0xff, sizeof (cnx->pending_acks)); | 462 | memset(&cnx->pending_acks, 0xff, sizeof (cnx->pending_acks)); |
461 | cnx->num_pending_acks = 0; | 463 | cnx->num_pending_acks = 0; |
462 | 464 | ||
@@ -469,9 +471,16 @@ static void veth_statemachine(void *p) | |||
469 | if (cnx->msgs) | 471 | if (cnx->msgs) |
470 | for (i = 0; i < VETH_NUMBUFFERS; ++i) | 472 | for (i = 0; i < VETH_NUMBUFFERS; ++i) |
471 | veth_recycle_msg(cnx, cnx->msgs + i); | 473 | veth_recycle_msg(cnx, cnx->msgs + i); |
474 | |||
475 | /* Drop the lock so we can do stuff that might sleep or | ||
476 | * take other locks. */ | ||
472 | spin_unlock_irq(&cnx->lock); | 477 | spin_unlock_irq(&cnx->lock); |
478 | |||
479 | del_timer_sync(&cnx->ack_timer); | ||
473 | veth_flush_pending(cnx); | 480 | veth_flush_pending(cnx); |
481 | |||
474 | spin_lock_irq(&cnx->lock); | 482 | spin_lock_irq(&cnx->lock); |
483 | |||
475 | if (cnx->state & VETH_STATE_RESET) | 484 | if (cnx->state & VETH_STATE_RESET) |
476 | goto restart; | 485 | goto restart; |
477 | } | 486 | } |
@@ -658,13 +667,9 @@ static void veth_stop_connection(u8 rlp) | |||
658 | veth_kick_statemachine(cnx); | 667 | veth_kick_statemachine(cnx); |
659 | spin_unlock_irq(&cnx->lock); | 668 | spin_unlock_irq(&cnx->lock); |
660 | 669 | ||
670 | /* Wait for the state machine to run. */ | ||
661 | flush_scheduled_work(); | 671 | flush_scheduled_work(); |
662 | 672 | ||
663 | /* FIXME: not sure if this is necessary - will already have | ||
664 | * been deleted by the state machine, just want to make sure | ||
665 | * its not running any more */ | ||
666 | del_timer_sync(&cnx->ack_timer); | ||
667 | |||
668 | if (cnx->num_events > 0) | 673 | if (cnx->num_events > 0) |
669 | mf_deallocate_lp_events(cnx->remote_lp, | 674 | mf_deallocate_lp_events(cnx->remote_lp, |
670 | HvLpEvent_Type_VirtualLan, | 675 | HvLpEvent_Type_VirtualLan, |