return 0;
}
-int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type)
+int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type, int kern_clean)
{
struct drm_buffer_manager *bm = &dev->bm;
struct drm_mem_type_manager *man = &bm->man[mem_type];
"memory manager type %u\n", mem_type);
return ret;
}
+
+ if ((man->kern_init_type) && (kern_clean == 0)) {
+ DRM_ERROR("Trying to take down kernel initialized "
+ "memory manager type %u\n", mem_type);
+ return -EPERM;
+ }
+
man->use_type = 0;
man->has_type = 0;
return ret;
}
-int drm_bo_init_mm(struct drm_device *dev,
- unsigned type,
- unsigned long p_offset, unsigned long p_size)
+int drm_bo_init_mm(struct drm_device *dev, unsigned type,
+ unsigned long p_offset, unsigned long p_size,
+ int kern_init)
{
struct drm_buffer_manager *bm = &dev->bm;
int ret = -EINVAL;
}
man->has_type = 1;
man->use_type = 1;
+ man->kern_init_type = kern_init;
INIT_LIST_HEAD(&man->lru);
INIT_LIST_HEAD(&man->pinned);
man = &bm->man[i];
if (man->has_type) {
man->use_type = 0;
- if ((i != DRM_BO_MEM_LOCAL) && drm_bo_clean_mm(dev, i)) {
+ if ((i != DRM_BO_MEM_LOCAL) && drm_bo_clean_mm(dev, i, 1)) {
ret = -EBUSY;
DRM_ERROR("DRM memory manager type %d "
"is not clean.\n", i);
* Initialize the system memory buffer type.
* Other types need to be driver / IOCTL initialized.
*/
- ret = drm_bo_init_mm(dev, DRM_BO_MEM_LOCAL, 0, 0);
+ ret = drm_bo_init_mm(dev, DRM_BO_MEM_LOCAL, 0, 0, 1);
if (ret)
goto out_unlock;
goto out;
}
ret = drm_bo_init_mm(dev, arg->mem_type,
- arg->p_offset, arg->p_size);
+ arg->p_offset, arg->p_size, 0);
out:
mutex_unlock(&dev->struct_mutex);
goto out;
}
ret = 0;
- if (drm_bo_clean_mm(dev, arg->mem_type)) {
- DRM_ERROR("Memory manager type %d not clean. "
- "Delaying takedown\n", arg->mem_type);
+ if (ret = drm_bo_clean_mm(dev, arg->mem_type, 0)) {
+ if (ret == -EINVAL)
+ DRM_ERROR("Memory manager type %d not clean. "
+ "Delaying takedown\n", arg->mem_type);
+ ret = 0;
}
out:
mutex_unlock(&dev->struct_mutex);
struct drm_mem_type_manager {
int has_type;
int use_type;
+ int kern_init_type;
struct drm_mm manager;
struct list_head lru;
struct list_head pinned;
extern int drm_bo_move_buffer(struct drm_buffer_object *bo,
uint64_t new_mem_flags,
int no_wait, int move_unfenced);
-extern int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type);
+extern int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type, int kern_clean);
extern int drm_bo_init_mm(struct drm_device *dev, unsigned type,
- unsigned long p_offset, unsigned long p_size);
+ unsigned long p_offset, unsigned long p_size,
+ int kern_init);
extern int drm_bo_handle_validate(struct drm_file *file_priv, uint32_t handle,
uint64_t flags, uint64_t mask, uint32_t hint,
uint32_t fence_class, int use_old_fence_class,
i915_probe_agp(dev->pdev, &agp_size, &prealloc_size);
printk("setting up %ld bytes of VRAM space\n", prealloc_size);
printk("setting up %ld bytes of TT space\n", (agp_size - prealloc_size));
- drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, prealloc_size >> PAGE_SHIFT);
- drm_bo_init_mm(dev, DRM_BO_MEM_TT, prealloc_size >> PAGE_SHIFT, (agp_size - prealloc_size) >> PAGE_SHIFT);
+ drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, prealloc_size >> PAGE_SHIFT, 1);
+ drm_bo_init_mm(dev, DRM_BO_MEM_TT, prealloc_size >> PAGE_SHIFT, (agp_size - prealloc_size) >> PAGE_SHIFT, 1);
I915_WRITE(LP_RING + RING_LEN, 0);
I915_WRITE(LP_RING + RING_HEAD, 0);
mutex_lock(&dev->struct_mutex);
drm_bo_usage_deref_locked(&dev_priv->ring_buffer);
- if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT)) {
+ if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT, 1)) {
DRM_ERROR("Memory manager type 3 not clean. "
"Delaying takedown\n");
}
- if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM)) {
+ if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1)) {
DRM_ERROR("Memory manager type 3 not clean. "
"Delaying takedown\n");
}
bar1_size = drm_get_resource_len(dev, 1) >> PAGE_SHIFT;
if (bar1_size < vram_size) {
if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0,
- bar1_size, vram_size - bar1_size))) {
+ bar1_size, vram_size - bar1_size, 1))) {
DRM_ERROR("Failed PRIV0 mm init: %d\n", ret);
return ret;
}
#ifdef HACK_OLD_MM
vram_size /= 4;
#endif
- if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, vram_size))) {
+ if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, vram_size, 1))) {
DRM_ERROR("Failed VRAM mm init: %d\n", ret);
return ret;
}
if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0,
dev_priv->gart_info.aper_size >>
- PAGE_SHIFT))) {
+ PAGE_SHIFT, 1))) {
DRM_ERROR("Failed TT mm init: %d\n", ret);
return ret;
}
dev_priv->fence_reg = SCRATCH_REG2;
drm_bo_driver_init(dev);
/* initialize vram */
- ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, dev_priv->vram.size);
+ ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, dev_priv->vram.size, 1);
if (ret != 0) {
radeon_ms_driver_unload(dev);
return ret;
/* initialize ttm */
ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0,
- dev_priv->gpu_gart_size / RADEON_PAGE_SIZE);
+ dev_priv->gpu_gart_size / RADEON_PAGE_SIZE, 1);
if (ret != 0) {
radeon_ms_driver_unload(dev);
return ret;
DRM_INFO("[radeon_ms] unloading\n");
/* clean ttm memory manager */
mutex_lock(&dev->struct_mutex);
- if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT)) {
+ if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT, 1)) {
DRM_ERROR("TT memory manager not clean. Delaying takedown\n");
}
mutex_unlock(&dev->struct_mutex);
DRM_INFO("[radeon_ms] bus down\n");
/* clean vram memory manager */
mutex_lock(&dev->struct_mutex);
- if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM)) {
+ if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1)) {
DRM_ERROR("VRAM memory manager not clean. Delaying takedown\n");
}
mutex_unlock(&dev->struct_mutex);