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.
This commit is contained in:
James Prestwood 2022-01-11 09:45:11 -08:00 committed by Denis Kenzior
parent c7a6730d28
commit 217bb6dc65
1 changed files with 29 additions and 21 deletions

View File

@ -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, &params,
scan_periodic_triggered,
scan_periodic_notify, sc, NULL);
sc->sp.id = scan_common(sc->wdev_id, false, &params,
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, &params,
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;
}