Revert "ANDROID: fixup task_struct to avoid ABI breakage"
Revert submission 3680024 Reason for revert: replacing with a fixed version Reverted changes: /q/submissionid:3680024 Bug: 430499939 Change-Id: Iddc2b99d2f80611d044d0015d62bb33936b4bcaf Signed-off-by: Suren Baghdasaryan <surenb@google.com>
This commit is contained in:
@@ -168,21 +168,11 @@ static struct file_system_type dma_buf_fs_type = {
|
||||
static struct task_dma_buf_record *find_task_dmabuf_record(
|
||||
struct task_struct *task, struct dma_buf *dmabuf)
|
||||
{
|
||||
struct task_dma_buf_info *dmabuf_info = get_task_dma_buf_info(task);
|
||||
struct task_dma_buf_record *rec;
|
||||
|
||||
if (!dmabuf_info)
|
||||
return NULL;
|
||||
lockdep_assert_held(&task->dmabuf_info->lock);
|
||||
|
||||
if (IS_ERR(dmabuf_info)) {
|
||||
pr_err("%s dmabuf accounting record is missing, error %ld\n",
|
||||
__func__, PTR_ERR(dmabuf_info));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lockdep_assert_held(&dmabuf_info->lock);
|
||||
|
||||
list_for_each_entry(rec, &dmabuf_info->dmabufs, node)
|
||||
list_for_each_entry(rec, &task->dmabuf_info->dmabufs, node)
|
||||
if (dmabuf == rec->dmabuf)
|
||||
return rec;
|
||||
|
||||
@@ -191,36 +181,26 @@ static struct task_dma_buf_record *find_task_dmabuf_record(
|
||||
|
||||
static int new_task_dmabuf_record(struct task_struct *task, struct dma_buf *dmabuf)
|
||||
{
|
||||
struct task_dma_buf_info *dmabuf_info = get_task_dma_buf_info(task);
|
||||
struct task_dma_buf_record *rec;
|
||||
|
||||
if (!dmabuf_info)
|
||||
return 0;
|
||||
|
||||
if (IS_ERR(dmabuf_info)) {
|
||||
pr_err("%s dmabuf accounting record is missing, error %ld\n",
|
||||
__func__, PTR_ERR(dmabuf_info));
|
||||
return PTR_ERR(dmabuf_info);
|
||||
}
|
||||
|
||||
lockdep_assert_held(&dmabuf_info->lock);
|
||||
lockdep_assert_held(&task->dmabuf_info->lock);
|
||||
|
||||
rec = kmalloc(sizeof(*rec), GFP_KERNEL);
|
||||
if (!rec)
|
||||
return -ENOMEM;
|
||||
|
||||
dmabuf_info->rss += dmabuf->size;
|
||||
task->dmabuf_info->rss += dmabuf->size;
|
||||
/*
|
||||
* dmabuf_info->lock protects against concurrent writers, so no
|
||||
* task->dmabuf_info->lock protects against concurrent writers, so no
|
||||
* worries about stale rss_hwm between the read and write, and we don't
|
||||
* need to cmpxchg here.
|
||||
*/
|
||||
if (dmabuf_info->rss > dmabuf_info->rss_hwm)
|
||||
dmabuf_info->rss_hwm = dmabuf_info->rss;
|
||||
if (task->dmabuf_info->rss > task->dmabuf_info->rss_hwm)
|
||||
task->dmabuf_info->rss_hwm = task->dmabuf_info->rss;
|
||||
|
||||
rec->dmabuf = dmabuf;
|
||||
rec->refcnt = 1;
|
||||
list_add(&rec->node, &dmabuf_info->dmabufs);
|
||||
list_add(&rec->node, &task->dmabuf_info->dmabufs);
|
||||
|
||||
atomic64_inc(&dmabuf->num_unique_refs);
|
||||
|
||||
@@ -242,30 +222,24 @@ static int new_task_dmabuf_record(struct task_struct *task, struct dma_buf *dmab
|
||||
*/
|
||||
int dma_buf_account_task(struct dma_buf *dmabuf, struct task_struct *task)
|
||||
{
|
||||
struct task_dma_buf_info *dmabuf_info;
|
||||
struct task_dma_buf_record *rec;
|
||||
int ret = 0;
|
||||
|
||||
if (!dmabuf || !task)
|
||||
return -EINVAL;
|
||||
|
||||
dmabuf_info = get_task_dma_buf_info(task);
|
||||
if (!dmabuf_info)
|
||||
return 0;
|
||||
|
||||
if (IS_ERR(dmabuf_info)) {
|
||||
pr_err("%s dmabuf accounting record is missing, error %ld\n",
|
||||
__func__, PTR_ERR(dmabuf_info));
|
||||
return PTR_ERR(dmabuf_info);
|
||||
if (!task->dmabuf_info) {
|
||||
pr_err("%s dmabuf accounting record was not allocated\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
spin_lock(&dmabuf_info->lock);
|
||||
spin_lock(&task->dmabuf_info->lock);
|
||||
rec = find_task_dmabuf_record(task, dmabuf);
|
||||
if (!rec)
|
||||
ret = new_task_dmabuf_record(task, dmabuf);
|
||||
else
|
||||
++rec->refcnt;
|
||||
spin_unlock(&dmabuf_info->lock);
|
||||
spin_unlock(&task->dmabuf_info->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -286,22 +260,17 @@ int dma_buf_account_task(struct dma_buf *dmabuf, struct task_struct *task)
|
||||
*/
|
||||
void dma_buf_unaccount_task(struct dma_buf *dmabuf, struct task_struct *task)
|
||||
{
|
||||
struct task_dma_buf_info *dmabuf_info = get_task_dma_buf_info(task);
|
||||
struct task_dma_buf_record *rec;
|
||||
|
||||
if (!dmabuf || !task)
|
||||
return;
|
||||
|
||||
if (!dmabuf_info)
|
||||
return;
|
||||
|
||||
if (IS_ERR(dmabuf_info)) {
|
||||
pr_err("%s dmabuf accounting record is missing, error %ld\n",
|
||||
__func__, PTR_ERR(dmabuf_info));
|
||||
return;
|
||||
if (!task->dmabuf_info) {
|
||||
pr_err("%s dmabuf accounting record was not allocated\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock(&dmabuf_info->lock);
|
||||
spin_lock(&task->dmabuf_info->lock);
|
||||
rec = find_task_dmabuf_record(task, dmabuf);
|
||||
if (!rec) { /* Failed fd_install? */
|
||||
pr_err("dmabuf not found in task list\n");
|
||||
@@ -311,11 +280,11 @@ void dma_buf_unaccount_task(struct dma_buf *dmabuf, struct task_struct *task)
|
||||
if (--rec->refcnt == 0) {
|
||||
list_del(&rec->node);
|
||||
kfree(rec);
|
||||
dmabuf_info->rss -= dmabuf->size;
|
||||
task->dmabuf_info->rss -= dmabuf->size;
|
||||
atomic64_dec(&dmabuf->num_unique_refs);
|
||||
}
|
||||
err:
|
||||
spin_unlock(&dmabuf_info->lock);
|
||||
spin_unlock(&task->dmabuf_info->lock);
|
||||
}
|
||||
|
||||
static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
|
||||
|
@@ -3309,27 +3309,21 @@ static int proc_stack_depth(struct seq_file *m, struct pid_namespace *ns,
|
||||
static int proc_dmabuf_rss_show(struct seq_file *m, struct pid_namespace *ns,
|
||||
struct pid *pid, struct task_struct *task)
|
||||
{
|
||||
struct task_dma_buf_info *dmabuf_info = get_task_dma_buf_info(task);
|
||||
if (!task->dmabuf_info) {
|
||||
pr_err("%s dmabuf accounting record was not allocated\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!dmabuf_info) {
|
||||
if (!(task->flags & PF_KTHREAD))
|
||||
seq_printf(m, "%lld\n", READ_ONCE(task->dmabuf_info->rss));
|
||||
else
|
||||
seq_puts(m, "0\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IS_ERR(dmabuf_info)) {
|
||||
pr_err("%s dmabuf accounting record is missing, error %ld\n",
|
||||
__func__, PTR_ERR(dmabuf_info));
|
||||
return PTR_ERR(dmabuf_info);
|
||||
}
|
||||
|
||||
seq_printf(m, "%lld\n", READ_ONCE(dmabuf_info->rss));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int proc_dmabuf_rss_hwm_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct task_dma_buf_info *dmabuf_info;
|
||||
struct inode *inode = m->private;
|
||||
struct task_struct *task;
|
||||
int ret = 0;
|
||||
@@ -3338,20 +3332,16 @@ static int proc_dmabuf_rss_hwm_show(struct seq_file *m, void *v)
|
||||
if (!task)
|
||||
return -ESRCH;
|
||||
|
||||
dmabuf_info = get_task_dma_buf_info(task);
|
||||
if (!dmabuf_info) {
|
||||
if (!task->dmabuf_info) {
|
||||
pr_err("%s dmabuf accounting record was not allocated\n", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(task->flags & PF_KTHREAD))
|
||||
seq_printf(m, "%lld\n", READ_ONCE(task->dmabuf_info->rss_hwm));
|
||||
else
|
||||
seq_puts(m, "0\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (IS_ERR(dmabuf_info)) {
|
||||
pr_err("%s dmabuf accounting record is missing, error %ld\n",
|
||||
__func__, PTR_ERR(dmabuf_info));
|
||||
ret = PTR_ERR(dmabuf_info);
|
||||
goto out;
|
||||
}
|
||||
|
||||
seq_printf(m, "%lld\n", READ_ONCE(dmabuf_info->rss_hwm));
|
||||
|
||||
out:
|
||||
put_task_struct(task);
|
||||
@@ -3368,7 +3358,6 @@ static ssize_t
|
||||
proc_dmabuf_rss_hwm_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *offset)
|
||||
{
|
||||
struct task_dma_buf_info *dmabuf_info;
|
||||
struct inode *inode = file_inode(file);
|
||||
struct task_struct *task;
|
||||
unsigned long long val;
|
||||
@@ -3385,22 +3374,15 @@ proc_dmabuf_rss_hwm_write(struct file *file, const char __user *buf,
|
||||
if (!task)
|
||||
return -ESRCH;
|
||||
|
||||
dmabuf_info = get_task_dma_buf_info(task);
|
||||
if (!dmabuf_info) {
|
||||
ret = -EINVAL;
|
||||
if (!task->dmabuf_info) {
|
||||
pr_err("%s dmabuf accounting record was not allocated\n", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (IS_ERR(dmabuf_info)) {
|
||||
pr_err("%s dmabuf accounting record is missing, error %ld\n",
|
||||
__func__, PTR_ERR(dmabuf_info));
|
||||
ret = PTR_ERR(dmabuf_info);
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock(&dmabuf_info->lock);
|
||||
dmabuf_info->rss_hwm = dmabuf_info->rss;
|
||||
spin_unlock(&dmabuf_info->lock);
|
||||
spin_lock(&task->dmabuf_info->lock);
|
||||
task->dmabuf_info->rss_hwm = task->dmabuf_info->rss;
|
||||
spin_unlock(&task->dmabuf_info->lock);
|
||||
|
||||
out:
|
||||
put_task_struct(task);
|
||||
@@ -3419,36 +3401,32 @@ static const struct file_operations proc_dmabuf_rss_hwm_operations = {
|
||||
static int proc_dmabuf_pss_show(struct seq_file *m, struct pid_namespace *ns,
|
||||
struct pid *pid, struct task_struct *task)
|
||||
{
|
||||
struct task_dma_buf_info *dmabuf_info;
|
||||
struct task_dma_buf_record *rec;
|
||||
u64 pss = 0;
|
||||
|
||||
dmabuf_info = get_task_dma_buf_info(task);
|
||||
if (!dmabuf_info) {
|
||||
seq_puts(m, "0\n");
|
||||
return 0;
|
||||
if (!task->dmabuf_info) {
|
||||
pr_err("%s dmabuf accounting record was not allocated\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (IS_ERR(dmabuf_info)) {
|
||||
pr_err("%s dmabuf accounting record is missing, error %ld\n",
|
||||
__func__, PTR_ERR(dmabuf_info));
|
||||
return PTR_ERR(dmabuf_info);
|
||||
}
|
||||
if (!(task->flags & PF_KTHREAD)) {
|
||||
spin_lock(&task->dmabuf_info->lock);
|
||||
list_for_each_entry(rec, &task->dmabuf_info->dmabufs, node) {
|
||||
s64 refs = atomic64_read(&rec->dmabuf->num_unique_refs);
|
||||
|
||||
spin_lock(&dmabuf_info->lock);
|
||||
list_for_each_entry(rec, &dmabuf_info->dmabufs, node) {
|
||||
s64 refs = atomic64_read(&rec->dmabuf->num_unique_refs);
|
||||
if (refs <= 0) {
|
||||
pr_err("dmabuf has <= refs %lld\n", refs);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (refs <= 0) {
|
||||
pr_err("dmabuf has <= refs %lld\n", refs);
|
||||
continue;
|
||||
pss += rec->dmabuf->size / (size_t)refs;
|
||||
}
|
||||
spin_unlock(&task->dmabuf_info->lock);
|
||||
|
||||
pss += rec->dmabuf->size / (size_t)refs;
|
||||
seq_printf(m, "%llu\n", pss);
|
||||
} else {
|
||||
seq_puts(m, "0\n");
|
||||
}
|
||||
spin_unlock(&dmabuf_info->lock);
|
||||
|
||||
seq_printf(m, "%llu\n", pss);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -690,28 +690,6 @@ struct task_dma_buf_info {
|
||||
struct list_head dmabufs;
|
||||
};
|
||||
|
||||
static inline bool task_has_dma_buf_info(struct task_struct *task)
|
||||
{
|
||||
return (task->flags & (PF_KTHREAD | PF_IO_WORKER)) == 0;
|
||||
}
|
||||
|
||||
extern struct task_struct init_task;
|
||||
|
||||
static inline
|
||||
struct task_dma_buf_info *get_task_dma_buf_info(struct task_struct *task)
|
||||
{
|
||||
if (!task)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (!task_has_dma_buf_info(task))
|
||||
return NULL;
|
||||
|
||||
if (!task->worker_private)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
return (struct task_dma_buf_info *)task->worker_private;
|
||||
}
|
||||
|
||||
/**
|
||||
* DEFINE_DMA_BUF_EXPORT_INFO - helper macro for exporters
|
||||
* @name: export-info name
|
||||
|
@@ -1003,7 +1003,6 @@ struct task_struct {
|
||||
int __user *clear_child_tid;
|
||||
|
||||
/* PF_KTHREAD | PF_IO_WORKER */
|
||||
/* Otherwise used as task_dma_buf_info pointer */
|
||||
void *worker_private;
|
||||
|
||||
u64 utime;
|
||||
@@ -1518,6 +1517,9 @@ struct task_struct {
|
||||
*/
|
||||
struct callback_head l1d_flush_kill;
|
||||
#endif
|
||||
|
||||
struct task_dma_buf_info *dmabuf_info;
|
||||
|
||||
ANDROID_KABI_RESERVE(1);
|
||||
ANDROID_KABI_RESERVE(2);
|
||||
ANDROID_KABI_RESERVE(3);
|
||||
|
@@ -214,7 +214,7 @@ struct task_struct init_task
|
||||
.android_vendor_data1 = {0, },
|
||||
.android_oem_data1 = {0, },
|
||||
#endif
|
||||
.worker_private = NULL,
|
||||
.dmabuf_info = NULL,
|
||||
};
|
||||
EXPORT_SYMBOL(init_task);
|
||||
|
||||
|
@@ -997,27 +997,21 @@ static inline void put_signal_struct(struct signal_struct *sig)
|
||||
|
||||
static void put_dmabuf_info(struct task_struct *tsk)
|
||||
{
|
||||
struct task_dma_buf_info *dmabuf_info = get_task_dma_buf_info(tsk);
|
||||
|
||||
if (!dmabuf_info)
|
||||
return;
|
||||
|
||||
if (IS_ERR(dmabuf_info)) {
|
||||
pr_err("%s dmabuf accounting record is missing, error %ld\n",
|
||||
__func__, PTR_ERR(dmabuf_info));
|
||||
if (!tsk->dmabuf_info) {
|
||||
pr_err("%s dmabuf accounting record was not allocated\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!refcount_dec_and_test(&dmabuf_info->refcnt))
|
||||
if (!refcount_dec_and_test(&tsk->dmabuf_info->refcnt))
|
||||
return;
|
||||
|
||||
if (READ_ONCE(dmabuf_info->rss))
|
||||
if (READ_ONCE(tsk->dmabuf_info->rss))
|
||||
pr_err("%s destroying task with non-zero dmabuf rss\n", __func__);
|
||||
|
||||
if (!list_empty(&dmabuf_info->dmabufs))
|
||||
if (!list_empty(&tsk->dmabuf_info->dmabufs))
|
||||
pr_err("%s destroying task with non-empty dmabuf list\n", __func__);
|
||||
|
||||
kfree(dmabuf_info);
|
||||
kfree(tsk->dmabuf_info);
|
||||
}
|
||||
|
||||
void __put_task_struct(struct task_struct *tsk)
|
||||
@@ -2297,66 +2291,55 @@ static void rv_task_fork(struct task_struct *p)
|
||||
|
||||
static int copy_dmabuf_info(u64 clone_flags, struct task_struct *p)
|
||||
{
|
||||
struct task_dma_buf_info *new_dmabuf_info;
|
||||
struct task_dma_buf_info *dmabuf_info;
|
||||
struct task_dma_buf_record *rec, *copy;
|
||||
|
||||
if (!task_has_dma_buf_info(p))
|
||||
return 0; /* Task is not supposed to have dmabuf_info */
|
||||
|
||||
dmabuf_info = get_task_dma_buf_info(current);
|
||||
/* Original might not have dmabuf_info and that's fine */
|
||||
if (IS_ERR(dmabuf_info))
|
||||
dmabuf_info = NULL;
|
||||
|
||||
if (dmabuf_info && (clone_flags & (CLONE_VM | CLONE_FILES))
|
||||
if (current->dmabuf_info && (clone_flags & (CLONE_VM | CLONE_FILES))
|
||||
== (CLONE_VM | CLONE_FILES)) {
|
||||
/*
|
||||
* Both MM and FD references to dmabufs are shared with the parent, so
|
||||
* we can share a RSS counter with the parent.
|
||||
*/
|
||||
refcount_inc(&dmabuf_info->refcnt);
|
||||
p->worker_private = dmabuf_info;
|
||||
refcount_inc(¤t->dmabuf_info->refcnt);
|
||||
p->dmabuf_info = current->dmabuf_info;
|
||||
return 0;
|
||||
}
|
||||
|
||||
new_dmabuf_info = kmalloc(sizeof(*new_dmabuf_info), GFP_KERNEL);
|
||||
if (!new_dmabuf_info)
|
||||
p->dmabuf_info = kmalloc(sizeof(*p->dmabuf_info), GFP_KERNEL);
|
||||
if (!p->dmabuf_info)
|
||||
return -ENOMEM;
|
||||
|
||||
refcount_set(&new_dmabuf_info->refcnt, 1);
|
||||
spin_lock_init(&new_dmabuf_info->lock);
|
||||
INIT_LIST_HEAD(&new_dmabuf_info->dmabufs);
|
||||
if (dmabuf_info) {
|
||||
spin_lock(&dmabuf_info->lock);
|
||||
new_dmabuf_info->rss = dmabuf_info->rss;
|
||||
new_dmabuf_info->rss_hwm = dmabuf_info->rss;
|
||||
list_for_each_entry(rec, &dmabuf_info->dmabufs, node) {
|
||||
refcount_set(&p->dmabuf_info->refcnt, 1);
|
||||
spin_lock_init(&p->dmabuf_info->lock);
|
||||
INIT_LIST_HEAD(&p->dmabuf_info->dmabufs);
|
||||
if (current->dmabuf_info) {
|
||||
spin_lock(¤t->dmabuf_info->lock);
|
||||
p->dmabuf_info->rss = current->dmabuf_info->rss;
|
||||
p->dmabuf_info->rss_hwm = current->dmabuf_info->rss;
|
||||
list_for_each_entry(rec, ¤t->dmabuf_info->dmabufs, node) {
|
||||
copy = kmalloc(sizeof(*copy), GFP_KERNEL);
|
||||
if (!copy) {
|
||||
spin_unlock(&dmabuf_info->lock);
|
||||
spin_unlock(¤t->dmabuf_info->lock);
|
||||
goto err_list_copy;
|
||||
}
|
||||
|
||||
copy->dmabuf = rec->dmabuf;
|
||||
copy->refcnt = rec->refcnt;
|
||||
list_add(©->node, &new_dmabuf_info->dmabufs);
|
||||
list_add(©->node, &p->dmabuf_info->dmabufs);
|
||||
}
|
||||
spin_unlock(&dmabuf_info->lock);
|
||||
spin_unlock(¤t->dmabuf_info->lock);
|
||||
} else {
|
||||
new_dmabuf_info->rss = 0;
|
||||
new_dmabuf_info->rss_hwm = 0;
|
||||
p->dmabuf_info->rss = 0;
|
||||
p->dmabuf_info->rss_hwm = 0;
|
||||
}
|
||||
p->worker_private = new_dmabuf_info;
|
||||
|
||||
return 0;
|
||||
|
||||
err_list_copy:
|
||||
list_for_each_entry_safe(rec, copy, &new_dmabuf_info->dmabufs, node) {
|
||||
list_for_each_entry_safe(rec, copy, &p->dmabuf_info->dmabufs, node) {
|
||||
list_del(&rec->node);
|
||||
kfree(rec);
|
||||
}
|
||||
kfree(new_dmabuf_info);
|
||||
kfree(p->dmabuf_info);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user