diff options
author | Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | 2008-04-06 09:33:50 +0200 |
---|---|---|
committer | Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | 2008-04-06 10:30:27 +0200 |
commit | 87ae5b22e3120d205f520a99cea31743903d49a2 (patch) | |
tree | 577fbcf75203f0c846fd1bc928e5638f371b5c29 | |
parent | 1692d30cea263a084bfea824cd8638000e97bc57 (diff) |
Fix emergency allocation accounting.
-rw-r--r-- | linux-core/drm_memory.c | 42 |
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); |