From 14093643710f3e5b2a4d7f3ec759a3668ae7601d Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Thu, 28 Apr 2022 21:07:39 -0500 Subject: [PATCH] scan: Sort scan_requests by wiphy work item priority MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Periodic scan requests are meant to be performed with a lower priority than normal scan requests. They're thus given a different priority when inserting them into the wiphy work queue. Unfortunately, the priority is not taken into account when they are inserted into the sr->requests queue. This can result in the scanning code being confused since it assumes the top of the queue is always the next scheduled or currently ongoing scan. As a result any further wiphy_work might never be started properly. Apr 27 16:34:40 iwd[5117]: ../iwd-1.26/src/wiphy.c:wiphy_radio_work_insert() Inserting work item 3 Apr 27 16:34:40 iwd[5117]: ../iwd-1.26/src/wiphy.c:wiphy_radio_work_next() Starting work item 3 Apr 27 16:34:40 iwd[5117]: ../iwd-1.26/src/scan.c:scan_periodic_timeout() 1 Apr 27 16:34:40 iwd[5117]: ../iwd-1.26/src/wiphy.c:wiphy_radio_work_insert() Inserting work item 4 Apr 27 16:34:43 iwd[5117]: ../iwd-1.26/src/wiphy.c:wiphy_radio_work_insert() Inserting work item 5 Apr 27 16:34:43 iwd[5117]: ../iwd-1.26/src/wiphy.c:wiphy_radio_work_done() Work item 3 done Apr 27 16:34:43 iwd[5117]: ../iwd-1.26/src/wiphy.c:wiphy_radio_work_next() Starting work item 5 Apr 27 16:34:43 iwd[5117]: ../iwd-1.26/src/scan.c:scan_notify() Scan notification Trigger Scan(33) Apr 27 16:34:43 iwd[5117]: ../iwd-1.26/src/scan.c:scan_request_triggered() Passive scan triggered for wdev 1 Apr 27 16:34:43 iwd[5117]: ../iwd-1.26/src/scan.c:scan_periodic_triggered() Periodic scan triggered for wdev 1 In the above log, scan request 5 (triggered by dbus) is started before scan request 4 (periodic scan). Yet the scanning code thinks scan request 4 was triggered. Fix this by using the wiphy_work priority to sort the sr->requests queue so that the scans are ordered in the same manner. Reported-by: Alvin Šipraga --- src/scan.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/scan.c b/src/scan.c index b0824e72..cc6e682c 100644 --- a/src/scan.c +++ b/src/scan.c @@ -611,6 +611,17 @@ static struct scan_request *scan_request_new(struct scan_context *sc, return sr; } +static int insert_by_priority(const void *a, const void *b, void *user_data) +{ + const struct scan_request *cur = b; + int priority = L_PTR_TO_INT(user_data); + + if (cur->work.priority <= priority) + return 1; + + return -1; +} + static uint32_t scan_common(uint64_t wdev_id, bool passive, const struct scan_parameters *params, int priority, @@ -630,7 +641,12 @@ static uint32_t scan_common(uint64_t wdev_id, bool passive, scan_cmds_add(sr->cmds, sc, passive, params); - l_queue_push_tail(sc->requests, sr); + /* + * sr->work isn't initialized yet, it will be done by + * wiphy_radio_work_insert(). Pass the priority as user_data instead + */ + l_queue_insert(sc->requests, sr, insert_by_priority, + L_INT_TO_PTR(priority)); return wiphy_radio_work_insert(sc->wiphy, &sr->work, priority, &work_ops); @@ -801,7 +817,8 @@ uint32_t scan_owe_hidden(uint64_t wdev_id, struct l_queue *list, } done: - l_queue_push_tail(sc->requests, sr); + l_queue_insert(sc->requests, sr, insert_by_priority, + L_INT_TO_PTR(WIPHY_WORK_PRIORITY_SCAN)); return wiphy_radio_work_insert(sc->wiphy, &sr->work, WIPHY_WORK_PRIORITY_SCAN, &work_ops);