28 #define pr_fmt(fmt) "[TTM] " fmt
34 #include <linux/sched.h>
35 #include <linux/wait.h>
37 #include <linux/module.h>
38 #include <linux/slab.h>
40 #define TTM_MEMORY_ALLOC_RETRIES 4
54 .name =
"zone_memory",
58 .name =
"emergency_memory",
62 .name =
"available_memory",
70 .name =
"used_memory",
74 static void ttm_mem_zone_kobj_release(
struct kobject *kobj)
79 pr_info(
"Zone %7s: Used memory at exit: %llu kiB\n",
92 spin_lock(&zone->
glob->lock);
93 if (attr == &ttm_mem_sys)
95 else if (attr == &ttm_mem_emer)
97 else if (attr == &ttm_mem_max)
99 else if (attr == &ttm_mem_swap)
101 else if (attr == &ttm_mem_used)
103 spin_unlock(&zone->
glob->lock);
106 (
unsigned long long) val >> 10);
122 chars =
sscanf(buffer,
"%lu", &val);
129 spin_lock(&zone->
glob->lock);
132 if (attr == &ttm_mem_emer) {
136 }
else if (attr == &ttm_mem_max) {
140 }
else if (attr == &ttm_mem_swap)
142 spin_unlock(&zone->
glob->lock);
144 ttm_check_swapping(zone->
glob);
149 static struct attribute *ttm_mem_zone_attrs[] = {
158 static const struct sysfs_ops ttm_mem_zone_ops = {
159 .show = &ttm_mem_zone_show,
160 .store = &ttm_mem_zone_store
163 static struct kobj_type ttm_mem_zone_kobj_type = {
164 .release = &ttm_mem_zone_kobj_release,
165 .sysfs_ops = &ttm_mem_zone_ops,
166 .default_attrs = ttm_mem_zone_attrs,
169 static void ttm_mem_global_kobj_release(
struct kobject *kobj)
177 static struct kobj_type ttm_mem_glob_kobj_type = {
178 .release = &ttm_mem_global_kobj_release,
181 static bool ttm_zones_above_swap_target(
struct ttm_mem_global *glob,
198 target = (extra >
target) ? 0ULL : target;
219 spin_lock(&glob->
lock);
223 while (ttm_zones_above_swap_target(glob, from_wq, extra)) {
225 spin_unlock(&glob->
lock);
227 spin_lock(&glob->
lock);
232 spin_unlock(&glob->
lock);
242 ttm_shrink(glob,
true, 0ULL);
258 zone->
name =
"kernel";
261 zone->
emer_mem = (mem >> 1) + (mem >> 2);
267 &zone->
kobj, &ttm_mem_zone_kobj_type, &glob->
kobj, zone->
name);
276 #ifdef CONFIG_HIGHMEM
294 zone->
name =
"highmem";
297 zone->
emer_mem = (mem >> 1) + (mem >> 2);
301 glob->zone_highmem = zone;
303 &zone->
kobj, &ttm_mem_zone_kobj_type, &glob->
kobj, zone->
name);
329 if (mem <= ((
uint64_t) 1ULL << 32)) {
341 zone->
name =
"dma32";
344 zone->
emer_mem = (mem >> 1) + (mem >> 2);
350 &zone->
kobj, &ttm_mem_zone_kobj_type, &glob->
kobj, zone->
name);
380 ret = ttm_mem_init_kernel_zone(glob, &si);
383 #ifdef CONFIG_HIGHMEM
384 ret = ttm_mem_init_highmem_zone(glob, &si);
388 ret = ttm_mem_init_dma32_zone(glob, &si);
394 pr_info(
"Zone %7s: Available graphics memory: %llu kiB\n",
395 zone->
name, (
unsigned long long)zone->
max_mem >> 10);
430 bool needs_swapping =
false;
434 spin_lock(&glob->
lock);
438 needs_swapping =
true;
443 spin_unlock(&glob->
lock);
457 spin_lock(&glob->
lock);
460 if (single_zone && zone != single_zone)
464 spin_unlock(&glob->
lock);
470 return ttm_mem_global_free_zone(glob,
NULL, amount);
483 spin_lock(&glob->
lock);
486 if (single_zone && zone != single_zone)
499 if (single_zone && zone != single_zone)
507 spin_unlock(&glob->
lock);
508 ttm_check_swapping(glob);
517 bool no_wait,
bool interruptible)
521 while (
unlikely(ttm_mem_global_reserve(glob,
529 ttm_shrink(glob,
false, memory + (memory >> 2) + 16);
536 bool no_wait,
bool interruptible)
543 return ttm_mem_global_alloc_zone(glob,
NULL, memory, no_wait,
550 bool no_wait,
bool interruptible)
560 #ifdef CONFIG_HIGHMEM
561 if (PageHighMem(page) && glob->zone_highmem !=
NULL)
562 zone = glob->zone_highmem;
567 return ttm_mem_global_alloc_zone(glob, zone,
PAGE_SIZE, no_wait,
575 #ifdef CONFIG_HIGHMEM
576 if (PageHighMem(page) && glob->zone_highmem !=
NULL)
577 zone = glob->zone_highmem;
582 ttm_mem_global_free_zone(glob, zone,
PAGE_SIZE);
588 if ((size & (size - 1)) == 0)
595 while (tmp_size < size)