/** * 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; }
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; }
/** * pcpu_populate_chunk - populate and map an area of a pcpu_chunk * @chunk: chunk of interest * @page_start: the start page * @page_end: the end page * * For each cpu, populate and map pages [@page_start,@page_end) into * @chunk. * * CONTEXT: * pcpu_alloc_mutex, does GFP_KERNEL allocation. */ static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int page_start, int page_end) { struct page **pages; pages = pcpu_get_pages(); if (!pages) return -ENOMEM; if (pcpu_alloc_pages(chunk, pages, page_start, page_end)) return -ENOMEM; if (pcpu_map_pages(chunk, pages, page_start, page_end)) { pcpu_free_pages(chunk, pages, page_start, page_end); return -ENOMEM; } pcpu_post_map_flush(chunk, page_start, page_end); return 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; }