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