Print this page
13902 Fix for 13717 may break 8-disk raidz2
13915 installctx() blocking allocate causes problems
Portions contributed by: Jerry Jelinek <gjelinek@gmail.com>
Change-Id: I934d69946cec42630fc541fa8c7385b862b69ca2

*** 18,28 **** * * CDDL HEADER END */ /* * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2020 Joyent, Inc. * Copyright 2021 RackTop Systems, Inc. */ /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */ --- 18,28 ---- * * CDDL HEADER END */ /* * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2021 Joyent, Inc. * Copyright 2021 RackTop Systems, Inc. */ /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */
*** 668,678 **** * Mark that both the parent and child need to have the FPU cleaned up * before returning to user land. */ installctx(ct, cfp, fpsave_ctxt, fprestore_ctxt, fp_new_lwp, ! fp_new_lwp, NULL, fp_free); } /* * Free any state associated with floating point context. * Fp_free can be called in three cases: --- 668,678 ---- * Mark that both the parent and child need to have the FPU cleaned up * before returning to user land. */ installctx(ct, cfp, fpsave_ctxt, fprestore_ctxt, fp_new_lwp, ! fp_new_lwp, NULL, fp_free, NULL); } /* * Free any state associated with floating point context. * Fp_free can be called in three cases:
*** 794,803 **** --- 794,804 ---- */ void fp_exec(void) { struct fpu_ctx *fp = &ttolwp(curthread)->lwp_pcb.pcb_fpu; + struct ctxop *ctx = installctx_preallocate(); if (fp_save_mech == FP_XSAVE) { fp->fpu_xsave_mask = XFEATURE_FP_ALL; }
*** 805,815 **** * Make sure that we're not preempted in the middle of initializing the * FPU on CPU. */ kpreempt_disable(); installctx(curthread, fp, fpsave_ctxt, fprestore_ctxt, fp_new_lwp, ! fp_new_lwp, NULL, fp_free); fpinit(); fp->fpu_flags = FPU_EN; kpreempt_enable(); } --- 806,816 ---- * Make sure that we're not preempted in the middle of initializing the * FPU on CPU. */ kpreempt_disable(); installctx(curthread, fp, fpsave_ctxt, fprestore_ctxt, fp_new_lwp, ! fp_new_lwp, NULL, fp_free, ctx); fpinit(); fp->fpu_flags = FPU_EN; kpreempt_enable(); }
*** 834,844 **** if (fp_save_mech == FP_XSAVE) { fp->fpu_xsave_mask = XFEATURE_FP_ALL; } installctx(curthread, fp, fpsave_ctxt, fprestore_ctxt, fp_new_lwp, ! fp_new_lwp, NULL, fp_free); fpinit(); /* * If FPU_VALID is set, it means someone has modified registers via * /proc. In this case, restore the current lwp's state. --- 835,845 ---- if (fp_save_mech == FP_XSAVE) { fp->fpu_xsave_mask = XFEATURE_FP_ALL; } installctx(curthread, fp, fpsave_ctxt, fprestore_ctxt, fp_new_lwp, ! fp_new_lwp, NULL, fp_free, NULL); fpinit(); /* * If FPU_VALID is set, it means someone has modified registers via * /proc. In this case, restore the current lwp's state.
*** 1316,1325 **** --- 1317,1327 ---- void kernel_fpu_begin(kfpu_state_t *kfpu, uint_t flags) { klwp_t *pl = curthread->t_lwp; + struct ctxop *ctx; if ((curthread->t_flag & T_KFPU) != 0) { panic("curthread attempting to nest kernel FPU states"); }
*** 1378,1404 **** * * 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) { kpreempt_disable(); if ((flags & KFPU_USE_LWP) == 0) fp_save(&pl->lwp_pcb.pcb_fpu); pl->lwp_pcb.pcb_fpu.fpu_flags |= FPU_KERNEL; - kpreempt_enable(); } /* ! * Set the context operations for kernel FPU usage. Note that this ! * cannot be done with pre-emption and interrupts disabled, since ! * installctx does a sleeping allocation. We haven't finished ! * initializing our kernel FPU state yet, but in the rare case that we ! * happen to save/restore before that, no harm is done. */ 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) { /* --- 1380,1408 ---- * * 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. */ ! ctx = installctx_preallocate(); kpreempt_disable(); + if (pl != NULL) { if ((flags & KFPU_USE_LWP) == 0) fp_save(&pl->lwp_pcb.pcb_fpu); pl->lwp_pcb.pcb_fpu.fpu_flags |= FPU_KERNEL; } /* ! * Set the context operations for kernel FPU usage. Note that this is ! * done with a preallocated buffer and under kpreempt_disable because ! * without a preallocated buffer, installctx does a sleeping ! * allocation. We haven't finished initializing our kernel FPU state ! * yet, and in the rare case that we happen to save/restore just as ! * installctx() exits its own kpreempt_enable() internal call, we ! * guard against restoring an uninitialized buffer (0xbaddcafe). */ installctx(curthread, kfpu, kernel_fpu_ctx_save, kernel_fpu_ctx_restore, ! NULL, NULL, NULL, NULL, ctx); curthread->t_flag |= T_KFPU; if ((flags & KFPU_USE_LWP) == KFPU_USE_LWP) { /*
*** 1418,1427 **** --- 1422,1432 ---- pf->fpu_flags = FPU_EN | FPU_KERNEL; } else { /* initialize the kfpu state */ kernel_fpu_ctx_restore(kfpu); } + kpreempt_enable(); } void kernel_fpu_end(kfpu_state_t *kfpu, uint_t flags) {