Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fdc0b8a6 authored by Daniel Vetter's avatar Daniel Vetter
Browse files

drm/sis: track obj->drm_fd relations in the driver



By attach a driver private struct to each open drm fd.

Because we steal the owner_list from drm_sman until things settle,
use list_move instead of list_add.

This requires to export a drm_sman function temporarily before
drm_sman will die for real completely.

Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 4cf73129
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -244,7 +244,7 @@ out:

EXPORT_SYMBOL(drm_sman_alloc);

static void drm_sman_free(struct drm_memblock_item *item)
void drm_sman_free(struct drm_memblock_item *item)
{
	struct drm_sman *sman = item->sman;

@@ -253,6 +253,7 @@ static void drm_sman_free(struct drm_memblock_item *item)
	item->mm->free(item->mm->private, item->mm_info);
	kfree(item);
}
EXPORT_SYMBOL(drm_sman_free);

int drm_sman_free_key(struct drm_sman *sman, unsigned int key)
{
+25 −0
Original line number Diff line number Diff line
@@ -76,10 +76,35 @@ static const struct file_operations sis_driver_fops = {
	.llseek = noop_llseek,
};

static int sis_driver_open(struct drm_device *dev, struct drm_file *file)
{
	struct sis_file_private *file_priv;

	DRM_DEBUG_DRIVER("\n");
	file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL);
	if (!file_priv)
		return -ENOMEM;

	file->driver_priv = file_priv;

	INIT_LIST_HEAD(&file_priv->obj_list);

	return 0;
}

void sis_driver_postclose(struct drm_device *dev, struct drm_file *file)
{
	struct sis_file_private *file_priv = file->driver_priv;

	kfree(file_priv);
}

static struct drm_driver driver = {
	.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR,
	.load = sis_driver_load,
	.unload = sis_driver_unload,
	.open = sis_driver_open,
	.postclose = sis_driver_postclose,
	.dma_quiescent = sis_idle,
	.reclaim_buffers = NULL,
	.reclaim_buffers_idlelocked = sis_reclaim_buffers_locked,
+14 −8
Original line number Diff line number Diff line
@@ -120,13 +120,14 @@ static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file
	return 0;
}

static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file_priv,
static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
			 void *data, int pool)
{
	drm_sis_private_t *dev_priv = dev->dev_private;
	drm_sis_mem_t *mem = data;
	int retval = 0;
	struct drm_memblock_item *item;
	struct sis_file_private *file_priv = file->driver_priv;

	mutex_lock(&dev->struct_mutex);

@@ -139,11 +140,10 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file_priv,
	}

	mem->size = (mem->size + SIS_MM_ALIGN_MASK) >> SIS_MM_ALIGN_SHIFT;
	item = drm_sman_alloc(&dev_priv->sman, pool, mem->size, 0,
			      (unsigned long)file_priv);
	item = drm_sman_alloc(&dev_priv->sman, pool, mem->size, 0, 0);

	mutex_unlock(&dev->struct_mutex);
	if (item) {
		list_move(&item->owner_list, &file_priv->obj_list);
		mem->offset = ((pool == 0) ?
			      dev_priv->vram_offset : dev_priv->agp_offset) +
		    (item->mm->
@@ -156,6 +156,7 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file_priv,
		mem->free = 0;
		retval = -ENOMEM;
	}
	mutex_unlock(&dev->struct_mutex);

	DRM_DEBUG("alloc %d, size = %d, offset = %d\n", pool, mem->size,
		  mem->offset);
@@ -301,12 +302,13 @@ void sis_lastclose(struct drm_device *dev)
}

void sis_reclaim_buffers_locked(struct drm_device *dev,
				struct drm_file *file_priv)
				struct drm_file *file)
{
	drm_sis_private_t *dev_priv = dev->dev_private;
	struct sis_file_private *file_priv = file->driver_priv;
	struct drm_memblock_item *entry, *next;

	mutex_lock(&dev->struct_mutex);
	if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)file_priv)) {
	if (list_empty(&file_priv->obj_list)) {
		mutex_unlock(&dev->struct_mutex);
		return;
	}
@@ -314,7 +316,11 @@ void sis_reclaim_buffers_locked(struct drm_device *dev,
	if (dev->driver->dma_quiescent)
		dev->driver->dma_quiescent(dev);

	drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv);

	list_for_each_entry_safe(entry, next, &file_priv->obj_list,
				 owner_list) {
		drm_sman_free(entry);
	}
	mutex_unlock(&dev->struct_mutex);
	return;
}
+1 −0
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ extern struct drm_memblock_item *drm_sman_alloc(struct drm_sman * sman,
 */

extern int drm_sman_free_key(struct drm_sman * sman, unsigned int key);
extern void drm_sman_free(struct drm_memblock_item *item);

/*
 * returns 1 iff there are no stale memory blocks associated with this owner.
+4 −0
Original line number Diff line number Diff line
@@ -64,4 +64,8 @@ typedef struct {
	unsigned int offset, size;
} drm_sis_fb_t;

struct sis_file_private {
	struct list_head obj_list;
};

#endif				/* __SIS_DRM_H__ */