add ihk_mc_allocate_aligned_pages()
This commit is contained in:
@@ -16,10 +16,12 @@
|
|||||||
#define PAGE_SHIFT 12
|
#define PAGE_SHIFT 12
|
||||||
#define PAGE_SIZE (1UL << PAGE_SHIFT)
|
#define PAGE_SIZE (1UL << PAGE_SHIFT)
|
||||||
#define PAGE_MASK (~((unsigned long)PAGE_SIZE - 1))
|
#define PAGE_MASK (~((unsigned long)PAGE_SIZE - 1))
|
||||||
|
#define PAGE_P2ALIGN 0
|
||||||
|
|
||||||
#define LARGE_PAGE_SHIFT 21
|
#define LARGE_PAGE_SHIFT 21
|
||||||
#define LARGE_PAGE_SIZE (1UL << LARGE_PAGE_SHIFT)
|
#define LARGE_PAGE_SIZE (1UL << LARGE_PAGE_SHIFT)
|
||||||
#define LARGE_PAGE_MASK (~((unsigned long)LARGE_PAGE_SIZE - 1))
|
#define LARGE_PAGE_MASK (~((unsigned long)LARGE_PAGE_SIZE - 1))
|
||||||
|
#define LARGE_PAGE_P2ALIGN (LARGE_PAGE_SHIFT - PAGE_SHIFT)
|
||||||
|
|
||||||
#define USER_END 0x0000800000000000UL
|
#define USER_END 0x0000800000000000UL
|
||||||
#define MAP_ST_START 0xffff800000000000UL
|
#define MAP_ST_START 0xffff800000000000UL
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ void *early_alloc_page(void)
|
|||||||
void *arch_alloc_page(enum ihk_mc_ap_flag flag)
|
void *arch_alloc_page(enum ihk_mc_ap_flag flag)
|
||||||
{
|
{
|
||||||
if (pa_ops)
|
if (pa_ops)
|
||||||
return pa_ops->alloc_page(1, flag);
|
return pa_ops->alloc_page(1, PAGE_P2ALIGN, flag);
|
||||||
else
|
else
|
||||||
return early_alloc_page();
|
return early_alloc_page();
|
||||||
}
|
}
|
||||||
@@ -45,14 +45,19 @@ void arch_free_page(void *ptr)
|
|||||||
pa_ops->free_page(ptr, 1);
|
pa_ops->free_page(ptr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ihk_mc_alloc_pages(int npages, enum ihk_mc_ap_flag flag)
|
void *ihk_mc_alloc_aligned_pages(int npages, int p2align, enum ihk_mc_ap_flag flag)
|
||||||
{
|
{
|
||||||
if (pa_ops)
|
if (pa_ops)
|
||||||
return pa_ops->alloc_page(npages, flag);
|
return pa_ops->alloc_page(npages, p2align, flag);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *ihk_mc_alloc_pages(int npages, enum ihk_mc_ap_flag flag)
|
||||||
|
{
|
||||||
|
return ihk_mc_alloc_aligned_pages(npages, PAGE_P2ALIGN, flag);
|
||||||
|
}
|
||||||
|
|
||||||
void ihk_mc_free_pages(void *p, int npages)
|
void ihk_mc_free_pages(void *p, int npages)
|
||||||
{
|
{
|
||||||
if (pa_ops)
|
if (pa_ops)
|
||||||
|
|||||||
27
kernel/mem.c
27
kernel/mem.c
@@ -42,9 +42,9 @@ static void reserve_pages(unsigned long start, unsigned long end, int type)
|
|||||||
ihk_pagealloc_reserve(pa_allocator, start, end);
|
ihk_pagealloc_reserve(pa_allocator, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *allocate_pages(int npages, enum ihk_mc_ap_flag flag)
|
void *allocate_aligned_pages(int npages, int p2align, enum ihk_mc_ap_flag flag)
|
||||||
{
|
{
|
||||||
unsigned long pa = ihk_pagealloc_alloc(pa_allocator, npages);
|
unsigned long pa = ihk_pagealloc_alloc(pa_allocator, npages, p2align);
|
||||||
/* all_pagealloc_alloc returns zero when error occured,
|
/* all_pagealloc_alloc returns zero when error occured,
|
||||||
and callee (in mcos/kernel/process.c) so propagate it */
|
and callee (in mcos/kernel/process.c) so propagate it */
|
||||||
if(pa)
|
if(pa)
|
||||||
@@ -54,13 +54,18 @@ void *allocate_pages(int npages, enum ihk_mc_ap_flag flag)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *allocate_pages(int npages, enum ihk_mc_ap_flag flag)
|
||||||
|
{
|
||||||
|
return allocate_aligned_pages(npages, PAGE_P2ALIGN, flag);
|
||||||
|
}
|
||||||
|
|
||||||
void free_pages(void *va, int npages)
|
void free_pages(void *va, int npages)
|
||||||
{
|
{
|
||||||
ihk_pagealloc_free(pa_allocator, virt_to_phys(va), npages);
|
ihk_pagealloc_free(pa_allocator, virt_to_phys(va), npages);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ihk_mc_pa_ops allocator = {
|
static struct ihk_mc_pa_ops allocator = {
|
||||||
.alloc_page = allocate_pages,
|
.alloc_page = allocate_aligned_pages,
|
||||||
.free_page = free_pages,
|
.free_page = free_pages,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -176,12 +181,15 @@ static void page_allocator_init(void)
|
|||||||
unsigned long page_map_pa, pages;
|
unsigned long page_map_pa, pages;
|
||||||
void *page_map;
|
void *page_map;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
uint64_t start;
|
||||||
|
uint64_t end;
|
||||||
|
|
||||||
pa_start = ihk_mc_get_memory_address(IHK_MC_GMA_AVAIL_START, 0);
|
start = ihk_mc_get_memory_address(IHK_MC_GMA_AVAIL_START, 0);
|
||||||
pa_end = ihk_mc_get_memory_address(IHK_MC_GMA_AVAIL_END, 0);
|
end = ihk_mc_get_memory_address(IHK_MC_GMA_AVAIL_END, 0);
|
||||||
|
|
||||||
pa_start &= PAGE_MASK;
|
start &= PAGE_MASK;
|
||||||
pa_end = (pa_end + PAGE_SIZE - 1) & PAGE_MASK;
|
pa_start = start & LARGE_PAGE_MASK;
|
||||||
|
pa_end = (end + PAGE_SIZE - 1) & PAGE_MASK;
|
||||||
|
|
||||||
#ifndef ATTACHED_MIC
|
#ifndef ATTACHED_MIC
|
||||||
page_map_pa = ihk_mc_get_memory_address(IHK_MC_GMA_HEAP_START, 0);
|
page_map_pa = ihk_mc_get_memory_address(IHK_MC_GMA_HEAP_START, 0);
|
||||||
@@ -198,6 +206,9 @@ static void page_allocator_init(void)
|
|||||||
PAGE_SIZE, page_map, &pages);
|
PAGE_SIZE, page_map, &pages);
|
||||||
|
|
||||||
reserve_pages(page_map_pa, page_map_pa + pages * PAGE_SIZE, 0);
|
reserve_pages(page_map_pa, page_map_pa + pages * PAGE_SIZE, 0);
|
||||||
|
if (pa_start < start) {
|
||||||
|
reserve_pages(pa_start, start, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* BIOS reserved ranges */
|
/* BIOS reserved ranges */
|
||||||
for (i = 1; i <= ihk_mc_get_memory_address(IHK_MC_NR_RESERVED_AREAS, 0);
|
for (i = 1; i <= ihk_mc_get_memory_address(IHK_MC_NR_RESERVED_AREAS, 0);
|
||||||
@@ -249,7 +260,7 @@ void *ihk_mc_map_virtual(unsigned long phys, int npages,
|
|||||||
offset = (phys & (PAGE_SIZE - 1));
|
offset = (phys & (PAGE_SIZE - 1));
|
||||||
phys = phys & PAGE_MASK;
|
phys = phys & PAGE_MASK;
|
||||||
|
|
||||||
p = (void *)ihk_pagealloc_alloc(vmap_allocator, npages);
|
p = (void *)ihk_pagealloc_alloc(vmap_allocator, npages, PAGE_P2ALIGN);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ void ihk_mc_reserve_arch_pages(unsigned long start, unsigned long end,
|
|||||||
void (*cb)(unsigned long, unsigned long, int));
|
void (*cb)(unsigned long, unsigned long, int));
|
||||||
|
|
||||||
struct ihk_mc_pa_ops {
|
struct ihk_mc_pa_ops {
|
||||||
void *(*alloc_page)(int, enum ihk_mc_ap_flag);
|
void *(*alloc_page)(int, int, enum ihk_mc_ap_flag);
|
||||||
void (*free_page)(void *, int);
|
void (*free_page)(void *, int);
|
||||||
|
|
||||||
void *(*alloc)(int, enum ihk_mc_ap_flag);
|
void *(*alloc)(int, enum ihk_mc_ap_flag);
|
||||||
@@ -74,6 +74,7 @@ void ihk_mc_map_micpa(unsigned long host_pa, unsigned long* mic_pa);
|
|||||||
int ihk_mc_free_micpa(unsigned long mic_pa);
|
int ihk_mc_free_micpa(unsigned long mic_pa);
|
||||||
void ihk_mc_clean_micpa(void);
|
void ihk_mc_clean_micpa(void);
|
||||||
|
|
||||||
|
void *ihk_mc_alloc_aligned_pages(int npages, int p2align, enum ihk_mc_ap_flag flag);
|
||||||
void *ihk_mc_alloc_pages(int npages, enum ihk_mc_ap_flag flag);
|
void *ihk_mc_alloc_pages(int npages, enum ihk_mc_ap_flag flag);
|
||||||
void ihk_mc_free_pages(void *p, int npages);
|
void ihk_mc_free_pages(void *p, int npages);
|
||||||
void *ihk_mc_allocate(int size, enum ihk_mc_ap_flag flag);
|
void *ihk_mc_allocate(int size, enum ihk_mc_ap_flag flag);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ void *__ihk_pagealloc_init(unsigned long start, unsigned long size,
|
|||||||
void *ihk_pagealloc_init(unsigned long start, unsigned long size,
|
void *ihk_pagealloc_init(unsigned long start, unsigned long size,
|
||||||
unsigned long unit);
|
unsigned long unit);
|
||||||
void ihk_pagealloc_destroy(void *__desc);
|
void ihk_pagealloc_destroy(void *__desc);
|
||||||
unsigned long ihk_pagealloc_alloc(void *__desc, int npages);
|
unsigned long ihk_pagealloc_alloc(void *__desc, int npages, int p2align);
|
||||||
void ihk_pagealloc_reserve(void *desc, unsigned long start, unsigned long end);
|
void ihk_pagealloc_reserve(void *desc, unsigned long start, unsigned long end);
|
||||||
void ihk_pagealloc_free(void *__desc, unsigned long address, int npages);
|
void ihk_pagealloc_free(void *__desc, unsigned long address, int npages);
|
||||||
unsigned long ihk_pagealloc_count(void *__desc);
|
unsigned long ihk_pagealloc_count(void *__desc);
|
||||||
|
|||||||
@@ -88,13 +88,14 @@ void ihk_pagealloc_destroy(void *__desc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long __ihk_pagealloc_large(struct ihk_page_allocator_desc *desc,
|
static unsigned long __ihk_pagealloc_large(struct ihk_page_allocator_desc *desc,
|
||||||
int npages)
|
int npages, int p2align)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned int i, j, mi;
|
unsigned int i, j, mi;
|
||||||
int nblocks;
|
int nblocks;
|
||||||
int nfrags;
|
int nfrags;
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
|
int mialign;
|
||||||
|
|
||||||
nblocks = (npages / 64);
|
nblocks = (npages / 64);
|
||||||
mask = -1;
|
mask = -1;
|
||||||
@@ -103,13 +104,14 @@ static unsigned long __ihk_pagealloc_large(struct ihk_page_allocator_desc *desc,
|
|||||||
++nblocks;
|
++nblocks;
|
||||||
mask = (1UL << nfrags) - 1;
|
mask = (1UL << nfrags) - 1;
|
||||||
}
|
}
|
||||||
|
mialign = (p2align <= 6)? 1: (1 << (p2align - 6));
|
||||||
|
|
||||||
flags = ihk_mc_spinlock_lock(&desc->lock);
|
flags = ihk_mc_spinlock_lock(&desc->lock);
|
||||||
for (i = 0, mi = desc->last; i < desc->count; i++, mi++) {
|
for (i = 0, mi = desc->last; i < desc->count; i++, mi++) {
|
||||||
if (mi >= desc->count) {
|
if (mi >= desc->count) {
|
||||||
mi = 0;
|
mi = 0;
|
||||||
}
|
}
|
||||||
if (mi + nblocks >= desc->count) {
|
if ((mi + nblocks >= desc->count) || (mi % mialign)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (j = mi; j < mi + nblocks - 1; j++) {
|
for (j = mi; j < mi + nblocks - 1; j++) {
|
||||||
@@ -131,18 +133,20 @@ static unsigned long __ihk_pagealloc_large(struct ihk_page_allocator_desc *desc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long ihk_pagealloc_alloc(void *__desc, int npages)
|
unsigned long ihk_pagealloc_alloc(void *__desc, int npages, int p2align)
|
||||||
{
|
{
|
||||||
struct ihk_page_allocator_desc *desc = __desc;
|
struct ihk_page_allocator_desc *desc = __desc;
|
||||||
unsigned int i, mi;
|
unsigned int i, mi;
|
||||||
int j;
|
int j;
|
||||||
unsigned long v, mask, flags;
|
unsigned long v, mask, flags;
|
||||||
|
int jalign;
|
||||||
|
|
||||||
if (npages >= 32) {
|
if ((npages >= 32) || (p2align >= 5)) {
|
||||||
return __ihk_pagealloc_large(desc, npages);
|
return __ihk_pagealloc_large(desc, npages, p2align);
|
||||||
}
|
}
|
||||||
|
|
||||||
mask = (1UL << npages) - 1;
|
mask = (1UL << npages) - 1;
|
||||||
|
jalign = (p2align <= 0)? 1: (1 << p2align);
|
||||||
|
|
||||||
flags = ihk_mc_spinlock_lock(&desc->lock);
|
flags = ihk_mc_spinlock_lock(&desc->lock);
|
||||||
for (i = 0, mi = desc->last; i < desc->count; i++, mi++) {
|
for (i = 0, mi = desc->last; i < desc->count; i++, mi++) {
|
||||||
@@ -155,6 +159,9 @@ unsigned long ihk_pagealloc_alloc(void *__desc, int npages)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (j = 0; j <= 64 - npages; j++) {
|
for (j = 0; j <= 64 - npages; j++) {
|
||||||
|
if (j % jalign) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!(v & (mask << j))) { /* free */
|
if (!(v & (mask << j))) { /* free */
|
||||||
desc->map[mi] |= (mask << j);
|
desc->map[mi] |= (mask << j);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user