Commit 83e79ae3 authored by Daniel Vetter's avatar Daniel Vetter
Browse files

Merge tag 'drm-misc-fixes-2023-01-05' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes



Several fixes to fix the error path of dma_buf_export, add a missing
structure declaration resulting in a compiler warning, fix the GEM
handle refcounting in panfrost, fix a corrupted image with AFBC on
meson, a memleak in virtio, improper plane width for imx, and a lockup
in drm_sched_entity_kill()

Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20230105074909.qd2h23hpxac4lxi7@houat
parents c8de5262 69555549
Loading
Loading
Loading
Loading
+2 −5
Original line number Original line Diff line number Diff line
@@ -168,14 +168,11 @@ void dma_buf_uninit_sysfs_statistics(void)
	kset_unregister(dma_buf_stats_kset);
	kset_unregister(dma_buf_stats_kset);
}
}


int dma_buf_stats_setup(struct dma_buf *dmabuf)
int dma_buf_stats_setup(struct dma_buf *dmabuf, struct file *file)
{
{
	struct dma_buf_sysfs_entry *sysfs_entry;
	struct dma_buf_sysfs_entry *sysfs_entry;
	int ret;
	int ret;


	if (!dmabuf || !dmabuf->file)
		return -EINVAL;

	if (!dmabuf->exp_name) {
	if (!dmabuf->exp_name) {
		pr_err("exporter name must not be empty if stats needed\n");
		pr_err("exporter name must not be empty if stats needed\n");
		return -EINVAL;
		return -EINVAL;
@@ -192,7 +189,7 @@ int dma_buf_stats_setup(struct dma_buf *dmabuf)


	/* create the directory for buffer stats */
	/* create the directory for buffer stats */
	ret = kobject_init_and_add(&sysfs_entry->kobj, &dma_buf_ktype, NULL,
	ret = kobject_init_and_add(&sysfs_entry->kobj, &dma_buf_ktype, NULL,
				   "%lu", file_inode(dmabuf->file)->i_ino);
				   "%lu", file_inode(file)->i_ino);
	if (ret)
	if (ret)
		goto err_sysfs_dmabuf;
		goto err_sysfs_dmabuf;


+2 −2
Original line number Original line Diff line number Diff line
@@ -13,7 +13,7 @@
int dma_buf_init_sysfs_statistics(void);
int dma_buf_init_sysfs_statistics(void);
void dma_buf_uninit_sysfs_statistics(void);
void dma_buf_uninit_sysfs_statistics(void);


int dma_buf_stats_setup(struct dma_buf *dmabuf);
int dma_buf_stats_setup(struct dma_buf *dmabuf, struct file *file);


void dma_buf_stats_teardown(struct dma_buf *dmabuf);
void dma_buf_stats_teardown(struct dma_buf *dmabuf);
#else
#else
@@ -25,7 +25,7 @@ static inline int dma_buf_init_sysfs_statistics(void)


static inline void dma_buf_uninit_sysfs_statistics(void) {}
static inline void dma_buf_uninit_sysfs_statistics(void) {}


static inline int dma_buf_stats_setup(struct dma_buf *dmabuf)
static inline int dma_buf_stats_setup(struct dma_buf *dmabuf, struct file *file)
{
{
	return 0;
	return 0;
}
}
+38 −44
Original line number Original line Diff line number Diff line
@@ -95,10 +95,11 @@ static int dma_buf_file_release(struct inode *inode, struct file *file)
		return -EINVAL;
		return -EINVAL;


	dmabuf = file->private_data;
	dmabuf = file->private_data;

	if (dmabuf) {
		mutex_lock(&db_list.lock);
		mutex_lock(&db_list.lock);
		list_del(&dmabuf->list_node);
		list_del(&dmabuf->list_node);
		mutex_unlock(&db_list.lock);
		mutex_unlock(&db_list.lock);
	}


	return 0;
	return 0;
}
}
@@ -528,17 +529,17 @@ static inline int is_dma_buf_file(struct file *file)
	return file->f_op == &dma_buf_fops;
	return file->f_op == &dma_buf_fops;
}
}


static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
static struct file *dma_buf_getfile(size_t size, int flags)
{
{
	static atomic64_t dmabuf_inode = ATOMIC64_INIT(0);
	static atomic64_t dmabuf_inode = ATOMIC64_INIT(0);
	struct file *file;
	struct inode *inode = alloc_anon_inode(dma_buf_mnt->mnt_sb);
	struct inode *inode = alloc_anon_inode(dma_buf_mnt->mnt_sb);
	struct file *file;


	if (IS_ERR(inode))
	if (IS_ERR(inode))
		return ERR_CAST(inode);
		return ERR_CAST(inode);


	inode->i_size = dmabuf->size;
	inode->i_size = size;
	inode_set_bytes(inode, dmabuf->size);
	inode_set_bytes(inode, size);


	/*
	/*
	 * The ->i_ino acquired from get_next_ino() is not unique thus
	 * The ->i_ino acquired from get_next_ino() is not unique thus
@@ -552,8 +553,6 @@ static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
				 flags, &dma_buf_fops);
				 flags, &dma_buf_fops);
	if (IS_ERR(file))
	if (IS_ERR(file))
		goto err_alloc_file;
		goto err_alloc_file;
	file->private_data = dmabuf;
	file->f_path.dentry->d_fsdata = dmabuf;


	return file;
	return file;


@@ -619,19 +618,11 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
	size_t alloc_size = sizeof(struct dma_buf);
	size_t alloc_size = sizeof(struct dma_buf);
	int ret;
	int ret;


	if (!exp_info->resv)
	if (WARN_ON(!exp_info->priv || !exp_info->ops
		alloc_size += sizeof(struct dma_resv);
	else
		/* prevent &dma_buf[1] == dma_buf->resv */
		alloc_size += 1;

	if (WARN_ON(!exp_info->priv
			  || !exp_info->ops
		    || !exp_info->ops->map_dma_buf
		    || !exp_info->ops->map_dma_buf
		    || !exp_info->ops->unmap_dma_buf
		    || !exp_info->ops->unmap_dma_buf
			  || !exp_info->ops->release)) {
		    || !exp_info->ops->release))
		return ERR_PTR(-EINVAL);
		return ERR_PTR(-EINVAL);
	}


	if (WARN_ON(exp_info->ops->cache_sgt_mapping &&
	if (WARN_ON(exp_info->ops->cache_sgt_mapping &&
		    (exp_info->ops->pin || exp_info->ops->unpin)))
		    (exp_info->ops->pin || exp_info->ops->unpin)))
@@ -643,10 +634,21 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
	if (!try_module_get(exp_info->owner))
	if (!try_module_get(exp_info->owner))
		return ERR_PTR(-ENOENT);
		return ERR_PTR(-ENOENT);


	file = dma_buf_getfile(exp_info->size, exp_info->flags);
	if (IS_ERR(file)) {
		ret = PTR_ERR(file);
		goto err_module;
	}

	if (!exp_info->resv)
		alloc_size += sizeof(struct dma_resv);
	else
		/* prevent &dma_buf[1] == dma_buf->resv */
		alloc_size += 1;
	dmabuf = kzalloc(alloc_size, GFP_KERNEL);
	dmabuf = kzalloc(alloc_size, GFP_KERNEL);
	if (!dmabuf) {
	if (!dmabuf) {
		ret = -ENOMEM;
		ret = -ENOMEM;
		goto err_module;
		goto err_file;
	}
	}


	dmabuf->priv = exp_info->priv;
	dmabuf->priv = exp_info->priv;
@@ -658,43 +660,35 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
	init_waitqueue_head(&dmabuf->poll);
	init_waitqueue_head(&dmabuf->poll);
	dmabuf->cb_in.poll = dmabuf->cb_out.poll = &dmabuf->poll;
	dmabuf->cb_in.poll = dmabuf->cb_out.poll = &dmabuf->poll;
	dmabuf->cb_in.active = dmabuf->cb_out.active = 0;
	dmabuf->cb_in.active = dmabuf->cb_out.active = 0;
	INIT_LIST_HEAD(&dmabuf->attachments);


	if (!resv) {
	if (!resv) {
		resv = (struct dma_resv *)&dmabuf[1];
		dmabuf->resv = (struct dma_resv *)&dmabuf[1];
		dma_resv_init(resv);
		dma_resv_init(dmabuf->resv);
	}
	} else {
		dmabuf->resv = resv;
		dmabuf->resv = resv;
	}


	file = dma_buf_getfile(dmabuf, exp_info->flags);
	ret = dma_buf_stats_setup(dmabuf, file);
	if (IS_ERR(file)) {
	if (ret)
		ret = PTR_ERR(file);
		goto err_dmabuf;
		goto err_dmabuf;
	}


	file->private_data = dmabuf;
	file->f_path.dentry->d_fsdata = dmabuf;
	dmabuf->file = file;
	dmabuf->file = file;


	INIT_LIST_HEAD(&dmabuf->attachments);

	mutex_lock(&db_list.lock);
	mutex_lock(&db_list.lock);
	list_add(&dmabuf->list_node, &db_list.head);
	list_add(&dmabuf->list_node, &db_list.head);
	mutex_unlock(&db_list.lock);
	mutex_unlock(&db_list.lock);


	ret = dma_buf_stats_setup(dmabuf);
	if (ret)
		goto err_sysfs;

	return dmabuf;
	return dmabuf;


err_sysfs:
	/*
	 * Set file->f_path.dentry->d_fsdata to NULL so that when
	 * dma_buf_release() gets invoked by dentry_ops, it exits
	 * early before calling the release() dma_buf op.
	 */
	file->f_path.dentry->d_fsdata = NULL;
	fput(file);
err_dmabuf:
err_dmabuf:
	if (!resv)
		dma_resv_fini(dmabuf->resv);
	kfree(dmabuf);
	kfree(dmabuf);
err_file:
	fput(file);
err_module:
err_module:
	module_put(exp_info->owner);
	module_put(exp_info->owner);
	return ERR_PTR(ret);
	return ERR_PTR(ret);
+8 −6
Original line number Original line Diff line number Diff line
@@ -614,6 +614,11 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
		break;
		break;
	}
	}


	if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_BG)
		width = ipu_src_rect_width(new_state);
	else
		width = drm_rect_width(&new_state->src) >> 16;

	eba = drm_plane_state_to_eba(new_state, 0);
	eba = drm_plane_state_to_eba(new_state, 0);


	/*
	/*
@@ -622,8 +627,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
	 */
	 */
	if (ipu_state->use_pre) {
	if (ipu_state->use_pre) {
		axi_id = ipu_chan_assign_axi_id(ipu_plane->dma);
		axi_id = ipu_chan_assign_axi_id(ipu_plane->dma);
		ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id,
		ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id, width,
					  ipu_src_rect_width(new_state),
					  drm_rect_height(&new_state->src) >> 16,
					  drm_rect_height(&new_state->src) >> 16,
					  fb->pitches[0], fb->format->format,
					  fb->pitches[0], fb->format->format,
					  fb->modifier, &eba);
					  fb->modifier, &eba);
@@ -678,9 +682,8 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
		break;
		break;
	}
	}


	ipu_dmfc_config_wait4eot(ipu_plane->dmfc, ALIGN(drm_rect_width(dst), 8));
	ipu_dmfc_config_wait4eot(ipu_plane->dmfc, width);


	width = ipu_src_rect_width(new_state);
	height = drm_rect_height(&new_state->src) >> 16;
	height = drm_rect_height(&new_state->src) >> 16;
	info = drm_format_info(fb->format->format);
	info = drm_format_info(fb->format->format);
	ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0],
	ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0],
@@ -744,8 +747,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
		ipu_cpmem_set_burstsize(ipu_plane->ipu_ch, 16);
		ipu_cpmem_set_burstsize(ipu_plane->ipu_ch, 16);


		ipu_cpmem_zero(ipu_plane->alpha_ch);
		ipu_cpmem_zero(ipu_plane->alpha_ch);
		ipu_cpmem_set_resolution(ipu_plane->alpha_ch,
		ipu_cpmem_set_resolution(ipu_plane->alpha_ch, width,
					 ipu_src_rect_width(new_state),
					 drm_rect_height(&new_state->src) >> 16);
					 drm_rect_height(&new_state->src) >> 16);
		ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8);
		ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8);
		ipu_cpmem_set_high_priority(ipu_plane->alpha_ch);
		ipu_cpmem_set_high_priority(ipu_plane->alpha_ch);
+2 −3
Original line number Original line Diff line number Diff line
@@ -436,15 +436,14 @@ void meson_viu_init(struct meson_drm *priv)


	/* Initialize OSD1 fifo control register */
	/* Initialize OSD1 fifo control register */
	reg = VIU_OSD_DDR_PRIORITY_URGENT |
	reg = VIU_OSD_DDR_PRIORITY_URGENT |
		VIU_OSD_HOLD_FIFO_LINES(31) |
		VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */
		VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */
		VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */
		VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */
		VIU_OSD_FIFO_LIMITS(2);      /* fifo_lim: 2*16=32 */
		VIU_OSD_FIFO_LIMITS(2);      /* fifo_lim: 2*16=32 */


	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
		reg |= VIU_OSD_BURST_LENGTH_32;
		reg |= (VIU_OSD_BURST_LENGTH_32 | VIU_OSD_HOLD_FIFO_LINES(31));
	else
	else
		reg |= VIU_OSD_BURST_LENGTH_64;
		reg |= (VIU_OSD_BURST_LENGTH_64 | VIU_OSD_HOLD_FIFO_LINES(4));


	writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
	writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
	writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
	writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
Loading