mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +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
Dom Cobley
parent
7ee09be470
commit
e10480e82d
@@ -61,6 +61,7 @@ extern void cma_reserve_pages_on_error(struct cma *cma);
|
||||
struct folio *cma_alloc_folio(struct cma *cma, int order, gfp_t gfp);
|
||||
bool cma_free_folio(struct cma *cma, const struct folio *folio);
|
||||
bool cma_validate_zones(struct cma *cma);
|
||||
int cma_check_range(u64 *start, u64 *end);
|
||||
#else
|
||||
static inline struct folio *cma_alloc_folio(struct cma *cma, int order, gfp_t gfp)
|
||||
{
|
||||
@@ -71,10 +72,16 @@ static inline bool cma_free_folio(struct cma *cma, const struct folio *folio)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool cma_validate_zones(struct cma *cma)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int cma_check_range(u64 *start, u64 *end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
36
mm/cma.c
36
mm/cma.c
@@ -1121,3 +1121,39 @@ void __init *cma_reserve_early(struct cma *cma, unsigned long size)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <linux/topology.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/numa_memblks.h>
|
||||
#include <linux/cma.h>
|
||||
#include <asm/numa.h>
|
||||
#include <acpi/acpi_numa.h>
|
||||
|
||||
@@ -52,6 +53,7 @@ static int __init emu_setup_memblk(struct numa_meminfo *ei,
|
||||
{
|
||||
struct numa_memblk *eb = &ei->blk[ei->nr_blks];
|
||||
struct numa_memblk *pb = &pi->blk[phys_blk];
|
||||
int ret;
|
||||
|
||||
if (ei->nr_blks >= NR_NODE_MEMBLKS) {
|
||||
pr_err("NUMA: Too many emulated memblks, failing emulation\n");
|
||||
@@ -63,6 +65,10 @@ static int __init emu_setup_memblk(struct numa_meminfo *ei,
|
||||
eb->end = pb->start + size;
|
||||
eb->nid = nid;
|
||||
|
||||
ret = cma_check_range(&eb->start, &eb->end);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (emu_nid_to_phys[nid] == NUMA_NO_NODE)
|
||||
emu_nid_to_phys[nid] = pb->nid;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user