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


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.

  24  */
  25 
  26 #include <sys/param.h>
  27 #include <sys/thread.h>
  28 #include <sys/cpuvar.h>
  29 #include <sys/inttypes.h>
  30 #include <sys/cmn_err.h>
  31 #include <sys/time.h>
  32 #include <sys/ksynch.h>
  33 #include <sys/systm.h>
  34 #include <sys/kcpc.h>
  35 #include <sys/cpc_impl.h>
  36 #include <sys/cpc_pcbe.h>
  37 #include <sys/atomic.h>
  38 #include <sys/sunddi.h>
  39 #include <sys/modctl.h>
  40 #include <sys/sdt.h>
  41 #include <sys/archsystm.h>
  42 #include <sys/promif.h>
  43 #include <sys/x_call.h>


 301 
 302         /*
 303          * Create the data store for this set.
 304          */
 305         set->ks_data = kmem_alloc(set->ks_nreqs * sizeof (uint64_t), KM_SLEEP);
 306 
 307         if ((error = kcpc_configure_reqs(ctx, set, subcode)) != 0) {
 308                 kmem_free(set->ks_data, set->ks_nreqs * sizeof (uint64_t));
 309                 kcpc_ctx_free(ctx);
 310                 t->t_cpc_ctx = NULL;
 311                 return (error);
 312         }
 313 
 314         set->ks_ctx = ctx;
 315         ctx->kc_set = set;
 316 
 317         /*
 318          * Add a device context to the subject thread.
 319          */
 320         installctx(t, ctx, kcpc_save, kcpc_restore, NULL,
 321             kcpc_lwp_create, NULL, kcpc_free);
 322 
 323         /*
 324          * Ask the backend to program the hardware.
 325          */
 326         if (t == curthread) {
 327                 int save_spl;
 328 
 329                 kpreempt_disable();
 330                 save_spl = spl_xcall();
 331                 kcpc_program(ctx, B_TRUE, B_TRUE);
 332                 splx(save_spl);
 333                 kpreempt_enable();
 334         } else {
 335                 /*
 336                  * Since we are the agent LWP, we know the victim LWP is stopped
 337                  * until we're done here; no need to worry about preemption or
 338                  * migration here. We still use an atomic op to clear the flag
 339                  * to ensure the flags are always self-consistent; they can
 340                  * still be accessed from, for instance, another CPU doing a
 341                  * kcpc_invalidate_all().


1407                  * overflow signal to all children if we have the LWPINHERIT
1408                  * and SIGOVF flags set. In addition, all counters should be
1409                  * set to UINT64_MAX, and their pic's overflow flag turned on
1410                  * so that our trap() processing knows to send a signal.
1411                  */
1412                 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_FREEZE);
1413                 for (i = 0; i < ks->ks_nreqs; i++) {
1414                         kcpc_request_t *kr = &ks->ks_req[i];
1415 
1416                         if (kr->kr_flags & CPC_OVF_NOTIFY_EMT) {
1417                                 *(kr->kr_data) = UINT64_MAX;
1418                                 atomic_or_uint(&kr->kr_picp->kp_flags,
1419                                     KCPC_PIC_OVERFLOWED);
1420                         }
1421                 }
1422                 ttolwp(ct)->lwp_pcb.pcb_flags |= CPC_OVERFLOW;
1423                 aston(ct);
1424         }
1425 
1426         installctx(ct, cctx, kcpc_save, kcpc_restore,
1427             NULL, kcpc_lwp_create, NULL, kcpc_free);
1428 }
1429 
1430 /*
1431  * Counter Stoppage Theory
1432  *
1433  * The counters may need to be stopped properly at the following occasions:
1434  *
1435  * 1) An LWP exits.
1436  * 2) A thread exits.
1437  * 3) An LWP performs an exec().
1438  * 4) A bound set is unbound.
1439  *
1440  * In addition to stopping the counters, the CPC context (a kcpc_ctx_t) may need
1441  * to be freed as well.
1442  *
1443  * Case 1: kcpc_passivate(), called via lwp_exit(), stops the counters. Later on
1444  * when the thread is freed, kcpc_free(), called by freectx(), frees the
1445  * context.
1446  *
1447  * Case 2: same as case 1 except kcpc_passivate is called from thread_exit().




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2021 Joyent, Inc.
  25  */
  26 
  27 #include <sys/param.h>
  28 #include <sys/thread.h>
  29 #include <sys/cpuvar.h>
  30 #include <sys/inttypes.h>
  31 #include <sys/cmn_err.h>
  32 #include <sys/time.h>
  33 #include <sys/ksynch.h>
  34 #include <sys/systm.h>
  35 #include <sys/kcpc.h>
  36 #include <sys/cpc_impl.h>
  37 #include <sys/cpc_pcbe.h>
  38 #include <sys/atomic.h>
  39 #include <sys/sunddi.h>
  40 #include <sys/modctl.h>
  41 #include <sys/sdt.h>
  42 #include <sys/archsystm.h>
  43 #include <sys/promif.h>
  44 #include <sys/x_call.h>


 302 
 303         /*
 304          * Create the data store for this set.
 305          */
 306         set->ks_data = kmem_alloc(set->ks_nreqs * sizeof (uint64_t), KM_SLEEP);
 307 
 308         if ((error = kcpc_configure_reqs(ctx, set, subcode)) != 0) {
 309                 kmem_free(set->ks_data, set->ks_nreqs * sizeof (uint64_t));
 310                 kcpc_ctx_free(ctx);
 311                 t->t_cpc_ctx = NULL;
 312                 return (error);
 313         }
 314 
 315         set->ks_ctx = ctx;
 316         ctx->kc_set = set;
 317 
 318         /*
 319          * Add a device context to the subject thread.
 320          */
 321         installctx(t, ctx, kcpc_save, kcpc_restore, NULL,
 322             kcpc_lwp_create, NULL, kcpc_free, NULL);
 323 
 324         /*
 325          * Ask the backend to program the hardware.
 326          */
 327         if (t == curthread) {
 328                 int save_spl;
 329 
 330                 kpreempt_disable();
 331                 save_spl = spl_xcall();
 332                 kcpc_program(ctx, B_TRUE, B_TRUE);
 333                 splx(save_spl);
 334                 kpreempt_enable();
 335         } else {
 336                 /*
 337                  * Since we are the agent LWP, we know the victim LWP is stopped
 338                  * until we're done here; no need to worry about preemption or
 339                  * migration here. We still use an atomic op to clear the flag
 340                  * to ensure the flags are always self-consistent; they can
 341                  * still be accessed from, for instance, another CPU doing a
 342                  * kcpc_invalidate_all().


1408                  * overflow signal to all children if we have the LWPINHERIT
1409                  * and SIGOVF flags set. In addition, all counters should be
1410                  * set to UINT64_MAX, and their pic's overflow flag turned on
1411                  * so that our trap() processing knows to send a signal.
1412                  */
1413                 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_FREEZE);
1414                 for (i = 0; i < ks->ks_nreqs; i++) {
1415                         kcpc_request_t *kr = &ks->ks_req[i];
1416 
1417                         if (kr->kr_flags & CPC_OVF_NOTIFY_EMT) {
1418                                 *(kr->kr_data) = UINT64_MAX;
1419                                 atomic_or_uint(&kr->kr_picp->kp_flags,
1420                                     KCPC_PIC_OVERFLOWED);
1421                         }
1422                 }
1423                 ttolwp(ct)->lwp_pcb.pcb_flags |= CPC_OVERFLOW;
1424                 aston(ct);
1425         }
1426 
1427         installctx(ct, cctx, kcpc_save, kcpc_restore,
1428             NULL, kcpc_lwp_create, NULL, kcpc_free, NULL);
1429 }
1430 
1431 /*
1432  * Counter Stoppage Theory
1433  *
1434  * The counters may need to be stopped properly at the following occasions:
1435  *
1436  * 1) An LWP exits.
1437  * 2) A thread exits.
1438  * 3) An LWP performs an exec().
1439  * 4) A bound set is unbound.
1440  *
1441  * In addition to stopping the counters, the CPC context (a kcpc_ctx_t) may need
1442  * to be freed as well.
1443  *
1444  * Case 1: kcpc_passivate(), called via lwp_exit(), stops the counters. Later on
1445  * when the thread is freed, kcpc_free(), called by freectx(), frees the
1446  * context.
1447  *
1448  * Case 2: same as case 1 except kcpc_passivate is called from thread_exit().