Example #1
0
/**
 * pcpu_map_pages - map pages into a pcpu_chunk
 * @chunk: chunk of interest
 * @pages: pages array containing pages to be mapped
 * @page_start: page index of the first page to map
 * @page_end: page index of the last page to map + 1
 *
 * For each cpu, map pages [@page_start,@page_end) into @chunk.  The
 * caller is responsible for calling pcpu_post_map_flush() after all
 * mappings are complete.
 *
 * This function is responsible for setting up whatever is necessary for
 * reverse lookup (addr -> chunk).
 */
static int pcpu_map_pages(struct pcpu_chunk *chunk,
			  struct page **pages, int page_start, int page_end)
{
	unsigned int cpu, tcpu;
	int i, err;

	for_each_possible_cpu(cpu) {
		err = __pcpu_map_pages(pcpu_chunk_addr(chunk, cpu, page_start),
				       &pages[pcpu_page_idx(cpu, page_start)],
				       page_end - page_start);
		if (err < 0)
			goto err;

		for (i = page_start; i < page_end; i++)
			pcpu_set_page_chunk(pages[pcpu_page_idx(cpu, i)],
					    chunk);
	}
	return 0;
err:
	for_each_possible_cpu(tcpu) {
		if (tcpu == cpu)
			break;
		__pcpu_unmap_pages(pcpu_chunk_addr(chunk, tcpu, page_start),
				   page_end - page_start);
	}
	pcpu_post_unmap_tlb_flush(chunk, page_start, page_end);
	return err;
}
Example #2
0
/**
 * pcpu_map_pages - map pages into a pcpu_chunk
 * @chunk: chunk of interest
 * @pages: pages array containing pages to be mapped
 * @populated: populated bitmap
 * @page_start: page index of the first page to map
 * @page_end: page index of the last page to map + 1
 *
 * For each cpu, map pages [@page_start,@page_end) into @chunk.  The
 * caller is responsible for calling pcpu_post_map_flush() after all
 * mappings are complete.
 *
 * This function is responsible for setting corresponding bits in
 * @chunk->populated bitmap and whatever is necessary for reverse
 * lookup (addr -> chunk).
 */
static int pcpu_map_pages(struct pcpu_chunk *chunk,
                          struct page **pages, unsigned long *populated,
                          int page_start, int page_end)
{
    unsigned int cpu, tcpu;
    int i, err;

    for_each_possible_cpu(cpu) {
        err = __pcpu_map_pages(pcpu_chunk_addr(chunk, cpu, page_start),
                               &pages[pcpu_page_idx(cpu, page_start)],
                               page_end - page_start);
        if (err < 0)
            goto err;
    }

    /* mapping successful, link chunk and mark populated */
    for (i = page_start; i < page_end; i++) {
        for_each_possible_cpu(cpu)
        pcpu_set_page_chunk(pages[pcpu_page_idx(cpu, i)],
                            chunk);
        __set_bit(i, populated);
    }

    return 0;

err:
    for_each_possible_cpu(tcpu) {
        if (tcpu == cpu)
            break;
        __pcpu_unmap_pages(pcpu_chunk_addr(chunk, tcpu, page_start),
                           page_end - page_start);
    }
    return err;
}