ANDROID: fixup dma_buf struct to avoid ABI breakage
Wrap dma_buf into dma_buf_ext object containing additional num_unique_refs field required for dmabuf PSS accounting. Bug: 424648392 Change-Id: I3929ec2cf7cda2626452b5c80949aecefec900e6 Signed-off-by: Suren Baghdasaryan <surenb@google.com>
This commit is contained in:
@@ -93,6 +93,7 @@ static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen)
|
|||||||
|
|
||||||
static void dma_buf_release(struct dentry *dentry)
|
static void dma_buf_release(struct dentry *dentry)
|
||||||
{
|
{
|
||||||
|
struct dma_buf_ext *dmabuf_ext;
|
||||||
struct dma_buf *dmabuf;
|
struct dma_buf *dmabuf;
|
||||||
|
|
||||||
dmabuf = dentry->d_fsdata;
|
dmabuf = dentry->d_fsdata;
|
||||||
@@ -115,13 +116,13 @@ static void dma_buf_release(struct dentry *dentry)
|
|||||||
if (dmabuf->resv == (struct dma_resv *)&dmabuf[1])
|
if (dmabuf->resv == (struct dma_resv *)&dmabuf[1])
|
||||||
dma_resv_fini(dmabuf->resv);
|
dma_resv_fini(dmabuf->resv);
|
||||||
|
|
||||||
if (atomic64_read(&dmabuf->num_unique_refs))
|
dmabuf_ext = get_dmabuf_ext(dmabuf);
|
||||||
|
if (atomic64_read(&dmabuf_ext->num_unique_refs))
|
||||||
pr_err("destroying dmabuf with non-zero task refs\n");
|
pr_err("destroying dmabuf with non-zero task refs\n");
|
||||||
|
|
||||||
WARN_ON(!list_empty(&dmabuf->attachments));
|
WARN_ON(!list_empty(&dmabuf->attachments));
|
||||||
module_put(dmabuf->owner);
|
module_put(dmabuf->owner);
|
||||||
kfree(dmabuf->name);
|
kfree(dmabuf->name);
|
||||||
kfree(dmabuf);
|
kfree(dmabuf_ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dma_buf_file_release(struct inode *inode, struct file *file)
|
static int dma_buf_file_release(struct inode *inode, struct file *file)
|
||||||
@@ -221,8 +222,7 @@ static int new_task_dmabuf_record(struct task_struct *task, struct dma_buf *dmab
|
|||||||
rec->dmabuf = dmabuf;
|
rec->dmabuf = dmabuf;
|
||||||
rec->refcnt = 1;
|
rec->refcnt = 1;
|
||||||
list_add(&rec->node, &dmabuf_info->dmabufs);
|
list_add(&rec->node, &dmabuf_info->dmabufs);
|
||||||
|
atomic64_inc(&get_dmabuf_ext(dmabuf)->num_unique_refs);
|
||||||
atomic64_inc(&dmabuf->num_unique_refs);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -312,7 +312,7 @@ void dma_buf_unaccount_task(struct dma_buf *dmabuf, struct task_struct *task)
|
|||||||
list_del(&rec->node);
|
list_del(&rec->node);
|
||||||
kfree(rec);
|
kfree(rec);
|
||||||
dmabuf_info->rss -= dmabuf->size;
|
dmabuf_info->rss -= dmabuf->size;
|
||||||
atomic64_dec(&dmabuf->num_unique_refs);
|
atomic64_dec(&get_dmabuf_ext(dmabuf)->num_unique_refs);
|
||||||
}
|
}
|
||||||
err:
|
err:
|
||||||
spin_unlock(&dmabuf_info->lock);
|
spin_unlock(&dmabuf_info->lock);
|
||||||
@@ -831,10 +831,11 @@ err_alloc_file:
|
|||||||
*/
|
*/
|
||||||
struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
||||||
{
|
{
|
||||||
|
struct dma_buf_ext *dmabuf_ext;
|
||||||
struct dma_buf *dmabuf;
|
struct dma_buf *dmabuf;
|
||||||
struct dma_resv *resv = exp_info->resv;
|
struct dma_resv *resv = exp_info->resv;
|
||||||
struct file *file;
|
struct file *file;
|
||||||
size_t alloc_size = sizeof(struct dma_buf);
|
size_t alloc_size = sizeof(struct dma_buf_ext);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (WARN_ON(!exp_info->priv || !exp_info->ops
|
if (WARN_ON(!exp_info->priv || !exp_info->ops
|
||||||
@@ -864,12 +865,13 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
|||||||
else
|
else
|
||||||
/* prevent &dma_buf[1] == dma_buf->resv */
|
/* prevent &dma_buf[1] == dma_buf->resv */
|
||||||
alloc_size += 1;
|
alloc_size += 1;
|
||||||
dmabuf = kzalloc(alloc_size, GFP_KERNEL);
|
dmabuf_ext = kzalloc(alloc_size, GFP_KERNEL);
|
||||||
if (!dmabuf) {
|
if (!dmabuf_ext) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err_file;
|
goto err_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dmabuf = &dmabuf_ext->dmabuf;
|
||||||
dmabuf->priv = exp_info->priv;
|
dmabuf->priv = exp_info->priv;
|
||||||
dmabuf->ops = exp_info->ops;
|
dmabuf->ops = exp_info->ops;
|
||||||
dmabuf->size = exp_info->size;
|
dmabuf->size = exp_info->size;
|
||||||
@@ -888,7 +890,7 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
|||||||
dmabuf->resv = resv;
|
dmabuf->resv = resv;
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic64_set(&dmabuf->num_unique_refs, 0);
|
atomic64_set(&dmabuf_ext->num_unique_refs, 0);
|
||||||
|
|
||||||
file->private_data = dmabuf;
|
file->private_data = dmabuf;
|
||||||
file->f_path.dentry->d_fsdata = dmabuf;
|
file->f_path.dentry->d_fsdata = dmabuf;
|
||||||
|
@@ -3437,7 +3437,7 @@ static int proc_dmabuf_pss_show(struct seq_file *m, struct pid_namespace *ns,
|
|||||||
|
|
||||||
spin_lock(&dmabuf_info->lock);
|
spin_lock(&dmabuf_info->lock);
|
||||||
list_for_each_entry(rec, &dmabuf_info->dmabufs, node) {
|
list_for_each_entry(rec, &dmabuf_info->dmabufs, node) {
|
||||||
s64 refs = atomic64_read(&rec->dmabuf->num_unique_refs);
|
s64 refs = atomic64_read(&get_dmabuf_ext(rec->dmabuf)->num_unique_refs);
|
||||||
|
|
||||||
if (refs <= 0) {
|
if (refs <= 0) {
|
||||||
pr_err("dmabuf has <= refs %lld\n", refs);
|
pr_err("dmabuf has <= refs %lld\n", refs);
|
||||||
|
@@ -535,6 +535,11 @@ struct dma_buf {
|
|||||||
} *sysfs_entry;
|
} *sysfs_entry;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ANDROID_KABI_RESERVE(1);
|
||||||
|
ANDROID_KABI_RESERVE(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dma_buf_ext {
|
||||||
/**
|
/**
|
||||||
* @num_unique_refs:
|
* @num_unique_refs:
|
||||||
*
|
*
|
||||||
@@ -542,10 +547,18 @@ struct dma_buf {
|
|||||||
*/
|
*/
|
||||||
atomic64_t num_unique_refs;
|
atomic64_t num_unique_refs;
|
||||||
|
|
||||||
ANDROID_KABI_RESERVE(1);
|
/*
|
||||||
ANDROID_KABI_RESERVE(2);
|
* dma_buf can have a reservation object after it, so keep this member
|
||||||
|
* at the end of this structure.
|
||||||
|
*/
|
||||||
|
struct dma_buf dmabuf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline struct dma_buf_ext *get_dmabuf_ext(struct dma_buf *dmabuf)
|
||||||
|
{
|
||||||
|
return container_of(dmabuf, struct dma_buf_ext, dmabuf);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct dma_buf_attach_ops - importer operations for an attachment
|
* struct dma_buf_attach_ops - importer operations for an attachment
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user