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 }
|