Am 03.11.2015 8:11 vorm. schrieb Anton Ivanov <anton.iva...@kot-begemot.co.uk>: > > On 02/11/15 22:13, Anton Ivanov wrote: > > On 02/11/15 21:50, Richard Weinberger wrote: > >> Am 02.11.2015 um 17:16 schrieb Anton Ivanov: > >>> -void idle_sleep(unsigned long long nsecs) > >>> +/** > >>> + * os_idle_sleep() - sleep for a given time of nsecs > >>> + * @nsecs: nanoseconds to sleep > >>> + */ > >>> +void os_idle_sleep(unsigned long long nsecs) > >>> { > >>> struct timespec ts; > >>> > >>> - /* > >>> - * nsecs can come in as zero, in which case, this starts a > >>> - * busy loop. To prevent this, reset nsecs to the tick > >>> - * interval if it is zero. > >>> - */ > >>> - if (nsecs == 0) > >>> - nsecs = UM_NSEC_PER_SEC / UM_HZ; > >>> + if (nsecs <= 0) { > >>> + return; > >>> + } > >>> > >>> - nsecs = sleep_time(nsecs); > >>> - ts = ((struct timespec) { .tv_sec = nsecs / UM_NSEC_PER_SEC, > >>> - .tv_nsec = nsecs % UM_NSEC_PER_SEC }); > >>> + ts = ((struct timespec) { > >>> + .tv_sec = nsecs / UM_NSEC_PER_SEC, > >>> + .tv_nsec = nsecs % UM_NSEC_PER_SEC > >>> + }); > >>> > >>> - if (nanosleep(&ts, &ts) == 0) > >>> + if (clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL)) { > >>> deliver_alarm(); > >>> - after_sleep_interval(&ts); > >>> + } > >> Hmm, now this function sleeps at most nsecs. If it is interrupted > >> the alarm is delivered. > >> Why only upon interruption and not also if clock_nanosleep() > >> completes? > > It is invoked differently. > > > > We changed process.c too. > > > > The old behaviour used to be to disable the timer, read timer remaining > > and program a nanosleep with that. This resulted in the timer actually > > firing in idle despite UML using the virtual clock for timers. > > > > With timer moving to MONOTONIC we could do the same, but we do not need > > to. Instead of disabling the timer we can leave it running and program a > > nanosleep which is long enough in most cases for the timer to fire. This > > is what the matching change in process.c does. Together, this results in > > saving at least 2 syscalls per each idle invocation. > > Re-reading this, I did not answer the question fully, apologies. > > clock_nanosleep here is usually programmed with a fixed value in > process.c which is of no relation to the time when the next timer > interrupt should be delivered. So there is no need to re-deliver an > interrupt at the end of a nanosleep as the end of the nanosleep is of no > significance as far as the timer subsystem is concerned. > > IMHO, the IRQ only needs to be relayed when the nanosleep is interrupted.
Ah, okay, now I understand the problem. I didn't think about this case! Nice catch Richard! Thanks Anton for figuring this out! With kind regards Thomas > > That differs to the old behaviour which programmed the nanosleep with > the remainder of the time till the next interrupt thus making it > necessary to relay once the nanosleep expires and restart the nanosleep > if it was interrupted by IO. > > A. > > > > > A. > > > >> Thanks, > >> //richard ------------------------------------------------------------------------------ _______________________________________________ User-mode-linux-devel mailing list User-mode-linux-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel