summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2008-04-06 09:33:50 +0200
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2008-04-06 10:30:27 +0200
commit87ae5b22e3120d205f520a99cea31743903d49a2 (patch)
tree577fbcf75203f0c846fd1bc928e5638f371b5c29 /linux-core
parent1692d30cea263a084bfea824cd8638000e97bc57 (diff)
Fix emergency allocation accounting.
Diffstat (limited to 'linux-core')
-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)
int drm_alloc_memctl(size_t size)
{
- int ret = 0;
+ int ret = 0;
unsigned long a_size = drm_size_align(size);
- unsigned long new_used = drm_memctl.cur_used + a_size;
+ unsigned long new_used;
spin_lock(&drm_memctl.lock);
- if (unlikely(new_used > drm_memctl.high_threshold)) {
- if (!DRM_SUSER(DRM_CURPROC) ||
- (new_used + drm_memctl.emer_used > drm_memctl.emer_threshold) ||
- (a_size > 2*PAGE_SIZE)) {
- ret = -ENOMEM;
- goto out;
- }
-
- /*
- * Allow small root-only allocations, even if the
- * high threshold is exceeded.
- */
-
- new_used -= drm_memctl.high_threshold;
- drm_memctl.emer_used += new_used;
- a_size -= new_used;
+ new_used = drm_memctl.cur_used + a_size;
+ if (likely(new_used < drm_memctl.high_threshold)) {
+ drm_memctl.cur_used = new_used;
+ goto out;
}
- drm_memctl.cur_used += a_size;
+
+ /*
+ * Allow small allocations from root-only processes to
+ * succeed until the emergency threshold is reached.
+ */
+
+ new_used += drm_memctl.emer_used;
+ if (unlikely(!DRM_SUSER(DRM_CURPROC) ||
+ (a_size > 16*PAGE_SIZE) ||
+ (new_used > drm_memctl.emer_threshold))) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ drm_memctl.cur_used = drm_memctl.high_threshold;
+ drm_memctl.emer_used = new_used - drm_memctl.high_threshold;
out:
spin_unlock(&drm_memctl.lock);
return ret;
}
EXPORT_SYMBOL(drm_alloc_memctl);
+
void drm_free_memctl(size_t size)
{
unsigned long a_size = drm_size_align(size);