Hello, So recently I've been looking at the interrupt subsystem for NetBSD/Xen, which is a little unusual in that several interrupts can batch together before a virtual cpu that is scheduled can be woken up to handle them.
When this happens, a single callback handler is invoked, which demultiplexes all the pending interrupts, and passes on to everyone of them the same trapframe that was passed to the callback. This is particularly interesting for the clock handler, because what would have been multiple ticks during any dormant period for the guest OS would be only called once, and so the handler invokes hardclock() a number of times to make up for lost time. Once again, it accounts for it using the exact same trapframe that it got from the demultiplexing callback handler - which if it were from userland, would account every tick to that particular userland process (which was presumably dormant for the duration lost). This got me thinking about deferred interrupts using spl(9), and how time is accounted for those. (I will confess that I have an insiduous interest, but I won't divulge what that is right now). For eg: if a clock interrupt from userland got deferred as pending, even if it came in from userland (is this possible ?), because the current spl level was at, say, SPL_HIGH, it now seems to be the case that the system accounts for the delayed execution by charging the *entire* time (from the last hardclock() inclusive of whatever was executing at SPL_HIGH, to the system and not the userland process, thus charging the time interval between when the last hardclock() was called, and when it was actually serviced, to the system instead of the user process that was originally interrupted. To emphasise my point, I've added a patch below that I think should reflect the accounting correctly. I'm not sure I've understood this correctly, so I'd appreciate it if someone who has a good understanding of this would be able to comment. Many Thanks, Cherry --- kern_clock.c.~1.138.~ 2018-09-21 11:28:02.792675611 +0000 +++ kern_clock.c 2018-10-16 12:06:38.753987323 +0000 @@ -352,6 +352,10 @@ } if (CLKF_USERMODE(frame)) { + if (p == NULL) { /* Account deferred clock ticks to current user. */ + p = l->l_proc; + mutex_spin_enter(&p->p_stmutex); + } KASSERT(p != NULL); if ((p->p_stflag & PST_PROFIL) && profsrc == PROFSRC_CLOCK) addupc_intr(l, CLKF_PC(frame)); -- ~cherry