mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
iichid: keep a fixed sampling cadence in polled mode
Touchpads using sampling mode have a sampling task which is run at a certain polling rate. When the system is under load this task may not complete quickly which might stretch the time taken beyond what the polling rate should be, leading to dropped touchpad motion. On my laptop this causes the touchpad to be barely useable when the system is under heavy load, and it is really difficult to move the cursor since so many events are dropped. This change adjusts the sampling loop to schedule the next polling event to take place at a specific time in the future, based on the polling period. If servicing the poll takes longer due to load then the next sample will still be scheduled at its original time. Approved by: wulf, khng (mentor) Differential Revision: https://reviews.freebsd.org/D0914
This commit is contained in:
1 parent
9ed1713e28
commit
e58325fb98
1 file changed
+17
-1
+17
-1
@@ -180,6 +180,7 @@ struct iichid_softc {
|
||||
int sampling_rate_slow; /* iicbus lock */
|
||||
int sampling_rate_fast;
|
||||
int sampling_hysteresis;
|
||||
sbintime_t next_sample; /* iicbus lock */
|
||||
int missing_samples; /* iicbus lock */
|
||||
int dup_samples; /* iicbus lock */
|
||||
iichid_size_t dup_size; /* iicbus lock */
|
||||
@@ -527,6 +528,7 @@ iichid_sampling_task(void *context, int pending)
|
||||
{
|
||||
struct iichid_softc *sc;
|
||||
device_t parent;
|
||||
sbintime_t now, period;
|
||||
iichid_size_t actual;
|
||||
bool bus_requested;
|
||||
int error, rate;
|
||||
@@ -569,8 +571,21 @@ rearm:
|
||||
rate = sc->sampling_rate_slow;
|
||||
else
|
||||
rate = sc->sampling_rate_fast;
|
||||
period = SBT_1S / MAX(rate, 1);
|
||||
/*
|
||||
* Schedule against an absolute deadline advanced by one
|
||||
* period per sample, so that neither the time spent in the
|
||||
* I2C transaction and handler dispatch nor the taskqueue
|
||||
* wakeup latency stretches the sampling period. If the
|
||||
* deadline has already passed then only advance the sample
|
||||
* by one period rather than bursting polls to catch up.
|
||||
*/
|
||||
now = sbinuptime();
|
||||
sc->next_sample += period;
|
||||
if (sc->next_sample <= now)
|
||||
sc->next_sample = now + period;
|
||||
taskqueue_enqueue_timeout_sbt(sc->taskqueue, &sc->sampling_task,
|
||||
SBT_1S / MAX(rate, 1), 0, C_PREL(2));
|
||||
sc->next_sample, 0, C_ABSOLUTE);
|
||||
}
|
||||
out:
|
||||
if (bus_requested)
|
||||
@@ -746,6 +761,7 @@ iichid_reset_callout(struct iichid_softc *sc)
|
||||
sc->missing_samples = sc->sampling_hysteresis;
|
||||
sc->dup_samples = 0;
|
||||
sc->dup_size = 0;
|
||||
sc->next_sample = sbinuptime();
|
||||
taskqueue_enqueue_timeout(sc->taskqueue, &sc->sampling_task, 0);
|
||||
|
||||
return (0);
|
||||
|
||||
Reference in new issue
Block a user