|
14 | 14 | #include <linux/cpuhotplug.h>
|
15 | 15 | #include <linux/memblock.h>
|
16 | 16 | #include <linux/kmemleak.h>
|
| 17 | +#include <linux/cma.h> |
| 18 | +#include <linux/crash_reserve.h> |
17 | 19 |
|
18 | 20 | #include <asm/page.h>
|
19 | 21 | #include <asm/sections.h>
|
@@ -469,6 +471,56 @@ void __init reserve_crashkernel_generic(unsigned long long crash_size,
|
469 | 471 | #endif
|
470 | 472 | }
|
471 | 473 |
|
| 474 | +struct range crashk_cma_ranges[CRASHKERNEL_CMA_RANGES_MAX]; |
| 475 | +#ifdef CRASHKERNEL_CMA |
| 476 | +int crashk_cma_cnt; |
| 477 | +void __init reserve_crashkernel_cma(unsigned long long cma_size) |
| 478 | +{ |
| 479 | + unsigned long long request_size = roundup(cma_size, PAGE_SIZE); |
| 480 | + unsigned long long reserved_size = 0; |
| 481 | + |
| 482 | + if (!cma_size) |
| 483 | + return; |
| 484 | + |
| 485 | + while (cma_size > reserved_size && |
| 486 | + crashk_cma_cnt < CRASHKERNEL_CMA_RANGES_MAX) { |
| 487 | + |
| 488 | + struct cma *res; |
| 489 | + |
| 490 | + if (cma_declare_contiguous(0, request_size, 0, 0, 0, false, |
| 491 | + "crashkernel", &res)) { |
| 492 | + /* reservation failed, try half-sized blocks */ |
| 493 | + if (request_size <= PAGE_SIZE) |
| 494 | + break; |
| 495 | + |
| 496 | + request_size = roundup(request_size / 2, PAGE_SIZE); |
| 497 | + continue; |
| 498 | + } |
| 499 | + |
| 500 | + crashk_cma_ranges[crashk_cma_cnt].start = cma_get_base(res); |
| 501 | + crashk_cma_ranges[crashk_cma_cnt].end = |
| 502 | + crashk_cma_ranges[crashk_cma_cnt].start + |
| 503 | + cma_get_size(res) - 1; |
| 504 | + ++crashk_cma_cnt; |
| 505 | + reserved_size += request_size; |
| 506 | + } |
| 507 | + |
| 508 | + if (cma_size > reserved_size) |
| 509 | + pr_warn("crashkernel CMA reservation failed: %lld MB requested, %lld MB reserved in %d ranges\n", |
| 510 | + cma_size >> 20, reserved_size >> 20, crashk_cma_cnt); |
| 511 | + else |
| 512 | + pr_info("crashkernel CMA reserved: %lld MB in %d ranges\n", |
| 513 | + reserved_size >> 20, crashk_cma_cnt); |
| 514 | +} |
| 515 | + |
| 516 | +#else /* CRASHKERNEL_CMA */ |
| 517 | +void __init reserve_crashkernel_cma(unsigned long long cma_size) |
| 518 | +{ |
| 519 | + if (cma_size) |
| 520 | + pr_warn("crashkernel CMA reservation not supported\n"); |
| 521 | +} |
| 522 | +#endif |
| 523 | + |
472 | 524 | #ifndef HAVE_ARCH_ADD_CRASH_RES_TO_IOMEM_EARLY
|
473 | 525 | static __init int insert_crashkernel_resources(void)
|
474 | 526 | {
|
|
0 commit comments