Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ulisses Furquim and committed by
Gustavo F. Padovan
f2d64f6a fa0fb93f

+1 -20
+1 -20
net/bluetooth/hci_core.c
··· 61 61 static void hci_cmd_work(struct work_struct *work); 62 62 static void hci_tx_work(struct work_struct *work); 63 63 64 - static DEFINE_MUTEX(hci_task_lock); 65 - 66 64 /* HCI device list */ 67 65 LIST_HEAD(hci_dev_list); 68 66 DEFINE_RWLOCK(hci_dev_list_lock); ··· 1830 1832 1831 1833 /* ---- Interface to upper protocols ---- */ 1832 1834 1833 - /* Register/Unregister protocols. 1834 - * hci_task_lock is used to ensure that no tasks are running. */ 1835 + /* Register/Unregister protocols. */ 1835 1836 int hci_register_proto(struct hci_proto *hp) 1836 1837 { 1837 1838 int err = 0; ··· 1840 1843 if (hp->id >= HCI_MAX_PROTO) 1841 1844 return -EINVAL; 1842 1845 1843 - mutex_lock(&hci_task_lock); 1844 - 1845 1846 if (!hci_proto[hp->id]) 1846 1847 hci_proto[hp->id] = hp; 1847 1848 else 1848 1849 err = -EEXIST; 1849 - 1850 - mutex_unlock(&hci_task_lock); 1851 1850 1852 1851 return err; 1853 1852 } ··· 1858 1865 if (hp->id >= HCI_MAX_PROTO) 1859 1866 return -EINVAL; 1860 1867 1861 - mutex_lock(&hci_task_lock); 1862 - 1863 1868 if (hci_proto[hp->id]) 1864 1869 hci_proto[hp->id] = NULL; 1865 1870 else 1866 1871 err = -ENOENT; 1867 - 1868 - mutex_unlock(&hci_task_lock); 1869 1872 1870 1873 return err; 1871 1874 } ··· 2428 2439 struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 2429 2440 struct sk_buff *skb; 2430 2441 2431 - mutex_lock(&hci_task_lock); 2432 - 2433 2442 BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 2434 2443 hdev->sco_cnt, hdev->le_cnt); 2435 2444 ··· 2444 2457 /* Send next queued raw (unknown type) packet */ 2445 2458 while ((skb = skb_dequeue(&hdev->raw_q))) 2446 2459 hci_send_frame(skb); 2447 - 2448 - mutex_unlock(&hci_task_lock); 2449 2460 } 2450 2461 2451 2462 /* ----- HCI RX task (incoming data processing) ----- */ ··· 2531 2546 2532 2547 BT_DBG("%s", hdev->name); 2533 2548 2534 - mutex_lock(&hci_task_lock); 2535 - 2536 2549 while ((skb = skb_dequeue(&hdev->rx_q))) { 2537 2550 if (atomic_read(&hdev->promisc)) { 2538 2551 /* Send copy to the sockets */ ··· 2574 2591 break; 2575 2592 } 2576 2593 } 2577 - 2578 - mutex_unlock(&hci_task_lock); 2579 2594 } 2580 2595 2581 2596 static void hci_cmd_work(struct work_struct *work)