IRC channel logs

2023-08-10.log

back to list of logs

<damo22>youpi: ast_check() is already running every clock interrupt on every cpu
<damo22>cause_ast_check isnt called as far as i can tell
<damo22>youpi: is there something that controls how often threads switch?
<youpi>it's the clock , but that's only for preemption
<youpi>when a thread wakes while the cpu is idle, it's supposed to just get scheduled immediately
<damo22>i fixed a bug that the cause_ast_check is not being called but ast_on is mistakenly being run on a different processor
<youpi>? cause_ast_check is precisely meant to make ast_on being called on a different processor
<damo22>yes
<damo22>but ast_on(cpu_number(), AST_BLOCK) is being called instead
<damo22>its not supposed to be called when cpu_number() != current cpu
<damo22>current processor
<youpi>which of such calls?
<damo22>let me find it
<damo22>+++ b/kern/sched_prim.c
<damo22>@@ -1297,11 +1297,20 @@ void thread_setrun(
<damo22>- current_processor()->first_quantum = FALSE;
<damo22>- ast_on(cpu_number(), AST_BLOCK);
<damo22>i think its supposed to check if th->last_processor == current_processor()
<damo22>and if its different, it should be calling cause_ast_check instaed
<damo22>i think ast_on(cpu_number(),...) is only valid when cpu_number() is mycpu
<damo22>there is a similar pattern lower in the code
<damo22>its in the * Preempt check
<youpi>damo22: no, it makes sense to mark the ast for next time an interrupt triggers, that's the A (asynchronous) letter of ast
<damo22>so if the processor is bound, there is a different preempt check
<damo22>see next block
<damo22>i mean a different ast setting
<damo22>* Cause ast on processor if processor is on line.
<youpi>it looks to me like the "target processor is idle" is missing causing an AST
<damo22>yes
<youpi>it looks to me like the introduction of calling hlt in idle processors missed that part
<damo22>and ast_check() does nothing if processor is idle
<youpi>that's expected
<youpi>ast_check is running *on* the processor
<youpi>so within the interrupt
<youpi>so the idle thread is already interrupted
<damo22>ok
<youpi>no need to IPI it
<youpi>see commit c669ea1b0
<youpi>it introduced machine_idle, making it call hlt
<youpi>and setting POWER_SAVE to 1
<youpi>and thus idle_thread_continue calls it
<youpi>but then it'll stay stuck there until next interrupt
<youpi>since the scheduler doesn't send an IPI when the target cpu is idle, it'll have to wait the clock interrupt
<damo22>oh hlt
<youpi>so in the scheduler code, when the target processor is idle, if POWER_SAVE is 1 a cause_ast_check needs to be sent
<youpi>yes, hlt, since pause is only very small energy saving :)
<youpi>maybe you should read the code of xnu
<youpi>which has much more calls to cause_ast_check
<youpi>well, they have wholy rewritten the scheduler code, though :)
<youpi>it looks to me like it's just thread_setrun which, along the pset->idle_count--; that notes it shouldn't be idle any more, should call cause_ast_check to interrupt the idle thread
<youpi>otherwise the thread will have to wait for next clock interrupt
<youpi>(since it's already dispatched on that cpu, it won't be scheduled on the current cpu...)
<damo22>ive implemented the ast IPI
<damo22>lets see what happens
<damo22>boots quicker
<damo22>ive almost got a shell
<damo22>Activating swap.. failed
<damo22>hmm just sitting there
<youpi>is the vm consuming cpu time?
<damo22>16%
<damo22>still the same line
<damo22>it was pretty quick up to INIT though
<damo22>i will try with smp 6
<damo22>this is smp 4
<damo22>hmm got stuck in rumpdisk
<damo22>cause_ast_check is supposed to do an IPI that calls ast_check() on the remote cpu right?
<youpi>yes, but also most importantly, cause an interrupt
<damo22>yes
<youpi>to get that called:
<youpi>i386/i386/locore.S: cmpl $0,CX(EXT(need_ast),%edx)
<damo22> case PROCESSOR_OFF_LINE:
<damo22> case PROCESSOR_IDLE:
<damo22> case PROCESSOR_DISPATCHING:
<damo22> /*
<damo22> * No ast.
<damo22> */
<damo22> break;
<youpi>yes, they don't have other needs for ast than the mere interrupt
<damo22>doesnt it need to set ast_on ?
<youpi>the idle thread doesn't even need to check need_ast
<youpi>the interrupt is enough for it to get out of hlt and thus try to schedule a thread
<damo22>ohhh
<damo22> is processor->slot_num the kernel id of the cpu to interrupt?
<youpi>yes
<damo22>ok then my code is correct
<damo22>i got a shell with smp 1
<damo22>bed