This avoids taking the kernel lock when ci_inatomic is set.  This
might speed up inteldrm(4) a bit.  Since uvm_grow() still needs the
kernel lock, some reorganization of the code is necessary.

I'm not sure this actaully has an impact.  If we end up here with
ci_inatomic set we're going to return EFAULT and take a slow path
anyway.  So maybe it is better to leave this until we make uvm_grow()
mpsafe?


Index: arch/amd64/amd64/trap.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/trap.c,v
retrieving revision 1.81
diff -u -p -r1.81 trap.c
--- arch/amd64/amd64/trap.c     14 Sep 2020 12:51:28 -0000      1.81
+++ arch/amd64/amd64/trap.c     24 Sep 2020 14:21:24 -0000
@@ -173,11 +173,10 @@ pageflttrap(struct trapframe *frame, uin
        pcb = &p->p_addr->u_pcb;
        va = trunc_page((vaddr_t)cr2);
 
-       KERNEL_LOCK();
-
        if (!usermode) {
                /* This will only trigger if SMEP is enabled */
                if (cr2 <= VM_MAXUSER_ADDRESS && frame->tf_err & PGEX_I) {
+                       KERNEL_LOCK();
                        fault("attempt to execute user address %p "
                            "in supervisor mode", (void *)cr2);
                        /* retain kernel lock */
@@ -186,6 +185,7 @@ pageflttrap(struct trapframe *frame, uin
                /* This will only trigger if SMAP is enabled */
                if (pcb->pcb_onfault == NULL && cr2 <= VM_MAXUSER_ADDRESS &&
                    frame->tf_err & PGEX_P) {
+                       KERNEL_LOCK();
                        fault("attempt to access user address %p "
                            "in supervisor mode", (void *)cr2);
                        /* retain kernel lock */
@@ -216,28 +216,29 @@ pageflttrap(struct trapframe *frame, uin
                caddr_t onfault = pcb->pcb_onfault;
 
                pcb->pcb_onfault = NULL;
+               KERNEL_LOCK();
                error = uvm_fault(map, va, frame->tf_err & PGEX_P ?
                    VM_FAULT_PROTECT : VM_FAULT_INVALID, ftype);
+               if (error == 0 && map != kernel_map)
+                       uvm_grow(p, va);
+               KERNEL_UNLOCK();
                pcb->pcb_onfault = onfault;
        } else
                error = EFAULT;
 
-       if (error == 0) {
-               if (map != kernel_map)
-                       uvm_grow(p, va);
-       } else if (!usermode) {
+       if (error && !usermode) {
                if (pcb->pcb_onfault != 0) {
-                       KERNEL_UNLOCK();
                        frame->tf_rip = (u_int64_t)pcb->pcb_onfault;
                        return 1;
                } else {
                        /* bad memory access in the kernel */
+                       KERNEL_LOCK();
                        fault("uvm_fault(%p, 0x%llx, 0, %d) -> %x",
                            map, cr2, ftype, error);
                        /* retain kernel lock */
                        return 0;
                }
-       } else {
+       } else if (error) {
                union sigval sv;
                int signal, sicode;
 
@@ -260,8 +261,6 @@ pageflttrap(struct trapframe *frame, uin
                sv.sival_ptr = (void *)cr2;
                trapsignal(p, signal, T_PAGEFLT, sicode, sv);
        }
-
-       KERNEL_UNLOCK();
 
        return 1;
 }

Reply via email to