diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2010-03-20 10:20:04 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-05-10 03:34:03 -0400 |
commit | f48fd9c8cd746fdb055a97249a209c77dca0f710 (patch) | |
tree | a3ab4ba27edc43bf3527a02fd7c6ba4167213056 /net/bluetooth | |
parent | 844c0972427ee5f661158160aaca10b22b3dda60 (diff) |
Bluetooth: Create per controller workqueue
Instead of having a global workqueue for all controllers, it makes
more sense to have a workqueue per controller.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_core.c | 14 | ||||
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 16 |
2 files changed, 17 insertions, 13 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 904f1e8a7a3b..5e83f8e0877a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/fcntl.h> | 37 | #include <linux/fcntl.h> |
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/skbuff.h> | 39 | #include <linux/skbuff.h> |
40 | #include <linux/workqueue.h> | ||
40 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
41 | #include <linux/notifier.h> | 42 | #include <linux/notifier.h> |
42 | #include <linux/rfkill.h> | 43 | #include <linux/rfkill.h> |
@@ -928,6 +929,10 @@ int hci_register_dev(struct hci_dev *hdev) | |||
928 | 929 | ||
929 | write_unlock_bh(&hci_dev_list_lock); | 930 | write_unlock_bh(&hci_dev_list_lock); |
930 | 931 | ||
932 | hdev->workqueue = create_singlethread_workqueue(hdev->name); | ||
933 | if (!hdev->workqueue) | ||
934 | goto nomem; | ||
935 | |||
931 | hci_register_sysfs(hdev); | 936 | hci_register_sysfs(hdev); |
932 | 937 | ||
933 | hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, | 938 | hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, |
@@ -942,6 +947,13 @@ int hci_register_dev(struct hci_dev *hdev) | |||
942 | hci_notify(hdev, HCI_DEV_REG); | 947 | hci_notify(hdev, HCI_DEV_REG); |
943 | 948 | ||
944 | return id; | 949 | return id; |
950 | |||
951 | nomem: | ||
952 | write_lock_bh(&hci_dev_list_lock); | ||
953 | list_del(&hdev->list); | ||
954 | write_unlock_bh(&hci_dev_list_lock); | ||
955 | |||
956 | return -ENOMEM; | ||
945 | } | 957 | } |
946 | EXPORT_SYMBOL(hci_register_dev); | 958 | EXPORT_SYMBOL(hci_register_dev); |
947 | 959 | ||
@@ -970,6 +982,8 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
970 | 982 | ||
971 | hci_unregister_sysfs(hdev); | 983 | hci_unregister_sysfs(hdev); |
972 | 984 | ||
985 | destroy_workqueue(hdev->workqueue); | ||
986 | |||
973 | __hci_dev_put(hdev); | 987 | __hci_dev_put(hdev); |
974 | 988 | ||
975 | return 0; | 989 | return 0; |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 0e8e1a59856c..a978449ab04d 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -14,8 +14,6 @@ static struct class *bt_class; | |||
14 | struct dentry *bt_debugfs = NULL; | 14 | struct dentry *bt_debugfs = NULL; |
15 | EXPORT_SYMBOL_GPL(bt_debugfs); | 15 | EXPORT_SYMBOL_GPL(bt_debugfs); |
16 | 16 | ||
17 | static struct workqueue_struct *bt_workq; | ||
18 | |||
19 | static inline char *link_typetostr(int type) | 17 | static inline char *link_typetostr(int type) |
20 | { | 18 | { |
21 | switch (type) { | 19 | switch (type) { |
@@ -161,14 +159,14 @@ void hci_conn_add_sysfs(struct hci_conn *conn) | |||
161 | { | 159 | { |
162 | BT_DBG("conn %p", conn); | 160 | BT_DBG("conn %p", conn); |
163 | 161 | ||
164 | queue_work(bt_workq, &conn->work_add); | 162 | queue_work(conn->hdev->workqueue, &conn->work_add); |
165 | } | 163 | } |
166 | 164 | ||
167 | void hci_conn_del_sysfs(struct hci_conn *conn) | 165 | void hci_conn_del_sysfs(struct hci_conn *conn) |
168 | { | 166 | { |
169 | BT_DBG("conn %p", conn); | 167 | BT_DBG("conn %p", conn); |
170 | 168 | ||
171 | queue_work(bt_workq, &conn->work_del); | 169 | queue_work(conn->hdev->workqueue, &conn->work_del); |
172 | } | 170 | } |
173 | 171 | ||
174 | static inline char *host_bustostr(int bus) | 172 | static inline char *host_bustostr(int bus) |
@@ -487,17 +485,11 @@ void hci_unregister_sysfs(struct hci_dev *hdev) | |||
487 | 485 | ||
488 | int __init bt_sysfs_init(void) | 486 | int __init bt_sysfs_init(void) |
489 | { | 487 | { |
490 | bt_workq = create_singlethread_workqueue("bluetooth"); | ||
491 | if (!bt_workq) | ||
492 | return -ENOMEM; | ||
493 | |||
494 | bt_debugfs = debugfs_create_dir("bluetooth", NULL); | 488 | bt_debugfs = debugfs_create_dir("bluetooth", NULL); |
495 | 489 | ||
496 | bt_class = class_create(THIS_MODULE, "bluetooth"); | 490 | bt_class = class_create(THIS_MODULE, "bluetooth"); |
497 | if (IS_ERR(bt_class)) { | 491 | if (IS_ERR(bt_class)) |
498 | destroy_workqueue(bt_workq); | ||
499 | return PTR_ERR(bt_class); | 492 | return PTR_ERR(bt_class); |
500 | } | ||
501 | 493 | ||
502 | return 0; | 494 | return 0; |
503 | } | 495 | } |
@@ -507,6 +499,4 @@ void bt_sysfs_cleanup(void) | |||
507 | class_destroy(bt_class); | 499 | class_destroy(bt_class); |
508 | 500 | ||
509 | debugfs_remove_recursive(bt_debugfs); | 501 | debugfs_remove_recursive(bt_debugfs); |
510 | |||
511 | destroy_workqueue(bt_workq); | ||
512 | } | 502 | } |