Panic in vm_map_stack

pluknet pluknet at gmail.com
Fri Mar 26 21:07:38 UTC 2010


On 26 March 2010 23:10, Tom Judge <tom at tomjudge.com> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> This is the function, I am guessing that I need to unlock the proc
> before calling vmspace_free ?
>
>

As far as I know you cannot lock a process around
locking vmspace and/or vm_map (at least on 6.x).
I used process reference counting for that purpose.
Sort of the following mumble..

        sx_slock(&allproc_lock);
        FOREACH_PROC_IN_SYSTEM(p) {
                struct vmspace *vm;

                PROC_LOCK(p);

                /* Keep this process around until we finish this request. */
                _PHOLD(p);
                PROC_UNLOCK(p);

                        vm = vmspace_acquire_ref(p);
                        if (vm == NULL) {
                                PRELE(p);
                                continue;
                        }
                        if (!vm_map_trylock_read(&vm->vm_map)) {
                                vmspace_free(vm);
                                PRELE(p);
                                continue;
                        }
                        vm_map_unlock_read(&vm->vm_map);
                        vmspace_free(vm);
                }

                /*
                 * Drop our hold on this process now
                 * that the request has completed.
                 */
                PRELE(p);
        }
        sx_sunlock(&allproc_lock);

>
>
>  673 /* Given credential, return memory usage in bytes. */
>  674 void
>  675 prison_memory(struct prison *pr)
>  676 {
>  677     struct proc *p;
>  678     struct thread *td;
>  679     struct vmspace *vm;
>  680     long mem_used = 0;
>  681     long full_mem_used = 0;
>  682     long proc_res = 0;
>  683
>  684     /*
>  685      * TODO: this is a really bad way of doing the
>  686      * search, as we end up going across all processes
>  687      * for each jail.  It'd be more efficient to just do
>  688      * this once in a period and update the relevant jail.
>  689      *
>  690      */
>  691     sx_slock(&allproc_lock);
>  692
>  693     FOREACH_PROC_IN_SYSTEM(p) {
>  694     int breakout;
>  695         proc_res=0;
>  696     vm = NULL;
>  697         if (PROC_TRYLOCK(p) == 0)
>  698         continue;
>  699     /*
>  700      * If this is a system or protected process, skip it.
>  701      */
>  702     if ((p->p_flag & P_SYSTEM) || (p->p_pid == 1) ||
>  703         (p->p_flag & P_PROTECTED) ||
>  704         (p->p_pid < 48)) {
>  705         PROC_UNLOCK(p);
>  706         continue;
>  707     }
>  708     /*
>  709      * If the process is in a non-running type state,
>  710      * don't touch it.  Check all the threads individually.
>  711      */
>  712     breakout = 0;
>  713     FOREACH_THREAD_IN_PROC(p, td) {
>  714         thread_lock(td);
>  715         if (!TD_ON_RUNQ(td) &&
>  716             !TD_IS_RUNNING(td) &&
>  717             !TD_IS_SLEEPING(td)) {
>  718             thread_unlock(td);
>  719             breakout = 1;
>  720             break;
>  721         }
>  722         thread_unlock(td);
>  723     }
>  724     if (breakout) {
>  725         PROC_UNLOCK(p);
>  726         continue;
>  727     }
>  728
>  729         if (p->p_state == PRS_NEW ||
>  730         p->p_state == PRS_ZOMBIE ||
>  731             !jailed(p->p_ucred) ||
>  732             (pr != p->p_ucred->cr_prison) ||
>  733             !p->p_vmspace) {
>  734             PROC_UNLOCK(p);
>  735             continue;
>  736         }
>  737     /*
>  738      * get the process size
>  739      */
>  740     vm = vmspace_acquire_ref(p);
>  741     if (vm == NULL) {
>  742         PROC_UNLOCK(p);
>  743         continue;
>  744     }
>  745
>  746         if (!vm_map_trylock_read(&vm->vm_map)) {
>  747         vmspace_free(vm);
>  748             PROC_UNLOCK(p);
>  749             continue;
>  750         }
>  751         full_mem_used += vmspace_swap_count(vm);
>  752         vm_map_unlock_read(&vm->vm_map);
>  753         proc_res = vmspace_resident_count(vm);
>  754         full_mem_used += proc_res;
>  755         mem_used += proc_res;
>  756         vmspace_free(vm);
>  757         PROC_UNLOCK(p);
>  758     }
>  759     sx_sunlock(&allproc_lock);
>  760
>  761     mem_used *= PAGE_SIZE;
>  762     full_mem_used *= PAGE_SIZE;
>  763     /* Copy the current memory usage to the prison struct */
>  764     mtx_lock(&pr->pr_mtx);
>  765     pr->pr_mem_usage = mem_used;
>  766     pr->pr_full_mem_usage = full_mem_used;
>  767     mtx_unlock(&pr->pr_mtx);
>  768 }
>  769
>
>
>
> Tom
>
>

-- 
wbr,
pluknet


More information about the freebsd-hackers mailing list