Message ID | 20250212175427.131356-1-arkadiusz.bokowy@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [BlueZ,v2] btdev: Broadcast EXT_ADV packets every 200 ms | expand |
Context | Check | Description |
---|---|---|
tedd_an/pre-ci_am | success | Success |
tedd_an/BuildEll | success | Build ELL PASS |
tedd_an/BluezMake | success | Bluez Make PASS |
tedd_an/MakeCheck | success | Bluez Make Check PASS |
tedd_an/MakeDistcheck | success | Make Distcheck PASS |
tedd_an/CheckValgrind | success | Check Valgrind PASS |
tedd_an/CheckSmatch | warning | CheckSparse WARNING emulator/btdev.c:449:29: warning: Variable length array is used. |
tedd_an/bluezmakeextell | success | Make External ELL PASS |
tedd_an/ScanBuild | success | Scan Build PASS |
> > No, it's not an optimization for my particular setup, but more > > generally for CPU load. I thought that it might be better not to run > > advertisement code too frequently. But I guess that lower values > > should also be OK, e.g. 100 ms or 50 ms. There is one "issue" with > > that, though.... Now, the advertisement packet will be sent one > > interval after the advertisement was enabled. If that's indeed an > > issue, it can be fixed by calling the callback function in the moment > > when the timer is armed. > > I'd keep the initial logic of sending the advertisement immediately I've fixed that in the v2 patch. > Btw, make sure you run the testers to confirm you are not breaking any > kernel testers. I've run the test-runner to verify everything (--auto). The result seems to be no worse than without my patch. What do I mean by that? The case is that I was not able to run the test-runner on the vanilla master branch with 100% success rate. There is always some failure with my "setup". However, when checking only the tools/mgmt-tester test, the success rate seems to be higher than without it (but it might be just a fluke). I run it like this: "tools/test-runner -k ~/linux/arch/x86/boot/bzImage -- tools/mgmt-tester". Anyway, I can see one test always failing - "Read Exp Feature - Success (Index None)" - it happens with and without my patch. Also, I've verified that the advertising broadcast code was executed (by adding some prints to that function). To conclude that, I'm afraid that I don't know how to run the test suite properly... So, my verification might miss something. I would advise you to verify that patch with your setup as well (if you can). Regards, Arek
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=933306 ---Test result--- Test Summary: CheckPatch PENDING 0.24 seconds GitLint PENDING 0.20 seconds BuildEll PASS 20.43 seconds BluezMake PASS 1590.06 seconds MakeCheck PASS 13.60 seconds MakeDistcheck PASS 157.66 seconds CheckValgrind PASS 213.77 seconds CheckSmatch WARNING 285.74 seconds bluezmakeextell PASS 98.26 seconds IncrementalBuild PENDING 0.28 seconds ScanBuild PASS 862.34 seconds Details ############################## Test: CheckPatch - PENDING Desc: Run checkpatch.pl script Output: ############################## Test: GitLint - PENDING Desc: Run gitlint Output: ############################## Test: CheckSmatch - WARNING Desc: Run smatch tool with source Output: emulator/btdev.c:449:29: warning: Variable length array is used. ############################## Test: IncrementalBuild - PENDING Desc: Incremental build with the patches in the series Output: --- Regards, Linux Bluetooth
Hi Arkadiusz, On Wed, Feb 12, 2025 at 1:10 PM Arkadiusz Bokowy <arkadiusz.bokowy@gmail.com> wrote: > > > > No, it's not an optimization for my particular setup, but more > > > generally for CPU load. I thought that it might be better not to run > > > advertisement code too frequently. But I guess that lower values > > > should also be OK, e.g. 100 ms or 50 ms. There is one "issue" with > > > that, though.... Now, the advertisement packet will be sent one > > > interval after the advertisement was enabled. If that's indeed an > > > issue, it can be fixed by calling the callback function in the moment > > > when the timer is armed. > > > > I'd keep the initial logic of sending the advertisement immediately > > I've fixed that in the v2 patch. Ive sent a v3 with a couple of updates so it should now use the advertisement interval rather than just assuming 200ms would cover all intervals. > > Btw, make sure you run the testers to confirm you are not breaking any > > kernel testers. > > I've run the test-runner to verify everything (--auto). The result > seems to be no worse than without my patch. What do I mean by that? > The case is that I was not able to run the test-runner on the vanilla > master branch with 100% success rate. There is always some failure > with my "setup". However, when checking only the tools/mgmt-tester > test, the success rate seems to be higher than without it (but it > might be just a fluke). I run it like this: "tools/test-runner -k > ~/linux/arch/x86/boot/bzImage -- tools/mgmt-tester". Anyway, I can see > one test always failing - "Read Exp Feature - Success (Index None)" - > it happens with and without my patch. Also, I've verified that the > advertising broadcast code was executed (by adding some prints to that > function). > > To conclude that, I'm afraid that I don't know how to run the test > suite properly... So, my verification might miss something. I would > advise you to verify that patch with your setup as well (if you can). On v3 there actually seems to be some regression with the following test: Ext Device Found - Advertising data - Zero padded - test passed Client set connectable: Success (0x00) Test setup condition complete, -1 left Client set connectable: Success (0x00) Test setup condition complete, -2 left qqemu-system-x86_64: terminating on signal 2 So we will probably need to fix that before we can apply it, I suspect we are getting more events than anticipated causing the steps to go into negative which probably is why it hangs, anyway it should have stopped when it reached the end. > Regards, > Arek
> I've sent a v3 with a couple of updates so it should now use the > advertisement interval rather than just assuming 200ms would cover all > intervals. Awesome! > So we will probably need to fix that before we can apply it, I suspect > we are getting more events than anticipated causing the steps to go > into negative which probably is why it hangs, anyway it should have > stopped when it reached the end. I think that I've fixed that in v4. The case is that sometimes the ext adv parameters are set with min/max advertisement intervals set to 0 (which is not valid I think ?). Because of that, the broadcast timer (with timeout 0) blocks everything and the test hangs. I've fixed it by providing a default advertising interval (according to the Bluetooth Core Spec), and checking for invalid values. Also, in case of high duty cycle advertising (direct advertising), the timeout is set to non-zero (10ms) in order not to hang everything. I've verified that with mgmt-tested and everything passes (except one test which always fails with my setup). Regards, Arek
diff --git a/emulator/btdev.c b/emulator/btdev.c index 60901ba56..fb2f2f41d 100644 --- a/emulator/btdev.c +++ b/emulator/btdev.c @@ -102,7 +102,8 @@ struct le_ext_adv { uint8_t adv_data_len; uint8_t scan_data[252]; uint8_t scan_data_len; - unsigned int id; + unsigned int broadcast_id; + unsigned int timeout_id; }; struct le_per_adv { @@ -575,8 +576,10 @@ static void le_ext_adv_free(void *data) /* Remove to queue */ queue_remove(ext_adv->dev->le_ext_adv, ext_adv); - if (ext_adv->id) - timeout_remove(ext_adv->id); + if (ext_adv->broadcast_id) + timeout_remove(ext_adv->broadcast_id); + if (ext_adv->timeout_id) + timeout_remove(ext_adv->timeout_id); free(ext_adv); } @@ -4756,9 +4759,13 @@ static void ext_adv_disable(void *data, void *user_data) if (handle && ext_adv->handle != handle) return; - if (ext_adv->id) { - timeout_remove(ext_adv->id); - ext_adv->id = 0; + if (ext_adv->broadcast_id) { + timeout_remove(ext_adv->broadcast_id); + ext_adv->broadcast_id = 0; + } + if (ext_adv->timeout_id) { + timeout_remove(ext_adv->timeout_id); + ext_adv->timeout_id = 0; } ext_adv->enable = 0x00; @@ -4975,9 +4982,10 @@ static void send_ext_adv(struct btdev *btdev, const struct btdev *remote, 1 + 24 + meta_event.lear.data_len); } -static void le_set_ext_adv_enable_complete(struct btdev *btdev, - struct le_ext_adv *ext_adv) +static bool ext_adv_broadcast(void *user_data) { + struct le_ext_adv *ext_adv = user_data; + struct btdev *btdev = ext_adv->dev; uint16_t report_type; int i; @@ -5013,7 +5021,10 @@ static void le_set_ext_adv_enable_complete(struct btdev *btdev, report_type, true); } } + + return true; } + static void adv_set_terminate(struct btdev *dev, uint8_t status, uint8_t handle, uint16_t conn_handle, uint8_t num_evts) { @@ -5032,7 +5043,7 @@ static bool ext_adv_timeout(void *user_data) { struct le_ext_adv *adv = user_data; - adv->id = 0; + adv->timeout_id = 0; adv_set_terminate(adv->dev, BT_HCI_ERR_ADV_TIMEOUT, adv->handle, 0x0000, 0x00); le_ext_adv_free(adv); @@ -5117,32 +5128,32 @@ static int cmd_set_ext_adv_enable(struct btdev *dev, const void *data, if (!cmd->enable) ext_adv_disable(ext_adv, NULL); - else if (eas->duration) - ext_adv->id = timeout_add(eas->duration * 10, - ext_adv_timeout, + else { + /* Send the first advertising report right away and + * start the timer for continuous advertising. */ + ext_adv_broadcast(ext_adv); + /* BLE advertising interval shall be between 20 ms + * and 10.24 s in 0.625 ms steps. Most devices which + * require fast advertising use an interval between + * 100 ms and 500 ms. + */ + ext_adv->broadcast_id = timeout_add(200 /* 200 ms */, + ext_adv_broadcast, ext_adv, NULL); + if (eas->duration) { + unsigned int duration_ms = eas->duration * 10; + ext_adv->timeout_id = timeout_add(duration_ms, + ext_adv_timeout, + ext_adv, NULL); + } + } + } exit_complete: cmd_complete(dev, BT_HCI_CMD_LE_SET_EXT_ADV_ENABLE, &status, sizeof(status)); - if (status == BT_HCI_ERR_SUCCESS && cmd->enable) { - /* Go through each sets and send adv event to peer device */ - for (i = 0; i < cmd->num_of_sets; i++) { - const struct bt_hci_cmd_ext_adv_set *eas; - struct le_ext_adv *ext_adv; - - eas = data + sizeof(*cmd) + (sizeof(*eas) * i); - - ext_adv = queue_find(dev->le_ext_adv, - match_ext_adv_handle, - UINT_TO_PTR(eas->handle)); - if (ext_adv) - le_set_ext_adv_enable_complete(dev, ext_adv); - } - } - return 0; } @@ -5492,43 +5503,6 @@ done: return 0; } -static void scan_ext_adv(struct btdev *dev, struct btdev *remote) -{ - const struct queue_entry *entry; - - for (entry = queue_get_entries(remote->le_ext_adv); entry; - entry = entry->next) { - struct le_ext_adv *ext_adv = entry->data; - uint16_t report_type; - - if (!ext_adv->enable) - continue; - - if (!ext_adv_match_addr(dev, ext_adv)) - continue; - - report_type = get_ext_adv_type(ext_adv->type); - send_ext_adv(dev, remote, ext_adv, report_type, false); - - if (dev->le_scan_type != 0x01) - continue; - - /* if scannable bit is set the send scan response */ - if (ext_adv->type & 0x02) { - if (ext_adv->type == 0x13) - report_type = 0x1b; - else if (ext_adv->type == 0x12) - report_type = 0x1a; - else if (!(ext_adv->type & 0x10)) - report_type &= 0x08; - else - continue; - - send_ext_adv(dev, remote, ext_adv, report_type, true); - } - } -} - static void scan_pa(struct btdev *dev, struct btdev *remote) { struct le_per_adv *per_adv = queue_find(dev->le_per_adv, @@ -5557,7 +5531,6 @@ static int cmd_set_ext_scan_enable_complete(struct btdev *dev, const void *data, if (!btdev_list[i] || btdev_list[i] == dev) continue; - scan_ext_adv(dev, btdev_list[i]); scan_pa(dev, btdev_list[i]); }