tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Removing dbregs



Le 14/07/2018 à 17:55, Maxime Villard a écrit :
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.diff

There 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().

... and in setregs() it should be:

	if (pcb->pcb_dbregs != NULL) {
		struct dbreg *dbregs = pcb->pcb_dbregs;
		kpreempt_disable();
		pcb->pcb_dbregs = NULL;
		x86_dbregs_clear(l);
		kpreempt_enable();
	}

damn my shit is wrong -- let's discuss the details offlist to avoid the
noise


Home | Main Index | Thread Index | Old Index