diff options
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap_handle.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/video/tegra/nvmap/nvmap_handle.c b/drivers/video/tegra/nvmap/nvmap_handle.c index a9150a36cf2a..cfb0a47ed283 100644 --- a/drivers/video/tegra/nvmap/nvmap_handle.c +++ b/drivers/video/tegra/nvmap/nvmap_handle.c @@ -35,6 +35,9 @@ #include <mach/iovmm.h> #include <mach/nvmap.h> +#include <linux/vmstat.h> +#include <linux/swap.h> + #include "nvmap.h" #include "nvmap_mru.h" #include "nvmap_common.h" @@ -286,6 +289,10 @@ static const unsigned int heap_policy_large[] = { 0, }; +/* Do not override single page policy if there is not much space to +avoid invoking system oom killer. */ +#define NVMAP_SMALL_POLICY_SYSMEM_THRESHOLD 50000000 + int nvmap_alloc_handle_id(struct nvmap_client *client, unsigned long id, unsigned int heap_mask, size_t align, unsigned int flags) @@ -313,6 +320,32 @@ int nvmap_alloc_handle_id(struct nvmap_client *client, h->secure = !!(flags & NVMAP_HANDLE_SECURE); h->flags = (flags & NVMAP_HANDLE_CACHE_FLAG); +#ifdef CONFIG_NVMAP_ALLOW_SYSMEM + /* Allow single pages allocations in system memory to save + * carveout space and avoid extra iovm mappings */ + if (nr_page == 1) { + if (heap_mask & NVMAP_HEAP_IOVMM) + heap_mask |= NVMAP_HEAP_SYSMEM; + else if (heap_mask & NVMAP_HEAP_CARVEOUT_GENERIC) { + /* Calculate size of free physical pages + * managed by kernel */ + unsigned long freeMem = + (global_page_state(NR_FREE_PAGES) + + global_page_state(NR_FILE_PAGES) - + total_swapcache_pages) << PAGE_SHIFT; + + if (freeMem > NVMAP_SMALL_POLICY_SYSMEM_THRESHOLD) + heap_mask |= NVMAP_HEAP_SYSMEM; + } + } +#endif + + /* This restriction is deprecated as alignments greater than + PAGE_SIZE are now correctly handled, but it is retained for + AP20 compatibility. */ + if (align > PAGE_SIZE) + heap_mask &= NVMAP_HEAP_CARVEOUT_MASK; + /* secure allocations can only be served from secure heaps */ if (h->secure) heap_mask &= NVMAP_SECURE_HEAPS; |