diff options
author | Thomas Hellstrom | 2008-01-17 06:10:36 -0600 |
---|---|---|
committer | Thomas Hellstrom | 2008-03-12 04:10:03 -0500 |
commit | c0a1cd052ac44d1b342fa3f26afe1bd21d92b194 (patch) | |
tree | 38c75825b1bb6208c24b524b5ac5994d902cb0bf /linux-core | |
parent | 7bcce66a1d5c93ff9b9f20d45d5b2c33c8ca8da9 (diff) | |
download | external-libdrm-c0a1cd052ac44d1b342fa3f26afe1bd21d92b194.tar.gz external-libdrm-c0a1cd052ac44d1b342fa3f26afe1bd21d92b194.tar.xz external-libdrm-c0a1cd052ac44d1b342fa3f26afe1bd21d92b194.zip |
Add an emergency pinnable memory quota for root-only processes.
Diffstat (limited to 'linux-core')
-rw-r--r-- | linux-core/drmP.h | 4 | ||||
-rw-r--r-- | linux-core/drm_memory.c | 44 | ||||
-rw-r--r-- | linux-core/drm_proc.c | 14 |
3 files changed, 53 insertions, 9 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 1fea807b..2f76f3df 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h | |||
@@ -1001,8 +1001,10 @@ extern int drm_unbind_agp(DRM_AGP_MEM * handle); | |||
1001 | extern void drm_free_memctl(size_t size); | 1001 | extern void drm_free_memctl(size_t size); |
1002 | extern int drm_alloc_memctl(size_t size); | 1002 | extern int drm_alloc_memctl(size_t size); |
1003 | extern void drm_query_memctl(uint64_t *cur_used, | 1003 | extern void drm_query_memctl(uint64_t *cur_used, |
1004 | uint64_t *emer_used, | ||
1004 | uint64_t *low_threshold, | 1005 | uint64_t *low_threshold, |
1005 | uint64_t *high_threshold); | 1006 | uint64_t *high_threshold, |
1007 | uint64_t *emer_threshold); | ||
1006 | extern void drm_init_memctl(size_t low_threshold, | 1008 | extern void drm_init_memctl(size_t low_threshold, |
1007 | size_t high_threshold, | 1009 | size_t high_threshold, |
1008 | size_t unit_size); | 1010 | size_t unit_size); |
diff --git a/linux-core/drm_memory.c b/linux-core/drm_memory.c index 402a680f..1a6c48df 100644 --- a/linux-core/drm_memory.c +++ b/linux-core/drm_memory.c | |||
@@ -39,8 +39,10 @@ | |||
39 | static struct { | 39 | static struct { |
40 | spinlock_t lock; | 40 | spinlock_t lock; |
41 | uint64_t cur_used; | 41 | uint64_t cur_used; |
42 | uint64_t emer_used; | ||
42 | uint64_t low_threshold; | 43 | uint64_t low_threshold; |
43 | uint64_t high_threshold; | 44 | uint64_t high_threshold; |
45 | uint64_t emer_threshold; | ||
44 | } drm_memctl = { | 46 | } drm_memctl = { |
45 | .lock = SPIN_LOCK_UNLOCKED | 47 | .lock = SPIN_LOCK_UNLOCKED |
46 | }; | 48 | }; |
@@ -59,14 +61,30 @@ static inline size_t drm_size_align(size_t size) | |||
59 | 61 | ||
60 | int drm_alloc_memctl(size_t size) | 62 | int drm_alloc_memctl(size_t size) |
61 | { | 63 | { |
62 | int ret; | 64 | int ret = 0; |
63 | 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; | ||
64 | 67 | ||
65 | spin_lock(&drm_memctl.lock); | 68 | spin_lock(&drm_memctl.lock); |
66 | ret = ((drm_memctl.cur_used + a_size) > drm_memctl.high_threshold) ? | 69 | if (unlikely(new_used > drm_memctl.high_threshold)) { |
67 | -ENOMEM : 0; | 70 | if (!DRM_SUSER(DRM_CURPROC) || |
68 | if (!ret) | 71 | (new_used + drm_memctl.emer_used > drm_memctl.emer_threshold) || |
69 | drm_memctl.cur_used += a_size; | 72 | (a_size > 2*PAGE_SIZE)) { |
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 | } | ||
86 | drm_memctl.cur_used += a_size; | ||
87 | out: | ||
70 | spin_unlock(&drm_memctl.lock); | 88 | spin_unlock(&drm_memctl.lock); |
71 | return ret; | 89 | return ret; |
72 | } | 90 | } |
@@ -77,19 +95,30 @@ void drm_free_memctl(size_t size) | |||
77 | unsigned long a_size = drm_size_align(size); | 95 | unsigned long a_size = drm_size_align(size); |
78 | 96 | ||
79 | spin_lock(&drm_memctl.lock); | 97 | spin_lock(&drm_memctl.lock); |
98 | if (likely(a_size >= drm_memctl.emer_used)) { | ||
99 | a_size -= drm_memctl.emer_used; | ||
100 | drm_memctl.emer_used = 0; | ||
101 | } else { | ||
102 | drm_memctl.emer_used -= a_size; | ||
103 | a_size = 0; | ||
104 | } | ||
80 | drm_memctl.cur_used -= a_size; | 105 | drm_memctl.cur_used -= a_size; |
81 | spin_unlock(&drm_memctl.lock); | 106 | spin_unlock(&drm_memctl.lock); |
82 | } | 107 | } |
83 | EXPORT_SYMBOL(drm_free_memctl); | 108 | EXPORT_SYMBOL(drm_free_memctl); |
84 | 109 | ||
85 | void drm_query_memctl(uint64_t *cur_used, | 110 | void drm_query_memctl(uint64_t *cur_used, |
111 | uint64_t *emer_used, | ||
86 | uint64_t *low_threshold, | 112 | uint64_t *low_threshold, |
87 | uint64_t *high_threshold) | 113 | uint64_t *high_threshold, |
114 | uint64_t *emer_threshold) | ||
88 | { | 115 | { |
89 | spin_lock(&drm_memctl.lock); | 116 | spin_lock(&drm_memctl.lock); |
90 | *cur_used = drm_memctl.cur_used; | 117 | *cur_used = drm_memctl.cur_used; |
118 | *emer_used = drm_memctl.emer_used; | ||
91 | *low_threshold = drm_memctl.low_threshold; | 119 | *low_threshold = drm_memctl.low_threshold; |
92 | *high_threshold = drm_memctl.high_threshold; | 120 | *high_threshold = drm_memctl.high_threshold; |
121 | *emer_threshold = drm_memctl.emer_threshold; | ||
93 | spin_unlock(&drm_memctl.lock); | 122 | spin_unlock(&drm_memctl.lock); |
94 | } | 123 | } |
95 | EXPORT_SYMBOL(drm_query_memctl); | 124 | EXPORT_SYMBOL(drm_query_memctl); |
@@ -99,9 +128,12 @@ void drm_init_memctl(size_t p_low_threshold, | |||
99 | size_t unit_size) | 128 | size_t unit_size) |
100 | { | 129 | { |
101 | spin_lock(&drm_memctl.lock); | 130 | spin_lock(&drm_memctl.lock); |
131 | drm_memctl.emer_used = 0; | ||
102 | drm_memctl.cur_used = 0; | 132 | drm_memctl.cur_used = 0; |
103 | drm_memctl.low_threshold = p_low_threshold * unit_size; | 133 | drm_memctl.low_threshold = p_low_threshold * unit_size; |
104 | drm_memctl.high_threshold = p_high_threshold * unit_size; | 134 | drm_memctl.high_threshold = p_high_threshold * unit_size; |
135 | drm_memctl.emer_threshold = (drm_memctl.high_threshold >> 4) + | ||
136 | drm_memctl.high_threshold; | ||
105 | spin_unlock(&drm_memctl.lock); | 137 | spin_unlock(&drm_memctl.lock); |
106 | } | 138 | } |
107 | 139 | ||
diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c index 67afee8e..42da5c69 100644 --- a/linux-core/drm_proc.c +++ b/linux-core/drm_proc.c | |||
@@ -445,9 +445,10 @@ static int drm__objects_info(char *buf, char **start, off_t offset, int request, | |||
445 | struct drm_buffer_manager *bm = &dev->bm; | 445 | struct drm_buffer_manager *bm = &dev->bm; |
446 | struct drm_fence_manager *fm = &dev->fm; | 446 | struct drm_fence_manager *fm = &dev->fm; |
447 | uint64_t used_mem; | 447 | uint64_t used_mem; |
448 | uint64_t used_emer; | ||
448 | uint64_t low_mem; | 449 | uint64_t low_mem; |
449 | uint64_t high_mem; | 450 | uint64_t high_mem; |
450 | 451 | uint64_t emer_mem; | |
451 | 452 | ||
452 | if (offset > DRM_PROC_LIMIT) { | 453 | if (offset > DRM_PROC_LIMIT) { |
453 | *eof = 1; | 454 | *eof = 1; |
@@ -476,7 +477,7 @@ static int drm__objects_info(char *buf, char **start, off_t offset, int request, | |||
476 | DRM_PROC_PRINT("Buffer objects are not supported by this driver.\n"); | 477 | DRM_PROC_PRINT("Buffer objects are not supported by this driver.\n"); |
477 | } | 478 | } |
478 | 479 | ||
479 | drm_query_memctl(&used_mem, &low_mem, &high_mem); | 480 | drm_query_memctl(&used_mem, &used_emer, &low_mem, &high_mem, &emer_mem); |
480 | 481 | ||
481 | if (used_mem > 16*PAGE_SIZE) { | 482 | if (used_mem > 16*PAGE_SIZE) { |
482 | DRM_PROC_PRINT("Used object memory is %lu pages.\n", | 483 | DRM_PROC_PRINT("Used object memory is %lu pages.\n", |
@@ -485,10 +486,19 @@ static int drm__objects_info(char *buf, char **start, off_t offset, int request, | |||
485 | DRM_PROC_PRINT("Used object memory is %lu bytes.\n", | 486 | DRM_PROC_PRINT("Used object memory is %lu bytes.\n", |
486 | (unsigned long) used_mem); | 487 | (unsigned long) used_mem); |
487 | } | 488 | } |
489 | if (used_emer > 16*PAGE_SIZE) { | ||
490 | DRM_PROC_PRINT("Used emergency memory is %lu pages.\n", | ||
491 | (unsigned long) (used_emer >> PAGE_SHIFT)); | ||
492 | } else { | ||
493 | DRM_PROC_PRINT("Used emergency memory is %lu bytes.\n\n", | ||
494 | (unsigned long) used_emer); | ||
495 | } | ||
488 | DRM_PROC_PRINT("Soft object memory usage threshold is %lu pages.\n", | 496 | DRM_PROC_PRINT("Soft object memory usage threshold is %lu pages.\n", |
489 | (unsigned long) (low_mem >> PAGE_SHIFT)); | 497 | (unsigned long) (low_mem >> PAGE_SHIFT)); |
490 | DRM_PROC_PRINT("Hard object memory usage threshold is %lu pages.\n", | 498 | DRM_PROC_PRINT("Hard object memory usage threshold is %lu pages.\n", |
491 | (unsigned long) (high_mem >> PAGE_SHIFT)); | 499 | (unsigned long) (high_mem >> PAGE_SHIFT)); |
500 | DRM_PROC_PRINT("Emergency root only memory usage threshold is %lu pages.\n", | ||
501 | (unsigned long) (emer_mem >> PAGE_SHIFT)); | ||
492 | 502 | ||
493 | DRM_PROC_PRINT("\n"); | 503 | DRM_PROC_PRINT("\n"); |
494 | 504 | ||