aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2011-06-23 18:29:58 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-12-18 14:07:55 -0500
commit721c41812daf7b38759942563773a7832e3c990d (patch)
tree8a0ab0aee4b619b91e9e68daca1a1369d29ab18d
parentb9cc553f12d14b692d0fcb607d28db783da68139 (diff)
Bluetooth: Move L2CAP timers to workqueue
L2CAP timers also need to run in process context. As the works in l2cap are small we are using the system worqueue. Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r--include/net/bluetooth/l2cap.h17
-rw-r--r--net/bluetooth/l2cap_core.c70
2 files changed, 40 insertions, 47 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 30719eb2e77c..03be9111dc51 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -482,10 +482,11 @@ struct l2cap_chan {
482 __u32 remote_acc_lat; 482 __u32 remote_acc_lat;
483 __u32 remote_flush_to; 483 __u32 remote_flush_to;
484 484
485 struct timer_list chan_timer; 485 struct delayed_work chan_timer;
486 struct timer_list retrans_timer; 486 struct delayed_work retrans_timer;
487 struct timer_list monitor_timer; 487 struct delayed_work monitor_timer;
488 struct timer_list ack_timer; 488 struct delayed_work ack_timer;
489
489 struct sk_buff *tx_send_head; 490 struct sk_buff *tx_send_head;
490 struct sk_buff_head tx_q; 491 struct sk_buff_head tx_q;
491 struct sk_buff_head srej_q; 492 struct sk_buff_head srej_q;
@@ -595,16 +596,16 @@ enum {
595}; 596};
596 597
597#define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) 598#define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
598#define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) 599#define __clear_chan_timer(c) l2cap_clear_timer(&c->chan_timer)
599#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ 600#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \
600 L2CAP_DEFAULT_RETRANS_TO); 601 L2CAP_DEFAULT_RETRANS_TO);
601#define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer) 602#define __clear_retrans_timer(c) l2cap_clear_timer(&c->retrans_timer)
602#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \ 603#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \
603 L2CAP_DEFAULT_MONITOR_TO); 604 L2CAP_DEFAULT_MONITOR_TO);
604#define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer) 605#define __clear_monitor_timer(c) l2cap_clear_timer(&c->monitor_timer)
605#define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \ 606#define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \
606 L2CAP_DEFAULT_ACK_TO); 607 L2CAP_DEFAULT_ACK_TO);
607#define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) 608#define __clear_ack_timer(c) l2cap_clear_timer(&c->ack_timer)
608 609
609static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2) 610static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
610{ 611{
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 0369a9bf60c6..89cda6d82d0c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -213,20 +213,18 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
213 return 0; 213 return 0;
214} 214}
215 215
216static void l2cap_set_timer(struct l2cap_chan *chan, struct timer_list *timer, long timeout) 216static void l2cap_set_timer(struct l2cap_chan *chan, struct delayed_work *work, long timeout)
217{ 217{
218 BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout); 218 BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout);
219 219
220 if (!mod_timer(timer, jiffies + msecs_to_jiffies(timeout))) 220 cancel_delayed_work_sync(work);
221 chan_hold(chan); 221
222 schedule_delayed_work(work, timeout);
222} 223}
223 224
224static void l2cap_clear_timer(struct l2cap_chan *chan, struct timer_list *timer) 225static void l2cap_clear_timer(struct delayed_work *work)
225{ 226{
226 BT_DBG("chan %p state %d", chan, chan->state); 227 cancel_delayed_work_sync(work);
227
228 if (timer_pending(timer) && del_timer(timer))
229 chan_put(chan);
230} 228}
231 229
232static char *state_to_string(int state) 230static char *state_to_string(int state)
@@ -264,23 +262,16 @@ static void l2cap_state_change(struct l2cap_chan *chan, int state)
264 chan->ops->state_change(chan->data, state); 262 chan->ops->state_change(chan->data, state);
265} 263}
266 264
267static void l2cap_chan_timeout(unsigned long arg) 265static void l2cap_chan_timeout(struct work_struct *work)
268{ 266{
269 struct l2cap_chan *chan = (struct l2cap_chan *) arg; 267 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
268 chan_timer.work);
270 struct sock *sk = chan->sk; 269 struct sock *sk = chan->sk;
271 int reason; 270 int reason;
272 271
273 BT_DBG("chan %p state %d", chan, chan->state); 272 BT_DBG("chan %p state %d", chan, chan->state);
274 273
275 bh_lock_sock(sk); 274 lock_sock(sk);
276
277 if (sock_owned_by_user(sk)) {
278 /* sk is owned by user. Try again later */
279 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
280 bh_unlock_sock(sk);
281 chan_put(chan);
282 return;
283 }
284 275
285 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG) 276 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
286 reason = ECONNREFUSED; 277 reason = ECONNREFUSED;
@@ -292,7 +283,7 @@ static void l2cap_chan_timeout(unsigned long arg)
292 283
293 l2cap_chan_close(chan, reason); 284 l2cap_chan_close(chan, reason);
294 285
295 bh_unlock_sock(sk); 286 release_sock(sk);
296 287
297 chan->ops->close(chan->data); 288 chan->ops->close(chan->data);
298 chan_put(chan); 289 chan_put(chan);
@@ -312,7 +303,7 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk)
312 list_add(&chan->global_l, &chan_list); 303 list_add(&chan->global_l, &chan_list);
313 write_unlock_bh(&chan_list_lock); 304 write_unlock_bh(&chan_list_lock);
314 305
315 setup_timer(&chan->chan_timer, l2cap_chan_timeout, (unsigned long) chan); 306 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
316 307
317 chan->state = BT_OPEN; 308 chan->state = BT_OPEN;
318 309
@@ -1251,17 +1242,18 @@ int __l2cap_wait_ack(struct sock *sk)
1251 return err; 1242 return err;
1252} 1243}
1253 1244
1254static void l2cap_monitor_timeout(unsigned long arg) 1245static void l2cap_monitor_timeout(struct work_struct *work)
1255{ 1246{
1256 struct l2cap_chan *chan = (void *) arg; 1247 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
1248 monitor_timer.work);
1257 struct sock *sk = chan->sk; 1249 struct sock *sk = chan->sk;
1258 1250
1259 BT_DBG("chan %p", chan); 1251 BT_DBG("chan %p", chan);
1260 1252
1261 bh_lock_sock(sk); 1253 lock_sock(sk);
1262 if (chan->retry_count >= chan->remote_max_tx) { 1254 if (chan->retry_count >= chan->remote_max_tx) {
1263 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); 1255 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
1264 bh_unlock_sock(sk); 1256 release_sock(sk);
1265 return; 1257 return;
1266 } 1258 }
1267 1259
@@ -1269,24 +1261,25 @@ static void l2cap_monitor_timeout(unsigned long arg)
1269 __set_monitor_timer(chan); 1261 __set_monitor_timer(chan);
1270 1262
1271 l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); 1263 l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
1272 bh_unlock_sock(sk); 1264 release_sock(sk);
1273} 1265}
1274 1266
1275static void l2cap_retrans_timeout(unsigned long arg) 1267static void l2cap_retrans_timeout(struct work_struct *work)
1276{ 1268{
1277 struct l2cap_chan *chan = (void *) arg; 1269 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
1270 retrans_timer.work);
1278 struct sock *sk = chan->sk; 1271 struct sock *sk = chan->sk;
1279 1272
1280 BT_DBG("chan %p", chan); 1273 BT_DBG("chan %p", chan);
1281 1274
1282 bh_lock_sock(sk); 1275 lock_sock(sk);
1283 chan->retry_count = 1; 1276 chan->retry_count = 1;
1284 __set_monitor_timer(chan); 1277 __set_monitor_timer(chan);
1285 1278
1286 set_bit(CONN_WAIT_F, &chan->conn_state); 1279 set_bit(CONN_WAIT_F, &chan->conn_state);
1287 1280
1288 l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); 1281 l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
1289 bh_unlock_sock(sk); 1282 release_sock(sk);
1290} 1283}
1291 1284
1292static void l2cap_drop_acked_frames(struct l2cap_chan *chan) 1285static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
@@ -1955,13 +1948,14 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
1955 (unsigned long) &efs); 1948 (unsigned long) &efs);
1956} 1949}
1957 1950
1958static void l2cap_ack_timeout(unsigned long arg) 1951static void l2cap_ack_timeout(struct work_struct *work)
1959{ 1952{
1960 struct l2cap_chan *chan = (void *) arg; 1953 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
1954 ack_timer.work);
1961 1955
1962 bh_lock_sock(chan->sk); 1956 lock_sock(chan->sk);
1963 l2cap_send_ack(chan); 1957 l2cap_send_ack(chan);
1964 bh_unlock_sock(chan->sk); 1958 release_sock(chan->sk);
1965} 1959}
1966 1960
1967static inline void l2cap_ertm_init(struct l2cap_chan *chan) 1961static inline void l2cap_ertm_init(struct l2cap_chan *chan)
@@ -1974,11 +1968,9 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan)
1974 chan->num_acked = 0; 1968 chan->num_acked = 0;
1975 chan->frames_sent = 0; 1969 chan->frames_sent = 0;
1976 1970
1977 setup_timer(&chan->retrans_timer, l2cap_retrans_timeout, 1971 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
1978 (unsigned long) chan); 1972 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
1979 setup_timer(&chan->monitor_timer, l2cap_monitor_timeout, 1973 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
1980 (unsigned long) chan);
1981 setup_timer(&chan->ack_timer, l2cap_ack_timeout, (unsigned long) chan);
1982 1974
1983 skb_queue_head_init(&chan->srej_q); 1975 skb_queue_head_init(&chan->srej_q);
1984 1976