/**************************************************************************1*2* Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR18* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,19* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL20* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,21* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR22* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE23* USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627#ifndef TTM_MEMORY_H28#define TTM_MEMORY_H2930#include <linux/workqueue.h>31#include <linux/spinlock.h>32#include <linux/wait.h>33#include <linux/errno.h>34#include <linux/kobject.h>35#include <linux/mm.h>3637/**38* struct ttm_mem_shrink - callback to shrink TTM memory usage.39*40* @do_shrink: The callback function.41*42* Arguments to the do_shrink functions are intended to be passed using43* inheritance. That is, the argument class derives from struct ttm_mem_srink,44* and can be accessed using container_of().45*/4647struct ttm_mem_shrink {48int (*do_shrink) (struct ttm_mem_shrink *);49};5051/**52* struct ttm_mem_global - Global memory accounting structure.53*54* @shrink: A single callback to shrink TTM memory usage. Extend this55* to a linked list to be able to handle multiple callbacks when needed.56* @swap_queue: A workqueue to handle shrinking in low memory situations. We57* need a separate workqueue since it will spend a lot of time waiting58* for the GPU, and this will otherwise block other workqueue tasks(?)59* At this point we use only a single-threaded workqueue.60* @work: The workqueue callback for the shrink queue.61* @queue: Wait queue for processes suspended waiting for memory.62* @lock: Lock to protect the @shrink - and the memory accounting members,63* that is, essentially the whole structure with some exceptions.64* @zones: Array of pointers to accounting zones.65* @num_zones: Number of populated entries in the @zones array.66* @zone_kernel: Pointer to the kernel zone.67* @zone_highmem: Pointer to the highmem zone if there is one.68* @zone_dma32: Pointer to the dma32 zone if there is one.69*70* Note that this structure is not per device. It should be global for all71* graphics devices.72*/7374#define TTM_MEM_MAX_ZONES 275struct ttm_mem_zone;76struct ttm_mem_global {77struct kobject kobj;78struct ttm_mem_shrink *shrink;79struct workqueue_struct *swap_queue;80struct work_struct work;81wait_queue_head_t queue;82spinlock_t lock;83struct ttm_mem_zone *zones[TTM_MEM_MAX_ZONES];84unsigned int num_zones;85struct ttm_mem_zone *zone_kernel;86#ifdef CONFIG_HIGHMEM87struct ttm_mem_zone *zone_highmem;88#else89struct ttm_mem_zone *zone_dma32;90#endif91};9293/**94* ttm_mem_init_shrink - initialize a struct ttm_mem_shrink object95*96* @shrink: The object to initialize.97* @func: The callback function.98*/99100static inline void ttm_mem_init_shrink(struct ttm_mem_shrink *shrink,101int (*func) (struct ttm_mem_shrink *))102{103shrink->do_shrink = func;104}105106/**107* ttm_mem_register_shrink - register a struct ttm_mem_shrink object.108*109* @glob: The struct ttm_mem_global object to register with.110* @shrink: An initialized struct ttm_mem_shrink object to register.111*112* Returns:113* -EBUSY: There's already a callback registered. (May change).114*/115116static inline int ttm_mem_register_shrink(struct ttm_mem_global *glob,117struct ttm_mem_shrink *shrink)118{119spin_lock(&glob->lock);120if (glob->shrink != NULL) {121spin_unlock(&glob->lock);122return -EBUSY;123}124glob->shrink = shrink;125spin_unlock(&glob->lock);126return 0;127}128129/**130* ttm_mem_unregister_shrink - unregister a struct ttm_mem_shrink object.131*132* @glob: The struct ttm_mem_global object to unregister from.133* @shrink: A previously registert struct ttm_mem_shrink object.134*135*/136137static inline void ttm_mem_unregister_shrink(struct ttm_mem_global *glob,138struct ttm_mem_shrink *shrink)139{140spin_lock(&glob->lock);141BUG_ON(glob->shrink != shrink);142glob->shrink = NULL;143spin_unlock(&glob->lock);144}145146extern int ttm_mem_global_init(struct ttm_mem_global *glob);147extern void ttm_mem_global_release(struct ttm_mem_global *glob);148extern int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,149bool no_wait, bool interruptible);150extern void ttm_mem_global_free(struct ttm_mem_global *glob,151uint64_t amount);152extern int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,153struct page *page,154bool no_wait, bool interruptible);155extern void ttm_mem_global_free_page(struct ttm_mem_global *glob,156struct page *page);157extern size_t ttm_round_pot(size_t size);158#endif159160161