Bluetooth: prioritizing data over HCI
This implement priority based scheduler using skbuffer priority set via SO_PRIORITY socket option. It introduces hci_chan_hash (list of HCI Channel/hci_chan) per connection, each item in this list refer to a L2CAP connection and it is used to queue the data for transmission. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
This commit is contained in:

committed by
Gustavo F. Padovan

parent
3c32fa93e5
commit
73d80deb7b
@@ -374,6 +374,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
|
||||
|
||||
skb_queue_head_init(&conn->data_q);
|
||||
|
||||
hci_chan_hash_init(conn);
|
||||
|
||||
setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn);
|
||||
setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
|
||||
setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept,
|
||||
@@ -432,6 +434,8 @@ int hci_conn_del(struct hci_conn *conn)
|
||||
|
||||
tasklet_disable(&hdev->tx_task);
|
||||
|
||||
hci_chan_hash_flush(conn);
|
||||
|
||||
hci_conn_hash_del(hdev, conn);
|
||||
if (hdev->notify)
|
||||
hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
|
||||
@@ -950,3 +954,52 @@ int hci_get_auth_info(struct hci_dev *hdev, void __user *arg)
|
||||
|
||||
return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
struct hci_chan *hci_chan_create(struct hci_conn *conn)
|
||||
{
|
||||
struct hci_dev *hdev = conn->hdev;
|
||||
struct hci_chan *chan;
|
||||
|
||||
BT_DBG("%s conn %p", hdev->name, conn);
|
||||
|
||||
chan = kzalloc(sizeof(struct hci_chan), GFP_ATOMIC);
|
||||
if (!chan)
|
||||
return NULL;
|
||||
|
||||
chan->conn = conn;
|
||||
skb_queue_head_init(&chan->data_q);
|
||||
|
||||
tasklet_disable(&hdev->tx_task);
|
||||
hci_chan_hash_add(conn, chan);
|
||||
tasklet_enable(&hdev->tx_task);
|
||||
|
||||
return chan;
|
||||
}
|
||||
|
||||
int hci_chan_del(struct hci_chan *chan)
|
||||
{
|
||||
struct hci_conn *conn = chan->conn;
|
||||
struct hci_dev *hdev = conn->hdev;
|
||||
|
||||
BT_DBG("%s conn %p chan %p", hdev->name, conn, chan);
|
||||
|
||||
tasklet_disable(&hdev->tx_task);
|
||||
hci_chan_hash_del(conn, chan);
|
||||
tasklet_enable(&hdev->tx_task);
|
||||
|
||||
skb_queue_purge(&chan->data_q);
|
||||
kfree(chan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hci_chan_hash_flush(struct hci_conn *conn)
|
||||
{
|
||||
struct hci_chan_hash *h = &conn->chan_hash;
|
||||
struct hci_chan *chan, *tmp;
|
||||
|
||||
BT_DBG("conn %p", conn);
|
||||
|
||||
list_for_each_entry_safe(chan, tmp, &h->list, list)
|
||||
hci_chan_del(chan);
|
||||
}
|
||||
|
Reference in New Issue
Block a user