PERFORCE change 103106 for review
Chris Jones
cdjones at FreeBSD.org
Thu Aug 3 09:28:58 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=103106
Change 103106 by cdjones at 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 */
};
More information about the p4-projects
mailing list