input: prevent the caller from sleeping in sysworkq

Sleeping in sysworkq is a very bad idea, it can trash any hope of
realtimeness at best, deadlock the whole system at worse.

Add a check to input_report to downgrade the event to K_NO_WAIT
automatically when called from the sysworkq, similarly to what's done by
other APIs (netbuf and bluetooth), though only log if messages are
actually dropped.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
This commit is contained in:
Fabio Baltieri 2024-11-27 12:20:57 +00:00 committed by Benjamin Cabé
commit 3146a5552f

View file

@ -50,7 +50,21 @@ int input_report(const struct device *dev,
};
#ifdef CONFIG_INPUT_MODE_THREAD
return k_msgq_put(&input_msgq, &evt, timeout);
int ret;
if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT) &&
k_current_get() == k_work_queue_thread_get(&k_sys_work_q)) {
LOG_DBG("Timeout discarded. No blocking in syswq.");
timeout = K_NO_WAIT;
}
ret = k_msgq_put(&input_msgq, &evt, timeout);
if (ret < 0) {
LOG_WRN("Event dropped, queue full, not blocking in syswq.");
return ret;
}
return 0;
#else
input_process(&evt);
return 0;