Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 27 Mar 2010 00:07:36 +0300
From:      pluknet <pluknet@gmail.com>
To:        Tom Judge <tom@tomjudge.com>
Cc:        Kostik Belousov <kostikbel@gmail.com>, freebsd-hackers@freebsd.org
Subject:   Re: Panic in vm_map_stack
Message-ID:  <a31046fc1003261407t32a8f8b9s15646328ef574704@mail.gmail.com>
In-Reply-To: <4BAD1498.5040402@tomjudge.com>
References:  <4BACF92E.60600@tomjudge.com> <20100326195659.GU2415@deviant.kiev.zoral.com.ua> <4BAD1498.5040402@tomjudge.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On 26 March 2010 23:10, Tom Judge <tom@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 =3D vmspace_acquire_ref(p);
                        if (vm =3D=3D 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);

>
>
> =A0673 /* Given credential, return memory usage in bytes. */
> =A0674 void
> =A0675 prison_memory(struct prison *pr)
> =A0676 {
> =A0677 =A0 =A0 struct proc *p;
> =A0678 =A0 =A0 struct thread *td;
> =A0679 =A0 =A0 struct vmspace *vm;
> =A0680 =A0 =A0 long mem_used =3D 0;
> =A0681 =A0 =A0 long full_mem_used =3D 0;
> =A0682 =A0 =A0 long proc_res =3D 0;
> =A0683
> =A0684 =A0 =A0 /*
> =A0685 =A0 =A0 =A0* TODO: this is a really bad way of doing the
> =A0686 =A0 =A0 =A0* search, as we end up going across all processes
> =A0687 =A0 =A0 =A0* for each jail. =A0It'd be more efficient to just do
> =A0688 =A0 =A0 =A0* this once in a period and update the relevant jail.
> =A0689 =A0 =A0 =A0*
> =A0690 =A0 =A0 =A0*/
> =A0691 =A0 =A0 sx_slock(&allproc_lock);
> =A0692
> =A0693 =A0 =A0 FOREACH_PROC_IN_SYSTEM(p) {
> =A0694 =A0 =A0 int breakout;
> =A0695 =A0 =A0 =A0 =A0 proc_res=3D0;
> =A0696 =A0 =A0 vm =3D NULL;
> =A0697 =A0 =A0 =A0 =A0 if (PROC_TRYLOCK(p) =3D=3D 0)
> =A0698 =A0 =A0 =A0 =A0 continue;
> =A0699 =A0 =A0 /*
> =A0700 =A0 =A0 =A0* If this is a system or protected process, skip it.
> =A0701 =A0 =A0 =A0*/
> =A0702 =A0 =A0 if ((p->p_flag & P_SYSTEM) || (p->p_pid =3D=3D 1) ||
> =A0703 =A0 =A0 =A0 =A0 (p->p_flag & P_PROTECTED) ||
> =A0704 =A0 =A0 =A0 =A0 (p->p_pid < 48)) {
> =A0705 =A0 =A0 =A0 =A0 PROC_UNLOCK(p);
> =A0706 =A0 =A0 =A0 =A0 continue;
> =A0707 =A0 =A0 }
> =A0708 =A0 =A0 /*
> =A0709 =A0 =A0 =A0* If the process is in a non-running type state,
> =A0710 =A0 =A0 =A0* don't touch it. =A0Check all the threads individually=
.
> =A0711 =A0 =A0 =A0*/
> =A0712 =A0 =A0 breakout =3D 0;
> =A0713 =A0 =A0 FOREACH_THREAD_IN_PROC(p, td) {
> =A0714 =A0 =A0 =A0 =A0 thread_lock(td);
> =A0715 =A0 =A0 =A0 =A0 if (!TD_ON_RUNQ(td) &&
> =A0716 =A0 =A0 =A0 =A0 =A0 =A0 !TD_IS_RUNNING(td) &&
> =A0717 =A0 =A0 =A0 =A0 =A0 =A0 !TD_IS_SLEEPING(td)) {
> =A0718 =A0 =A0 =A0 =A0 =A0 =A0 thread_unlock(td);
> =A0719 =A0 =A0 =A0 =A0 =A0 =A0 breakout =3D 1;
> =A0720 =A0 =A0 =A0 =A0 =A0 =A0 break;
> =A0721 =A0 =A0 =A0 =A0 }
> =A0722 =A0 =A0 =A0 =A0 thread_unlock(td);
> =A0723 =A0 =A0 }
> =A0724 =A0 =A0 if (breakout) {
> =A0725 =A0 =A0 =A0 =A0 PROC_UNLOCK(p);
> =A0726 =A0 =A0 =A0 =A0 continue;
> =A0727 =A0 =A0 }
> =A0728
> =A0729 =A0 =A0 =A0 =A0 if (p->p_state =3D=3D PRS_NEW ||
> =A0730 =A0 =A0 =A0 =A0 p->p_state =3D=3D PRS_ZOMBIE ||
> =A0731 =A0 =A0 =A0 =A0 =A0 =A0 !jailed(p->p_ucred) ||
> =A0732 =A0 =A0 =A0 =A0 =A0 =A0 (pr !=3D p->p_ucred->cr_prison) ||
> =A0733 =A0 =A0 =A0 =A0 =A0 =A0 !p->p_vmspace) {
> =A0734 =A0 =A0 =A0 =A0 =A0 =A0 PROC_UNLOCK(p);
> =A0735 =A0 =A0 =A0 =A0 =A0 =A0 continue;
> =A0736 =A0 =A0 =A0 =A0 }
> =A0737 =A0 =A0 /*
> =A0738 =A0 =A0 =A0* get the process size
> =A0739 =A0 =A0 =A0*/
> =A0740 =A0 =A0 vm =3D vmspace_acquire_ref(p);
> =A0741 =A0 =A0 if (vm =3D=3D NULL) {
> =A0742 =A0 =A0 =A0 =A0 PROC_UNLOCK(p);
> =A0743 =A0 =A0 =A0 =A0 continue;
> =A0744 =A0 =A0 }
> =A0745
> =A0746 =A0 =A0 =A0 =A0 if (!vm_map_trylock_read(&vm->vm_map)) {
> =A0747 =A0 =A0 =A0 =A0 vmspace_free(vm);
> =A0748 =A0 =A0 =A0 =A0 =A0 =A0 PROC_UNLOCK(p);
> =A0749 =A0 =A0 =A0 =A0 =A0 =A0 continue;
> =A0750 =A0 =A0 =A0 =A0 }
> =A0751 =A0 =A0 =A0 =A0 full_mem_used +=3D vmspace_swap_count(vm);
> =A0752 =A0 =A0 =A0 =A0 vm_map_unlock_read(&vm->vm_map);
> =A0753 =A0 =A0 =A0 =A0 proc_res =3D vmspace_resident_count(vm);
> =A0754 =A0 =A0 =A0 =A0 full_mem_used +=3D proc_res;
> =A0755 =A0 =A0 =A0 =A0 mem_used +=3D proc_res;
> =A0756 =A0 =A0 =A0 =A0 vmspace_free(vm);
> =A0757 =A0 =A0 =A0 =A0 PROC_UNLOCK(p);
> =A0758 =A0 =A0 }
> =A0759 =A0 =A0 sx_sunlock(&allproc_lock);
> =A0760
> =A0761 =A0 =A0 mem_used *=3D PAGE_SIZE;
> =A0762 =A0 =A0 full_mem_used *=3D PAGE_SIZE;
> =A0763 =A0 =A0 /* Copy the current memory usage to the prison struct */
> =A0764 =A0 =A0 mtx_lock(&pr->pr_mtx);
> =A0765 =A0 =A0 pr->pr_mem_usage =3D mem_used;
> =A0766 =A0 =A0 pr->pr_full_mem_usage =3D full_mem_used;
> =A0767 =A0 =A0 mtx_unlock(&pr->pr_mtx);
> =A0768 }
> =A0769
>
>
>
> Tom
>
>

--=20
wbr,
pluknet



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?a31046fc1003261407t32a8f8b9s15646328ef574704>