Skip to content

Commit

Permalink
binder: Extend kmem_cache to binder_task_work_cb and binder_txn_fd_fixup
Browse files Browse the repository at this point in the history
Change-Id: Ifcbf563b624871f28e9da1d7a367d48e90cab81c
Signed-off-by: Juhyung Park <qkrwngud825@gmail.com>
Signed-off-by: Helium-Studio <67852324+Helium-Studio@users.noreply.github.com>
Signed-off-by: onettboots <blackcocopet@gmail.com>
  • Loading branch information
arter97 authored and onettboots committed May 26, 2024
1 parent 2a3f6cc commit fa1215f
Showing 1 changed file with 106 additions and 4 deletions.
110 changes: 106 additions & 4 deletions drivers/android/binder.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ static struct kmem_cache *binder_ref_pool;
static struct kmem_cache *binder_thread_pool;
static struct kmem_cache *binder_transaction_pool;
static struct kmem_cache *binder_work_pool;
static struct kmem_cache *binder_twcb_pool;
static struct kmem_cache *binder_fixup_pool;

static struct binder_transaction_log_entry *binder_transaction_log_add(
struct binder_transaction_log *log)
Expand Down Expand Up @@ -1970,6 +1972,27 @@ static struct binder_thread *binder_get_txn_from_and_acq_inner(
return NULL;
}

/**
* binder_free_txn_fixups() - free unprocessed fd fixups
* @t: binder transaction for t->from
*
* If the transaction is being torn down prior to being
* processed by the target process, free all of the
* fd fixups and fput the file structs. It is safe to
* call this function after the fixups have been
* processed -- in that case, the list will be empty.
*/
static void binder_free_txn_fixups(struct binder_transaction *t)
{
struct binder_txn_fd_fixup *fixup, *tmp;

list_for_each_entry_safe(fixup, tmp, &t->fd_fixups, fixup_entry) {
fput(fixup->file);
list_del(&fixup->fixup_entry);
kmem_cache_free(binder_fixup_pool, fixup);
}
}

static void binder_free_transaction(struct binder_transaction *t)
{
struct binder_proc *target_proc;
Expand Down Expand Up @@ -2316,7 +2339,7 @@ static void binder_do_fd_close(struct callback_head *twork)
struct binder_task_work_cb, twork);

fput(twcb->file);
kfree(twcb);
kmem_cache_free(binder_twcb_pool, twcb);
}

/**
Expand All @@ -2330,7 +2353,7 @@ static void binder_deferred_fd_close(int fd)
{
struct binder_task_work_cb *twcb;

twcb = kmalloc(sizeof(*twcb), GFP_KERNEL);
twcb = kmem_cache_alloc(binder_twcb_pool, GFP_KERNEL);
if (!twcb)
return;
init_task_work(&twcb->twork, binder_do_fd_close);
Expand All @@ -2339,7 +2362,7 @@ static void binder_deferred_fd_close(int fd)
filp_close(twcb->file, current->files);
task_work_add(current, &twcb->twork, true);
} else {
kfree(twcb);
kmem_cache_free(binder_twcb_pool, twcb);
}
}

Expand Down Expand Up @@ -2681,7 +2704,7 @@ static int binder_translate_fd(int fd,
* of the fd in the target needs to be done from a
* target thread.
*/
fixup = kmalloc(sizeof(*fixup), GFP_KERNEL);
fixup = kmem_cache_alloc(binder_fixup_pool, GFP_KERNEL);
if (!fixup) {
ret = -ENOMEM;
goto err_get_unused_fd;
Expand Down Expand Up @@ -4569,6 +4592,71 @@ static int binder_wait_for_work(struct binder_thread *thread,
return ret;
}

/**
* binder_apply_fd_fixups() - finish fd translation
* @proc: binder_proc associated @t->buffer
* @t: binder transaction with list of fd fixups
*
* Now that we are in the context of the transaction target
* process, we can allocate and install fds. Process the
* list of fds to translate and fixup the buffer with the
* new fds.
*
* If we fail to allocate an fd, then free the resources by
* fput'ing files that have not been processed and ksys_close'ing
* any fds that have already been allocated.
*/
static int binder_apply_fd_fixups(struct binder_proc *proc,
struct binder_transaction *t)
{
struct binder_txn_fd_fixup *fixup, *tmp;
int ret = 0;

list_for_each_entry(fixup, &t->fd_fixups, fixup_entry) {
int fd = get_unused_fd_flags(O_CLOEXEC);

if (fd < 0) {
binder_debug(BINDER_DEBUG_TRANSACTION,
"failed fd fixup txn %d fd %d\n",
t->debug_id, fd);
ret = -ENOMEM;
break;
}
binder_debug(BINDER_DEBUG_TRANSACTION,
"fd fixup txn %d fd %d\n",
t->debug_id, fd);
trace_binder_transaction_fd_recv(t, fd, fixup->offset);
fd_install(fd, fixup->file);
fixup->file = NULL;
if (binder_alloc_copy_to_buffer(&proc->alloc, t->buffer,
fixup->offset, &fd,
sizeof(u32))) {
ret = -EINVAL;
break;
}
}
list_for_each_entry_safe(fixup, tmp, &t->fd_fixups, fixup_entry) {
if (fixup->file) {
fput(fixup->file);
} else if (ret) {
u32 fd;
int err;

err = binder_alloc_copy_from_buffer(&proc->alloc, &fd,
t->buffer,
fixup->offset,
sizeof(fd));
WARN_ON(err);
if (!err)
binder_deferred_fd_close(fd);
}
list_del(&fixup->fixup_entry);
kmem_cache_free(binder_fixup_pool, fixup);
}

return ret;
}

static int binder_thread_read(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
Expand Down Expand Up @@ -6776,8 +6864,20 @@ static int __init binder_create_pools(void)
if (!binder_work_pool)
goto err_work_pool;

binder_twcb_pool = KMEM_CACHE(binder_task_work_cb, SLAB_HWCACHE_ALIGN);
if (!binder_twcb_pool)
goto err_twcb_pool;

binder_fixup_pool = KMEM_CACHE(binder_txn_fd_fixup, SLAB_HWCACHE_ALIGN);
if (!binder_fixup_pool)
goto err_fixup_pool;

return 0;

err_fixup_pool:
kmem_cache_destroy(binder_twcb_pool);
err_twcb_pool:
kmem_cache_destroy(binder_work_pool);
err_work_pool:
kmem_cache_destroy(binder_transaction_pool);
err_transaction_pool:
Expand Down Expand Up @@ -6805,6 +6905,8 @@ static void __init binder_destroy_pools(void)
kmem_cache_destroy(binder_thread_pool);
kmem_cache_destroy(binder_transaction_pool);
kmem_cache_destroy(binder_work_pool);
kmem_cache_destroy(binder_twcb_pool);
kmem_cache_destroy(binder_fixup_pool);
}

static int __init binder_init(void)
Expand Down

0 comments on commit fa1215f

Please sign in to comment.