Commit f48fd9c8 authored by Marcel Holtmann's avatar Marcel Holtmann
Browse files

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: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 844c0972
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -107,6 +107,8 @@ struct hci_dev {
	unsigned long	acl_last_tx;
	unsigned long	acl_last_tx;
	unsigned long	sco_last_tx;
	unsigned long	sco_last_tx;


	struct workqueue_struct	*workqueue;

	struct tasklet_struct	cmd_task;
	struct tasklet_struct	cmd_task;
	struct tasklet_struct	rx_task;
	struct tasklet_struct	rx_task;
	struct tasklet_struct	tx_task;
	struct tasklet_struct	tx_task;
+14 −0
Original line number Original line Diff line number Diff line
@@ -37,6 +37,7 @@
#include <linux/fcntl.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <linux/notifier.h>
#include <linux/rfkill.h>
#include <linux/rfkill.h>
@@ -928,6 +929,10 @@ int hci_register_dev(struct hci_dev *hdev)


	write_unlock_bh(&hci_dev_list_lock);
	write_unlock_bh(&hci_dev_list_lock);


	hdev->workqueue = create_singlethread_workqueue(hdev->name);
	if (!hdev->workqueue)
		goto nomem;

	hci_register_sysfs(hdev);
	hci_register_sysfs(hdev);


	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
@@ -942,6 +947,13 @@ int hci_register_dev(struct hci_dev *hdev)
	hci_notify(hdev, HCI_DEV_REG);
	hci_notify(hdev, HCI_DEV_REG);


	return id;
	return id;

nomem:
	write_lock_bh(&hci_dev_list_lock);
	list_del(&hdev->list);
	write_unlock_bh(&hci_dev_list_lock);

	return -ENOMEM;
}
}
EXPORT_SYMBOL(hci_register_dev);
EXPORT_SYMBOL(hci_register_dev);


@@ -970,6 +982,8 @@ int hci_unregister_dev(struct hci_dev *hdev)


	hci_unregister_sysfs(hdev);
	hci_unregister_sysfs(hdev);


	destroy_workqueue(hdev->workqueue);

	__hci_dev_put(hdev);
	__hci_dev_put(hdev);


	return 0;
	return 0;
+3 −13
Original line number Original line Diff line number Diff line
@@ -14,8 +14,6 @@ static struct class *bt_class;
struct dentry *bt_debugfs = NULL;
struct dentry *bt_debugfs = NULL;
EXPORT_SYMBOL_GPL(bt_debugfs);
EXPORT_SYMBOL_GPL(bt_debugfs);


static struct workqueue_struct *bt_workq;

static inline char *link_typetostr(int type)
static inline char *link_typetostr(int type)
{
{
	switch (type) {
	switch (type) {
@@ -161,14 +159,14 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
{
{
	BT_DBG("conn %p", conn);
	BT_DBG("conn %p", conn);


	queue_work(bt_workq, &conn->work_add);
	queue_work(conn->hdev->workqueue, &conn->work_add);
}
}


void hci_conn_del_sysfs(struct hci_conn *conn)
void hci_conn_del_sysfs(struct hci_conn *conn)
{
{
	BT_DBG("conn %p", conn);
	BT_DBG("conn %p", conn);


	queue_work(bt_workq, &conn->work_del);
	queue_work(conn->hdev->workqueue, &conn->work_del);
}
}


static inline char *host_bustostr(int bus)
static inline char *host_bustostr(int bus)
@@ -487,17 +485,11 @@ void hci_unregister_sysfs(struct hci_dev *hdev)


int __init bt_sysfs_init(void)
int __init bt_sysfs_init(void)
{
{
	bt_workq = create_singlethread_workqueue("bluetooth");
	if (!bt_workq)
		return -ENOMEM;

	bt_debugfs = debugfs_create_dir("bluetooth", NULL);
	bt_debugfs = debugfs_create_dir("bluetooth", NULL);


	bt_class = class_create(THIS_MODULE, "bluetooth");
	bt_class = class_create(THIS_MODULE, "bluetooth");
	if (IS_ERR(bt_class)) {
	if (IS_ERR(bt_class))
		destroy_workqueue(bt_workq);
		return PTR_ERR(bt_class);
		return PTR_ERR(bt_class);
	}


	return 0;
	return 0;
}
}
@@ -507,6 +499,4 @@ void bt_sysfs_cleanup(void)
	class_destroy(bt_class);
	class_destroy(bt_class);


	debugfs_remove_recursive(bt_debugfs);
	debugfs_remove_recursive(bt_debugfs);

	destroy_workqueue(bt_workq);
}
}