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

Commit 9ce35d37 authored by Dinesh K Garg's avatar Dinesh K Garg
Browse files

mink: fix race condition in cb server exit



There could be a race condition between invoke and accept threads of
CB server. If exit for some reason, accept threads would exit and invoke
thread may be processing a CB req that lands up on wait Q after accept
threads have exited. This could cause invoke thread ot hang on wait Q.
Adding a notification mechanism that would set flag if system is either
shutting down or going to reboot. This would help invoke thread to avoid
wait on Q if system was under shutdown when it was about to land on Q.

Change-Id: I8ba942f4ff6284a2ac72e30cec4107ce36e9522f
Signed-off-by: default avatarDinesh K Garg <dineshg@codeaurora.org>
parent 13667470
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/module.h>
@@ -17,6 +17,7 @@
#include <linux/uaccess.h>
#include <linux/dma-buf.h>
#include <linux/kref.h>
#include <linux/signal.h>

#include <soc/qcom/scm.h>
#include <asm/cacheflush.h>
@@ -1446,6 +1447,7 @@ static long process_accept_req(struct file *filp, unsigned int cmd,
						unsigned long arg)
{
	int ret = -1;
	sigset_t pending_sig;
	struct smcinvoke_file_data *server_obj = filp->private_data;
	struct smcinvoke_accept user_args = {0};
	struct smcinvoke_cb_txn *cb_txn = NULL;
@@ -1517,6 +1519,21 @@ static long process_accept_req(struct file *filp, unsigned int cmd,
		if (ret) {
			pr_debug("%s wait_event interrupted: ret = %d\n",
							__func__, ret);
			/*
			 * Ideally, we should destroy server if accept threads
			 * are returning due to client being killed or device
			 * going down (Shutdown/Reboot) but that would make
			 * server_info invalid. Other accept/invoke threads are
			 * using server_info and would crash. So dont do that.
			 */
			pending_sig = (&current->pending)->signal;
			if (sigismember(&pending_sig, SIGKILL)) {
				mutex_lock(&g_smcinvoke_lock);
				server_info->state =
					SMCINVOKE_SERVER_STATE_DEFUNCT;
				wake_up_interruptible(&server_info->rsp_wait_q);
				mutex_unlock(&g_smcinvoke_lock);
			}
			goto out;
		}