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

Commit 9ba404f4 authored by Amandeep Virk's avatar Amandeep Virk
Browse files

soc: qcom: spcom: fix pending rx packet handling



When spcomlib read() system call exits on ERESTARTSYS,
an rx packet arriving later is stuck till next read()
context arrives.
The ERESTARTSYS error is not handled in userspace if the userspace
app is killed/suspended. So, new spcom session reads the response
that belongs to the previous spcom session.
Logic is added to read pending data in rx_buf only if received in
the same spcom session.

Change-Id: Ib3bad1dc8c0101fcad9a39b20d4925c065baa81d
Signed-off-by: default avatarAmandeep Virk <avirk@codeaurora.org>
parent 70fe4cf2
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -185,6 +185,12 @@ struct spcom_channel {
	size_t actual_rx_size;	/* actual data size received */
	void *rpmsg_rx_buf;

	/**
	 * to track if rx_buf is read in the same session
	 * in which it is updated
	 */
	uint32_t rx_buf_txn_id;

	/* shared buffer lock/unlock support */
	int dmabuf_fd_table[SPCOM_MAX_ION_BUF_PER_CH];
	struct dma_buf *dmabuf_handle_table[SPCOM_MAX_ION_BUF_PER_CH];
@@ -341,6 +347,7 @@ static int spcom_init_channel(struct spcom_channel *ch,
	ch->actual_rx_size = 0;
	ch->is_busy = false;
	ch->txn_id = INITIAL_TXN_ID; /* use non-zero nonce for debug */
	ch->rx_buf_txn_id = ch->txn_id;
	memset(ch->pid, 0, sizeof(ch->pid));
	ch->rpmsg_abort = false;
	ch->rpmsg_rx_buf = NULL;
@@ -394,6 +401,16 @@ static int spcom_rx(struct spcom_channel *ch,

	mutex_lock(&ch->lock);

	if (ch->rx_buf_txn_id != ch->txn_id) {
		pr_debug("rpmsg_rx_buf is updated in a different session\n");
		if (ch->rpmsg_rx_buf) {
			memset(ch->rpmsg_rx_buf, 0, ch->actual_rx_size);
			kfree((void *)ch->rpmsg_rx_buf);
			ch->rpmsg_rx_buf = NULL;
			ch->actual_rx_size = 0;
		}
	}

	/* check for already pending data */
	if (!ch->actual_rx_size) {
		reinit_completion(&ch->rx_done);
@@ -2161,6 +2178,7 @@ static void spcom_signal_rx_done(struct work_struct *ignored)
		}
		ch->rpmsg_rx_buf = rx_item->rpmsg_rx_buf;
		ch->actual_rx_size = rx_item->rx_buf_size;
		ch->rx_buf_txn_id = ch->txn_id;
		complete_all(&ch->rx_done);
		mutex_unlock(&ch->lock);