Author: vangyzen
Date: Fri Jun 12 21:10:45 2020
New Revision: 362119
URL: https://svnweb.freebsd.org/changeset/base/362119

Log:
  FPU init: Do potentially blocking operations before disabling interrupts
  
  In particular, uma_zcreate creates sysctl oids, which locks an sx lock,
  which uses IPIs under contention.  IPIs tend not to work very well
  when interrupts are disabled.  Who knew, right?
  
  Reviewed by:  cem kib
  MFC after:    2 weeks
  Sponsored by: Dell EMC Isilon
  Differential Revision:        https://reviews.freebsd.org/D25098

Modified:
  head/sys/amd64/amd64/fpu.c
  head/sys/i386/i386/npx.c

Modified: head/sys/amd64/amd64/fpu.c
==============================================================================
--- head/sys/amd64/amd64/fpu.c  Fri Jun 12 20:39:42 2020        (r362118)
+++ head/sys/amd64/amd64/fpu.c  Fri Jun 12 21:10:45 2020        (r362119)
@@ -368,8 +368,18 @@ fpuinitstate(void *arg __unused)
        register_t saveintr;
        int cp[4], i, max_ext_n;
 
+       /* Do potentially blocking operations before disabling interrupts. */
+       fpu_save_area_zone = uma_zcreate("FPU_save_area",
+           cpu_max_ext_state_size, NULL, NULL, NULL, NULL,
+           XSAVE_AREA_ALIGN - 1, 0);
        fpu_initialstate = malloc(cpu_max_ext_state_size, M_DEVBUF,
            M_WAITOK | M_ZERO);
+       if (use_xsave) {
+               max_ext_n = flsl(xsave_mask);
+               xsave_area_desc = malloc(max_ext_n * sizeof(struct
+                   xsave_area_elm_descr), M_DEVBUF, M_WAITOK | M_ZERO);
+       }
+
        saveintr = intr_disable();
        stop_emulating();
 
@@ -399,9 +409,6 @@ fpuinitstate(void *arg __unused)
                    offsetof(struct xstate_hdr, xstate_bv));
                *xstate_bv = XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE;
 
-               max_ext_n = flsl(xsave_mask);
-               xsave_area_desc = malloc(max_ext_n * sizeof(struct
-                   xsave_area_elm_descr), M_DEVBUF, M_WAITOK | M_ZERO);
                /* x87 state */
                xsave_area_desc[0].offset = 0;
                xsave_area_desc[0].size = 160;
@@ -415,10 +422,6 @@ fpuinitstate(void *arg __unused)
                        xsave_area_desc[i].size = cp[0];
                }
        }
-
-       fpu_save_area_zone = uma_zcreate("FPU_save_area",
-           cpu_max_ext_state_size, NULL, NULL, NULL, NULL,
-           XSAVE_AREA_ALIGN - 1, 0);
 
        start_emulating();
        intr_restore(saveintr);

Modified: head/sys/i386/i386/npx.c
==============================================================================
--- head/sys/i386/i386/npx.c    Fri Jun 12 20:39:42 2020        (r362118)
+++ head/sys/i386/i386/npx.c    Fri Jun 12 21:10:45 2020        (r362119)
@@ -479,8 +479,21 @@ npxinitstate(void *arg __unused)
        if (!hw_float)
                return;
 
+       /* Do potentially blocking operations before disabling interrupts. */
+       fpu_save_area_zone = uma_zcreate("FPU_save_area",
+           cpu_max_ext_state_size, NULL, NULL, NULL, NULL,
+           XSAVE_AREA_ALIGN - 1, 0);
        npx_initialstate = malloc(cpu_max_ext_state_size, M_DEVBUF,
            M_WAITOK | M_ZERO);
+       if (use_xsave) {
+               if (xsave_mask >> 32 != 0)
+                       max_ext_n = fls(xsave_mask >> 32) + 32;
+               else
+                       max_ext_n = fls(xsave_mask);
+               xsave_area_desc = malloc(max_ext_n * sizeof(struct
+                   xsave_area_elm_descr), M_DEVBUF, M_WAITOK | M_ZERO);
+       }
+
        saveintr = intr_disable();
        stop_emulating();
 
@@ -522,12 +535,6 @@ npxinitstate(void *arg __unused)
                    offsetof(struct xstate_hdr, xstate_bv));
                *xstate_bv = XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE;
 
-               if (xsave_mask >> 32 != 0)
-                       max_ext_n = fls(xsave_mask >> 32) + 32;
-               else
-                       max_ext_n = fls(xsave_mask);
-               xsave_area_desc = malloc(max_ext_n * sizeof(struct
-                   xsave_area_elm_descr), M_DEVBUF, M_WAITOK | M_ZERO);
                /* x87 state */
                xsave_area_desc[0].offset = 0;
                xsave_area_desc[0].size = 160;
@@ -541,10 +548,6 @@ npxinitstate(void *arg __unused)
                        xsave_area_desc[i].size = cp[0];
                }
        }
-
-       fpu_save_area_zone = uma_zcreate("FPU_save_area",
-           cpu_max_ext_state_size, NULL, NULL, NULL, NULL,
-           XSAVE_AREA_ALIGN - 1, 0);
 
        start_emulating();
        intr_restore(saveintr);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to