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