[PATCH v6 4/7] qmi: Implement QMI service request rate limiting in 'can_write_data'.
Grant Erickson <[email protected]> Wed, 19 Mar 2025 12:22:31 -0700
| Newsgroups | dev.linux.lists.ofono |
|---|---|
| Message-ID | <ff3f37eb09769e57b2c5abf6d7bc217b99370d10.1742411889.git.gerickson@nuovations.com> |
Determine if we need to rate-limit QMI services requests to a
transport-specific minimum request period. If so, return true so that
the queue can be retried again later.
Adds the following data members to 'qmi_transport':
* Minimum request period
- The minimum period, in microseconds, for back-to-back QMI
service requests.
* Last request time
- Time, in microseconds, when the last QMI service request was
sent.
to support the implementation.
---
drivers/qmimodem/qmi.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c
index bbe6440abe0f..33063483692e 100644
--- a/drivers/qmimodem/qmi.c
+++ b/drivers/qmimodem/qmi.c
@@ -92,6 +92,18 @@ struct qmi_transport {
const struct qmi_transport_ops *ops;
struct debug_data debug;
bool writer_active : 1;
+
+ /**
+ * If specified via qmi_qmux_device_options, the minimum period
+ * for back-to-back QMI service requests.
+ */
+ unsigned int min_req_period_us;
+
+ /**
+ * The time, in microseconds, when the last QMI service request
+ * was sent.
+ */
+ uint64_t last_req_sent_time_us;
};
struct qmi_qmux_device {
@@ -653,8 +665,28 @@ static bool can_write_data(struct l_io *io, void *user_data)
{
struct qmi_transport *transport = user_data;
struct qmi_request *req;
+ const bool throttle_enabled = transport->min_req_period_us > 0;
+ uint64_t now;
int r;
+ /*
+ * Determine if we need to rate-limit commands to a
+ * transport-specific minimum request period. If so,
+ * return true so that the queue can be retried again
+ * later.
+ */
+ if (throttle_enabled) {
+ now = l_time_now();
+
+ if (transport->last_req_sent_time_us != 0) {
+ const uint64_t delta = l_time_diff(now,
+ transport->last_req_sent_time_us);
+
+ if (delta < transport->min_req_period_us)
+ return true;
+ }
+ }
+
req = l_queue_pop_head(transport->req_queue);
if (!req)
return false;
@@ -665,6 +697,12 @@ static bool can_write_data(struct l_io *io, void *user_data)
return false;
}
+_Pragma("GCC diagnostic push")
+_Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+ if (throttle_enabled)
+ transport->last_req_sent_time_us = now;
+_Pragma("GCC diagnostic pop")
+
if (l_queue_length(transport->req_queue) > 0)
return true;
--
2.45.0