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

Commit 60d8d0ad authored by Mohammed Javid's avatar Mohammed Javid Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: Fix the problem with nested sleeping primitives



prepare_to_wait() will enqueue the thread on the given queue
and put it into the given execution state,
which is TASK_INTERRUPTIBLE.

Further processing in function, calls  mutex_lock(),
will go into a new version of the going-to-sleep code,
changing the task state.

That, of course, may well interfere with the outer
sleeping code.

So, nesting of sleeping primitives in this way is discouraged.

And new warning was added to point out this kind of nesting.

Fix the nesting of sleeping primitives with the new solution
provide in linux kernel.

Change-Id: Id1a5f64472cd2d63e679706c6482db98f89ec765
Signed-off-by: default avatarMohammed Javid <mjavid@codeaurora.org>
parent 780c4f61
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -516,15 +516,15 @@ ssize_t ipa_read(struct file *filp, char __user *buf, size_t count,
	char __user *start;
	struct ipa_push_msg *msg = NULL;
	int ret;
	DEFINE_WAIT(wait);
	DEFINE_WAIT_FUNC(wait, woken_wake_function);
	int locked;

	start = buf;

	add_wait_queue(&ipa_ctx->msg_waitq, &wait);
	while (1) {
		mutex_lock(&ipa_ctx->msg_lock);
		locked = 1;
		prepare_to_wait(&ipa_ctx->msg_waitq, &wait, TASK_INTERRUPTIBLE);
		if (!list_empty(&ipa_ctx->msg_list)) {
			msg = list_first_entry(&ipa_ctx->msg_list,
					struct ipa_push_msg, link);
@@ -576,10 +576,10 @@ ssize_t ipa_read(struct file *filp, char __user *buf, size_t count,

		locked = 0;
		mutex_unlock(&ipa_ctx->msg_lock);
		schedule();
		wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
	}

	finish_wait(&ipa_ctx->msg_waitq, &wait);
	remove_wait_queue(&ipa_ctx->msg_waitq, &wait);
	if (start != buf && ret != -EFAULT)
		ret = buf - start;

+4 −6
Original line number Diff line number Diff line
@@ -522,17 +522,15 @@ ssize_t ipa3_read(struct file *filp, char __user *buf, size_t count,
	char __user *start;
	struct ipa3_push_msg *msg = NULL;
	int ret;
	DEFINE_WAIT(wait);
	DEFINE_WAIT_FUNC(wait, woken_wake_function);
	int locked;

	start = buf;

	add_wait_queue(&ipa3_ctx->msg_waitq, &wait);
	while (1) {
		mutex_lock(&ipa3_ctx->msg_lock);
		locked = 1;
		prepare_to_wait(&ipa3_ctx->msg_waitq,
				&wait,
				TASK_INTERRUPTIBLE);

		if (!list_empty(&ipa3_ctx->msg_list)) {
			msg = list_first_entry(&ipa3_ctx->msg_list,
@@ -585,10 +583,10 @@ ssize_t ipa3_read(struct file *filp, char __user *buf, size_t count,

		locked = 0;
		mutex_unlock(&ipa3_ctx->msg_lock);
		schedule();
		wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
	}

	finish_wait(&ipa3_ctx->msg_waitq, &wait);
	remove_wait_queue(&ipa3_ctx->msg_waitq, &wait);
	if (start != buf && ret != -EFAULT)
		ret = buf - start;