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>