blob: e12c3cf2c90fecdeb3056a582af7d5d96dc3ffa6 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#pragma once
#include <iovec.h>
#include <sys/types.h>
#include <vm/pmm.h>
#include <zircon/types.h>
__BEGIN_CDECLS
// This library exists to calculate memory ranges to be used as arenas
// for the pmm based on a predefined memory limit. The limit is passed in
// MB via the kernel.memory-limit-mb cmdline argument. The library will
// calculate memory arenas based on provided ranges, reserved boot regions,
// and the limit provided and add those to the system when
// memory_limit_add_arenas is called.
//
// A system that has a single contiguous range of memory may look something
// like this with a couple reserved regions at the front. Limiting memory in
// this case is simple since we can shrink the range on the right.
// +-------------------------------------------------+
// |--| || |
// +-------------------------------------------------+
// becomes
// +---------------------+
// |--| || |
// +---------------------+
// A more complicated layout might be two contiguous memory ranges with reserved
// boot regions in each:
// +--------------------------------+ +-------------+
// | |-| |-----| | | |--| |
// +--------------------------------+ +-------------+
// In this case we would have to ensure reach reserved range is mantained but
// also keep it within a limit. It could end up like the following after we
// track front/back space in each range and adjust things as needed (front /
// back are noted by characters):
// +------+ +---------------------+ +------+
// f | |-| | b f | |-----| | b f | |--| | b
// +------+ +---------------------+ +------+
// Even more complicated layouts like the following also need to be handled:
// +--------+ +--------+ +---------------+ +--------+
// | |-| | | |--| | | |--| | | || |
// +--------+ +--------+ +---------------+ +--------+
//
// In this case we would need to ensure we fit all four reserved regions in four
// separate ranges, then grow each one outward as the limit allowed.
//
// For the reasons above, the library makes multiple passes through the memory
// arenas to ensure all reserved regions are protected, and while doing so it
// tracks 'spare' memory nearby so that it can be added to the PMM if the
// limit provided facilitates it.
// Checks if a memory limit exists and initializes the lib bookkeeping.
//
// Returns ZX_OK on success, ZX_ERR_BAD_STATE if already initialized, or
// ERR_NOT_SUPPORTED if no memory limit was passed via kernel.memory-limit-mb
zx_status_t memory_limit_init();
// Adds a given range of memory to the memory allocator to use in
// sorting out memory arenas.
//
// @range_base: the start address of the range.
// @range_size: size of the range in bytes
// @arena_template: a structure containing the default values for flags,
// priority, and name used for arenas created by this function in the
// event of any failure conditions.
//
// Returns ZX_OK on completion, and ZX_ERR_INVALID_ARGS if parameters are
// invalid
zx_status_t memory_limit_add_range(uintptr_t range_base,
size_t range_size,
pmm_arena_info_t arena_template);
// Uses the ranges provided by memory_limit_add_range to calculate the
// acceptable memory arenas to fit within our imposed memory limitations
// while still including all required reserved boot regions.
//
// @arena_template: a structure containing the default values for flags,
// priority, and name used for arenas created by this function in the
// event of any failure conditions.
zx_status_t memory_limit_add_arenas(pmm_arena_info_t arena_template);
__END_CDECLS