Rev 4560 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4560 | Rev 6084 | ||
---|---|---|---|
Line 48... | Line 48... | ||
48 | * optimized for alloc/free calls, not lookups. Hence, we use an rb-tree to |
48 | * optimized for alloc/free calls, not lookups. Hence, we use an rb-tree to |
49 | * speed up offset lookups. |
49 | * speed up offset lookups. |
50 | * |
50 | * |
51 | * You must not use multiple offset managers on a single address_space. |
51 | * You must not use multiple offset managers on a single address_space. |
52 | * Otherwise, mm-core will be unable to tear down memory mappings as the VM will |
52 | * Otherwise, mm-core will be unable to tear down memory mappings as the VM will |
53 | * no longer be linear. Please use VM_NONLINEAR in that case and implement your |
- | |
54 | * own offset managers. |
53 | * no longer be linear. |
55 | * |
54 | * |
56 | * This offset manager works on page-based addresses. That is, every argument |
55 | * This offset manager works on page-based addresses. That is, every argument |
57 | * and return code (with the exception of drm_vma_node_offset_addr()) is given |
56 | * and return code (with the exception of drm_vma_node_offset_addr()) is given |
58 | * in number of pages, not number of bytes. That means, object sizes and offsets |
57 | * in number of pages, not number of bytes. That means, object sizes and offsets |
59 | * must always be page-aligned (as usual). |
58 | * must always be page-aligned (as usual). |
Line 111... | Line 110... | ||
111 | write_unlock(&mgr->vm_lock); |
110 | write_unlock(&mgr->vm_lock); |
112 | } |
111 | } |
113 | EXPORT_SYMBOL(drm_vma_offset_manager_destroy); |
112 | EXPORT_SYMBOL(drm_vma_offset_manager_destroy); |
Line 114... | Line 113... | ||
114 | 113 | ||
115 | /** |
114 | /** |
116 | * drm_vma_offset_lookup() - Find node in offset space |
115 | * drm_vma_offset_lookup_locked() - Find node in offset space |
117 | * @mgr: Manager object |
116 | * @mgr: Manager object |
118 | * @start: Start address for object (page-based) |
117 | * @start: Start address for object (page-based) |
119 | * @pages: Size of object (page-based) |
118 | * @pages: Size of object (page-based) |
120 | * |
119 | * |
121 | * Find a node given a start address and object size. This returns the _best_ |
120 | * Find a node given a start address and object size. This returns the _best_ |
122 | * match for the given node. That is, @start may point somewhere into a valid |
121 | * match for the given node. That is, @start may point somewhere into a valid |
123 | * region and the given node will be returned, as long as the node spans the |
122 | * region and the given node will be returned, as long as the node spans the |
124 | * whole requested area (given the size in number of pages as @pages). |
123 | * whole requested area (given the size in number of pages as @pages). |
- | 124 | * |
|
- | 125 | * Note that before lookup the vma offset manager lookup lock must be acquired |
|
- | 126 | * with drm_vma_offset_lock_lookup(). See there for an example. This can then be |
|
- | 127 | * used to implement weakly referenced lookups using kref_get_unless_zero(). |
|
- | 128 | * |
|
- | 129 | * Example: |
|
- | 130 | * drm_vma_offset_lock_lookup(mgr); |
|
- | 131 | * node = drm_vma_offset_lookup_locked(mgr); |
|
- | 132 | * if (node) |
|
- | 133 | * kref_get_unless_zero(container_of(node, sth, entr)); |
|
- | 134 | * drm_vma_offset_unlock_lookup(mgr); |
|
125 | * |
135 | * |
126 | * RETURNS: |
136 | * RETURNS: |
127 | * Returns NULL if no suitable node can be found. Otherwise, the best match |
137 | * Returns NULL if no suitable node can be found. Otherwise, the best match |
128 | * is returned. It's the caller's responsibility to make sure the node doesn't |
138 | * is returned. It's the caller's responsibility to make sure the node doesn't |
129 | * get destroyed before the caller can access it. |
139 | * get destroyed before the caller can access it. |
130 | */ |
- | |
131 | struct drm_vma_offset_node *drm_vma_offset_lookup(struct drm_vma_offset_manager *mgr, |
- | |
132 | unsigned long start, |
- | |
133 | unsigned long pages) |
- | |
134 | { |
- | |
135 | struct drm_vma_offset_node *node; |
- | |
136 | - | ||
137 | read_lock(&mgr->vm_lock); |
- | |
138 | node = drm_vma_offset_lookup_locked(mgr, start, pages); |
- | |
139 | read_unlock(&mgr->vm_lock); |
- | |
140 | - | ||
141 | return node; |
- | |
142 | } |
- | |
143 | EXPORT_SYMBOL(drm_vma_offset_lookup); |
- | |
144 | - | ||
145 | /** |
- | |
146 | * drm_vma_offset_lookup_locked() - Find node in offset space |
- | |
147 | * @mgr: Manager object |
- | |
148 | * @start: Start address for object (page-based) |
- | |
149 | * @pages: Size of object (page-based) |
- | |
150 | * |
- | |
151 | * Same as drm_vma_offset_lookup() but requires the caller to lock offset lookup |
- | |
152 | * manually. See drm_vma_offset_lock_lookup() for an example. |
- | |
153 | * |
- | |
154 | * RETURNS: |
- | |
155 | * Returns NULL if no suitable node can be found. Otherwise, the best match |
- | |
156 | * is returned. |
- | |
157 | */ |
140 | */ |
158 | struct drm_vma_offset_node *drm_vma_offset_lookup_locked(struct drm_vma_offset_manager *mgr, |
141 | struct drm_vma_offset_node *drm_vma_offset_lookup_locked(struct drm_vma_offset_manager *mgr, |
159 | unsigned long start, |
142 | unsigned long start, |
160 | unsigned long pages) |
143 | unsigned long pages) |
161 | { |
144 | { |