diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2005-09-01 11:28:59 +1000 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-31 22:37:56 -0400 |
commit | abfda4719c61550be4efaf277d4a904a7930d410 (patch) | |
tree | 868c89f3f74f3771a336bca4c9abcbc75e61105c | |
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>
-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 d5b08dc8a9f..c19b32e0a5a 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -450,13 +450,15 @@ static void veth_statemachine(void *p) if (cnx->state & VETH_STATE_RESET) { int i; - del_timer(&cnx->ack_timer); - if (cnx->state & VETH_STATE_OPEN) HvCallEvent_closeLpEventPath(cnx->remote_lp, HvLpEvent_Type_VirtualLan); - /* reset ack data */ + /* + * Reset ack data. This prevents the ack_timer actually + * doing anything, even if it runs one more time when + * we drop the lock below. + */ memset(&cnx->pending_acks, 0xff, sizeof (cnx->pending_acks)); cnx->num_pending_acks = 0; @@ -469,9 +471,16 @@ static void veth_statemachine(void *p) if (cnx->msgs) for (i = 0; i < VETH_NUMBUFFERS; ++i) veth_recycle_msg(cnx, cnx->msgs + i); + + /* Drop the lock so we can do stuff that might sleep or + * take other locks. */ spin_unlock_irq(&cnx->lock); + + del_timer_sync(&cnx->ack_timer); veth_flush_pending(cnx); + spin_lock_irq(&cnx->lock); + if (cnx->state & VETH_STATE_RESET) goto restart; } @@ -658,13 +667,9 @@ static void veth_stop_connection(u8 rlp) veth_kick_statemachine(cnx); spin_unlock_irq(&cnx->lock); + /* Wait for the state machine to run. */ flush_scheduled_work(); - /* FIXME: not sure if this is necessary - will already have - * been deleted by the state machine, just want to make sure - * its not running any more */ - del_timer_sync(&cnx->ack_timer); - if (cnx->num_events > 0) mf_deallocate_lp_events(cnx->remote_lp, HvLpEvent_Type_VirtualLan, |