From: "Gustavo F. Padovan" <padovan@profusion.mobi>
To: linux-bluetooth@vger.kernel.org
Cc: "Gustavo F. Padovan" <padovan@profusion.mobi>
Subject: [RFC 06/22] Bluetooth: Move L2CAP timers to workqueue
Date: Sat, 17 Dec 2011 19:29:26 -0200 [thread overview]
Message-ID: <1324157382-1815-7-git-send-email-padovan@profusion.mobi> (raw)
In-Reply-To: <1324157382-1815-6-git-send-email-padovan@profusion.mobi>
From: "Gustavo F. Padovan" <padovan@profusion.mobi>
L2CAP timers also need to run in process context. As the works in l2cap
are small we are using the system worqueue.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 17 +++++-----
net/bluetooth/l2cap_core.c | 70 ++++++++++++++++++-----------------------
2 files changed, 40 insertions(+), 47 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 30719eb..03be911 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -482,10 +482,11 @@ struct l2cap_chan {
__u32 remote_acc_lat;
__u32 remote_flush_to;
- struct timer_list chan_timer;
- struct timer_list retrans_timer;
- struct timer_list monitor_timer;
- struct timer_list ack_timer;
+ struct delayed_work chan_timer;
+ struct delayed_work retrans_timer;
+ struct delayed_work monitor_timer;
+ struct delayed_work ack_timer;
+
struct sk_buff *tx_send_head;
struct sk_buff_head tx_q;
struct sk_buff_head srej_q;
@@ -595,16 +596,16 @@ enum {
};
#define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
-#define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer)
+#define __clear_chan_timer(c) l2cap_clear_timer(&c->chan_timer)
#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \
L2CAP_DEFAULT_RETRANS_TO);
-#define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer)
+#define __clear_retrans_timer(c) l2cap_clear_timer(&c->retrans_timer)
#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \
L2CAP_DEFAULT_MONITOR_TO);
-#define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer)
+#define __clear_monitor_timer(c) l2cap_clear_timer(&c->monitor_timer)
#define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \
L2CAP_DEFAULT_ACK_TO);
-#define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer)
+#define __clear_ack_timer(c) l2cap_clear_timer(&c->ack_timer)
static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
{
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 0369a9b..89cda6d 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)
return 0;
}
-static void l2cap_set_timer(struct l2cap_chan *chan, struct timer_list *timer, long timeout)
+static void l2cap_set_timer(struct l2cap_chan *chan, struct delayed_work *work, long timeout)
{
BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout);
- if (!mod_timer(timer, jiffies + msecs_to_jiffies(timeout)))
- chan_hold(chan);
+ cancel_delayed_work_sync(work);
+
+ schedule_delayed_work(work, timeout);
}
-static void l2cap_clear_timer(struct l2cap_chan *chan, struct timer_list *timer)
+static void l2cap_clear_timer(struct delayed_work *work)
{
- BT_DBG("chan %p state %d", chan, chan->state);
-
- if (timer_pending(timer) && del_timer(timer))
- chan_put(chan);
+ cancel_delayed_work_sync(work);
}
static char *state_to_string(int state)
@@ -264,23 +262,16 @@ static void l2cap_state_change(struct l2cap_chan *chan, int state)
chan->ops->state_change(chan->data, state);
}
-static void l2cap_chan_timeout(unsigned long arg)
+static void l2cap_chan_timeout(struct work_struct *work)
{
- struct l2cap_chan *chan = (struct l2cap_chan *) arg;
+ struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
+ chan_timer.work);
struct sock *sk = chan->sk;
int reason;
BT_DBG("chan %p state %d", chan, chan->state);
- bh_lock_sock(sk);
-
- if (sock_owned_by_user(sk)) {
- /* sk is owned by user. Try again later */
- __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
- bh_unlock_sock(sk);
- chan_put(chan);
- return;
- }
+ lock_sock(sk);
if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
reason = ECONNREFUSED;
@@ -292,7 +283,7 @@ static void l2cap_chan_timeout(unsigned long arg)
l2cap_chan_close(chan, reason);
- bh_unlock_sock(sk);
+ release_sock(sk);
chan->ops->close(chan->data);
chan_put(chan);
@@ -312,7 +303,7 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk)
list_add(&chan->global_l, &chan_list);
write_unlock_bh(&chan_list_lock);
- setup_timer(&chan->chan_timer, l2cap_chan_timeout, (unsigned long) chan);
+ INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
chan->state = BT_OPEN;
@@ -1251,17 +1242,18 @@ int __l2cap_wait_ack(struct sock *sk)
return err;
}
-static void l2cap_monitor_timeout(unsigned long arg)
+static void l2cap_monitor_timeout(struct work_struct *work)
{
- struct l2cap_chan *chan = (void *) arg;
+ struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
+ monitor_timer.work);
struct sock *sk = chan->sk;
BT_DBG("chan %p", chan);
- bh_lock_sock(sk);
+ lock_sock(sk);
if (chan->retry_count >= chan->remote_max_tx) {
l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
- bh_unlock_sock(sk);
+ release_sock(sk);
return;
}
@@ -1269,24 +1261,25 @@ static void l2cap_monitor_timeout(unsigned long arg)
__set_monitor_timer(chan);
l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
- bh_unlock_sock(sk);
+ release_sock(sk);
}
-static void l2cap_retrans_timeout(unsigned long arg)
+static void l2cap_retrans_timeout(struct work_struct *work)
{
- struct l2cap_chan *chan = (void *) arg;
+ struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
+ retrans_timer.work);
struct sock *sk = chan->sk;
BT_DBG("chan %p", chan);
- bh_lock_sock(sk);
+ lock_sock(sk);
chan->retry_count = 1;
__set_monitor_timer(chan);
set_bit(CONN_WAIT_F, &chan->conn_state);
l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
- bh_unlock_sock(sk);
+ release_sock(sk);
}
static 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)
(unsigned long) &efs);
}
-static void l2cap_ack_timeout(unsigned long arg)
+static void l2cap_ack_timeout(struct work_struct *work)
{
- struct l2cap_chan *chan = (void *) arg;
+ struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
+ ack_timer.work);
- bh_lock_sock(chan->sk);
+ lock_sock(chan->sk);
l2cap_send_ack(chan);
- bh_unlock_sock(chan->sk);
+ release_sock(chan->sk);
}
static inline void l2cap_ertm_init(struct l2cap_chan *chan)
@@ -1974,11 +1968,9 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan)
chan->num_acked = 0;
chan->frames_sent = 0;
- setup_timer(&chan->retrans_timer, l2cap_retrans_timeout,
- (unsigned long) chan);
- setup_timer(&chan->monitor_timer, l2cap_monitor_timeout,
- (unsigned long) chan);
- setup_timer(&chan->ack_timer, l2cap_ack_timeout, (unsigned long) chan);
+ INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
+ INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
+ INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
skb_queue_head_init(&chan->srej_q);
--
1.7.6.4
next prev parent reply other threads:[~2011-12-17 21:29 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-17 21:29 [RFC 00/22] Bluetooth: change tasklets to workqueue Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 01/22] Bluetooth: Process recv path in a workqueue instead of a tasklet Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 02/22] Bluetooth: Replace spin_lock by mutex in hci_dev Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 03/22] Bluetooth: Use delayed_work for connection timeout Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 04/22] Bluetooth: Use delayed work for advertisiment cache timeout Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 05/22] Bluetooth: hci_conn_auto_accept() doesn't need locking Gustavo F. Padovan
2011-12-17 21:29 ` Gustavo F. Padovan [this message]
2011-12-17 21:29 ` [RFC 07/22] Bluetooth: Don't use spin_lock socket lock anymore Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 08/22] Bluetooth: Remove sk_backlog usage from L2CAP Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 09/22] Bluetooth: move hci_task_lock to mutex Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 10/22] Bluetooth: convert chan_lock " Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 11/22] Bluetooth: Use RCU to manipulate chan_list Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 12/22] Bluetooth: convert conn hash to RCU Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 13/22] Bluetooth: Don't disable tasklets to call hdev->notify() Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 14/22] Bluetooth: Move command task to workqueue Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 15/22] Bluetooth: convert tx_task " Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 16/22] Bluetooth: convert info timer to delayed_work Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 17/22] Bluetooth: remove power_on work_struct Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 18/22] Bluetooth: invert locking order in connect path Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 19/22] Bluetooth: Change l2cap chan_list to use RCU Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 20/22] Bluetooth: move power_off to system workqueue Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 21/22] Bluetooth: Use new alloc_workqueue() Gustavo F. Padovan
2011-12-17 21:29 ` [RFC 22/22] Bluetooth: Remove work_add and work_del from hci_sysfs Gustavo F. Padovan
2011-12-17 22:15 ` [RFC 19/22] Bluetooth: Change l2cap chan_list to use RCU Marcel Holtmann
2011-12-19 10:42 ` Andrei Emeltchenko
2011-12-19 13:53 ` Gustavo Padovan
2011-12-17 22:13 ` [RFC 17/22] Bluetooth: remove power_on work_struct Marcel Holtmann
2012-01-26 13:20 ` [RFC 11/22] Bluetooth: Use RCU to manipulate chan_list Andrei Emeltchenko
2011-12-19 9:58 ` [RFC 10/22] Bluetooth: convert chan_lock to mutex Andrei Emeltchenko
2011-12-19 9:53 ` [RFC 07/22] Bluetooth: Don't use spin_lock socket lock anymore Andrei Emeltchenko
2011-12-19 11:05 ` [RFC 06/22] Bluetooth: Move L2CAP timers to workqueue Andrei Emeltchenko
2011-12-19 12:59 ` Ulisses Furquim
2011-12-17 21:34 ` [RFC 00/22] Bluetooth: change tasklets " Gustavo Padovan
2011-12-17 22:17 ` Marcel Holtmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1324157382-1815-7-git-send-email-padovan@profusion.mobi \
--to=padovan@profusion.mobi \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).