of: reserved_mem: Check that memory reserved in device tree is in use

Inside of dma_alloc_attrs(), verify that devices with a reserved memory
region are actually using the region, in order to prevent wastage of
memory.

Change-Id: I56852a761d3253ec2a3a7db0f6501c73983e55c6
Signed-off-by: Chris Goldsworthy <[email protected]>
This commit is contained in:
Chris Goldsworthy 2019-09-20 14:31:04 -07:00
commit d9c9998b16
4 changed files with 67 additions and 0 deletions

View file

@ -86,6 +86,16 @@ config OF_RESERVED_MEM
depends on OF_EARLY_FLATTREE
default y if DMA_DECLARE_COHERENT || DMA_CMA
config OF_RESERVED_MEM_CHECK
bool "Reserved memory registration check"
depends on OF_RESERVED_MEM
help
If a device has a reserved memory region and allocates memory
through the DMA API, check to see if the device and region have been
associated through a call to of_reserved_mem_device_init_by_idx()
before performing an allocation. If the association hasn't occurred,
WARN_ON.
config OF_RESOLVE
bool

View file

@ -385,6 +385,51 @@ void of_reserved_mem_device_release(struct device *dev)
}
EXPORT_SYMBOL_GPL(of_reserved_mem_device_release);
#ifdef CONFIG_OF_RESERVED_MEM_CHECK
/**
* of_reserved_mem_device_is_init() - test if a device's reserved memory
* will be used in DMA allocations
* @dev: device we want to perform test on
*
* Check if a device and its reserved memory region (if it has one) have
* been associated with one another through a call to
* of_reserved_mem_device_init_by_idx().
*
* Return false if the device has reserved memory and it's not in use, true
* otherwise.
*/
bool of_reserved_mem_device_is_init(struct device *dev)
{
struct device_node *mem_dev_node;
struct rmem_assigned_device *rd;
bool ret = false;
if (!dev->of_node)
return true;
mem_dev_node = of_parse_phandle(dev->of_node, "memory-region", 0);
if (!mem_dev_node)
return true;
if (!of_device_is_available(mem_dev_node) || !__find_rmem(mem_dev_node))
goto exit;
of_node_put(mem_dev_node);
mutex_lock(&of_rmem_assigned_device_mutex);
list_for_each_entry(rd, &of_rmem_assigned_device_list, list) {
if (rd->dev == dev) {
ret = true;
break;
}
}
mutex_unlock(&of_rmem_assigned_device_mutex);
return ret;
exit:
of_node_put(mem_dev_node);
return true;
}
#endif /* CONFIG_OF_RESERVED_MEM_CHECK */
/**
* of_reserved_mem_lookup() - acquire reserved_mem from a device node
* @np: node pointer of the desired reserved-memory region