Commit 1a09bcb97ca1b4eb9a6ea381fbc3beb7a9d2895d
1 parent
c9b6667537
Bluetooth: keep reference if any ERTM timer is enabled
ERTM use the generic L2CAP timer functions to keep a reference to the channel. This is useful for avoiding crashes. Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Showing 2 changed files with 31 additions and 28 deletions Side-by-side Diff
include/net/bluetooth/l2cap.h
... | ... | @@ -441,12 +441,15 @@ |
441 | 441 | |
442 | 442 | #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) |
443 | 443 | #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) |
444 | -#define __mod_retrans_timer() mod_timer(&chan->retrans_timer, \ | |
445 | - jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO)); | |
446 | -#define __mod_monitor_timer() mod_timer(&chan->monitor_timer, \ | |
447 | - jiffies + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO)); | |
448 | -#define __mod_ack_timer() mod_timer(&chan->ack_timer, \ | |
449 | - jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO)); | |
444 | +#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ | |
445 | + L2CAP_DEFAULT_RETRANS_TO); | |
446 | +#define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer) | |
447 | +#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \ | |
448 | + L2CAP_DEFAULT_MONITOR_TO); | |
449 | +#define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer) | |
450 | +#define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \ | |
451 | + L2CAP_DEFAULT_ACK_TO); | |
452 | +#define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) | |
450 | 453 | |
451 | 454 | static inline int l2cap_tx_window_full(struct l2cap_chan *ch) |
452 | 455 | { |
net/bluetooth/l2cap_core.c
... | ... | @@ -389,9 +389,9 @@ |
389 | 389 | if (chan->mode == L2CAP_MODE_ERTM) { |
390 | 390 | struct srej_list *l, *tmp; |
391 | 391 | |
392 | - del_timer(&chan->retrans_timer); | |
393 | - del_timer(&chan->monitor_timer); | |
394 | - del_timer(&chan->ack_timer); | |
392 | + __clear_retrans_timer(chan); | |
393 | + __clear_monitor_timer(chan); | |
394 | + __clear_ack_timer(chan); | |
395 | 395 | |
396 | 396 | skb_queue_purge(&chan->srej_q); |
397 | 397 | skb_queue_purge(&chan->busy_q); |
... | ... | @@ -697,9 +697,9 @@ |
697 | 697 | sk = chan->sk; |
698 | 698 | |
699 | 699 | if (chan->mode == L2CAP_MODE_ERTM) { |
700 | - del_timer(&chan->retrans_timer); | |
701 | - del_timer(&chan->monitor_timer); | |
702 | - del_timer(&chan->ack_timer); | |
700 | + __clear_retrans_timer(chan); | |
701 | + __clear_monitor_timer(chan); | |
702 | + __clear_ack_timer(chan); | |
703 | 703 | } |
704 | 704 | |
705 | 705 | req.dcid = cpu_to_le16(chan->dcid); |
... | ... | @@ -1177,7 +1177,7 @@ |
1177 | 1177 | } |
1178 | 1178 | |
1179 | 1179 | chan->retry_count++; |
1180 | - __mod_monitor_timer(); | |
1180 | + __set_monitor_timer(chan); | |
1181 | 1181 | |
1182 | 1182 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); |
1183 | 1183 | bh_unlock_sock(sk); |
... | ... | @@ -1192,7 +1192,7 @@ |
1192 | 1192 | |
1193 | 1193 | bh_lock_sock(sk); |
1194 | 1194 | chan->retry_count = 1; |
1195 | - __mod_monitor_timer(); | |
1195 | + __set_monitor_timer(chan); | |
1196 | 1196 | |
1197 | 1197 | chan->conn_state |= L2CAP_CONN_WAIT_F; |
1198 | 1198 | |
... | ... | @@ -1216,7 +1216,7 @@ |
1216 | 1216 | } |
1217 | 1217 | |
1218 | 1218 | if (!chan->unacked_frames) |
1219 | - del_timer(&chan->retrans_timer); | |
1219 | + __clear_retrans_timer(chan); | |
1220 | 1220 | } |
1221 | 1221 | |
1222 | 1222 | void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) |
... | ... | @@ -1343,7 +1343,7 @@ |
1343 | 1343 | |
1344 | 1344 | l2cap_do_send(chan, tx_skb); |
1345 | 1345 | |
1346 | - __mod_retrans_timer(); | |
1346 | + __set_retrans_timer(chan); | |
1347 | 1347 | |
1348 | 1348 | bt_cb(skb)->tx_seq = chan->next_tx_seq; |
1349 | 1349 | chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; |
... | ... | @@ -3260,8 +3260,8 @@ |
3260 | 3260 | l2cap_send_sframe(chan, control); |
3261 | 3261 | chan->retry_count = 1; |
3262 | 3262 | |
3263 | - del_timer(&chan->retrans_timer); | |
3264 | - __mod_monitor_timer(); | |
3263 | + __clear_retrans_timer(chan); | |
3264 | + __set_monitor_timer(chan); | |
3265 | 3265 | |
3266 | 3266 | chan->conn_state |= L2CAP_CONN_WAIT_F; |
3267 | 3267 | |
... | ... | @@ -3352,7 +3352,7 @@ |
3352 | 3352 | |
3353 | 3353 | chan->conn_state |= L2CAP_CONN_RNR_SENT; |
3354 | 3354 | |
3355 | - del_timer(&chan->ack_timer); | |
3355 | + __clear_ack_timer(chan); | |
3356 | 3356 | |
3357 | 3357 | queue_work(_busy_wq, &chan->busy_work); |
3358 | 3358 | |
3359 | 3359 | |
... | ... | @@ -3521,9 +3521,9 @@ |
3521 | 3521 | |
3522 | 3522 | if (L2CAP_CTRL_FINAL & rx_control && |
3523 | 3523 | chan->conn_state & L2CAP_CONN_WAIT_F) { |
3524 | - del_timer(&chan->monitor_timer); | |
3524 | + __clear_monitor_timer(chan); | |
3525 | 3525 | if (chan->unacked_frames > 0) |
3526 | - __mod_retrans_timer(); | |
3526 | + __set_retrans_timer(chan); | |
3527 | 3527 | chan->conn_state &= ~L2CAP_CONN_WAIT_F; |
3528 | 3528 | } |
3529 | 3529 | |
... | ... | @@ -3604,7 +3604,7 @@ |
3604 | 3604 | |
3605 | 3605 | l2cap_send_srejframe(chan, tx_seq); |
3606 | 3606 | |
3607 | - del_timer(&chan->ack_timer); | |
3607 | + __clear_ack_timer(chan); | |
3608 | 3608 | } |
3609 | 3609 | return 0; |
3610 | 3610 | |
... | ... | @@ -3629,7 +3629,7 @@ |
3629 | 3629 | l2cap_retransmit_frames(chan); |
3630 | 3630 | } |
3631 | 3631 | |
3632 | - __mod_ack_timer(); | |
3632 | + __set_ack_timer(chan); | |
3633 | 3633 | |
3634 | 3634 | chan->num_acked = (chan->num_acked + 1) % num_to_ack; |
3635 | 3635 | if (chan->num_acked == num_to_ack - 1) |
... | ... | @@ -3655,7 +3655,7 @@ |
3655 | 3655 | if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { |
3656 | 3656 | if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && |
3657 | 3657 | (chan->unacked_frames > 0)) |
3658 | - __mod_retrans_timer(); | |
3658 | + __set_retrans_timer(chan); | |
3659 | 3659 | |
3660 | 3660 | chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; |
3661 | 3661 | l2cap_send_srejtail(chan); |
... | ... | @@ -3674,7 +3674,7 @@ |
3674 | 3674 | } else { |
3675 | 3675 | if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && |
3676 | 3676 | (chan->unacked_frames > 0)) |
3677 | - __mod_retrans_timer(); | |
3677 | + __set_retrans_timer(chan); | |
3678 | 3678 | |
3679 | 3679 | chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; |
3680 | 3680 | if (chan->conn_state & L2CAP_CONN_SREJ_SENT) |
... | ... | @@ -3757,7 +3757,7 @@ |
3757 | 3757 | chan->conn_state |= L2CAP_CONN_SEND_FBIT; |
3758 | 3758 | |
3759 | 3759 | if (!(chan->conn_state & L2CAP_CONN_SREJ_SENT)) { |
3760 | - del_timer(&chan->retrans_timer); | |
3760 | + __clear_retrans_timer(chan); | |
3761 | 3761 | if (rx_control & L2CAP_CTRL_POLL) |
3762 | 3762 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL); |
3763 | 3763 | return; |
3764 | 3764 | |
... | ... | @@ -3775,9 +3775,9 @@ |
3775 | 3775 | |
3776 | 3776 | if (L2CAP_CTRL_FINAL & rx_control && |
3777 | 3777 | chan->conn_state & L2CAP_CONN_WAIT_F) { |
3778 | - del_timer(&chan->monitor_timer); | |
3778 | + __clear_monitor_timer(chan); | |
3779 | 3779 | if (chan->unacked_frames > 0) |
3780 | - __mod_retrans_timer(); | |
3780 | + __set_retrans_timer(chan); | |
3781 | 3781 | chan->conn_state &= ~L2CAP_CONN_WAIT_F; |
3782 | 3782 | } |
3783 | 3783 |