diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-12-14 18:08:48 +0100 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-12-18 20:07:56 +0100 |
commit | 8192edef03f9b47f1cc1120724db525e63e218f3 (patch) | |
tree | 5eac8bda79aefa69b41b9914d256aac4431e3c44 /net/bluetooth/hci_conn.c | |
parent | Bluetooth: convert chan_lock to mutex (diff) | |
download | linux-8192edef03f9b47f1cc1120724db525e63e218f3.tar.xz linux-8192edef03f9b47f1cc1120724db525e63e218f3.zip |
Bluetooth: Use RCU to manipulate chan_list
Instead of using tasklet_disable() to prevent acess to the channel use, we
can use RCU and improve the performance of our code.
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r-- | net/bluetooth/hci_conn.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index e6d8a220b5d9..b04467674a13 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -960,9 +960,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) chan->conn = conn; skb_queue_head_init(&chan->data_q); - tasklet_disable(&hdev->tx_task); - list_add(&conn->chan_list, &chan->list); - tasklet_enable(&hdev->tx_task); + list_add_rcu(&chan->list, &conn->chan_list); return chan; } @@ -974,9 +972,9 @@ int hci_chan_del(struct hci_chan *chan) BT_DBG("%s conn %p chan %p", hdev->name, conn, chan); - tasklet_disable(&hdev->tx_task); - list_del(&chan->list); - tasklet_enable(&hdev->tx_task); + list_del_rcu(&chan->list); + + synchronize_rcu(); skb_queue_purge(&chan->data_q); kfree(chan); @@ -986,10 +984,10 @@ int hci_chan_del(struct hci_chan *chan) void hci_chan_list_flush(struct hci_conn *conn) { - struct hci_chan *chan, *tmp; + struct hci_chan *chan; BT_DBG("conn %p", conn); - list_for_each_entry_safe(chan, tmp, &conn->chan_list, list) + list_for_each_entry_rcu(chan, &conn->chan_list, list) hci_chan_del(chan); } |