aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hellstrom2008-04-06 02:33:50 -0500
committerThomas Hellstrom2008-04-06 03:30:27 -0500
commit87ae5b22e3120d205f520a99cea31743903d49a2 (patch)
tree577fbcf75203f0c846fd1bc928e5638f371b5c29
parent1692d30cea263a084bfea824cd8638000e97bc57 (diff)
downloadexternal-libdrm-87ae5b22e3120d205f520a99cea31743903d49a2.tar.gz
external-libdrm-87ae5b22e3120d205f520a99cea31743903d49a2.tar.xz
external-libdrm-87ae5b22e3120d205f520a99cea31743903d49a2.zip
Fix emergency allocation accounting.
-rw-r--r--linux-core/drm_memory.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/linux-core/drm_memory.c b/linux-core/drm_memory.c
index 12e01414..75f5b521 100644
--- a/linux-core/drm_memory.c
+++ b/linux-core/drm_memory.c
@@ -61,35 +61,39 @@ static inline size_t drm_size_align(size_t size)
61 61
62int drm_alloc_memctl(size_t size) 62int drm_alloc_memctl(size_t size)
63{ 63{
64 int ret = 0; 64 int ret = 0;
65 unsigned long a_size = drm_size_align(size); 65 unsigned long a_size = drm_size_align(size);
66 unsigned long new_used = drm_memctl.cur_used + a_size; 66 unsigned long new_used;
67 67
68 spin_lock(&drm_memctl.lock); 68 spin_lock(&drm_memctl.lock);
69 if (unlikely(new_used > drm_memctl.high_threshold)) { 69 new_used = drm_memctl.cur_used + a_size;
70 if (!DRM_SUSER(DRM_CURPROC) || 70 if (likely(new_used < drm_memctl.high_threshold)) {
71 (new_used + drm_memctl.emer_used > drm_memctl.emer_threshold) || 71 drm_memctl.cur_used = new_used;
72 (a_size > 2*PAGE_SIZE)) { 72 goto out;
73 ret = -ENOMEM;
74 goto out;
75 }
76
77 /*
78 * Allow small root-only allocations, even if the
79 * high threshold is exceeded.
80 */
81
82 new_used -= drm_memctl.high_threshold;
83 drm_memctl.emer_used += new_used;
84 a_size -= new_used;
85 } 73 }
86 drm_memctl.cur_used += a_size; 74
75 /*
76 * Allow small allocations from root-only processes to
77 * succeed until the emergency threshold is reached.
78 */
79
80 new_used += drm_memctl.emer_used;
81 if (unlikely(!DRM_SUSER(DRM_CURPROC) ||
82 (a_size > 16*PAGE_SIZE) ||
83 (new_used > drm_memctl.emer_threshold))) {
84 ret = -ENOMEM;
85 goto out;
86 }
87
88 drm_memctl.cur_used = drm_memctl.high_threshold;
89 drm_memctl.emer_used = new_used - drm_memctl.high_threshold;
87out: 90out:
88 spin_unlock(&drm_memctl.lock); 91 spin_unlock(&drm_memctl.lock);
89 return ret; 92 return ret;
90} 93}
91EXPORT_SYMBOL(drm_alloc_memctl); 94EXPORT_SYMBOL(drm_alloc_memctl);
92 95
96
93void drm_free_memctl(size_t size) 97void drm_free_memctl(size_t size)
94{ 98{
95 unsigned long a_size = drm_size_align(size); 99 unsigned long a_size = drm_size_align(size);