1247835Skib/**************************************************************************
2247835Skib *
3247835Skib * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
4247835Skib * All Rights Reserved.
5247835Skib *
6247835Skib * Permission is hereby granted, free of charge, to any person obtaining a
7247835Skib * copy of this software and associated documentation files (the
8247835Skib * "Software"), to deal in the Software without restriction, including
9247835Skib * without limitation the rights to use, copy, modify, merge, publish,
10247835Skib * distribute, sub license, and/or sell copies of the Software, and to
11247835Skib * permit persons to whom the Software is furnished to do so, subject to
12247835Skib * the following conditions:
13247835Skib *
14247835Skib * The above copyright notice and this permission notice (including the
15247835Skib * next paragraph) shall be included in all copies or substantial portions
16247835Skib * of the Software.
17247835Skib *
18247835Skib * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19247835Skib * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20247835Skib * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21247835Skib * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22247835Skib * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23247835Skib * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24247835Skib * USE OR OTHER DEALINGS IN THE SOFTWARE.
25247835Skib *
26247835Skib **************************************************************************/
27247835Skib/* $FreeBSD$ */
28247835Skib
29247835Skib#ifndef TTM_MEMORY_H
30247835Skib#define TTM_MEMORY_H
31247835Skib
32247835Skib/**
33247835Skib * struct ttm_mem_shrink - callback to shrink TTM memory usage.
34247835Skib *
35247835Skib * @do_shrink: The callback function.
36247835Skib *
37247835Skib * Arguments to the do_shrink functions are intended to be passed using
38247835Skib * inheritance. That is, the argument class derives from struct ttm_mem_shrink,
39247835Skib * and can be accessed using container_of().
40247835Skib */
41247835Skib
42247835Skibstruct ttm_mem_shrink {
43247835Skib	int (*do_shrink) (struct ttm_mem_shrink *);
44247835Skib};
45247835Skib
46247835Skib/**
47247835Skib * struct ttm_mem_global - Global memory accounting structure.
48247835Skib *
49247835Skib * @shrink: A single callback to shrink TTM memory usage. Extend this
50247835Skib * to a linked list to be able to handle multiple callbacks when needed.
51247835Skib * @swap_queue: A workqueue to handle shrinking in low memory situations. We
52247835Skib * need a separate workqueue since it will spend a lot of time waiting
53247835Skib * for the GPU, and this will otherwise block other workqueue tasks(?)
54247835Skib * At this point we use only a single-threaded workqueue.
55247835Skib * @work: The workqueue callback for the shrink queue.
56247835Skib * @lock: Lock to protect the @shrink - and the memory accounting members,
57247835Skib * that is, essentially the whole structure with some exceptions.
58247835Skib * @zones: Array of pointers to accounting zones.
59247835Skib * @num_zones: Number of populated entries in the @zones array.
60247835Skib * @zone_kernel: Pointer to the kernel zone.
61247835Skib * @zone_highmem: Pointer to the highmem zone if there is one.
62247835Skib * @zone_dma32: Pointer to the dma32 zone if there is one.
63247835Skib *
64247835Skib * Note that this structure is not per device. It should be global for all
65247835Skib * graphics devices.
66247835Skib */
67247835Skib
68247835Skib#define TTM_MEM_MAX_ZONES 2
69247835Skibstruct ttm_mem_zone;
70247835Skibstruct ttm_mem_global {
71247835Skib	u_int kobj_ref;
72247835Skib	struct ttm_mem_shrink *shrink;
73247835Skib	struct taskqueue *swap_queue;
74247835Skib	struct task work;
75247835Skib	struct mtx lock;
76247835Skib	struct ttm_mem_zone *zones[TTM_MEM_MAX_ZONES];
77247835Skib	unsigned int num_zones;
78247835Skib	struct ttm_mem_zone *zone_kernel;
79247835Skib	struct ttm_mem_zone *zone_dma32;
80247835Skib};
81247835Skib
82247835Skib/**
83247835Skib * ttm_mem_init_shrink - initialize a struct ttm_mem_shrink object
84247835Skib *
85247835Skib * @shrink: The object to initialize.
86247835Skib * @func: The callback function.
87247835Skib */
88247835Skib
89247835Skibstatic inline void ttm_mem_init_shrink(struct ttm_mem_shrink *shrink,
90247835Skib				       int (*func) (struct ttm_mem_shrink *))
91247835Skib{
92247835Skib	shrink->do_shrink = func;
93247835Skib}
94247835Skib
95247835Skib/**
96247835Skib * ttm_mem_register_shrink - register a struct ttm_mem_shrink object.
97247835Skib *
98247835Skib * @glob: The struct ttm_mem_global object to register with.
99247835Skib * @shrink: An initialized struct ttm_mem_shrink object to register.
100247835Skib *
101247835Skib * Returns:
102247835Skib * -EBUSY: There's already a callback registered. (May change).
103247835Skib */
104247835Skib
105247835Skibstatic inline int ttm_mem_register_shrink(struct ttm_mem_global *glob,
106247835Skib					  struct ttm_mem_shrink *shrink)
107247835Skib{
108247835Skib	mtx_lock(&glob->lock);
109247835Skib	if (glob->shrink != NULL) {
110247835Skib		mtx_unlock(&glob->lock);
111247835Skib		return -EBUSY;
112247835Skib	}
113247835Skib	glob->shrink = shrink;
114247835Skib	mtx_unlock(&glob->lock);
115247835Skib	return 0;
116247835Skib}
117247835Skib
118247835Skib/**
119247835Skib * ttm_mem_unregister_shrink - unregister a struct ttm_mem_shrink object.
120247835Skib *
121247835Skib * @glob: The struct ttm_mem_global object to unregister from.
122247835Skib * @shrink: A previously registert struct ttm_mem_shrink object.
123247835Skib *
124247835Skib */
125247835Skib
126247835Skibstatic inline void ttm_mem_unregister_shrink(struct ttm_mem_global *glob,
127247835Skib					     struct ttm_mem_shrink *shrink)
128247835Skib{
129247835Skib	mtx_lock(&glob->lock);
130247835Skib	MPASS(glob->shrink == shrink);
131247835Skib	glob->shrink = NULL;
132247835Skib	mtx_unlock(&glob->lock);
133247835Skib}
134247835Skib
135247835Skibstruct vm_page;
136247835Skib
137247835Skibextern int ttm_mem_global_init(struct ttm_mem_global *glob);
138247835Skibextern void ttm_mem_global_release(struct ttm_mem_global *glob);
139247835Skibextern int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
140247835Skib				bool no_wait, bool interruptible);
141247835Skibextern void ttm_mem_global_free(struct ttm_mem_global *glob,
142247835Skib				uint64_t amount);
143247835Skibextern int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
144247835Skib				     struct vm_page *page,
145247835Skib				     bool no_wait, bool interruptible);
146247835Skibextern void ttm_mem_global_free_page(struct ttm_mem_global *glob,
147247835Skib				     struct vm_page *page);
148247835Skibextern size_t ttm_round_pot(size_t size);
149247835Skib#endif
150