Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/include/drm/drm_mm.h
10814 views
1
/**************************************************************************
2
*
3
* Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX. USA.
4
* All Rights Reserved.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the
8
* "Software"), to deal in the Software without restriction, including
9
* without limitation the rights to use, copy, modify, merge, publish,
10
* distribute, sub license, and/or sell copies of the Software, and to
11
* permit persons to whom the Software is furnished to do so, subject to
12
* the following conditions:
13
*
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
16
* of the Software.
17
*
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24
* USE OR OTHER DEALINGS IN THE SOFTWARE.
25
*
26
*
27
**************************************************************************/
28
/*
29
* Authors:
30
* Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
31
*/
32
33
#ifndef _DRM_MM_H_
34
#define _DRM_MM_H_
35
36
/*
37
* Generic range manager structs
38
*/
39
#include <linux/list.h>
40
#ifdef CONFIG_DEBUG_FS
41
#include <linux/seq_file.h>
42
#endif
43
44
struct drm_mm_node {
45
struct list_head node_list;
46
struct list_head hole_stack;
47
unsigned hole_follows : 1;
48
unsigned scanned_block : 1;
49
unsigned scanned_prev_free : 1;
50
unsigned scanned_next_free : 1;
51
unsigned scanned_preceeds_hole : 1;
52
unsigned allocated : 1;
53
unsigned long start;
54
unsigned long size;
55
struct drm_mm *mm;
56
};
57
58
struct drm_mm {
59
/* List of all memory nodes that immediately precede a free hole. */
60
struct list_head hole_stack;
61
/* head_node.node_list is the list of all memory nodes, ordered
62
* according to the (increasing) start address of the memory node. */
63
struct drm_mm_node head_node;
64
struct list_head unused_nodes;
65
int num_unused;
66
spinlock_t unused_lock;
67
unsigned int scan_check_range : 1;
68
unsigned scan_alignment;
69
unsigned long scan_size;
70
unsigned long scan_hit_start;
71
unsigned scan_hit_size;
72
unsigned scanned_blocks;
73
unsigned long scan_start;
74
unsigned long scan_end;
75
struct drm_mm_node *prev_scanned_node;
76
};
77
78
static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
79
{
80
return node->allocated;
81
}
82
83
static inline bool drm_mm_initialized(struct drm_mm *mm)
84
{
85
return mm->hole_stack.next;
86
}
87
#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
88
&(mm)->head_node.node_list, \
89
node_list)
90
#define drm_mm_for_each_scanned_node_reverse(entry, n, mm) \
91
for (entry = (mm)->prev_scanned_node, \
92
next = entry ? list_entry(entry->node_list.next, \
93
struct drm_mm_node, node_list) : NULL; \
94
entry != NULL; entry = next, \
95
next = entry ? list_entry(entry->node_list.next, \
96
struct drm_mm_node, node_list) : NULL) \
97
/*
98
* Basic range manager support (drm_mm.c)
99
*/
100
extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
101
unsigned long size,
102
unsigned alignment,
103
int atomic);
104
extern struct drm_mm_node *drm_mm_get_block_range_generic(
105
struct drm_mm_node *node,
106
unsigned long size,
107
unsigned alignment,
108
unsigned long start,
109
unsigned long end,
110
int atomic);
111
static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent,
112
unsigned long size,
113
unsigned alignment)
114
{
115
return drm_mm_get_block_generic(parent, size, alignment, 0);
116
}
117
static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
118
unsigned long size,
119
unsigned alignment)
120
{
121
return drm_mm_get_block_generic(parent, size, alignment, 1);
122
}
123
static inline struct drm_mm_node *drm_mm_get_block_range(
124
struct drm_mm_node *parent,
125
unsigned long size,
126
unsigned alignment,
127
unsigned long start,
128
unsigned long end)
129
{
130
return drm_mm_get_block_range_generic(parent, size, alignment,
131
start, end, 0);
132
}
133
static inline struct drm_mm_node *drm_mm_get_block_atomic_range(
134
struct drm_mm_node *parent,
135
unsigned long size,
136
unsigned alignment,
137
unsigned long start,
138
unsigned long end)
139
{
140
return drm_mm_get_block_range_generic(parent, size, alignment,
141
start, end, 1);
142
}
143
extern int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node,
144
unsigned long size, unsigned alignment);
145
extern int drm_mm_insert_node_in_range(struct drm_mm *mm,
146
struct drm_mm_node *node,
147
unsigned long size, unsigned alignment,
148
unsigned long start, unsigned long end);
149
extern void drm_mm_put_block(struct drm_mm_node *cur);
150
extern void drm_mm_remove_node(struct drm_mm_node *node);
151
extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
152
extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
153
unsigned long size,
154
unsigned alignment,
155
int best_match);
156
extern struct drm_mm_node *drm_mm_search_free_in_range(
157
const struct drm_mm *mm,
158
unsigned long size,
159
unsigned alignment,
160
unsigned long start,
161
unsigned long end,
162
int best_match);
163
extern int drm_mm_init(struct drm_mm *mm, unsigned long start,
164
unsigned long size);
165
extern void drm_mm_takedown(struct drm_mm *mm);
166
extern int drm_mm_clean(struct drm_mm *mm);
167
extern int drm_mm_pre_get(struct drm_mm *mm);
168
169
static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
170
{
171
return block->mm;
172
}
173
174
void drm_mm_init_scan(struct drm_mm *mm, unsigned long size,
175
unsigned alignment);
176
void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size,
177
unsigned alignment,
178
unsigned long start,
179
unsigned long end);
180
int drm_mm_scan_add_block(struct drm_mm_node *node);
181
int drm_mm_scan_remove_block(struct drm_mm_node *node);
182
183
extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
184
#ifdef CONFIG_DEBUG_FS
185
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
186
#endif
187
188
#endif
189
190