summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/nvmap/nvmap_handle.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/tegra/nvmap/nvmap_handle.c')
-rw-r--r--drivers/video/tegra/nvmap/nvmap_handle.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/video/tegra/nvmap/nvmap_handle.c b/drivers/video/tegra/nvmap/nvmap_handle.c
index 3b1c2ee06b10..de47aa7a5e58 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"
@@ -319,6 +322,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)
@@ -340,8 +347,29 @@ int nvmap_alloc_handle_id(struct nvmap_client *client,
h->secure = !!(flags & NVMAP_HANDLE_SECURE);
h->flags = (flags & NVMAP_HANDLE_CACHE_FLAG);
h->align = max_t(size_t, align, L1_CACHE_BYTES);
+
#ifndef CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM
- /* This resriction is deprecated as alignments greater than
+#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 (h->align > PAGE_SIZE)