mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-07 10:29:52 +00:00
numa/emulation: Check emulated zones around the CMA window
... Make sure CMA zones do not straddle the emulated NUMA nodes ... Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
This commit is contained in:
committed by
Phil Elwell
parent
56fda5adce
commit
a27d76f451
@@ -7,6 +7,7 @@
|
|||||||
* Author: Maíra Canal <mcanal@igalia.com>
|
* Author: Maíra Canal <mcanal@igalia.com>
|
||||||
* Author: Tvrtko Ursulin <tursulin@igalia.com>
|
* Author: Tvrtko Ursulin <tursulin@igalia.com>
|
||||||
*/
|
*/
|
||||||
|
#include <linux/cma.h>
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
|
|
||||||
#include "numa_emulation.h"
|
#include "numa_emulation.h"
|
||||||
@@ -55,6 +56,10 @@ int __init numa_emu_init(void)
|
|||||||
if (i == (emu_nodes - 1) && e != end)
|
if (i == (emu_nodes - 1) && e != end)
|
||||||
e = end;
|
e = end;
|
||||||
|
|
||||||
|
ret = cma_check_range(&s, &e);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
pr_info("Faking a node at [mem %pap-%pap]\n", &s, &e);
|
pr_info("Faking a node at [mem %pap-%pap]\n", &s, &e);
|
||||||
ret = numa_add_memblk(i, s, e + 1);
|
ret = numa_add_memblk(i, s, e + 1);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|||||||
@@ -56,4 +56,14 @@ extern bool cma_release(struct cma *cma, const struct page *pages, unsigned long
|
|||||||
extern int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data);
|
extern int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data);
|
||||||
|
|
||||||
extern void cma_reserve_pages_on_error(struct cma *cma);
|
extern void cma_reserve_pages_on_error(struct cma *cma);
|
||||||
|
|
||||||
|
#ifdef CONFIG_CMA
|
||||||
|
extern int cma_check_range(u64 *start, u64 *end);
|
||||||
|
#else
|
||||||
|
static inline int cma_check_range(u64 *start, u64 *end)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
36
mm/cma.c
36
mm/cma.c
@@ -587,3 +587,39 @@ int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct cma_check_range_data {
|
||||||
|
u64 start, end;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int check_range(struct cma *cma_, void *data)
|
||||||
|
{
|
||||||
|
struct cma_check_range_data *range = data;
|
||||||
|
struct cma_check_range_data cma;
|
||||||
|
bool starts_in_range;
|
||||||
|
bool ends_in_range;
|
||||||
|
|
||||||
|
cma.start = cma_get_base(cma_);
|
||||||
|
cma.end = cma.start + cma_get_size(cma_) - 1;
|
||||||
|
|
||||||
|
starts_in_range = cma.start >= range->start && cma.start <= range->end;
|
||||||
|
ends_in_range = cma.end >= range->start && cma.end <= range->end;
|
||||||
|
|
||||||
|
if (starts_in_range == ends_in_range)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pr_notice("CMA %s [%llx-%llx] straddles range [%llx-%llx]\n",
|
||||||
|
cma_->name, cma.start, cma.end, range->start, range->end);
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cma_check_range(u64 *start, u64 *end)
|
||||||
|
{
|
||||||
|
struct cma_check_range_data range = {
|
||||||
|
.start = *start,
|
||||||
|
.end = *end,
|
||||||
|
};
|
||||||
|
|
||||||
|
return cma_for_each_area(check_range, &range);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user