Bluetooth: Limit duration of Remote Name Resolve
authorArchie Pusaka <apusaka@chromium.org>
Thu, 25 Nov 2021 07:04:37 +0000 (15:04 +0800)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 25 Nov 2021 20:08:19 +0000 (21:08 +0100)
When doing remote name request, we cannot scan. In the normal case it's
OK since we can expect it to finish within a short amount of time.
However, there is a possibility to scan lots of devices that
(1) requires Remote Name Resolve
(2) is unresponsive to Remote Name Resolve
When this happens, we are stuck to do Remote Name Resolve until all is
done before continue scanning.

This patch adds a time limit to stop us spending too long on remote
name request.

Signed-off-by: Archie Pusaka <apusaka@chromium.org>
Reviewed-by: Miao-chen Chou <mcchou@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_event.c

index bb07a6d0d5978b8b0cde98e0760c5e9ba8223c59..7bae8376fd6f84259947546c21d8f668e89ec3d7 100644 (file)
@@ -88,6 +88,7 @@ struct discovery_state {
        u8                      (*uuids)[16];
        unsigned long           scan_start;
        unsigned long           scan_duration;
+       unsigned long           name_resolve_timeout;
 };
 
 #define SUSPEND_NOTIFIER_TIMEOUT       msecs_to_jiffies(2000) /* 2 seconds */
@@ -1759,6 +1760,8 @@ void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c);
 #define DISCOV_LE_FAST_ADV_INT_MIN     0x00A0  /* 100 msec */
 #define DISCOV_LE_FAST_ADV_INT_MAX     0x00F0  /* 150 msec */
 
+#define NAME_RESOLVE_DURATION          msecs_to_jiffies(10240) /* 10.24 sec */
+
 void mgmt_fill_version_info(void *ver);
 int mgmt_new_settings(struct hci_dev *hdev);
 void mgmt_index_added(struct hci_dev *hdev);
index 324d376f97d4a2765984cb8d84ef4826d9aba397..9d8d2d9e5d1f41b2b75cf94ebe71ade27d5c47cb 100644 (file)
@@ -2129,6 +2129,12 @@ static bool hci_resolve_next_name(struct hci_dev *hdev)
        if (list_empty(&discov->resolve))
                return false;
 
+       /* We should stop if we already spent too much time resolving names. */
+       if (time_after(jiffies, discov->name_resolve_timeout)) {
+               bt_dev_warn_ratelimited(hdev, "Name resolve takes too long.");
+               return false;
+       }
+
        e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
        if (!e)
                return false;
@@ -2716,6 +2722,7 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
        if (e && hci_resolve_name(hdev, e) == 0) {
                e->name_state = NAME_PENDING;
                hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
+               discov->name_resolve_timeout = jiffies + NAME_RESOLVE_DURATION;
        } else {
                /* When BR/EDR inquiry is active and no LE scanning is in
                 * progress, then change discovery state to indicate completion.