Print this page
patch as-lock-macro-simplification


 214                 mutex_enter(&p->p_lock);
 215                 pool_barrier_exit();
 216                 continuelwps(p);
 217                 mutex_exit(&p->p_lock);
 218                 error = EAGAIN;
 219                 goto forkerr;
 220         }
 221 
 222         TRACE_2(TR_FAC_PROC, TR_PROC_FORK, "proc_fork:cp %p p %p", cp, p);
 223 
 224         /*
 225          * Assign an address space to child
 226          */
 227         if (isvfork) {
 228                 /*
 229                  * Clear any watched areas and remember the
 230                  * watched pages for restoring in vfwait().
 231                  */
 232                 as = p->p_as;
 233                 if (avl_numnodes(&as->a_wpage) != 0) {
 234                         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
 235                         as_clearwatch(as);
 236                         p->p_wpage = as->a_wpage;
 237                         avl_create(&as->a_wpage, wp_compare,
 238                             sizeof (struct watched_page),
 239                             offsetof(struct watched_page, wp_link));
 240                         AS_LOCK_EXIT(as, &as->a_lock);
 241                 }
 242                 cp->p_as = as;
 243                 cp->p_flag |= SVFORK;
 244 
 245                 /*
 246                  * Use the parent's shm segment list information for
 247                  * the child as it uses its address space till it execs.
 248                  */
 249                 cp->p_segacct = p->p_segacct;
 250         } else {
 251                 /*
 252                  * We need to hold P_PR_LOCK until the address space has
 253                  * been duplicated and we've had a chance to remove from the
 254                  * child any DTrace probes that were in the parent. Holding
 255                  * P_PR_LOCK prevents any new probes from being added and any
 256                  * extant probes from being removed.
 257                  */
 258                 mutex_enter(&p->p_lock);
 259                 sprlock_proc(p);
 260                 p->p_flag |= SFORKING;


 575         } else {
 576                 CPU_STATS_ADDQ(CPU, sys, sysfork, 1);
 577                 DTRACE_PROC1(create, proc_t *, cp);
 578                 /*
 579                  * It is CL_FORKRET's job to drop pidlock.
 580                  * If we do it here, the process could be set running
 581                  * and disappear before CL_FORKRET() is called.
 582                  */
 583                 CL_FORKRET(curthread, cp->p_tlist);
 584                 schedctl_set_cidpri(curthread);
 585                 ASSERT(MUTEX_NOT_HELD(&pidlock));
 586         }
 587 
 588         return (r.r_vals);
 589 
 590 forklwperr:
 591         if (isvfork) {
 592                 if (avl_numnodes(&p->p_wpage) != 0) {
 593                         /* restore watchpoints to parent */
 594                         as = p->p_as;
 595                         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
 596                         as->a_wpage = p->p_wpage;
 597                         avl_create(&p->p_wpage, wp_compare,
 598                             sizeof (struct watched_page),
 599                             offsetof(struct watched_page, wp_link));
 600                         as_setwatch(as);
 601                         AS_LOCK_EXIT(as, &as->a_lock);
 602                 }
 603         } else {
 604                 if (cp->p_segacct)
 605                         shmexit(cp);
 606                 as = cp->p_as;
 607                 cp->p_as = &kas;
 608                 as_free(as);
 609         }
 610 
 611         if (cp->p_lwpdir) {
 612                 for (i = 0, ldp = cp->p_lwpdir; i < cp->p_lwpdir_sz; i++, ldp++)
 613                         if ((lep = ldp->ld_entry) != NULL)
 614                                 kmem_free(lep, sizeof (*lep));
 615                 kmem_free(cp->p_lwpdir,
 616                     cp->p_lwpdir_sz * sizeof (*cp->p_lwpdir));
 617         }
 618         cp->p_lwpdir = NULL;
 619         cp->p_lwpfree = NULL;
 620         cp->p_lwpdir_sz = 0;
 621 


1433                  *
1434                  * Because this is potentially a very long-term wait,
1435                  * we call cv_wait_sig() (for its jobcontrol and /proc
1436                  * side-effects) unless there is a current signal, in
1437                  * which case we use cv_wait() because we cannot return
1438                  * from this function until the child has released the
1439                  * address space.  Calling cv_wait_sig() with a current
1440                  * signal would lead to an indefinite loop here because
1441                  * cv_wait_sig() returns immediately in this case.
1442                  */
1443                 if (signalled)
1444                         cv_wait(&pp->p_cv, &pp->p_lock);
1445                 else
1446                         signalled = !cv_wait_sig(&pp->p_cv, &pp->p_lock);
1447                 mutex_exit(&pp->p_lock);
1448         }
1449 
1450         /* restore watchpoints to parent */
1451         if (pr_watch_active(pp)) {
1452                 struct as *as = pp->p_as;
1453                 AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
1454                 as_setwatch(as);
1455                 AS_LOCK_EXIT(as, &as->a_lock);
1456         }
1457 
1458         mutex_enter(&pp->p_lock);
1459         prbarrier(pp);  /* barrier against /proc locking */
1460         continuelwps(pp);
1461         mutex_exit(&pp->p_lock);
1462 }


 214                 mutex_enter(&p->p_lock);
 215                 pool_barrier_exit();
 216                 continuelwps(p);
 217                 mutex_exit(&p->p_lock);
 218                 error = EAGAIN;
 219                 goto forkerr;
 220         }
 221 
 222         TRACE_2(TR_FAC_PROC, TR_PROC_FORK, "proc_fork:cp %p p %p", cp, p);
 223 
 224         /*
 225          * Assign an address space to child
 226          */
 227         if (isvfork) {
 228                 /*
 229                  * Clear any watched areas and remember the
 230                  * watched pages for restoring in vfwait().
 231                  */
 232                 as = p->p_as;
 233                 if (avl_numnodes(&as->a_wpage) != 0) {
 234                         AS_LOCK_ENTER(as, RW_WRITER);
 235                         as_clearwatch(as);
 236                         p->p_wpage = as->a_wpage;
 237                         avl_create(&as->a_wpage, wp_compare,
 238                             sizeof (struct watched_page),
 239                             offsetof(struct watched_page, wp_link));
 240                         AS_LOCK_EXIT(as);
 241                 }
 242                 cp->p_as = as;
 243                 cp->p_flag |= SVFORK;
 244 
 245                 /*
 246                  * Use the parent's shm segment list information for
 247                  * the child as it uses its address space till it execs.
 248                  */
 249                 cp->p_segacct = p->p_segacct;
 250         } else {
 251                 /*
 252                  * We need to hold P_PR_LOCK until the address space has
 253                  * been duplicated and we've had a chance to remove from the
 254                  * child any DTrace probes that were in the parent. Holding
 255                  * P_PR_LOCK prevents any new probes from being added and any
 256                  * extant probes from being removed.
 257                  */
 258                 mutex_enter(&p->p_lock);
 259                 sprlock_proc(p);
 260                 p->p_flag |= SFORKING;


 575         } else {
 576                 CPU_STATS_ADDQ(CPU, sys, sysfork, 1);
 577                 DTRACE_PROC1(create, proc_t *, cp);
 578                 /*
 579                  * It is CL_FORKRET's job to drop pidlock.
 580                  * If we do it here, the process could be set running
 581                  * and disappear before CL_FORKRET() is called.
 582                  */
 583                 CL_FORKRET(curthread, cp->p_tlist);
 584                 schedctl_set_cidpri(curthread);
 585                 ASSERT(MUTEX_NOT_HELD(&pidlock));
 586         }
 587 
 588         return (r.r_vals);
 589 
 590 forklwperr:
 591         if (isvfork) {
 592                 if (avl_numnodes(&p->p_wpage) != 0) {
 593                         /* restore watchpoints to parent */
 594                         as = p->p_as;
 595                         AS_LOCK_ENTER(as, RW_WRITER);
 596                         as->a_wpage = p->p_wpage;
 597                         avl_create(&p->p_wpage, wp_compare,
 598                             sizeof (struct watched_page),
 599                             offsetof(struct watched_page, wp_link));
 600                         as_setwatch(as);
 601                         AS_LOCK_EXIT(as);
 602                 }
 603         } else {
 604                 if (cp->p_segacct)
 605                         shmexit(cp);
 606                 as = cp->p_as;
 607                 cp->p_as = &kas;
 608                 as_free(as);
 609         }
 610 
 611         if (cp->p_lwpdir) {
 612                 for (i = 0, ldp = cp->p_lwpdir; i < cp->p_lwpdir_sz; i++, ldp++)
 613                         if ((lep = ldp->ld_entry) != NULL)
 614                                 kmem_free(lep, sizeof (*lep));
 615                 kmem_free(cp->p_lwpdir,
 616                     cp->p_lwpdir_sz * sizeof (*cp->p_lwpdir));
 617         }
 618         cp->p_lwpdir = NULL;
 619         cp->p_lwpfree = NULL;
 620         cp->p_lwpdir_sz = 0;
 621 


1433                  *
1434                  * Because this is potentially a very long-term wait,
1435                  * we call cv_wait_sig() (for its jobcontrol and /proc
1436                  * side-effects) unless there is a current signal, in
1437                  * which case we use cv_wait() because we cannot return
1438                  * from this function until the child has released the
1439                  * address space.  Calling cv_wait_sig() with a current
1440                  * signal would lead to an indefinite loop here because
1441                  * cv_wait_sig() returns immediately in this case.
1442                  */
1443                 if (signalled)
1444                         cv_wait(&pp->p_cv, &pp->p_lock);
1445                 else
1446                         signalled = !cv_wait_sig(&pp->p_cv, &pp->p_lock);
1447                 mutex_exit(&pp->p_lock);
1448         }
1449 
1450         /* restore watchpoints to parent */
1451         if (pr_watch_active(pp)) {
1452                 struct as *as = pp->p_as;
1453                 AS_LOCK_ENTER(as, RW_WRITER);
1454                 as_setwatch(as);
1455                 AS_LOCK_EXIT(as);
1456         }
1457 
1458         mutex_enter(&pp->p_lock);
1459         prbarrier(pp);  /* barrier against /proc locking */
1460         continuelwps(pp);
1461         mutex_exit(&pp->p_lock);
1462 }