Non-rt sleep is extremely inaccurate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I reported this on https://bugzilla.kernel.org/show_bug.cgi?id=216702
two weeks ago, but I believe that the bug tracker has less activity
than this mailing list.

Here's the bug report I pasted:
std::this_thread::sleep_for and other types of sleep in non-realtime
tasks are extremely inaccurate on some RT kernels.
A sleep of 10ms may sometimes take over 700ms to complete.
The PC is idle, and there are no RT tasks running.

This has been tested on modern Intel CPUs (1165G7 and 1260p) as well
as Ryzen 4800HS.

I have tested many combinations of CPU governors and performance
settings but the problem is not fixed by those.

I initially tried  5.10, 5.16, 5.19, and 6.0, and all except 5.10
exhibited the same behavior.

With a 5.10 kernel, I may run the sample code for 20 minutes and get
3-4 messages about the sleep taking at most 25ms.

With the other kernels, multiple times per minute I get sleeps of up to 700ms.

Later I tried v6.1-rc5-rt3 which exhibits the same problem too 7-8
messages per minute.

5.16.2 with 5.16.2-rt18 works better, with 1-2 messages per minute.

5.15.49 with 5.15.49-rt47  works almost flawlessly.

I have tried the same kernels without the RT patch on the same
computers, and the problem does not occur.

I have built the kernels myself, and have also tried with the ones from:
https://packages.debian.org/search?arch=amd64&keywords=linux-image-rt

I have tried using the config from 5.10 on the 6.0 kernel, but the
problem still appears on the 6.0 rt kernel.

I would really like to use the RT patch on 6.1 or  6.2 when available
since the system we are using has an Intel Hybrid 12th gen CPU, the
support of which is being greatly improved lately.

I am attaching an example to reproduce the issue:
#include "thread"
#include "iostream"

int main(int , char **)
{
  while (true)
  {
    auto begin = std::chrono::system_clock::now();
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    auto end = std::chrono::system_clock::now();
    if (end - begin > std::chrono::milliseconds(20))
    {
      std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count()
                << std::endl;
    }
  }
  return 0;
}

[Index of Archives]     [RT Stable]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux