From 217bb6dc652179706d0326f353aabd2b1daf4438 Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Tue, 11 Jan 2022 09:45:11 -0800 Subject: [PATCH] scan: don't special case periodic scan work Periodic scans were handled specially where they were only started if no other requests were pending in the scan queue. This is fine, and what we want, but this can actually be handled automatically by nature of the wiphy work queue rather than needing to check the request queue explicitly. Instead we can insert periodic scans at a lower priority than other scans. This puts them at the end of the work queue, as well as allows future requests to jump ahead if a periodic scan has not yet started. Eventually, once all pending scans are done, the peridoic scan may begin. This is no different than the preivous behavior and avoids the need for any special checks once scan requests complete. One check was added to address the problem of the periodic scan timer firing before the scan could even start. Currently this happened to be handled fine in scan_periodic_queue, as it checks the queue length. Since this check was removed we must see check for this condition inside scan_periodic_timeout. --- src/scan.c | 50 +++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/src/scan.c b/src/scan.c index 57b1be95..0767fa22 100644 --- a/src/scan.c +++ b/src/scan.c @@ -69,7 +69,6 @@ struct scan_periodic { scan_trigger_func_t trigger; scan_notify_func_t callback; void *userdata; - bool retry:1; uint32_t id; bool needs_active_scan:1; }; @@ -882,27 +881,32 @@ static bool scan_periodic_notify(int err, struct l_queue *bss_list, return false; } +static void scan_periodic_destroy(void *user_data) +{ + struct scan_context *sc = user_data; + + sc->sp.id = 0; +} + static bool scan_periodic_queue(struct scan_context *sc) { - if (!l_queue_isempty(sc->requests)) { - sc->sp.retry = true; - return false; - } + struct scan_parameters params = {}; if (sc->sp.needs_active_scan && known_networks_has_hidden()) { - struct scan_parameters params = { - .randomize_mac_addr_hint = true - }; + params.randomize_mac_addr_hint = true; sc->sp.needs_active_scan = false; - - sc->sp.id = scan_active_full(sc->wdev_id, ¶ms, - scan_periodic_triggered, - scan_periodic_notify, sc, NULL); + sc->sp.id = scan_common(sc->wdev_id, false, ¶ms, + WIPHY_WORK_PRIORITY_PERIODIC_SCAN, + scan_periodic_triggered, + scan_periodic_notify, sc, + scan_periodic_destroy); } else - sc->sp.id = scan_passive(sc->wdev_id, NULL, - scan_periodic_triggered, - scan_periodic_notify, sc, NULL); + sc->sp.id = scan_common(sc->wdev_id, true, ¶ms, + WIPHY_WORK_PRIORITY_PERIODIC_SCAN, + scan_periodic_triggered, + scan_periodic_notify, sc, + scan_periodic_destroy); return sc->sp.id != 0; } @@ -974,7 +978,6 @@ bool scan_periodic_stop(uint64_t wdev_id) sc->sp.trigger = NULL; sc->sp.callback = NULL; sc->sp.userdata = NULL; - sc->sp.retry = false; sc->sp.needs_active_scan = false; return true; @@ -1005,6 +1008,16 @@ static void scan_periodic_timeout(struct l_timeout *timeout, void *user_data) l_debug("%" PRIx64, sc->wdev_id); + /* + * Timeout triggered before periodic scan could even start, just rearm + * with the same interval. + */ + if (sc->sp.id) { + l_debug("Periodic scan timer called before scan could start!"); + scan_periodic_rearm(sc); + return; + } + sc->sp.interval *= 2; if (sc->sp.interval > SCAN_MAX_INTERVAL) sc->sp.interval = SCAN_MAX_INTERVAL; @@ -1049,11 +1062,6 @@ static bool start_next_scan_request(struct wiphy_radio_work_item *item) scan_request_failed(sc, sr, -EIO); - if (sc->sp.retry) { - sc->sp.retry = false; - scan_periodic_queue(sc); - } - return true; }