Subversion Repositories Kolibri OS

Rev

Rev 5078 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5078 Rev 6296
1
/**************************************************************************
1
/**************************************************************************
2
 *
2
 *
3
 * Copyright © 2011 VMware, Inc., Palo Alto, CA., USA
3
 * Copyright © 2011-2015 VMware, Inc., Palo Alto, CA., USA
4
 * All Rights Reserved.
4
 * All Rights Reserved.
5
 *
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the
7
 * copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
8
 * "Software"), to deal in the Software without restriction, including
9
 * without limitation the rights to use, copy, modify, merge, publish,
9
 * without limitation the rights to use, copy, modify, merge, publish,
10
 * distribute, sub license, and/or sell copies of the Software, and to
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
11
 * permit persons to whom the Software is furnished to do so, subject to
12
 * the following conditions:
12
 * the following conditions:
13
 *
13
 *
14
 * The above copyright notice and this permission notice (including the
14
 * The above copyright notice and this permission notice (including the
15
 * next paragraph) shall be included in all copies or substantial portions
15
 * next paragraph) shall be included in all copies or substantial portions
16
 * of the Software.
16
 * of the Software.
17
 *
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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,
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
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,
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
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
23
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
25
 *
26
 **************************************************************************/
26
 **************************************************************************/
27
 
27
 
28
#include 
28
#include 
29
 
29
 
30
#include 
30
#include 
31
#include "vmwgfx_drv.h"
31
#include "vmwgfx_drv.h"
32
 
32
 
33
 
33
 
34
/**
34
/**
35
 * vmw_dmabuf_to_placement - Validate a buffer to placement.
35
 * vmw_dmabuf_pin_in_placement - Validate a buffer to placement.
36
 *
36
 *
37
 * @dev_priv:  Driver private.
37
 * @dev_priv:  Driver private.
38
 * @buf:  DMA buffer to move.
38
 * @buf:  DMA buffer to move.
39
 * @pin:  Pin buffer if true.
39
 * @placement:  The placement to pin it.
40
 * @interruptible:  Use interruptible wait.
40
 * @interruptible:  Use interruptible wait.
41
 *
41
 *
42
 * May only be called by the current master since it assumes that the
-
 
43
 * master lock is the current master's lock.
-
 
44
 * This function takes the master's lock in write mode.
-
 
45
 * Flushes and unpins the query bo to avoid failures.
-
 
46
 *
-
 
47
 * Returns
42
 * Returns
48
 *  -ERESTARTSYS if interrupted by a signal.
43
 *  -ERESTARTSYS if interrupted by a signal.
49
 */
44
 */
50
int vmw_dmabuf_to_placement(struct vmw_private *dev_priv,
45
int vmw_dmabuf_pin_in_placement(struct vmw_private *dev_priv,
51
			    struct vmw_dma_buffer *buf,
46
				struct vmw_dma_buffer *buf,
52
			    struct ttm_placement *placement,
47
				struct ttm_placement *placement,
53
			    bool interruptible)
48
				bool interruptible)
54
{
49
{
55
	struct ttm_buffer_object *bo = &buf->base;
50
	struct ttm_buffer_object *bo = &buf->base;
56
	int ret;
51
	int ret;
57
 
52
 
58
//   ret = ttm_write_lock(&vmaster->lock, interruptible);
53
	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
59
//   if (unlikely(ret != 0))
54
	if (unlikely(ret != 0))
60
//       return ret;
55
		return ret;
61
 
56
 
62
	vmw_execbuf_release_pinned_bo(dev_priv);
57
	vmw_execbuf_release_pinned_bo(dev_priv);
63
 
58
 
64
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
59
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
65
	if (unlikely(ret != 0))
60
	if (unlikely(ret != 0))
66
		goto err;
61
		goto err;
67
 
62
 
68
	ret = ttm_bo_validate(bo, placement, interruptible, false);
63
	ret = ttm_bo_validate(bo, placement, interruptible, false);
-
 
64
	if (!ret)
-
 
65
		vmw_bo_pin_reserved(buf, true);
69
 
66
 
70
	ttm_bo_unreserve(bo);
67
	ttm_bo_unreserve(bo);
71
 
68
 
72
err:
69
err:
73
//   ttm_write_unlock(&vmaster->lock);
70
	ttm_write_unlock(&dev_priv->reservation_sem);
74
	return ret;
71
	return ret;
75
}
72
}
76
 
73
 
77
/**
74
/**
78
 * vmw_dmabuf_to_vram_or_gmr - Move a buffer to vram or gmr.
75
 * vmw_dmabuf_pin_in_vram_or_gmr - Move a buffer to vram or gmr.
79
 *
76
 *
80
 * May only be called by the current master since it assumes that the
-
 
81
 * master lock is the current master's lock.
-
 
82
 * This function takes the master's lock in write mode.
77
 * This function takes the reservation_sem in write mode.
83
 * Flushes and unpins the query bo if @pin == true to avoid failures.
78
 * Flushes and unpins the query bo to avoid failures.
84
 *
79
 *
85
 * @dev_priv:  Driver private.
80
 * @dev_priv:  Driver private.
86
 * @buf:  DMA buffer to move.
81
 * @buf:  DMA buffer to move.
87
 * @pin:  Pin buffer if true.
82
 * @pin:  Pin buffer if true.
88
 * @interruptible:  Use interruptible wait.
83
 * @interruptible:  Use interruptible wait.
89
 *
84
 *
90
 * Returns
85
 * Returns
91
 * -ERESTARTSYS if interrupted by a signal.
86
 * -ERESTARTSYS if interrupted by a signal.
92
 */
87
 */
93
int vmw_dmabuf_to_vram_or_gmr(struct vmw_private *dev_priv,
88
int vmw_dmabuf_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
94
			      struct vmw_dma_buffer *buf,
89
				  struct vmw_dma_buffer *buf,
95
			      bool pin, bool interruptible)
90
				  bool interruptible)
96
{
91
{
97
	struct ttm_buffer_object *bo = &buf->base;
92
	struct ttm_buffer_object *bo = &buf->base;
98
	struct ttm_placement *placement;
-
 
99
	int ret;
93
	int ret;
100
 
94
 
101
//   ret = ttm_write_lock(&vmaster->lock, interruptible);
95
	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
102
//   if (unlikely(ret != 0))
96
	if (unlikely(ret != 0))
103
//       return ret;
-
 
104
 
97
		return ret;
105
	if (pin)
98
 
106
		vmw_execbuf_release_pinned_bo(dev_priv);
99
	vmw_execbuf_release_pinned_bo(dev_priv);
107
 
100
 
108
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
101
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
109
	if (unlikely(ret != 0))
102
	if (unlikely(ret != 0))
110
		goto err;
103
		goto err;
111
 
-
 
112
	/**
-
 
113
	 * Put BO in VRAM if there is space, otherwise as a GMR.
-
 
114
	 * If there is no space in VRAM and GMR ids are all used up,
-
 
115
	 * start evicting GMRs to make room. If the DMA buffer can't be
-
 
116
	 * used as a GMR, this will return -ENOMEM.
-
 
117
	 */
-
 
118
 
-
 
119
	if (pin)
104
 
120
		placement = &vmw_vram_gmr_ne_placement;
105
	ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, interruptible,
121
	else
-
 
122
		placement = &vmw_vram_gmr_placement;
-
 
123
 
-
 
124
	ret = ttm_bo_validate(bo, placement, interruptible, false);
106
			      false);
125
	if (likely(ret == 0) || ret == -ERESTARTSYS)
107
	if (likely(ret == 0) || ret == -ERESTARTSYS)
-
 
108
		goto out_unreserve;
126
		goto err_unreserve;
-
 
127
 
-
 
128
 
109
 
129
	/**
-
 
130
	 * If that failed, try VRAM again, this time evicting
-
 
131
	 * previous contents.
110
	ret = ttm_bo_validate(bo, &vmw_vram_placement, interruptible, false);
132
	 */
-
 
133
 
-
 
134
	if (pin)
111
 
135
		placement = &vmw_vram_ne_placement;
-
 
136
	else
-
 
137
		placement = &vmw_vram_placement;
-
 
138
 
112
out_unreserve:
139
	ret = ttm_bo_validate(bo, placement, interruptible, false);
113
	if (!ret)
140
 
114
		vmw_bo_pin_reserved(buf, true);
141
err_unreserve:
115
 
142
	ttm_bo_unreserve(bo);
116
	ttm_bo_unreserve(bo);
143
err:
117
err:
144
//   ttm_write_unlock(&vmaster->lock);
118
	ttm_write_unlock(&dev_priv->reservation_sem);
145
	return ret;
119
	return ret;
146
}
120
}
147
 
121
 
148
/**
122
/**
149
 * vmw_dmabuf_to_vram - Move a buffer to vram.
123
 * vmw_dmabuf_pin_in_vram - Move a buffer to vram.
150
 *
124
 *
151
 * May only be called by the current master since it assumes that the
125
 * This function takes the reservation_sem in write mode.
152
 * master lock is the current master's lock.
126
 * Flushes and unpins the query bo to avoid failures.
153
 * This function takes the master's lock in write mode.
-
 
154
 *
127
 *
155
 * @dev_priv:  Driver private.
128
 * @dev_priv:  Driver private.
156
 * @buf:  DMA buffer to move.
129
 * @buf:  DMA buffer to move.
157
 * @pin:  Pin buffer in vram if true.
-
 
158
 * @interruptible:  Use interruptible wait.
130
 * @interruptible:  Use interruptible wait.
159
 *
131
 *
160
 * Returns
132
 * Returns
161
 * -ERESTARTSYS if interrupted by a signal.
133
 * -ERESTARTSYS if interrupted by a signal.
162
 */
134
 */
163
int vmw_dmabuf_to_vram(struct vmw_private *dev_priv,
135
int vmw_dmabuf_pin_in_vram(struct vmw_private *dev_priv,
164
		       struct vmw_dma_buffer *buf,
136
			   struct vmw_dma_buffer *buf,
165
		       bool pin, bool interruptible)
137
			   bool interruptible)
166
{
138
{
167
	struct ttm_placement *placement;
-
 
168
 
-
 
169
	if (pin)
-
 
170
		placement = &vmw_vram_ne_placement;
-
 
171
	else
-
 
172
		placement = &vmw_vram_placement;
-
 
173
 
-
 
174
	return vmw_dmabuf_to_placement(dev_priv, buf,
139
	return vmw_dmabuf_pin_in_placement(dev_priv, buf, &vmw_vram_placement,
175
				       placement,
-
 
176
				       interruptible);
140
					   interruptible);
177
}
141
}
178
 
142
 
179
/**
143
/**
180
 * vmw_dmabuf_to_start_of_vram - Move a buffer to start of vram.
144
 * vmw_dmabuf_pin_in_start_of_vram - Move a buffer to start of vram.
181
 *
145
 *
182
 * May only be called by the current master since it assumes that the
-
 
183
 * master lock is the current master's lock.
-
 
184
 * This function takes the master's lock in write mode.
146
 * This function takes the reservation_sem in write mode.
185
 * Flushes and unpins the query bo if @pin == true to avoid failures.
147
 * Flushes and unpins the query bo to avoid failures.
186
 *
148
 *
187
 * @dev_priv:  Driver private.
149
 * @dev_priv:  Driver private.
188
 * @buf:  DMA buffer to move.
150
 * @buf:  DMA buffer to pin.
189
 * @pin:  Pin buffer in vram if true.
-
 
190
 * @interruptible:  Use interruptible wait.
151
 * @interruptible:  Use interruptible wait.
191
 *
152
 *
192
 * Returns
153
 * Returns
193
 * -ERESTARTSYS if interrupted by a signal.
154
 * -ERESTARTSYS if interrupted by a signal.
194
 */
155
 */
195
int vmw_dmabuf_to_start_of_vram(struct vmw_private *dev_priv,
156
int vmw_dmabuf_pin_in_start_of_vram(struct vmw_private *dev_priv,
196
				struct vmw_dma_buffer *buf,
157
				    struct vmw_dma_buffer *buf,
197
				bool pin, bool interruptible)
158
				    bool interruptible)
198
{
159
{
199
	struct ttm_buffer_object *bo = &buf->base;
160
	struct ttm_buffer_object *bo = &buf->base;
200
	struct ttm_placement placement;
161
	struct ttm_placement placement;
-
 
162
	struct ttm_place place;
201
	int ret = 0;
163
	int ret = 0;
202
 
-
 
203
	if (pin)
164
 
204
		placement = vmw_vram_ne_placement;
-
 
205
	else
165
	place = vmw_vram_placement.placement[0];
206
		placement = vmw_vram_placement;
166
	place.lpfn = bo->num_pages;
207
	placement.lpfn = bo->num_pages;
-
 
208
 
167
	placement.num_placement = 1;
209
//   ret = ttm_write_lock(&vmaster->lock, interruptible);
168
	placement.placement = &place;
210
//   if (unlikely(ret != 0))
169
	placement.num_busy_placement = 1;
-
 
170
	placement.busy_placement = &place;
-
 
171
 
211
//       return ret;
172
	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
-
 
173
	if (unlikely(ret != 0))
212
 
174
		return ret;
213
	if (pin)
175
 
214
		vmw_execbuf_release_pinned_bo(dev_priv);
176
	vmw_execbuf_release_pinned_bo(dev_priv);
215
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
177
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
216
	if (unlikely(ret != 0))
178
	if (unlikely(ret != 0))
217
		goto err_unlock;
179
		goto err_unlock;
-
 
180
 
218
 
181
	/*
-
 
182
	 * Is this buffer already in vram but not at the start of it?
-
 
183
	 * In that case, evict it first because TTM isn't good at handling
-
 
184
	 * that situation.
219
	/* Is this buffer already in vram but not at the start of it? */
185
	 */
220
	if (bo->mem.mem_type == TTM_PL_VRAM &&
186
	if (bo->mem.mem_type == TTM_PL_VRAM &&
221
	    bo->mem.start < bo->num_pages &&
187
	    bo->mem.start < bo->num_pages &&
222
	    bo->mem.start > 0)
188
	    bo->mem.start > 0)
223
		(void) ttm_bo_validate(bo, &vmw_sys_placement, false, false);
189
		(void) ttm_bo_validate(bo, &vmw_sys_placement, false, false);
224
 
190
 
225
	ret = ttm_bo_validate(bo, &placement, interruptible, false);
191
	ret = ttm_bo_validate(bo, &placement, interruptible, false);
226
 
192
 
227
	/* For some reason we didn't up at the start of vram */
193
	/* For some reason we didn't end up at the start of vram */
-
 
194
	WARN_ON(ret == 0 && bo->offset != 0);
-
 
195
	if (!ret)
228
	WARN_ON(ret == 0 && bo->offset != 0);
196
		vmw_bo_pin_reserved(buf, true);
229
 
197
 
230
	ttm_bo_unreserve(bo);
198
	ttm_bo_unreserve(bo);
231
err_unlock:
199
err_unlock:
232
//   ttm_write_unlock(&vmaster->lock);
200
	ttm_write_unlock(&dev_priv->reservation_sem);
233
 
201
 
234
	return ret;
202
	return ret;
235
}
203
}
236
 
-
 
237
 
204
 
238
/**
205
/**
239
 * vmw_dmabuf_upin - Unpin the buffer given buffer, does not move the buffer.
206
 * vmw_dmabuf_unpin - Unpin the buffer given buffer, does not move the buffer.
240
 *
-
 
241
 * May only be called by the current master since it assumes that the
-
 
242
 * master lock is the current master's lock.
207
 *
243
 * This function takes the master's lock in write mode.
208
 * This function takes the reservation_sem in write mode.
244
 *
209
 *
245
 * @dev_priv:  Driver private.
210
 * @dev_priv:  Driver private.
246
 * @buf:  DMA buffer to unpin.
211
 * @buf:  DMA buffer to unpin.
247
 * @interruptible:  Use interruptible wait.
212
 * @interruptible:  Use interruptible wait.
248
 *
213
 *
249
 * Returns
214
 * Returns
250
 * -ERESTARTSYS if interrupted by a signal.
215
 * -ERESTARTSYS if interrupted by a signal.
251
 */
216
 */
252
int vmw_dmabuf_unpin(struct vmw_private *dev_priv,
217
int vmw_dmabuf_unpin(struct vmw_private *dev_priv,
253
		     struct vmw_dma_buffer *buf,
218
		     struct vmw_dma_buffer *buf,
254
		     bool interruptible)
219
		     bool interruptible)
255
{
220
{
256
	/*
-
 
257
	 * We could in theory early out if the buffer is
221
	struct ttm_buffer_object *bo = &buf->base;
258
	 * unpinned but we need to lock and reserve the buffer
-
 
259
	 * anyways so we don't gain much by that.
-
 
260
	 */
222
	int ret;
261
	return vmw_dmabuf_to_placement(dev_priv, buf,
-
 
262
				       &vmw_evictable_placement,
-
 
263
				       interruptible);
-
 
264
}
-
 
-
 
223
 
-
 
224
	ret = ttm_read_lock(&dev_priv->reservation_sem, interruptible);
-
 
225
	if (unlikely(ret != 0))
-
 
226
		return ret;
-
 
227
 
-
 
228
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
-
 
229
	if (unlikely(ret != 0))
-
 
230
		goto err;
-
 
231
 
-
 
232
	vmw_bo_pin_reserved(buf, false);
-
 
233
 
-
 
234
	ttm_bo_unreserve(bo);
-
 
235
 
-
 
236
err:
-
 
237
	ttm_read_unlock(&dev_priv->reservation_sem);
-
 
238
	return ret;
265
 
239
}
266
 
240
 
267
/**
241
/**
268
 * vmw_bo_get_guest_ptr - Get the guest ptr representing the current placement
242
 * vmw_bo_get_guest_ptr - Get the guest ptr representing the current placement
269
 * of a buffer.
243
 * of a buffer.
270
 *
244
 *
271
 * @bo: Pointer to a struct ttm_buffer_object. Must be pinned or reserved.
245
 * @bo: Pointer to a struct ttm_buffer_object. Must be pinned or reserved.
272
 * @ptr: SVGAGuestPtr returning the result.
246
 * @ptr: SVGAGuestPtr returning the result.
273
 */
247
 */
274
void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *bo,
248
void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *bo,
275
			  SVGAGuestPtr *ptr)
249
			  SVGAGuestPtr *ptr)
276
{
250
{
277
	if (bo->mem.mem_type == TTM_PL_VRAM) {
251
	if (bo->mem.mem_type == TTM_PL_VRAM) {
278
		ptr->gmrId = SVGA_GMR_FRAMEBUFFER;
252
		ptr->gmrId = SVGA_GMR_FRAMEBUFFER;
279
		ptr->offset = bo->offset;
253
		ptr->offset = bo->offset;
280
	} else {
254
	} else {
281
		ptr->gmrId = bo->mem.start;
255
		ptr->gmrId = bo->mem.start;
282
		ptr->offset = 0;
256
		ptr->offset = 0;
283
	}
257
	}
284
}
258
}
285
 
259
 
286
 
260
 
287
/**
261
/**
288
 * vmw_bo_pin - Pin or unpin a buffer object without moving it.
262
 * vmw_bo_pin_reserved - Pin or unpin a buffer object without moving it.
289
 *
263
 *
290
 * @bo: The buffer object. Must be reserved.
264
 * @vbo: The buffer object. Must be reserved.
291
 * @pin: Whether to pin or unpin.
265
 * @pin: Whether to pin or unpin.
292
 *
266
 *
293
 */
267
 */
294
void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin)
268
void vmw_bo_pin_reserved(struct vmw_dma_buffer *vbo, bool pin)
295
{
269
{
296
	uint32_t pl_flags;
270
	struct ttm_place pl;
297
	struct ttm_placement placement;
271
	struct ttm_placement placement;
-
 
272
	struct ttm_buffer_object *bo = &vbo->base;
298
	uint32_t old_mem_type = bo->mem.mem_type;
273
	uint32_t old_mem_type = bo->mem.mem_type;
299
	int ret;
274
	int ret;
300
 
275
 
301
	lockdep_assert_held(&bo->resv->lock.base);
276
	lockdep_assert_held(&bo->resv->lock.base);
-
 
277
 
-
 
278
	if (pin) {
-
 
279
		if (vbo->pin_count++ > 0)
-
 
280
			return;
-
 
281
	} else {
-
 
282
		WARN_ON(vbo->pin_count <= 0);
-
 
283
		if (--vbo->pin_count > 0)
-
 
284
			return;
-
 
285
	}
-
 
286
 
-
 
287
	pl.fpfn = 0;
302
 
288
	pl.lpfn = 0;
303
	pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | VMW_PL_FLAG_MOB
289
	pl.flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | VMW_PL_FLAG_MOB
304
		| TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED;
290
		| TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED;
305
	if (pin)
291
	if (pin)
306
		pl_flags |= TTM_PL_FLAG_NO_EVICT;
292
		pl.flags |= TTM_PL_FLAG_NO_EVICT;
307
 
293
 
308
	memset(&placement, 0, sizeof(placement));
294
	memset(&placement, 0, sizeof(placement));
309
	placement.num_placement = 1;
295
	placement.num_placement = 1;
310
	placement.placement = &pl_flags;
296
	placement.placement = &pl;
311
 
297
 
312
	ret = ttm_bo_validate(bo, &placement, false, true);
298
	ret = ttm_bo_validate(bo, &placement, false, true);
313
 
299
 
314
	BUG_ON(ret != 0 || bo->mem.mem_type != old_mem_type);
300
	BUG_ON(ret != 0 || bo->mem.mem_type != old_mem_type);
315
}
301
}