Пример #1
0
/*
 * Returns remaining count of pages to be swapped out by followup call.
 */
static inline int swap_out_mm(struct mm_struct * mm, int count, int * mmcounter, zone_t * classzone)
{
	unsigned long address;
	struct vm_area_struct* vma;

	/*
	 * Find the proper vm-area after freezing the vma chain 
	 * and ptes.
	 */
	spin_lock(&mm->page_table_lock);

continue_scan:
	address = mm->swap_address;
	if (address == TASK_SIZE || swap_mm != mm) {
		/* We raced: don't count this mm but try again */
		++*mmcounter;
		goto out_unlock;
	}
	vma = find_vma(mm, address);
	if (vma) {
		if (address < vma->vm_start)
			address = vma->vm_start;

		for (;;) {
			count = swap_out_vma(mm, vma, address, count, classzone);
			vma = vma->vm_next;
			if (!vma)
				break;
			/* we reach this with a lock depth of 1 and 2 */
#if 0
			if (conditional_schedule_needed()) {
				break_spin_lock(&mm->page_table_lock);
				goto continue_scan;
			}
#endif
			if (!count)
				goto out_unlock;
			address = vma->vm_start;
		}
	}
	/* Indicate that we reached the end of address space */
	mm->swap_address = TASK_SIZE;

out_unlock:
	spin_unlock(&mm->page_table_lock);
	return count;
}
Пример #2
0
static int swap_out_mm(struct mm_struct * mm, int gfp_mask)
{
	unsigned long address;
	struct vm_area_struct* vma;

	/*
	 * Go through process' page directory.
	 */
	address = mm->swap_address;

	/*
	 * Find the proper vm-area after freezing the vma chain 
	 * and ptes.
	 */
	spin_lock(&mm->page_table_lock);
	vma = find_vma(mm, address);
	if (vma) {
		if (address < vma->vm_start)
			address = vma->vm_start;

		for (;;) {
			int result = swap_out_vma(mm, vma, address, gfp_mask);
			if (result)
				return result;
			if (!mm->swap_cnt)
				goto out_unlock;
			vma = vma->vm_next;
			if (!vma)
				break;
			address = vma->vm_start;
		}
	}
	/* Reset to 0 when we reach the end of address space */
	mm->swap_address = 0;
	mm->swap_cnt = 0;

out_unlock:
	spin_unlock(&mm->page_table_lock);

	/* We didn't find anything for the process */
	return 0;
}
Пример #3
0
// swap_out_mm - call swap_out_vma to try to unmap a set of vma ('require' NUM pages).
int
swap_out_mm(struct mm_struct *mm, size_t require) {
    assert(mm != NULL);
    if (require == 0 || mm->map_count == 0) {
        return 0;
    }
    assert(!list_empty(&(mm->mmap_list)));

    uintptr_t addr = mm->swap_address;
    struct vma_struct *vma;

    if ((vma = find_vma(mm, addr)) == NULL) {
        addr = mm->swap_address = 0;
        vma = le2vma(list_next(&(mm->mmap_list)), list_link);
    }
    assert(vma != NULL && addr <= vma->vm_end);

    if (addr < vma->vm_start) {
        addr = vma->vm_start;
    }

    int i;
    size_t free_count = 0;
    for (i = 0; i <= mm->map_count; i ++) {
        int ret = swap_out_vma(mm, vma, addr, require);
        free_count += ret, require -= ret;
        if (require == 0) {
            break;
        }
        list_entry_t *le = list_next(&(vma->list_link));
        if (le == &(mm->mmap_list)) {
            le = list_next(le);
        }
        vma = le2vma(le, list_link);
        addr = vma->vm_start;
    }
    return free_count;
}