All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ] mgmt-tester: add tests for discoverable timeout
@ 2025-11-16 13:51 Pauli Virtanen
  2025-11-16 15:13 ` [BlueZ] " bluez.test.bot
  2025-11-17 16:30 ` [PATCH BlueZ] " patchwork-bot+bluetooth
  0 siblings, 2 replies; 3+ messages in thread
From: Pauli Virtanen @ 2025-11-16 13:51 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

Test that the discoverable timeout can be set successfully and that the
timeout actually triggers:

Set discoverable on timeout - Success 1
Set discoverable on timeout - Success 2 (Timeout)
---

Notes:
    These tests can be used to observe a deadlock in kernel of the type:
    
    [T1]                                                [T2]
    hci_dev_lock()
                                                        discov_off()
                                                           hci_dev_lock()
      mgmt_index_removed()
        cancel_delayed_work_sync(&hdev->discov_off)
        -> deadlock
    
    This requires specific timing. Adding sleep in mgmt_index_removed()
    makes it hit:
    
    diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
    index c11cdef42b6f..34a44e92779c 100644
    --- a/net/bluetooth/mgmt.c
    +++ b/net/bluetooth/mgmt.c
    @@ -9487,6 +9487,8 @@ void mgmt_index_removed(struct hci_dev *hdev)
            struct mgmt_ev_ext_index ev;
            struct cmd_lookup match = { NULL, hdev, MGMT_STATUS_INVALID_INDEX };
    
    +       usleep_range(11*1000*1000, 12*1000*1000);
    +
            if (hci_test_quirk(hdev, HCI_QUIRK_RAW_DEVICE))
                    return;
    
    Then mgmt-tester -s "Set discoverable on timeout - Success 1" triggers
    
    ======================================================
    WARNING: possible circular locking dependency detected
    6.18.0-rc2-00379-g183db933c900-dirty #1006 Not tainted
    ------------------------------------------------------
    mgmt-tester/44 is trying to acquire lock:
    ffff888002138830 ((work_completion)(&(&hdev->discov_off)->work)){+.+.}-{0:0}, at: __flush_work+0x4dc/0xc90
    
    but task is already holding lock:
    ffff8880021380b0 (&hdev->lock){+.+.}-{4:4}, at: hci_unregister_dev+0x2e8/0x4d0
    
    which lock already depends on the new lock.
    
    the existing dependency chain (in reverse order) is:
    
    -> #1 (&hdev->lock){+.+.}-{4:4}:
           __mutex_lock+0x1a6/0x21f0
           discov_off+0x7c/0x1c0
           process_one_work+0x7ed/0x13c0
           worker_thread+0x601/0xff0
           kthread+0x3e6/0x860
           ret_from_fork+0x3da/0x570
           ret_from_fork_asm+0x19/0x30
    
    -> #0 ((work_completion)(&(&hdev->discov_off)->work)){+.+.}-{0:0}:
           __lock_acquire+0x14be/0x2610
           lock_acquire+0xf2/0x2a0
           __flush_work+0x4f9/0xc90
           cancel_delayed_work_sync+0xae/0xe0
           mgmt_index_removed+0x246/0x2d0
           hci_unregister_dev+0x2f0/0x4d0
           vhci_release+0x188/0x260
           __fput+0x35b/0x9e0
           fput_close_sync+0xde/0x190
           __x64_sys_close+0x96/0x100
           do_syscall_64+0x72/0x300
           entry_SYSCALL_64_after_hwframe+0x74/0x7c
    
    other info that might help us debug this:
    
     Possible unsafe locking scenario:
    
           CPU0                    CPU1
           ----                    ----
      lock(&hdev->lock);
                                   lock((work_completion)(&(&hdev->discov_off)->work));
                                   lock(&hdev->lock);
      lock((work_completion)(&(&hdev->discov_off)->work));
    
     *** DEADLOCK ***
    
    2 locks held by mgmt-tester/44:
     #0: ffff8880021380b0 (&hdev->lock){+.+.}-{4:4}, at: hci_unregister_dev+0x2e8/0x4d0
     #1: ffffffffa0992c00 (rcu_read_lock){....}-{1:3}, at: __flush_work+0xdc/0xc90

 tools/mgmt-tester.c | 63 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 60 insertions(+), 3 deletions(-)

diff --git a/tools/mgmt-tester.c b/tools/mgmt-tester.c
index 663879a8f..90dfa3527 100644
--- a/tools/mgmt-tester.c
+++ b/tools/mgmt-tester.c
@@ -343,6 +343,7 @@ struct generic_data {
 	const void * (*expect_func)(uint16_t *len);
 	uint32_t expect_settings_set;
 	uint32_t expect_settings_unset;
+	uint32_t expect_settings_spontaneous;
 	uint16_t expect_alt_ev;
 	const void *expect_alt_ev_param;
 	bool (*verify_alt_ev_func)(const void *param, uint16_t length);
@@ -1206,6 +1207,7 @@ static const struct generic_data set_bondable_on_invalid_index_test = {
 
 static const uint8_t set_discoverable_on_param[] = { 0x01, 0x00, 0x00 };
 static const uint8_t set_discoverable_timeout_param[] = { 0x01, 0x0a, 0x00 };
+static const uint8_t set_discoverable_timeout_1_param[] = { 0x01, 0x01, 0x00 };
 static const uint8_t set_discoverable_invalid_param[] = { 0x02, 0x00, 0x00 };
 static const uint8_t set_discoverable_off_param[] = { 0x00, 0x00, 0x00 };
 static const uint8_t set_discoverable_offtimeout_param[] = { 0x00, 0x01, 0x00 };
@@ -1307,6 +1309,36 @@ static const struct generic_data set_discoverable_on_success_test_2 = {
 	.expect_hci_len = sizeof(set_discoverable_on_scan_enable_param),
 };
 
+static const struct generic_data set_discoverable_on_timeout_success_test_1 = {
+	.setup_settings = settings_powered_connectable,
+	.send_opcode = MGMT_OP_SET_DISCOVERABLE,
+	.send_param = set_discoverable_timeout_param,
+	.send_len = sizeof(set_discoverable_timeout_param),
+	.expect_status = MGMT_STATUS_SUCCESS,
+	.expect_param = set_discoverable_on_settings_param_2,
+	.expect_len = sizeof(set_discoverable_on_settings_param_2),
+	.expect_hci_command = BT_HCI_CMD_WRITE_SCAN_ENABLE,
+	.expect_hci_param = set_discoverable_on_scan_enable_param,
+	.expect_hci_len = sizeof(set_discoverable_on_scan_enable_param),
+};
+
+static const struct generic_data set_discoverable_on_timeout_success_test_2 = {
+	.setup_settings = settings_powered_connectable,
+	.send_opcode = MGMT_OP_SET_DISCOVERABLE,
+	.send_param = set_discoverable_timeout_1_param,
+	.send_len = sizeof(set_discoverable_timeout_1_param),
+	.expect_status = MGMT_STATUS_SUCCESS,
+	.expect_settings_set = MGMT_SETTING_DISCOVERABLE,
+	.expect_settings_spontaneous = MGMT_SETTING_POWERED |
+					MGMT_SETTING_CONNECTABLE |
+					MGMT_SETTING_BREDR,
+	.expect_param = set_discoverable_on_settings_param_2,
+	.expect_len = sizeof(set_discoverable_on_settings_param_2),
+	.expect_hci_command = BT_HCI_CMD_WRITE_SCAN_ENABLE,
+	.expect_hci_param = set_discoverable_on_scan_enable_param,
+	.expect_hci_len = sizeof(set_discoverable_on_scan_enable_param),
+};
+
 static uint8_t set_discov_on_le_param[] = { 0x0b, 0x06, 0x00, 0x00 };
 static uint8_t set_discov_adv_data[32] = { 0x06, 0x02, 0x01, 0x06,
 								0x02, 0x0a, };
@@ -7333,12 +7365,27 @@ static void command_generic_new_settings(uint16_t index, uint16_t length,
 					const void *param, void *user_data)
 {
 	struct test_data *data = tester_get_data();
+	const struct generic_data *test = data->test_data;
+	uint32_t settings;
 
-	tester_print("New settings event received");
+	if (length != 4) {
+		tester_warn("Invalid parameter size for new settings event");
+		tester_test_failed();
+		return;
+	}
+
+	settings = get_le32(param);
+	tester_print("New settings 0x%08x received (local)", settings);
 
 	mgmt_unregister(data->mgmt, data->mgmt_settings_id);
 
-	tester_test_failed();
+	if (!test->expect_settings_spontaneous) {
+		tester_test_failed();
+		return;
+	}
+
+	if (settings == test->expect_settings_spontaneous)
+		test_condition_complete(data);
 }
 
 static void command_generic_new_settings_alt(uint16_t index, uint16_t length,
@@ -11592,7 +11639,8 @@ static void test_command_generic(const void *test_data)
 
 	index = test->send_index_none ? MGMT_INDEX_NONE : data->mgmt_index;
 
-	if (test->expect_settings_set || test->expect_settings_unset) {
+	if (test->expect_settings_set || test->expect_settings_unset ||
+					test->expect_settings_spontaneous) {
 		tester_print("Registering new settings notification");
 
 		id = mgmt_register(data->mgmt, MGMT_EV_NEW_SETTINGS, index,
@@ -11603,6 +11651,9 @@ static void test_command_generic(const void *test_data)
 				command_generic_new_settings_alt, NULL, NULL);
 		data->mgmt_alt_settings_id = id;
 		test_add_condition(data);
+
+		if (test->expect_settings_spontaneous)
+			test_add_condition(data);
 	}
 
 	if (test->expect_alt_ev) {
@@ -13146,6 +13197,12 @@ int main(int argc, char *argv[])
 	test_bredrle("Set discoverable on - Success 2",
 				&set_discoverable_on_success_test_2,
 				NULL, test_command_generic);
+	test_bredrle("Set discoverable on timeout - Success 1",
+				&set_discoverable_on_timeout_success_test_1,
+				NULL, test_command_generic);
+	test_bredrle_full("Set discoverable on timeout - Success 2 (Timeout)",
+				&set_discoverable_on_timeout_success_test_2,
+				NULL, test_command_generic, 8);
 	test_le("Set discoverable on (LE) - Success 1",
 				&set_discov_on_le_success_1,
 				NULL, test_command_generic);
-- 
2.51.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* RE: [BlueZ] mgmt-tester: add tests for discoverable timeout
  2025-11-16 13:51 [PATCH BlueZ] mgmt-tester: add tests for discoverable timeout Pauli Virtanen
@ 2025-11-16 15:13 ` bluez.test.bot
  2025-11-17 16:30 ` [PATCH BlueZ] " patchwork-bot+bluetooth
  1 sibling, 0 replies; 3+ messages in thread
From: bluez.test.bot @ 2025-11-16 15:13 UTC (permalink / raw)
  To: linux-bluetooth, pav

[-- Attachment #1: Type: text/plain, Size: 1262 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1023990

---Test result---

Test Summary:
CheckPatch                    PENDING   0.30 seconds
GitLint                       PENDING   0.29 seconds
BuildEll                      PASS      20.27 seconds
BluezMake                     PASS      2635.21 seconds
MakeCheck                     PASS      20.62 seconds
MakeDistcheck                 PASS      186.26 seconds
CheckValgrind                 PASS      240.25 seconds
CheckSmatch                   PASS      315.36 seconds
bluezmakeextell               PASS      129.57 seconds
IncrementalBuild              PENDING   0.30 seconds
ScanBuild                     PASS      937.58 seconds

Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:

##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:

##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:



---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH BlueZ] mgmt-tester: add tests for discoverable timeout
  2025-11-16 13:51 [PATCH BlueZ] mgmt-tester: add tests for discoverable timeout Pauli Virtanen
  2025-11-16 15:13 ` [BlueZ] " bluez.test.bot
@ 2025-11-17 16:30 ` patchwork-bot+bluetooth
  1 sibling, 0 replies; 3+ messages in thread
From: patchwork-bot+bluetooth @ 2025-11-17 16:30 UTC (permalink / raw)
  To: Pauli Virtanen; +Cc: linux-bluetooth

Hello:

This patch was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Sun, 16 Nov 2025 15:51:58 +0200 you wrote:
> Test that the discoverable timeout can be set successfully and that the
> timeout actually triggers:
> 
> Set discoverable on timeout - Success 1
> Set discoverable on timeout - Success 2 (Timeout)
> ---
> 
> [...]

Here is the summary with links:
  - [BlueZ] mgmt-tester: add tests for discoverable timeout
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=f5043771c27b

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-11-17 16:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-16 13:51 [PATCH BlueZ] mgmt-tester: add tests for discoverable timeout Pauli Virtanen
2025-11-16 15:13 ` [BlueZ] " bluez.test.bot
2025-11-17 16:30 ` [PATCH BlueZ] " patchwork-bot+bluetooth

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.