Print this page
Fix for 13717 may break 8-disk raidz2

@@ -1379,14 +1379,31 @@
          * We might have already saved once (due to a prior use of the kernel
          * FPU or another code path) so FPU_VALID could be set. This is handled
          * by fp_save, as is the FPU_EN check.
          */
         if (pl != NULL) {
+                fpu_ctx_t *pf = &pl->lwp_pcb.pcb_fpu;
+
                 kpreempt_disable();
-                if ((flags & KFPU_USE_LWP) == 0)
-                        fp_save(&pl->lwp_pcb.pcb_fpu);
-                pl->lwp_pcb.pcb_fpu.fpu_flags |= FPU_KERNEL;
+                if ((flags & KFPU_USE_LWP) == 0) {
+                        fp_save(pf);
+                } else {
+                        /*
+                         * For pure kernel threads with an LWP, we can use the
+                         * LWP's pcb_fpu to save/restore context.
+                         */
+                        VERIFY(curthread->t_procp->p_flag & SSYS);
+                        VERIFY(kfpu == NULL);
+                        ASSERT((pf->fpu_flags & FPU_EN) == 0);
+
+                        /* Always restore the fpu to the initial state. */
+                        if (fp_save_mech == FP_XSAVE)
+                                pf->fpu_xsave_mask = XFEATURE_FP_ALL;
+                        fpinit();
+                        pf->fpu_flags = FPU_EN;
+                }
+                pf->fpu_flags |= FPU_KERNEL;
                 kpreempt_enable();
         }
 
         /*
          * Set the context operations for kernel FPU usage. Note that this

@@ -1398,27 +1415,11 @@
         installctx(curthread, kfpu, kernel_fpu_ctx_save, kernel_fpu_ctx_restore,
             NULL, NULL, NULL, NULL);
 
         curthread->t_flag |= T_KFPU;
 
-        if ((flags & KFPU_USE_LWP) == KFPU_USE_LWP) {
-                /*
-                 * For pure kernel threads with an LWP, we can use the LWP's
-                 * pcb_fpu to save/restore context.
-                 */
-                fpu_ctx_t *pf = &pl->lwp_pcb.pcb_fpu;
-
-                VERIFY(curthread->t_procp->p_flag & SSYS);
-                VERIFY(kfpu == NULL);
-                ASSERT((pf->fpu_flags & FPU_EN) == 0);
-
-                /* Always restore the fpu to the initial state. */
-                if (fp_save_mech == FP_XSAVE)
-                        pf->fpu_xsave_mask = XFEATURE_FP_ALL;
-                fpinit();
-                pf->fpu_flags = FPU_EN | FPU_KERNEL;
-        } else {
+        if ((flags & KFPU_USE_LWP) == 0) {
                 /* initialize the kfpu state */
                 kernel_fpu_ctx_restore(kfpu);
         }
 }