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

Commit 1f5fefc6 authored by Kyle Yan's avatar Kyle Yan
Browse files

Revert "android: binder: Fix preemption and locking issues"



This reverts commit f48e2696.

No longer needed as of 4.9.38 as binder has been reformatted to use
fine-grained locking.

Change-Id: I7126d0e576b78a4c6a879ab849ba46e7f2a0b627
Signed-off-by: default avatarKyle Yan <kyan@codeaurora.org>
parent 805ee046
Loading
Loading
Loading
Loading
+49 −131
Original line number Diff line number Diff line
@@ -406,7 +406,6 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
	struct files_struct *files = proc->files;
	unsigned long rlim_cur;
	unsigned long irqs;
	int ret;

	if (files == NULL)
		return -ESRCH;
@@ -417,11 +416,7 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
	rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE);
	unlock_task_sighand(proc->tsk, &irqs);

	preempt_enable_no_resched();
	ret = __alloc_fd(files, 0, rlim_cur, flags);
	preempt_disable();

	return ret;
	return __alloc_fd(files, 0, rlim_cur, flags);
}

/*
@@ -430,11 +425,8 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
static void task_fd_install(
	struct binder_proc *proc, unsigned int fd, struct file *file)
{
	if (proc->files) {
		preempt_enable_no_resched();
	if (proc->files)
		__fd_install(proc->files, fd, file);
		preempt_disable();
	}
}

/*
@@ -462,7 +454,6 @@ static inline void binder_lock(const char *tag)
{
	trace_binder_lock(tag);
	mutex_lock(&binder_main_lock);
	preempt_disable();
	trace_binder_locked(tag);
}

@@ -470,62 +461,8 @@ static inline void binder_unlock(const char *tag)
{
	trace_binder_unlock(tag);
	mutex_unlock(&binder_main_lock);
	preempt_enable();
}

static inline void *kzalloc_preempt_disabled(size_t size)
{
	void *ptr;

	ptr = kzalloc(size, GFP_NOWAIT);
	if (ptr)
		return ptr;

	preempt_enable_no_resched();
	ptr = kzalloc(size, GFP_KERNEL);
	preempt_disable();

	return ptr;
}

static inline long copy_to_user_preempt_disabled(void __user *to, const void *from, long n)
{
	long ret;

	preempt_enable_no_resched();
	ret = copy_to_user(to, from, n);
	preempt_disable();
	return ret;
}

static inline long copy_from_user_preempt_disabled(void *to, const void __user *from, long n)
{
	long ret;

	preempt_enable_no_resched();
	ret = copy_from_user(to, from, n);
	preempt_disable();
	return ret;
}

#define get_user_preempt_disabled(x, ptr)	\
({						\
	int __ret;				\
	preempt_enable_no_resched();		\
	__ret = get_user(x, ptr);		\
	preempt_disable();			\
	__ret;					\
})

#define put_user_preempt_disabled(x, ptr)	\
({						\
	int __ret;				\
	preempt_enable_no_resched();		\
	__ret = put_user(x, ptr);		\
	preempt_disable();			\
	__ret;					\
})

static void binder_set_nice(long nice)
{
	long min_nice;
@@ -658,8 +595,6 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
	else
		mm = get_task_mm(proc->tsk);

	preempt_enable_no_resched();

	if (mm) {
		down_write(&mm->mmap_sem);
		vma = proc->vma;
@@ -714,9 +649,6 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
		up_write(&mm->mmap_sem);
		mmput(mm);
	}

	preempt_disable();

	return 0;

free_range:
@@ -739,9 +671,6 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
		up_write(&mm->mmap_sem);
		mmput(mm);
	}

	preempt_disable();
	
	return -ENOMEM;
}

@@ -1010,7 +939,7 @@ static struct binder_node *binder_new_node(struct binder_proc *proc,
			return NULL;
	}

	node = kzalloc_preempt_disabled(sizeof(*node));
	node = kzalloc(sizeof(*node), GFP_KERNEL);
	if (node == NULL)
		return NULL;
	binder_stats_created(BINDER_STAT_NODE);
@@ -1154,7 +1083,7 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc,
		else
			return ref;
	}
	new_ref = kzalloc_preempt_disabled(sizeof(*ref));
	new_ref = kzalloc(sizeof(*ref), GFP_KERNEL);
	if (new_ref == NULL)
		return NULL;
	binder_stats_created(BINDER_STAT_REF);
@@ -2028,14 +1957,14 @@ static void binder_transaction(struct binder_proc *proc,
	e->to_proc = target_proc->pid;

	/* TODO: reuse incoming transaction for reply */
	t = kzalloc_preempt_disabled(sizeof(*t));
	t = kzalloc(sizeof(*t), GFP_KERNEL);
	if (t == NULL) {
		return_error = BR_FAILED_REPLY;
		goto err_alloc_t_failed;
	}
	binder_stats_created(BINDER_STAT_TRANSACTION);

	tcomplete = kzalloc_preempt_disabled(sizeof(*tcomplete));
	tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
	if (tcomplete == NULL) {
		return_error = BR_FAILED_REPLY;
		goto err_alloc_tcomplete_failed;
@@ -2096,14 +2025,14 @@ static void binder_transaction(struct binder_proc *proc,
				      ALIGN(tr->data_size, sizeof(void *)));
	offp = off_start;

	if (copy_from_user_preempt_disabled(t->buffer->data, (const void __user *)(uintptr_t)
	if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t)
			   tr->data.ptr.buffer, tr->data_size)) {
		binder_user_error("%d:%d got transaction with invalid data ptr\n",
				proc->pid, thread->pid);
		return_error = BR_FAILED_REPLY;
		goto err_copy_data_failed;
	}
	if (copy_from_user_preempt_disabled(offp, (const void __user *)(uintptr_t)
	if (copy_from_user(offp, (const void __user *)(uintptr_t)
			   tr->data.ptr.offsets, tr->offsets_size)) {
		binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
				proc->pid, thread->pid);
@@ -2221,8 +2150,7 @@ static void binder_transaction(struct binder_proc *proc,
				return_error = BR_FAILED_REPLY;
				goto err_bad_offset;
			}
			if (copy_from_user_preempt_disabled(
					sg_bufp,
			if (copy_from_user(sg_bufp,
					   (const void __user *)(uintptr_t)
					   bp->buffer, bp->length)) {
				binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
@@ -2331,7 +2259,7 @@ static int binder_thread_write(struct binder_proc *proc,
	void __user *end = buffer + size;

	while (ptr < end && thread->return_error == BR_OK) {
		if (get_user_preempt_disabled(cmd, (uint32_t __user *)ptr))
		if (get_user(cmd, (uint32_t __user *)ptr))
			return -EFAULT;
		ptr += sizeof(uint32_t);
		trace_binder_command(cmd);
@@ -2349,7 +2277,7 @@ static int binder_thread_write(struct binder_proc *proc,
			struct binder_ref *ref;
			const char *debug_string;

			if (get_user_preempt_disabled(target, (uint32_t __user *)ptr))
			if (get_user(target, (uint32_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(uint32_t);
			if (target == 0 && context->binder_context_mgr_node &&
@@ -2401,10 +2329,10 @@ static int binder_thread_write(struct binder_proc *proc,
			binder_uintptr_t cookie;
			struct binder_node *node;

			if (get_user_preempt_disabled(node_ptr, (binder_uintptr_t __user *)ptr))
			if (get_user(node_ptr, (binder_uintptr_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(binder_uintptr_t);
			if (get_user_preempt_disabled(cookie, (binder_uintptr_t __user *)ptr))
			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(binder_uintptr_t);
			node = binder_get_node(proc, node_ptr);
@@ -2462,7 +2390,7 @@ static int binder_thread_write(struct binder_proc *proc,
			binder_uintptr_t data_ptr;
			struct binder_buffer *buffer;

			if (get_user_preempt_disabled(data_ptr, (binder_uintptr_t __user *)ptr))
			if (get_user(data_ptr, (binder_uintptr_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(binder_uintptr_t);

@@ -2504,8 +2432,7 @@ static int binder_thread_write(struct binder_proc *proc,
		case BC_REPLY_SG: {
			struct binder_transaction_data_sg tr;

			if (copy_from_user_preempt_disabled(&tr, ptr,
							    sizeof(tr)))
			if (copy_from_user(&tr, ptr, sizeof(tr)))
				return -EFAULT;
			ptr += sizeof(tr);
			binder_transaction(proc, thread, &tr.transaction_data,
@@ -2516,7 +2443,7 @@ static int binder_thread_write(struct binder_proc *proc,
		case BC_REPLY: {
			struct binder_transaction_data tr;

			if (copy_from_user_preempt_disabled(&tr, ptr, sizeof(tr)))
			if (copy_from_user(&tr, ptr, sizeof(tr)))
				return -EFAULT;
			ptr += sizeof(tr);
			binder_transaction(proc, thread, &tr,
@@ -2567,10 +2494,10 @@ static int binder_thread_write(struct binder_proc *proc,
			struct binder_ref *ref;
			struct binder_ref_death *death;

			if (get_user_preempt_disabled(target, (uint32_t __user *)ptr))
			if (get_user(target, (uint32_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(uint32_t);
			if (get_user_preempt_disabled(cookie, (binder_uintptr_t __user *)ptr))
			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(binder_uintptr_t);
			ref = binder_get_ref(proc, target, false);
@@ -2599,7 +2526,7 @@ static int binder_thread_write(struct binder_proc *proc,
						proc->pid, thread->pid);
					break;
				}
				death = kzalloc_preempt_disabled(sizeof(*death));
				death = kzalloc(sizeof(*death), GFP_KERNEL);
				if (death == NULL) {
					thread->return_error = BR_ERROR;
					binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
@@ -2653,7 +2580,8 @@ static int binder_thread_write(struct binder_proc *proc,
			struct binder_work *w;
			binder_uintptr_t cookie;
			struct binder_ref_death *death = NULL;
			if (get_user_preempt_disabled(cookie, (binder_uintptr_t __user *)ptr))

			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
				return -EFAULT;

			ptr += sizeof(cookie);
@@ -2685,8 +2613,7 @@ static int binder_thread_write(struct binder_proc *proc,
					wake_up_interruptible(&proc->wait);
				}
			}
		}
		break;
		} break;

		default:
			pr_err("%d:%d unknown command %d\n",
@@ -2735,7 +2662,7 @@ static int binder_thread_read(struct binder_proc *proc,
	int wait_for_proc_work;

	if (*consumed == 0) {
		if (put_user_preempt_disabled(BR_NOOP, (uint32_t __user *)ptr))
		if (put_user(BR_NOOP, (uint32_t __user *)ptr))
			return -EFAULT;
		ptr += sizeof(uint32_t);
	}
@@ -2746,7 +2673,7 @@ static int binder_thread_read(struct binder_proc *proc,

	if (thread->return_error != BR_OK && ptr < end) {
		if (thread->return_error2 != BR_OK) {
			if (put_user_preempt_disabled(thread->return_error2, (uint32_t __user *)ptr))
			if (put_user(thread->return_error2, (uint32_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(uint32_t);
			binder_stat_br(proc, thread, thread->return_error2);
@@ -2754,7 +2681,7 @@ static int binder_thread_read(struct binder_proc *proc,
				goto done;
			thread->return_error2 = BR_OK;
		}
		if (put_user_preempt_disabled(thread->return_error, (uint32_t __user *)ptr))
		if (put_user(thread->return_error, (uint32_t __user *)ptr))
			return -EFAULT;
		ptr += sizeof(uint32_t);
		binder_stat_br(proc, thread, thread->return_error);
@@ -2832,7 +2759,7 @@ static int binder_thread_read(struct binder_proc *proc,
		} break;
		case BINDER_WORK_TRANSACTION_COMPLETE: {
			cmd = BR_TRANSACTION_COMPLETE;
				if (put_user_preempt_disabled(cmd, (uint32_t __user *) ptr))
			if (put_user(cmd, (uint32_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(uint32_t);

@@ -2874,14 +2801,14 @@ static int binder_thread_read(struct binder_proc *proc,
				node->has_weak_ref = 0;
			}
			if (cmd != BR_NOOP) {
					if (put_user_preempt_disabled(cmd, (uint32_t __user *) ptr))
				if (put_user(cmd, (uint32_t __user *)ptr))
					return -EFAULT;
				ptr += sizeof(uint32_t);
					if (put_user_preempt_disabled(node->ptr, (binder_uintptr_t __user *)
				if (put_user(node->ptr,
					     (binder_uintptr_t __user *)ptr))
					return -EFAULT;
				ptr += sizeof(binder_uintptr_t);
					if (put_user_preempt_disabled(node->cookie, (binder_uintptr_t __user *)
				if (put_user(node->cookie,
					     (binder_uintptr_t __user *)ptr))
					return -EFAULT;
				ptr += sizeof(binder_uintptr_t);
@@ -2925,10 +2852,11 @@ static int binder_thread_read(struct binder_proc *proc,
				cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE;
			else
				cmd = BR_DEAD_BINDER;
				if (put_user_preempt_disabled(cmd, (uint32_t __user *) ptr))
			if (put_user(cmd, (uint32_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(uint32_t);
			if (put_user_preempt_disabled(death->cookie, (binder_uintptr_t __user *) ptr))
			if (put_user(death->cookie,
				     (binder_uintptr_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(binder_uintptr_t);
			binder_stat_br(proc, thread, cmd);
@@ -2995,10 +2923,10 @@ static int binder_thread_read(struct binder_proc *proc,
					ALIGN(t->buffer->data_size,
					    sizeof(void *));

		if (put_user_preempt_disabled(cmd, (uint32_t __user *) ptr))
		if (put_user(cmd, (uint32_t __user *)ptr))
			return -EFAULT;
		ptr += sizeof(uint32_t);
		if (copy_to_user_preempt_disabled(ptr, &tr, sizeof(tr)))
		if (copy_to_user(ptr, &tr, sizeof(tr)))
			return -EFAULT;
		ptr += sizeof(tr);

@@ -3040,7 +2968,7 @@ static int binder_thread_read(struct binder_proc *proc,
		binder_debug(BINDER_DEBUG_THREADS,
			     "%d:%d BR_SPAWN_LOOPER\n",
			     proc->pid, thread->pid);
		if (put_user_preempt_disabled(BR_SPAWN_LOOPER, (uint32_t __user *) buffer))
		if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))
			return -EFAULT;
		binder_stat_br(proc, thread, BR_SPAWN_LOOPER);
	}
@@ -3115,7 +3043,7 @@ static struct binder_thread *binder_get_thread(struct binder_proc *proc)
			break;
	}
	if (*p == NULL) {
		thread = kzalloc_preempt_disabled(sizeof(*thread));
		thread = kzalloc(sizeof(*thread), GFP_KERNEL);
		if (thread == NULL)
			return NULL;
		binder_stats_created(BINDER_STAT_THREAD);
@@ -3219,7 +3147,7 @@ static int binder_ioctl_write_read(struct file *filp,
		ret = -EINVAL;
		goto out;
	}
	if (copy_from_user_preempt_disabled(&bwr, ubuf, sizeof(bwr))) {
	if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
		ret = -EFAULT;
		goto out;
	}
@@ -3237,7 +3165,7 @@ static int binder_ioctl_write_read(struct file *filp,
		trace_binder_write_done(ret);
		if (ret < 0) {
			bwr.read_consumed = 0;
			if (copy_to_user_preempt_disabled(ubuf, &bwr, sizeof(bwr)))
			if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
				ret = -EFAULT;
			goto out;
		}
@@ -3251,7 +3179,7 @@ static int binder_ioctl_write_read(struct file *filp,
		if (!list_empty(&proc->todo))
			wake_up_interruptible(&proc->wait);
		if (ret < 0) {
			if (copy_to_user_preempt_disabled(ubuf, &bwr, sizeof(bwr)))
			if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
				ret = -EFAULT;
			goto out;
		}
@@ -3261,7 +3189,7 @@ static int binder_ioctl_write_read(struct file *filp,
		     proc->pid, thread->pid,
		     (u64)bwr.write_consumed, (u64)bwr.write_size,
		     (u64)bwr.read_consumed, (u64)bwr.read_size);
	if (copy_to_user_preempt_disabled(ubuf, &bwr, sizeof(bwr))) {
	if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
		ret = -EFAULT;
		goto out;
	}
@@ -3345,7 +3273,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
			goto err;
		break;
	case BINDER_SET_MAX_THREADS:
		if (copy_from_user_preempt_disabled(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
		if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
			ret = -EINVAL;
			goto err;
		}
@@ -3368,7 +3296,8 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
			ret = -EINVAL;
			goto err;
		}
			if (put_user_preempt_disabled(BINDER_CURRENT_PROTOCOL_VERSION, &ver->protocol_version)) {
		if (put_user(BINDER_CURRENT_PROTOCOL_VERSION,
			     &ver->protocol_version)) {
			ret = -EINVAL;
			goto err;
		}
@@ -3430,7 +3359,6 @@ static const struct vm_operations_struct binder_vm_ops = {
static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
{
	int ret;

	struct vm_struct *area;
	struct binder_proc *proc = filp->private_data;
	const char *failure_string;
@@ -3491,11 +3419,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
	vma->vm_ops = &binder_vm_ops;
	vma->vm_private_data = proc;

	/* binder_update_page_range assumes preemption is disabled */
	preempt_disable();
	ret = binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma);
	preempt_enable_no_resched();
	if (ret) {
	if (binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma)) {
		ret = -ENOMEM;
		failure_string = "alloc small buf";
		goto err_alloc_small_buf_failed;
@@ -3781,12 +3705,8 @@ static void binder_deferred_func(struct work_struct *work)
	int defer;

	do {
		trace_binder_lock(__func__);
		mutex_lock(&binder_main_lock);
		trace_binder_locked(__func__);

		binder_lock(__func__);
		mutex_lock(&binder_deferred_lock);
		preempt_disable();
		if (!hlist_empty(&binder_deferred_list)) {
			proc = hlist_entry(binder_deferred_list.first,
					struct binder_proc, deferred_work_node);
@@ -3812,9 +3732,7 @@ static void binder_deferred_func(struct work_struct *work)
		if (defer & BINDER_DEFERRED_RELEASE)
			binder_deferred_release(proc); /* frees proc */

		trace_binder_unlock(__func__);
		mutex_unlock(&binder_main_lock);
		preempt_enable_no_resched();
		binder_unlock(__func__);
		if (files)
			put_files_struct(files);
	} while (proc);