diff options
author | Thomas Hellstrom | 2008-04-06 02:33:50 -0500 |
---|---|---|
committer | Thomas Hellstrom | 2008-04-06 03:30:27 -0500 |
commit | 87ae5b22e3120d205f520a99cea31743903d49a2 (patch) | |
tree | 577fbcf75203f0c846fd1bc928e5638f371b5c29 | |
parent | 1692d30cea263a084bfea824cd8638000e97bc57 (diff) | |
download | external-libdrm-87ae5b22e3120d205f520a99cea31743903d49a2.tar.gz external-libdrm-87ae5b22e3120d205f520a99cea31743903d49a2.tar.xz external-libdrm-87ae5b22e3120d205f520a99cea31743903d49a2.zip |
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) | |||
61 | 61 | ||
62 | int drm_alloc_memctl(size_t size) | 62 | int 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; | ||
87 | out: | 90 | out: |
88 | spin_unlock(&drm_memctl.lock); | 91 | spin_unlock(&drm_memctl.lock); |
89 | return ret; | 92 | return ret; |
90 | } | 93 | } |
91 | EXPORT_SYMBOL(drm_alloc_memctl); | 94 | EXPORT_SYMBOL(drm_alloc_memctl); |
92 | 95 | ||
96 | |||
93 | void drm_free_memctl(size_t size) | 97 | void 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); |