Le 14/07/2018 à 17:40, Kamil Rytarowski a écrit :
On 14.07.2018 12:52, Maxime Villard wrote:Le 14/07/2018 à 10:29, Martin Husemann a écrit :On Fri, Jul 13, 2018 at 11:49:33PM +0200, Kamil Rytarowski wrote:#ifdefing it out in a non-benchmarking application (I was checking ones that do something with syscalls) is more negligible than 0,3% of overhead in the kernel in a loop.My vote is on #ifdef by a default-off kernel option as well. Next step: optimize the switch, but that is no priority then. Can't we use pcu(9) for that?I've written this [1], from memory I think it's enough. Kamil, please test it, because I intend to commit it soon. Same for i386. We don't update DR6/DR7 on each return to userland, and rather do it during context switches, only when one of the two LWPs is using dbregs. When none is (which always is the case), we don't touch. [1] http://m00nbsd.net/garbage/dbregs/amd64.diffThere are panic, different to the ones that I observed in the past but still there. [ 118.880204] panic: kernel diagnostic assertion "pcb->pcb_dbregs != NULL" failed: file "/usr/src/sys/arch/x86/x86/dbregs.c", line 13 8 [ 118.880204] cpu0: Begin traceback... [ 118.880204] vpanic() at netbsd:vpanic+0x16f [ 118.880204] ch_voltag_convert_in() at netbsd:ch_voltag_convert_in [ 118.880204] x86_dbregs_store_dr6() at netbsd:x86_dbregs_store_dr6+0x4c [ 118.880204] trap() at netbsd:trap+0x97b I will try to fix the patch and be back to you.
I think I missed a kpreempt_disable when we allocate, we don't want a preemption. Eg, in x86_dbregs_read(): if (pcb->pcb_dbregs == NULL) { struct dbreg *dbregs = pool_get(&x86_dbregspl, PR_WAITOK); memcpy(dbregs, &initdbstate, sizeof(initdbstate)); kpreempt_disable(); pcb->pcb_dbregs = dbregs; kpreempt_enable(); } Because if we get preempted before the 'memcpy' finishes, we load dr12367 with an inconsistent state. Later it causes x86_dbregs_user_trap() to return true. Same in x86_dbregs_write().