diff options
Diffstat (limited to 'net/sctp/sm_sideeffect.c')
| -rw-r--r-- | net/sctp/sm_sideeffect.c | 14 | 
1 files changed, 11 insertions, 3 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 2bc29463e1dc..9f36fe911d08 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -1523,9 +1523,17 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type,  			timeout = asoc->timeouts[cmd->obj.to];  			BUG_ON(!timeout); -			timer->expires = jiffies + timeout; -			sctp_association_hold(asoc); -			add_timer(timer); +			/* +			 * SCTP has a hard time with timer starts.  Because we process +			 * timer starts as side effects, it can be hard to tell if we +			 * have already started a timer or not, which leads to BUG +			 * halts when we call add_timer. So here, instead of just starting +			 * a timer, if the timer is already started, and just mod +			 * the timer with the shorter of the two expiration times +			 */ +			if (!timer_pending(timer)) +				sctp_association_hold(asoc); +			timer_reduce(timer, jiffies + timeout);  			break;  		case SCTP_CMD_TIMER_RESTART:  | 
