diff options
author | Ulisses Furquim <ulisses@profusion.mobi> | 2011-12-20 14:10:51 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-12-20 23:19:18 -0500 |
commit | f2d64f6aa6c681ca00a71c2b3304ed80dc317752 (patch) | |
tree | 9963338b8b8f6e3519e6e08e334fca91268e8184 /net/bluetooth | |
parent | fa0fb93f2ac308a76fa64eb57c18511dadf97089 (diff) |
Bluetooth: Remove global mutex hci_task_lock
The hci_task_lock mutex (previously a lock) was supposed to protect the
register/unregister of HCI protocols against RX/TX tasks. This will not
be needed anymore because SCO and L2CAP will always be compiled.
Moreover, with the recent move of RX/TX to workqueues per device the
global hci_task_lock was causing starvation between different HCI
devices.
Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_core.c | 21 |
1 files changed, 1 insertions, 20 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 884eb85a136a..fea8dad72e3a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -61,8 +61,6 @@ static void hci_rx_work(struct work_struct *work); | |||
61 | static void hci_cmd_work(struct work_struct *work); | 61 | static void hci_cmd_work(struct work_struct *work); |
62 | static void hci_tx_work(struct work_struct *work); | 62 | static void hci_tx_work(struct work_struct *work); |
63 | 63 | ||
64 | static DEFINE_MUTEX(hci_task_lock); | ||
65 | |||
66 | /* HCI device list */ | 64 | /* HCI device list */ |
67 | LIST_HEAD(hci_dev_list); | 65 | LIST_HEAD(hci_dev_list); |
68 | DEFINE_RWLOCK(hci_dev_list_lock); | 66 | DEFINE_RWLOCK(hci_dev_list_lock); |
@@ -1832,8 +1830,7 @@ EXPORT_SYMBOL(hci_recv_stream_fragment); | |||
1832 | 1830 | ||
1833 | /* ---- Interface to upper protocols ---- */ | 1831 | /* ---- Interface to upper protocols ---- */ |
1834 | 1832 | ||
1835 | /* Register/Unregister protocols. | 1833 | /* Register/Unregister protocols. */ |
1836 | * hci_task_lock is used to ensure that no tasks are running. */ | ||
1837 | int hci_register_proto(struct hci_proto *hp) | 1834 | int hci_register_proto(struct hci_proto *hp) |
1838 | { | 1835 | { |
1839 | int err = 0; | 1836 | int err = 0; |
@@ -1843,15 +1840,11 @@ int hci_register_proto(struct hci_proto *hp) | |||
1843 | if (hp->id >= HCI_MAX_PROTO) | 1840 | if (hp->id >= HCI_MAX_PROTO) |
1844 | return -EINVAL; | 1841 | return -EINVAL; |
1845 | 1842 | ||
1846 | mutex_lock(&hci_task_lock); | ||
1847 | |||
1848 | if (!hci_proto[hp->id]) | 1843 | if (!hci_proto[hp->id]) |
1849 | hci_proto[hp->id] = hp; | 1844 | hci_proto[hp->id] = hp; |
1850 | else | 1845 | else |
1851 | err = -EEXIST; | 1846 | err = -EEXIST; |
1852 | 1847 | ||
1853 | mutex_unlock(&hci_task_lock); | ||
1854 | |||
1855 | return err; | 1848 | return err; |
1856 | } | 1849 | } |
1857 | EXPORT_SYMBOL(hci_register_proto); | 1850 | EXPORT_SYMBOL(hci_register_proto); |
@@ -1865,15 +1858,11 @@ int hci_unregister_proto(struct hci_proto *hp) | |||
1865 | if (hp->id >= HCI_MAX_PROTO) | 1858 | if (hp->id >= HCI_MAX_PROTO) |
1866 | return -EINVAL; | 1859 | return -EINVAL; |
1867 | 1860 | ||
1868 | mutex_lock(&hci_task_lock); | ||
1869 | |||
1870 | if (hci_proto[hp->id]) | 1861 | if (hci_proto[hp->id]) |
1871 | hci_proto[hp->id] = NULL; | 1862 | hci_proto[hp->id] = NULL; |
1872 | else | 1863 | else |
1873 | err = -ENOENT; | 1864 | err = -ENOENT; |
1874 | 1865 | ||
1875 | mutex_unlock(&hci_task_lock); | ||
1876 | |||
1877 | return err; | 1866 | return err; |
1878 | } | 1867 | } |
1879 | EXPORT_SYMBOL(hci_unregister_proto); | 1868 | EXPORT_SYMBOL(hci_unregister_proto); |
@@ -2439,8 +2428,6 @@ static void hci_tx_work(struct work_struct *work) | |||
2439 | struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); | 2428 | struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); |
2440 | struct sk_buff *skb; | 2429 | struct sk_buff *skb; |
2441 | 2430 | ||
2442 | mutex_lock(&hci_task_lock); | ||
2443 | |||
2444 | BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, | 2431 | BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, |
2445 | hdev->sco_cnt, hdev->le_cnt); | 2432 | hdev->sco_cnt, hdev->le_cnt); |
2446 | 2433 | ||
@@ -2457,8 +2444,6 @@ static void hci_tx_work(struct work_struct *work) | |||
2457 | /* Send next queued raw (unknown type) packet */ | 2444 | /* Send next queued raw (unknown type) packet */ |
2458 | while ((skb = skb_dequeue(&hdev->raw_q))) | 2445 | while ((skb = skb_dequeue(&hdev->raw_q))) |
2459 | hci_send_frame(skb); | 2446 | hci_send_frame(skb); |
2460 | |||
2461 | mutex_unlock(&hci_task_lock); | ||
2462 | } | 2447 | } |
2463 | 2448 | ||
2464 | /* ----- HCI RX task (incoming data processing) ----- */ | 2449 | /* ----- HCI RX task (incoming data processing) ----- */ |
@@ -2546,8 +2531,6 @@ static void hci_rx_work(struct work_struct *work) | |||
2546 | 2531 | ||
2547 | BT_DBG("%s", hdev->name); | 2532 | BT_DBG("%s", hdev->name); |
2548 | 2533 | ||
2549 | mutex_lock(&hci_task_lock); | ||
2550 | |||
2551 | while ((skb = skb_dequeue(&hdev->rx_q))) { | 2534 | while ((skb = skb_dequeue(&hdev->rx_q))) { |
2552 | if (atomic_read(&hdev->promisc)) { | 2535 | if (atomic_read(&hdev->promisc)) { |
2553 | /* Send copy to the sockets */ | 2536 | /* Send copy to the sockets */ |
@@ -2591,8 +2574,6 @@ static void hci_rx_work(struct work_struct *work) | |||
2591 | break; | 2574 | break; |
2592 | } | 2575 | } |
2593 | } | 2576 | } |
2594 | |||
2595 | mutex_unlock(&hci_task_lock); | ||
2596 | } | 2577 | } |
2597 | 2578 | ||
2598 | static void hci_cmd_work(struct work_struct *work) | 2579 | static void hci_cmd_work(struct work_struct *work) |