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

Reply via email to