summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_gem.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-09-14 19:50:30 +0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-09-18 01:43:32 +0400
commit07f73f6912667621276b002e33844ef283d98203 (patch)
tree4da6860e7d4a165ef1fe233becc74005f9964ca2 /drivers/gpu/drm/drm_gem.c
parent3ef94daae7530b4ebcd2e5f48f1028cd2d2470ba (diff)
downloadlinux-07f73f6912667621276b002e33844ef283d98203.tar.xz
drm/i915: Improve behaviour under memory pressure
Due to the necessity of having to take the struct_mutex, the i915 shrinker can not free the inactive lists if we fail to allocate memory whilst processing a batch buffer, triggering an OOM and an ENOMEM that is reported back to userspace. In order to fare better under such circumstances we need to manually retry a failed allocation after evicting inactive buffers. To do so involves 3 steps: 1. Marking the backing shm pages as NORETRY. 2. Updating the get_pages() callers to evict something on failure and then retry. 3. Revamping the evict something logic to be smarter about the required buffer size and prefer to use volatile or clean inactive pages. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/gpu/drm/drm_gem.c')
-rw-r--r--drivers/gpu/drm/drm_gem.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 230c9ffdd5e9..80391995bdec 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -142,6 +142,19 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
if (IS_ERR(obj->filp))
goto free;
+ /* Basically we want to disable the OOM killer and handle ENOMEM
+ * ourselves by sacrificing pages from cached buffers.
+ * XXX shmem_file_[gs]et_gfp_mask()
+ */
+ mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping,
+ GFP_HIGHUSER |
+ __GFP_COLD |
+ __GFP_FS |
+ __GFP_RECLAIMABLE |
+ __GFP_NORETRY |
+ __GFP_NOWARN |
+ __GFP_NOMEMALLOC);
+
kref_init(&obj->refcount);
kref_init(&obj->handlecount);
obj->size = size;