summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Artamonov <kartamonov@nvidia.com>2011-06-26 21:22:37 +0300
committerAnnamaria Pyreddy <apyreddy@nvidia.com>2011-08-19 16:42:47 -0700
commit9d650429b634914e0705c37d84a9cfa44375391a (patch)
tree51924a95dab29907ecdb21511e84be73da5ac429
parenta4be690ae1ef80d7084d263a63efe8c1654e0971 (diff)
video: tegra: nvmap: single page allocation policy corrected
When user doesn't use default heap policy and selects GART or carveout allocation, automatic single-page-to-sysmem rule doesn't work. Because of broken rule many single page allocations take extra space in carveout and create unnecessary page mappings in GART and SMMU. The fix adds sysmem bit to heap mask when allocation is single page and GART or carveout is present in heap mask. bug 730124 bug 731923 The change also does sanity check of available system memory before adding sysmem bit for carveout allocations. bug 777839 Reviewed-on: http://git-master/r/31383 (cherry picked from commit 502c2becc54b49d26371f9b167f0c6f82a1bc37f) Bug 844307 Conflicts: drivers/video/tegra/nvmap/nvmap_handle.c Reviewed-on: http://git-master/r/38429 (cherry picked from commit ddfc93d27830a28a1c9786fd5bce6dc35727e9ff) Change-Id: I9b8f84a5a7daf192d1d412926f91e5de71938818 Reviewed-on: http://git-master/r/47829 Reviewed-by: Andre Sihera <asihera@nvidia.com> Tested-by: Andre Sihera <asihera@nvidia.com> Reviewed-by: Kirill Artamonov <kartamonov@nvidia.com> Reviewed-by: Krishna Reddy <vdumpa@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r--drivers/video/tegra/nvmap/nvmap_handle.c33
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;