コード例 #1
0
static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size)
{
	int page_start = PFN_DOWN(off);
	int page_end = PFN_UP(off + size);
	struct page **pages;
	unsigned long *populated;
	int rs, re;

	
	rs = page_start;
	pcpu_next_unpop(chunk, &rs, &re, page_end);
	if (rs == page_start && re == page_end)
		return;

	
	WARN_ON(chunk->immutable);

	pages = pcpu_get_pages_and_bitmap(chunk, &populated, false);
	BUG_ON(!pages);

	
	pcpu_pre_unmap_flush(chunk, page_start, page_end);

	pcpu_for_each_pop_region(chunk, rs, re, page_start, page_end)
		pcpu_unmap_pages(chunk, pages, populated, rs, re);

	

	pcpu_for_each_pop_region(chunk, rs, re, page_start, page_end)
		pcpu_free_pages(chunk, pages, populated, rs, re);

	
	bitmap_copy(chunk->populated, populated, pcpu_unit_pages);
}
コード例 #2
0
static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size)
{
	int page_start = PFN_DOWN(off);
	int page_end = PFN_UP(off + size);
	int free_end = page_start, unmap_end = page_start;
	struct page **pages;
	unsigned long *populated;
	unsigned int cpu;
	int rs, re, rc;

	
	rs = page_start;
	pcpu_next_pop(chunk, &rs, &re, page_end);
	if (rs == page_start && re == page_end)
		goto clear;

	
	WARN_ON(chunk->immutable);

	pages = pcpu_get_pages_and_bitmap(chunk, &populated, true);
	if (!pages)
		return -ENOMEM;

	
	pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) {
		rc = pcpu_alloc_pages(chunk, pages, populated, rs, re);
		if (rc)
			goto err_free;
		free_end = re;
	}
コード例 #3
0
ファイル: percpu-vm.c プロジェクト: yangliang913/fastsocket
/**
 * pcpu_populate_chunk - populate and map an area of a pcpu_chunk
 * @chunk: chunk of interest
 * @off: offset to the area to populate
 * @size: size of the area to populate in bytes
 *
 * For each cpu, populate and map pages [@page_start,@page_end) into
 * @chunk.  The area is cleared on return.
 *
 * CONTEXT:
 * pcpu_alloc_mutex, does GFP_KERNEL allocation.
 */
static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size)
{
    int page_start = PFN_DOWN(off);
    int page_end = PFN_UP(off + size);
    int free_end = page_start, unmap_end = page_start;
    struct page **pages;
    unsigned long *populated;
    unsigned int cpu;
    int rs, re, rc;

    /* quick path, check whether all pages are already there */
    rs = page_start;
    pcpu_next_pop(chunk, &rs, &re, page_end);
    if (rs == page_start && re == page_end)
        goto clear;

    /* need to allocate and map pages, this chunk can't be immutable */
    WARN_ON(chunk->immutable);

    pages = pcpu_get_pages_and_bitmap(chunk, &populated, true);
    if (!pages)
        return -ENOMEM;

    /* alloc and map */
    pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) {
        rc = pcpu_alloc_pages(chunk, pages, populated, rs, re);
        if (rc)
            goto err_free;
        free_end = re;
    }
コード例 #4
0
ファイル: percpu-vm.c プロジェクト: yangliang913/fastsocket
/**
 * pcpu_depopulate_chunk - depopulate and unmap an area of a pcpu_chunk
 * @chunk: chunk to depopulate
 * @off: offset to the area to depopulate
 * @size: size of the area to depopulate in bytes
 * @flush: whether to flush cache and tlb or not
 *
 * For each cpu, depopulate and unmap pages [@page_start,@page_end)
 * from @chunk.  If @flush is true, vcache is flushed before unmapping
 * and tlb after.
 *
 * CONTEXT:
 * pcpu_alloc_mutex.
 */
static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size)
{
    int page_start = PFN_DOWN(off);
    int page_end = PFN_UP(off + size);
    struct page **pages;
    unsigned long *populated;
    int rs, re;

    /* quick path, check whether it's empty already */
    rs = page_start;
    pcpu_next_unpop(chunk, &rs, &re, page_end);
    if (rs == page_start && re == page_end)
        return;

    /* immutable chunks can't be depopulated */
    WARN_ON(chunk->immutable);

    /*
     * If control reaches here, there must have been at least one
     * successful population attempt so the temp pages array must
     * be available now.
     */
    pages = pcpu_get_pages_and_bitmap(chunk, &populated, false);
    BUG_ON(!pages);

    /* unmap and free */
    pcpu_pre_unmap_flush(chunk, page_start, page_end);

    pcpu_for_each_pop_region(chunk, rs, re, page_start, page_end)
    pcpu_unmap_pages(chunk, pages, populated, rs, re);

    /* no need to flush tlb, vmalloc will handle it lazily */

    pcpu_for_each_pop_region(chunk, rs, re, page_start, page_end)
    pcpu_free_pages(chunk, pages, populated, rs, re);

    /* commit new bitmap */
    bitmap_copy(chunk->populated, populated, pcpu_unit_pages);
}
コード例 #5
0
/*! 2016-03-19 study -ing */
static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size)
{
	int page_start = PFN_DOWN(off);
	int page_end = PFN_UP(off + size);
	int free_end = page_start, unmap_end = page_start;
	struct page **pages;
	unsigned long *populated;
	unsigned int cpu;
	int rs, re, rc;

	/* quick path, check whether all pages are already there */
	rs = page_start;
	pcpu_next_pop(chunk, &rs, &re, page_end);
	/*! populate 하려는 page_start, end 와 populated 의 rs, re 가 일치하면
	 *  더 할일 없이 goto clear.
	 */
	if (rs == page_start && re == page_end)
		goto clear;

	/* need to allocate and map pages, this chunk can't be immutable */
	WARN_ON(chunk->immutable);

	pages = pcpu_get_pages_and_bitmap(chunk, &populated, true);
	if (!pages)
		return -ENOMEM;

	/* alloc and map */
	/*! rs: region start, re: region end (Page Frame number 단위)
	 * page_start ~ page_end 까지 pcpu_next_unpop하며 loop 수행
	 */
	pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) {
		rc = pcpu_alloc_pages(chunk, pages, populated, rs, re);
		/*! 한번이라도 alloc 실패 시 go to err_free.  */
		if (rc)
			goto err_free;
		free_end = re;
	}