Rev 4075 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4075 | Rev 5078 | ||
---|---|---|---|
Line 35... | Line 35... | ||
35 | #include |
35 | #include |
36 | #include |
36 | #include |
37 | #include |
37 | #include |
38 | #include |
38 | #include |
Line 39... | Line -... | ||
39 | - | ||
40 | struct sysinfo { |
- | |
41 | u32_t totalram; /* Total usable main memory size */ |
- | |
42 | u32_t freeram; /* Available memory size */ |
- | |
43 | u32_t sharedram; /* Amount of shared memory */ |
- | |
44 | u32_t bufferram; /* Memory used by buffers */ |
- | |
45 | u32_t totalswap; /* Total swap space size */ |
- | |
46 | u32_t freeswap; /* swap space still available */ |
- | |
47 | u32_t totalhigh; /* Total high memory size */ |
- | |
48 | u32_t freehigh; /* Available high memory size */ |
- | |
49 | u32_t mem_unit; /* Memory unit size in bytes */ |
- | |
50 | }; |
- | |
51 | - | ||
52 | - | ||
53 | #define TTM_MEMORY_ALLOC_RETRIES 4 |
- | |
54 | - | ||
55 | struct ttm_mem_zone { |
- | |
56 | struct kobject kobj; |
- | |
57 | struct ttm_mem_global *glob; |
- | |
58 | const char *name; |
- | |
59 | uint64_t zone_mem; |
- | |
60 | uint64_t emer_mem; |
- | |
61 | uint64_t max_mem; |
- | |
62 | uint64_t swap_limit; |
- | |
63 | uint64_t used_mem; |
- | |
64 | }; |
- | |
65 | - | ||
66 | #if 0 |
- | |
67 | - | ||
68 | static struct attribute ttm_mem_sys = { |
- | |
69 | .name = "zone_memory", |
- | |
70 | .mode = S_IRUGO |
- | |
71 | }; |
- | |
72 | static struct attribute ttm_mem_emer = { |
- | |
73 | .name = "emergency_memory", |
- | |
74 | .mode = S_IRUGO | S_IWUSR |
- | |
75 | }; |
- | |
76 | static struct attribute ttm_mem_max = { |
- | |
77 | .name = "available_memory", |
- | |
78 | .mode = S_IRUGO | S_IWUSR |
- | |
79 | }; |
- | |
80 | static struct attribute ttm_mem_swap = { |
- | |
81 | .name = "swap_limit", |
- | |
82 | .mode = S_IRUGO | S_IWUSR |
- | |
83 | }; |
- | |
84 | static struct attribute ttm_mem_used = { |
- | |
85 | .name = "used_memory", |
- | |
86 | .mode = S_IRUGO |
- | |
87 | }; |
- | |
Line 88... | Line -... | ||
88 | #endif |
- | |
89 | - | ||
90 | static void ttm_mem_zone_kobj_release(struct kobject *kobj) |
- | |
91 | { |
- | |
92 | struct ttm_mem_zone *zone = |
- | |
93 | container_of(kobj, struct ttm_mem_zone, kobj); |
- | |
94 | - | ||
95 | pr_info("Zone %7s: Used memory at exit: %llu kiB\n", |
- | |
96 | zone->name, (unsigned long long)zone->used_mem >> 10); |
- | |
97 | kfree(zone); |
- | |
98 | } |
- | |
99 | - | ||
100 | #if 0 |
- | |
101 | static ssize_t ttm_mem_zone_show(struct kobject *kobj, |
- | |
102 | struct attribute *attr, |
- | |
103 | char *buffer) |
- | |
104 | { |
- | |
105 | struct ttm_mem_zone *zone = |
- | |
106 | container_of(kobj, struct ttm_mem_zone, kobj); |
- | |
107 | uint64_t val = 0; |
- | |
108 | - | ||
109 | spin_lock(&zone->glob->lock); |
- | |
110 | if (attr == &ttm_mem_sys) |
- | |
111 | val = zone->zone_mem; |
- | |
112 | else if (attr == &ttm_mem_emer) |
- | |
113 | val = zone->emer_mem; |
- | |
114 | else if (attr == &ttm_mem_max) |
- | |
115 | val = zone->max_mem; |
- | |
116 | else if (attr == &ttm_mem_swap) |
- | |
117 | val = zone->swap_limit; |
- | |
118 | else if (attr == &ttm_mem_used) |
- | |
119 | val = zone->used_mem; |
- | |
120 | spin_unlock(&zone->glob->lock); |
- | |
121 | - | ||
122 | return snprintf(buffer, PAGE_SIZE, "%llu\n", |
- | |
123 | (unsigned long long) val >> 10); |
- | |
124 | } |
- | |
125 | - | ||
126 | static void ttm_check_swapping(struct ttm_mem_global *glob); |
- | |
127 | - | ||
128 | static ssize_t ttm_mem_zone_store(struct kobject *kobj, |
- | |
129 | struct attribute *attr, |
- | |
130 | const char *buffer, |
- | |
131 | size_t size) |
- | |
132 | { |
- | |
133 | struct ttm_mem_zone *zone = |
- | |
134 | container_of(kobj, struct ttm_mem_zone, kobj); |
- | |
135 | int chars; |
- | |
136 | unsigned long val; |
- | |
137 | uint64_t val64; |
- | |
138 | - | ||
139 | chars = sscanf(buffer, "%lu", &val); |
- | |
140 | if (chars == 0) |
- | |
141 | return size; |
- | |
142 | - | ||
143 | val64 = val; |
- | |
144 | val64 <<= 10; |
- | |
145 | - | ||
146 | spin_lock(&zone->glob->lock); |
- | |
147 | if (val64 > zone->zone_mem) |
- | |
148 | val64 = zone->zone_mem; |
- | |
149 | if (attr == &ttm_mem_emer) { |
- | |
150 | zone->emer_mem = val64; |
- | |
151 | if (zone->max_mem > val64) |
- | |
152 | zone->max_mem = val64; |
- | |
153 | } else if (attr == &ttm_mem_max) { |
- | |
154 | zone->max_mem = val64; |
- | |
155 | if (zone->emer_mem < val64) |
- | |
156 | zone->emer_mem = val64; |
- | |
157 | } else if (attr == &ttm_mem_swap) |
- | |
158 | zone->swap_limit = val64; |
- | |
159 | spin_unlock(&zone->glob->lock); |
- | |
160 | - | ||
161 | ttm_check_swapping(zone->glob); |
- | |
162 | - | ||
163 | return size; |
- | |
164 | } |
- | |
165 | #endif |
- | |
166 | - | ||
167 | //static struct attribute *ttm_mem_zone_attrs[] = { |
- | |
168 | // &ttm_mem_sys, |
- | |
169 | // &ttm_mem_emer, |
- | |
170 | // &ttm_mem_max, |
- | |
171 | // &ttm_mem_swap, |
- | |
172 | // &ttm_mem_used, |
- | |
173 | // NULL |
- | |
174 | //}; |
- | |
175 | - | ||
176 | //static const struct sysfs_ops ttm_mem_zone_ops = { |
- | |
177 | // .show = &ttm_mem_zone_show, |
- | |
178 | // .store = &ttm_mem_zone_store |
- | |
179 | //}; |
- | |
180 | - | ||
181 | static struct kobj_type ttm_mem_zone_kobj_type = { |
- | |
182 | .release = &ttm_mem_zone_kobj_release, |
- | |
183 | // .sysfs_ops = &ttm_mem_zone_ops, |
- | |
184 | // .default_attrs = ttm_mem_zone_attrs, |
- | |
185 | }; |
- | |
186 | - | ||
187 | static void ttm_mem_global_kobj_release(struct kobject *kobj) |
- | |
188 | { |
- | |
189 | struct ttm_mem_global *glob = |
- | |
190 | container_of(kobj, struct ttm_mem_global, kobj); |
- | |
191 | - | ||
192 | kfree(glob); |
- | |
193 | } |
- | |
194 | - | ||
195 | static struct kobj_type ttm_mem_glob_kobj_type = { |
- | |
196 | .release = &ttm_mem_global_kobj_release, |
- | |
197 | }; |
- | |
198 | - | ||
199 | #if 0 |
- | |
200 | static bool ttm_zones_above_swap_target(struct ttm_mem_global *glob, |
- | |
201 | bool from_wq, uint64_t extra) |
- | |
202 | { |
- | |
203 | unsigned int i; |
- | |
204 | struct ttm_mem_zone *zone; |
- | |
205 | uint64_t target; |
- | |
206 | - | ||
207 | for (i = 0; i < glob->num_zones; ++i) { |
- | |
208 | zone = glob->zones[i]; |
- | |
209 | - | ||
210 | if (from_wq) |
- | |
211 | target = zone->swap_limit; |
- | |
212 | else if (capable(CAP_SYS_ADMIN)) |
- | |
213 | target = zone->emer_mem; |
- | |
214 | else |
- | |
215 | target = zone->max_mem; |
- | |
216 | - | ||
217 | target = (extra > target) ? 0ULL : target; |
- | |
218 | - | ||
219 | if (zone->used_mem > target) |
- | |
220 | return true; |
- | |
221 | } |
- | |
222 | return false; |
- | |
223 | } |
- | |
224 | - | ||
225 | /** |
- | |
226 | * At this point we only support a single shrink callback. |
- | |
227 | * Extend this if needed, perhaps using a linked list of callbacks. |
- | |
228 | * Note that this function is reentrant: |
- | |
229 | * many threads may try to swap out at any given time. |
- | |
230 | */ |
- | |
231 | - | ||
232 | static void ttm_shrink(struct ttm_mem_global *glob, bool from_wq, |
- | |
233 | uint64_t extra) |
- | |
234 | { |
- | |
235 | int ret; |
- | |
236 | struct ttm_mem_shrink *shrink; |
- | |
237 | - | ||
238 | spin_lock(&glob->lock); |
- | |
239 | if (glob->shrink == NULL) |
- | |
240 | goto out; |
- | |
241 | - | ||
242 | while (ttm_zones_above_swap_target(glob, from_wq, extra)) { |
- | |
243 | shrink = glob->shrink; |
- | |
244 | spin_unlock(&glob->lock); |
- | |
245 | ret = shrink->do_shrink(shrink); |
- | |
246 | spin_lock(&glob->lock); |
- | |
247 | if (unlikely(ret != 0)) |
- | |
248 | goto out; |
- | |
249 | } |
- | |
250 | out: |
- | |
251 | spin_unlock(&glob->lock); |
- | |
252 | } |
- | |
253 | - | ||
254 | - | ||
255 | - | ||
256 | static void ttm_shrink_work(struct work_struct *work) |
- | |
257 | { |
- | |
258 | struct ttm_mem_global *glob = |
- | |
259 | container_of(work, struct ttm_mem_global, work); |
- | |
260 | - | ||
261 | ttm_shrink(glob, true, 0ULL); |
- | |
262 | } |
- | |
263 | #endif |
- | |
264 | - | ||
265 | static int ttm_mem_init_kernel_zone(struct ttm_mem_global *glob, |
- | |
266 | const struct sysinfo *si) |
- | |
267 | { |
- | |
268 | struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL); |
- | |
269 | uint64_t mem; |
- | |
270 | int ret; |
- | |
271 | - | ||
272 | if (unlikely(!zone)) |
- | |
273 | return -ENOMEM; |
- | |
274 | - | ||
275 | // mem = si->totalram - si->totalhigh; |
- | |
276 | // mem *= si->mem_unit; |
- | |
277 | - | ||
278 | zone->name = "kernel"; |
- | |
279 | zone->zone_mem = mem; |
- | |
280 | zone->max_mem = mem >> 1; |
- | |
281 | zone->emer_mem = (mem >> 1) + (mem >> 2); |
- | |
282 | zone->swap_limit = zone->max_mem - (mem >> 3); |
- | |
283 | zone->used_mem = 0; |
- | |
284 | zone->glob = glob; |
- | |
285 | glob->zone_kernel = zone; |
- | |
286 | ret = kobject_init_and_add( |
- | |
287 | &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name); |
- | |
288 | if (unlikely(ret != 0)) { |
- | |
289 | kobject_put(&zone->kobj); |
- | |
290 | return ret; |
- | |
291 | } |
- | |
292 | glob->zones[glob->num_zones++] = zone; |
- | |
Line 293... | Line -... | ||
293 | return 0; |
- | |
294 | } |
- | |
295 | 39 | ||
296 | #if 0 |
- | |
297 | #ifdef CONFIG_HIGHMEM |
40 | |
298 | static int ttm_mem_init_highmem_zone(struct ttm_mem_global *glob, |
- | |
299 | const struct sysinfo *si) |
- | |
300 | { |
41 | |
- | 42 | int ttm_mem_global_init(struct ttm_mem_global *glob) |
|
Line 301... | Line 43... | ||
301 | struct ttm_mem_zone *zone; |
43 | { |
302 | uint64_t mem; |
- | |
Line 303... | Line -... | ||
303 | int ret; |
- | |
304 | - | ||
305 | if (si->totalhigh == 0) |
- | |
306 | return 0; |
- | |
307 | - | ||
308 | zone = kzalloc(sizeof(*zone), GFP_KERNEL); |
- | |
309 | if (unlikely(!zone)) |
- | |
310 | return -ENOMEM; |
- | |
311 | - | ||
312 | mem = si->totalram; |
- | |
313 | mem *= si->mem_unit; |
- | |
314 | - | ||
315 | zone->name = "highmem"; |
- | |
316 | zone->zone_mem = mem; |
- | |
317 | zone->max_mem = mem >> 1; |
- | |
318 | zone->emer_mem = (mem >> 1) + (mem >> 2); |
- | |
319 | zone->swap_limit = zone->max_mem - (mem >> 3); |
- | |
320 | zone->used_mem = 0; |
- | |
321 | zone->glob = glob; |
- | |
322 | glob->zone_highmem = zone; |
- | |
323 | ret = kobject_init_and_add( |
- | |
324 | &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name); |
- | |
325 | if (unlikely(ret != 0)) { |
- | |
326 | kobject_put(&zone->kobj); |
- | |
327 | return ret; |
- | |
328 | } |
- | |
329 | glob->zones[glob->num_zones++] = zone; |
- | |
330 | return 0; |
- | |
331 | } |
- | |
332 | #else |
- | |
333 | static int ttm_mem_init_dma32_zone(struct ttm_mem_global *glob, |
- | |
Line 334... | Line -... | ||
334 | const struct sysinfo *si) |
- | |
335 | { |
- | |
Line 336... | Line -... | ||
336 | struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL); |
- | |
337 | uint64_t mem; |
44 | int ret; |
Line 338... | Line -... | ||
338 | int ret; |
- | |
339 | - | ||
340 | if (unlikely(!zone)) |
- | |
341 | return -ENOMEM; |
- | |
342 | - | ||
343 | mem = si->totalram; |
- | |
344 | mem *= si->mem_unit; |
- | |
345 | - | ||
346 | /** |
- | |
347 | * No special dma32 zone needed. |
- | |
348 | */ |
- | |
349 | - | ||
350 | if (mem <= ((uint64_t) 1ULL << 32)) { |
- | |
351 | kfree(zone); |
- | |
352 | return 0; |
- | |
353 | } |
- | |
354 | - | ||
355 | /* |
- | |
356 | * Limit max dma32 memory to 4GB for now |
- | |
357 | * until we can figure out how big this |
- | |
358 | * zone really is. |
- | |
359 | */ |
- | |
360 | - | ||
361 | mem = ((uint64_t) 1ULL << 32); |
- | |
362 | zone->name = "dma32"; |
- | |
363 | zone->zone_mem = mem; |
- | |
364 | zone->max_mem = mem >> 1; |
- | |
365 | zone->emer_mem = (mem >> 1) + (mem >> 2); |
- | |
366 | zone->swap_limit = zone->max_mem - (mem >> 3); |
- | |
367 | zone->used_mem = 0; |
- | |
368 | zone->glob = glob; |
- | |
369 | glob->zone_dma32 = zone; |
45 | int i; |
- | 46 | ||
- | 47 | spin_lock_init(&glob->lock); |
|
- | 48 | ||
370 | ret = kobject_init_and_add( |
49 | |
371 | &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name); |
50 | |
372 | if (unlikely(ret != 0)) { |
- | |
373 | kobject_put(&zone->kobj); |
- | |
Line 374... | Line 51... | ||
374 | return ret; |
51 | ttm_page_alloc_init(glob, 4*1024); |
375 | } |
52 | |
376 | glob->zones[glob->num_zones++] = zone; |
53 | return 0; |
377 | return 0; |
- | |
Line 378... | Line 54... | ||
378 | } |
54 | out_no_zone: |
379 | #endif |
55 | ttm_mem_global_release(glob); |
380 | 56 | return ret; |
|
Line 381... | Line -... | ||
381 | - | ||
382 | - | ||
383 | void ttm_mem_global_release(struct ttm_mem_global *glob) |
- | |
384 | { |
- | |
385 | unsigned int i; |
- | |
386 | struct ttm_mem_zone *zone; |
- | |
387 | - | ||
388 | /* let the page allocator first stop the shrink work. */ |
- | |
389 | ttm_page_alloc_fini(); |
- | |
390 | ttm_dma_page_alloc_fini(); |
- | |
391 | - | ||
392 | flush_workqueue(glob->swap_queue); |
- | |
Line 393... | Line -... | ||
393 | destroy_workqueue(glob->swap_queue); |
- | |
394 | glob->swap_queue = NULL; |
- | |
395 | for (i = 0; i < glob->num_zones; ++i) { |
- | |
396 | zone = glob->zones[i]; |
- | |
397 | kobject_del(&zone->kobj); |
- | |
398 | kobject_put(&zone->kobj); |
- | |
399 | } |
- | |
400 | kobject_del(&glob->kobj); |
- | |
401 | kobject_put(&glob->kobj); |
- | |
402 | } |
- | |
403 | EXPORT_SYMBOL(ttm_mem_global_release); |
- | |
404 | - | ||
405 | static void ttm_check_swapping(struct ttm_mem_global *glob) |
- | |
406 | { |
- | |
407 | bool needs_swapping = false; |
- | |
408 | unsigned int i; |
- | |
409 | struct ttm_mem_zone *zone; |
- | |
410 | - | ||
411 | spin_lock(&glob->lock); |
- | |
412 | for (i = 0; i < glob->num_zones; ++i) { |
- | |
413 | zone = glob->zones[i]; |
- | |
414 | if (zone->used_mem > zone->swap_limit) { |
- | |
415 | needs_swapping = true; |
- | |
416 | break; |
- | |
417 | } |
- | |
418 | } |
- | |
419 | - | ||
420 | spin_unlock(&glob->lock); |
- | |
421 | - | ||
422 | if (unlikely(needs_swapping)) |
- | |
423 | (void)queue_work(glob->swap_queue, &glob->work); |
- | |
424 | - | ||
425 | } |
- | |
426 | - | ||
427 | static void ttm_mem_global_free_zone(struct ttm_mem_global *glob, |
- | |
428 | struct ttm_mem_zone *single_zone, |
- | |
429 | uint64_t amount) |
- | |
430 | { |
- | |
431 | unsigned int i; |
- | |
432 | struct ttm_mem_zone *zone; |
- | |
433 | - | ||
434 | spin_lock(&glob->lock); |
- | |
435 | for (i = 0; i < glob->num_zones; ++i) { |
- | |
436 | zone = glob->zones[i]; |
- | |
437 | if (single_zone && zone != single_zone) |
- | |
438 | continue; |
- | |
439 | zone->used_mem -= amount; |
- | |
440 | } |
- | |
441 | spin_unlock(&glob->lock); |
- | |
442 | } |
- | |
443 | - | ||
444 | void ttm_mem_global_free(struct ttm_mem_global *glob, |
- | |
445 | uint64_t amount) |
- | |
446 | { |
- | |
447 | return ttm_mem_global_free_zone(glob, NULL, amount); |
- | |
448 | } |
- | |
449 | EXPORT_SYMBOL(ttm_mem_global_free); |
- | |
450 | - | ||
451 | static int ttm_mem_global_reserve(struct ttm_mem_global *glob, |
- | |
452 | struct ttm_mem_zone *single_zone, |
- | |
453 | uint64_t amount, bool reserve) |
- | |
454 | { |
- | |
455 | uint64_t limit; |
- | |
456 | int ret = -ENOMEM; |
- | |
457 | unsigned int i; |
- | |
458 | struct ttm_mem_zone *zone; |
- | |
459 | - | ||
460 | spin_lock(&glob->lock); |
- | |
461 | for (i = 0; i < glob->num_zones; ++i) { |
- | |
462 | zone = glob->zones[i]; |
- | |
463 | if (single_zone && zone != single_zone) |
- | |
464 | continue; |
- | |
465 | - | ||
466 | limit = zone->emer_mem; |
- | |
467 | - | ||
468 | if (zone->used_mem > limit) |
- | |
469 | goto out_unlock; |
- | |
470 | } |
- | |
471 | - | ||
472 | if (reserve) { |
- | |
473 | for (i = 0; i < glob->num_zones; ++i) { |
- | |
474 | zone = glob->zones[i]; |
- | |
475 | if (single_zone && zone != single_zone) |
57 | } |
- | 58 | EXPORT_SYMBOL(ttm_mem_global_init); |
|
Line 476... | Line -... | ||
476 | continue; |
- | |
477 | zone->used_mem += amount; |
- | |
478 | } |
- | |
479 | } |
- | |
480 | - | ||
481 | ret = 0; |
- | |
482 | out_unlock: |
- | |
483 | spin_unlock(&glob->lock); |
- | |
484 | ttm_check_swapping(glob); |
- | |
485 | - | ||
486 | return ret; |
- | |
487 | } |
- | |
488 | - | ||
489 | - | ||
490 | static int ttm_mem_global_alloc_zone(struct ttm_mem_global *glob, |
- | |
491 | struct ttm_mem_zone *single_zone, |
- | |
492 | uint64_t memory, |
- | |
493 | bool no_wait, bool interruptible) |
- | |
494 | { |
- | |
495 | int count = TTM_MEMORY_ALLOC_RETRIES; |
- | |
496 | - | ||
497 | while (unlikely(ttm_mem_global_reserve(glob, |
- | |
498 | single_zone, |
- | |
499 | memory, true) |
- | |
500 | != 0)) { |
- | |
501 | if (no_wait) |
- | |
502 | return -ENOMEM; |
- | |
503 | if (unlikely(count-- == 0)) |
- | |
504 | return -ENOMEM; |
- | |
505 | ttm_shrink(glob, false, memory + (memory >> 2) + 16); |
- | |
506 | } |
- | |
507 | - | ||
508 | return 0; |
- | |
509 | } |
- | |
510 | - | ||
511 | int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory, |
- | |
512 | bool no_wait, bool interruptible) |
- | |
513 | { |
- | |
514 | /** |
- | |
515 | * Normal allocations of kernel memory are registered in |
- | |
516 | * all zones. |
- | |
517 | */ |
- | |
518 | - | ||
519 | return ttm_mem_global_alloc_zone(glob, NULL, memory, no_wait, |
- | |
520 | interruptible); |
- | |
521 | } |
- | |
522 | EXPORT_SYMBOL(ttm_mem_global_alloc); |
- | |
523 | - | ||
524 | int ttm_mem_global_alloc_page(struct ttm_mem_global *glob, |
- | |
525 | struct page *page, |
- | |
526 | bool no_wait, bool interruptible) |
- | |
527 | { |
- | |
528 | - | ||
529 | struct ttm_mem_zone *zone = NULL; |
- | |
530 | - | ||
531 | /** |
- | |
532 | * Page allocations may be registed in a single zone |
- | |
533 | * only if highmem or !dma32. |
- | |
534 | */ |
- | |
535 | - | ||
536 | #ifdef CONFIG_HIGHMEM |
- | |
537 | if (PageHighMem(page) && glob->zone_highmem != NULL) |
- | |
538 | zone = glob->zone_highmem; |
- | |
539 | #else |
- | |
540 | if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL) |
- | |
541 | zone = glob->zone_kernel; |
- | |
542 | #endif |
- | |
543 | return ttm_mem_global_alloc_zone(glob, zone, PAGE_SIZE, no_wait, |
- | |
544 | interruptible); |
- | |
545 | } |
- | |
546 | - | ||
547 | void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page) |
- | |
548 | { |
- | |
549 | struct ttm_mem_zone *zone = NULL; |
- | |
550 | - | ||
551 | #ifdef CONFIG_HIGHMEM |
- | |
552 | if (PageHighMem(page) && glob->zone_highmem != NULL) |
- | |
Line 553... | Line 59... | ||
553 | zone = glob->zone_highmem; |
59 | |
554 | #else |
60 | void ttm_mem_global_release(struct ttm_mem_global *glob) |
555 | if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL) |
61 | { |
556 | zone = glob->zone_kernel; |
62 | unsigned int i; |
Line 580... | Line 86... | ||
580 | return tmp_size; |
86 | return tmp_size; |
581 | } |
87 | } |
582 | return 0; |
88 | return 0; |
583 | } |
89 | } |
584 | EXPORT_SYMBOL(ttm_round_pot); |
90 | EXPORT_SYMBOL(ttm_round_pot);=><=>> |
585 | - | ||
586 | void ttm_mem_global_free(struct ttm_mem_global *glob, |
- | |
587 | uint64_t amount) |
- | |
588 | { |
- | |
589 | return 0; |
- | |
590 | } |
- | |
591 | - | ||
592 | - | ||
593 | int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory, |
- | |
594 | bool no_wait, bool interruptible) |
- | |
595 | { |
- | |
596 | return 0; |
- | |
597 | } |
- | |
598 | - | ||
599 | EXPORT_SYMBOL(ttm_mem_global_alloc); |
- | |
600 | - | ||
601 | int ttm_mem_global_init(struct ttm_mem_global *glob) |
- | |
602 | { |
- | |
603 | return 0; |
- | |
604 | } |
- | |
605 | EXPORT_SYMBOL(ttm_mem_global_init);=><=>>>>>>>><>><>=>>>=><=> |
- |