Date: Thu, 3 Aug 2006 09:28:56 GMT From: Chris Jones <cdjones@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 103106 for review Message-ID: <200608030928.k739Su4G002546@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=103106 Change 103106 by cdjones@cdjones-impulse on 2006/08/03 09:28:12 Address concerns on hackers@ about reading from memory that doesn't exist anymore. NOTE: this is known-buggy code that causes kernel panics, but I'm checking it in as a way point towards working code. Affected files ... .. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_jail.c#19 edit .. //depot/projects/soc2006/cdjones_jail/src/sys/sys/jail.h#15 edit Differences ... ==== //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_jail.c#19 (text+ko) ==== @@ -102,23 +102,26 @@ static void jsched_td(void *arg) { - struct prison *pr; - pr = arg; + struct prison *pr = arg; + /* int pr_id = pr->pr_id; */ + int flags = J_SCHED_TD_ACTIVE; + pr->pr_scheduler_flags_ptr = &flags; /* printf("Starting jsched_td\n"); */ for (;;) { - if (pr->pr_scheduler_flags & J_SCHED_TD_DIE) + if (flags & J_SCHED_TD_DIE) break; - + + mtx_lock(&pr->pr_mtx); /* Scheduling stuff goes here. */ /* printf("jsched_td running\n"); */ + mtx_unlock(&pr->pr_mtx); + tsleep(pr, 0, "-", hz); } -/* printf("Exiting jsched_td\n"); */ - - pr->pr_scheduler_flags = J_SCHED_TD_DEAD; + printf("Exiting jsched_td\n"); kthread_exit(0); } @@ -126,20 +129,23 @@ jpager_td(void *arg) { struct proc *p; - struct prison *pr; + struct prison *pr = arg; struct thread *td; long limit, cursize, newsize, usage; int breakout; - - pr = arg; - + int pr_id = pr->pr_id; + int flags = J_SCHED_TD_ACTIVE; + pr->pr_scheduler_flags_ptr = &flags; + printf("Starting jpager/%d with memory limit %ld bytes\n", - pr->pr_id, (long) prison_memory_limit(pr)); + pr_id, (long) prison_memory_limit(pr)); for (;;) { - if (pr->pr_pager_flags & J_PAGER_TD_DIE) + if (flags & J_PAGER_TD_DIE) break; - + + mtx_lock(&pr->pr_mtx); + /* TODO: consider whether it might be better to start * pushing back when we approach the limit, rather than * when we hit it. @@ -154,11 +160,11 @@ */ printf("jpager/%d: memory %ld / %ld bytes\n", - pr->pr_id, usage, limit); + pr_id, usage, limit); if ((usage - limit) > 0) { - printf("jpager/%d: overcommitted by %ld bytes (%lf percent)\n", - pr->pr_id, usage - limit, + printf("jpager/%d: overcommitted by %ld bytes (%f percent)\n", + pr_id, usage - limit, (double) 100 * ((double) (usage - limit) / (double) limit)); sx_slock(&allproc_lock); LIST_FOREACH(p, &allproc, p_list) { @@ -209,11 +215,12 @@ newsize = 0; PROC_UNLOCK(p); printf("jpager/%d: squeezing process %d from %ld to %ld\n", - pr->pr_id, p->p_pid, cursize, newsize); + pr_id, p->p_pid, cursize, newsize); vm_pageout_map_deactivate_pages(&p->p_vmspace->vm_map, newsize); } /* end LIST_FOREACH procs */ sx_sunlock(&allproc_lock); } + mtx_unlock(&pr->pr_mtx); /* TODO --- make interval into a sysctl. */ /* 6 seconds because VM recomputes totals every 5. */ @@ -222,8 +229,6 @@ } printf("Exiting jpager_td\n"); - - pr->pr_pager_flags = J_PAGER_TD_DEAD; kthread_exit(0); } @@ -299,12 +304,10 @@ mtx_unlock(&allprison_mtx); /* TODO #ifdef SCHED_HIER */ - pr->pr_scheduler_flags = J_SCHED_TD_ACTIVE; if (kthread_create(jsched_td, pr, (void *) j_sched_proc, 0, 0, "jsched %d", pr->pr_id)) goto e_dropprref; KASSERT(j_sched_proc != NULL, ("NULL j_sched_proc")); pr->pr_scheduler = j_sched_proc; - pr->pr_pager_flags = J_PAGER_TD_ACTIVE; if (kthread_create(jpager_td, pr, (void *) j_pager_proc, 0, 0, "jpager %d", pr->pr_id)) goto e_dropprref; KASSERT(j_pager_proc != NULL, ("NULL j_pager_proc")); @@ -320,6 +323,7 @@ td->td_retval[0] = jaa.jid; return (0); e_dropprref: + /* TODO: kill pager, scheduler if they've started. */ mtx_lock(&allprison_mtx); LIST_REMOVE(pr, pr_list); prisoncount--; @@ -424,19 +428,20 @@ void prison_free(struct prison *pr) { - mtx_lock(&allprison_mtx); mtx_lock(&pr->pr_mtx); pr->pr_ref--; if (pr->pr_ref == 0) { + *pr->pr_scheduler_flags_ptr = J_SCHED_TD_DIE; + kthread_resume(pr->pr_scheduler); + *pr->pr_pager_flags_ptr = J_PAGER_TD_DIE; + kthread_resume(pr->pr_pager); + LIST_REMOVE(pr, pr_list); mtx_unlock(&pr->pr_mtx); prisoncount--; mtx_unlock(&allprison_mtx); - /* Tell scheduler to die. No need to wait for it. */ - pr->pr_scheduler_flags |= J_SCHED_TD_DIE; - pr->pr_pager_flags |= J_PAGER_TD_DIE; wakeup(pr); TASK_INIT(&pr->pr_task, 0, prison_complete, pr); @@ -583,7 +588,11 @@ vm_pindex_t prison_memory_limit(struct prison *pr) { - return pr->pr_mem_limit; + vm_pindex_t memlimit; + mtx_lock(&pr->pr_mtx); + memlimit = (vm_pindex_t) pr->pr_mem_limit; + mtx_unlock(&pr->pr_mtx); + return memlimit; } /* ==== //depot/projects/soc2006/cdjones_jail/src/sys/sys/jail.h#15 (text+ko) ==== @@ -101,9 +101,9 @@ struct mtx pr_mtx; unsigned int pr_priority; /* (p) jail priority */ struct proc *pr_scheduler; /* (c) scheduler pid */ - int pr_scheduler_flags; /* (p) communication to scheduler */ + int *pr_scheduler_flags_ptr; /* (p) communication to scheduler */ struct proc *pr_pager; /* (c) pager pid */ - int pr_pager_flags; /* (p) communication to pager */ + int *pr_pager_flags_ptr; /* (p) communication to pager */ size_t pr_mem_limit; /* (p) memory allocation limit */ size_t pr_mem_usage; /* (p) memory in use */ };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608030928.k739Su4G002546>