In vm_pageout_worker(), we do not account for the time that it takes to scan the active and inactive queues, or delays in starting vm_pageout_worker(), when computing the sleep time. Consequently, as the amount of time that vm_pageout_worker() spends scanning the queues varies, so does the timing of the calls to pidctrl_daemon(). For example, under a PostgreSQL workload, I see the interval between calls stretch by 10+%. This change computes a sleep time based on the next desired execution tick for the controller.
On my test machine, calls to pidctrl_daemon() often occur one tick earlier than expected, and this triggers the "multiple calls within an interval" case. Suppose that calls occur at time t, t+99, and t+199. The effect of the "multiple calls within an interval" handling at time t+99 is that the integral term has much reduced impact on the output.