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

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: hci_conn: Fix not cleaning up PA_LINK connections

Contrary to what was stated on d36349ea73d8 ("Bluetooth: hci_conn:
Fix running bis_cleanup for hci_conn->type PA_LINK") the PA_LINK does
in fact needs to run bis_cleanup in order to terminate the PA Sync,
since that is bond to the listening socket which is the entity that
controls the lifetime of PA Sync, so if it is closed/released the PA
Sync shall be terminated, terminating the PA Sync shall not result in
the BIG Sync being terminated since once the later is established it
doesn't depend on the former anymore.

If the use user wants to reconnect/rebind a number of BIS(s) it shall
keep the socket open until it no longer needs the PA Sync, which means
it retains full control of the lifetime of both PA and BIG Syncs.

Fixes: d36349ea73d8 ("Bluetooth: hci_conn: Fix running bis_cleanup for hci_conn->type PA_LINK")
Fixes: a7bcffc673de ("Bluetooth: Add PA_LINK to distinguish BIG sync and PA sync connections")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

+21 -21
+19 -14
net/bluetooth/hci_conn.c
··· 769 769 d->count++; 770 770 } 771 771 772 - static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *conn) 772 + static int hci_le_big_terminate(struct hci_dev *hdev, struct hci_conn *conn) 773 773 { 774 774 struct iso_list_data *d; 775 775 int ret; 776 776 777 - bt_dev_dbg(hdev, "big 0x%2.2x sync_handle 0x%4.4x", big, conn->sync_handle); 777 + bt_dev_dbg(hdev, "hcon %p big 0x%2.2x sync_handle 0x%4.4x", conn, 778 + conn->iso_qos.bcast.big, conn->sync_handle); 778 779 779 780 d = kzalloc(sizeof(*d), GFP_KERNEL); 780 781 if (!d) 781 782 return -ENOMEM; 782 783 783 - d->big = big; 784 + d->big = conn->iso_qos.bcast.big; 784 785 d->sync_handle = conn->sync_handle; 785 786 786 - if (test_and_clear_bit(HCI_CONN_PA_SYNC, &conn->flags)) { 787 + if (conn->type == PA_LINK && 788 + test_and_clear_bit(HCI_CONN_PA_SYNC, &conn->flags)) { 787 789 hci_conn_hash_list_flag(hdev, find_bis, PA_LINK, 788 790 HCI_CONN_PA_SYNC, d); 789 791 ··· 802 800 if (!d->count) 803 801 d->big_sync_term = true; 804 802 } 803 + 804 + if (!d->pa_sync_term && !d->big_sync_term) 805 + return 0; 805 806 806 807 ret = hci_cmd_sync_queue(hdev, big_terminate_sync, d, 807 808 terminate_big_destroy); ··· 857 852 858 853 hci_le_terminate_big(hdev, conn); 859 854 } else { 860 - hci_le_big_terminate(hdev, conn->iso_qos.bcast.big, 861 - conn); 855 + hci_le_big_terminate(hdev, conn); 862 856 } 863 857 } 864 858 ··· 998 994 conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu; 999 995 break; 1000 996 case CIS_LINK: 1001 - case BIS_LINK: 1002 - case PA_LINK: 1003 997 /* conn->src should reflect the local identity address */ 1004 998 hci_copy_identity_address(hdev, &conn->src, &conn->src_type); 1005 999 1006 - /* set proper cleanup function */ 1007 - if (!bacmp(dst, BDADDR_ANY)) 1008 - conn->cleanup = bis_cleanup; 1009 - else if (conn->role == HCI_ROLE_MASTER) 1000 + if (conn->role == HCI_ROLE_MASTER) 1010 1001 conn->cleanup = cis_cleanup; 1011 1002 1012 - conn->mtu = hdev->iso_mtu ? hdev->iso_mtu : 1013 - hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu; 1003 + conn->mtu = hdev->iso_mtu; 1004 + break; 1005 + case PA_LINK: 1006 + case BIS_LINK: 1007 + /* conn->src should reflect the local identity address */ 1008 + hci_copy_identity_address(hdev, &conn->src, &conn->src_type); 1009 + conn->cleanup = bis_cleanup; 1010 + conn->mtu = hdev->iso_mtu; 1014 1011 break; 1015 1012 case SCO_LINK: 1016 1013 if (lmp_esco_capable(hdev))
+1 -6
net/bluetooth/hci_event.c
··· 7001 7001 continue; 7002 7002 } 7003 7003 7004 - if (ev->status != 0x42) { 7004 + if (ev->status != 0x42) 7005 7005 /* Mark PA sync as established */ 7006 7006 set_bit(HCI_CONN_PA_SYNC, &bis->flags); 7007 - /* Reset cleanup callback of PA Sync so it doesn't 7008 - * terminate the sync when deleting the connection. 7009 - */ 7010 - conn->cleanup = NULL; 7011 - } 7012 7007 7013 7008 bis->sync_handle = conn->sync_handle; 7014 7009 bis->iso_qos.bcast.big = ev->handle;
+1 -1
net/bluetooth/hci_sync.c
··· 6999 6999 7000 7000 hci_dev_lock(hdev); 7001 7001 7002 - if (!hci_conn_valid(hdev, conn)) 7002 + if (hci_conn_valid(hdev, conn)) 7003 7003 clear_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags); 7004 7004 7005 7005 if (!err)