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

Commit 73a41283 authored by Hardik Arya's avatar Hardik Arya
Browse files

diag: Read and drop socket data when no fwd_ctxt available



Diag socket channel where no fwd_ctxt is available is not
reading data from socket when data is ready which is resulting
to memory allocation failure on ipc router side after multiple
SSR. The patch handles this case by reading and dropping the
data when it is available.

Change-Id: I631acce2946699e0a94d2510d46bf646ad117804
Signed-off-by: default avatarHardik Arya <harya@codeaurora.org>
parent 7cb74543
Loading
Loading
Loading
Loading
+41 −2
Original line number Diff line number Diff line
@@ -352,6 +352,7 @@ static void diag_state_open_socket(void *ctxt);
static void diag_state_close_socket(void *ctxt);
static int diag_socket_write(void *ctxt, unsigned char *buf, int len);
static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len);
static void diag_socket_drop_data(struct diag_socket_info *info);
static void diag_socket_queue_read(void *ctxt);

static struct diag_peripheral_ops socket_ops = {
@@ -613,6 +614,9 @@ static void socket_read_work_fn(struct work_struct *work)
		return;
	}

	if (!info->fwd_ctxt && info->port_type == PORT_TYPE_SERVER)
		diag_socket_drop_data(info);

	if (!atomic_read(&info->opened) && info->port_type == PORT_TYPE_SERVER)
		diagfwd_buffers_init(info->fwd_ctxt);

@@ -683,6 +687,41 @@ static void handle_ctrl_pkt(struct diag_socket_info *info, void *buf, int len)
	}
}

static void diag_socket_drop_data(struct diag_socket_info *info)
{
	int err = 0;
	int pkt_len = 0;
	int read_len = 0;
	unsigned char *temp = NULL;
	struct kvec iov;
	struct msghdr read_msg = {NULL, 0};
	struct sockaddr_qrtr src_addr = {0};
	unsigned long flags;

	temp = vzalloc(PERIPHERAL_BUF_SZ);
	if (!temp)
		return;

	while (info->data_ready > 0) {
		iov.iov_base = temp;
		iov.iov_len = PERIPHERAL_BUF_SZ;
		read_msg.msg_name = &src_addr;
		read_msg.msg_namelen = sizeof(src_addr);
		err = info->hdl->ops->ioctl(info->hdl, TIOCINQ,
					(unsigned long)&pkt_len);
		if (err || pkt_len < 0)
			break;
		spin_lock_irqsave(&info->lock, flags);
		info->data_ready--;
		spin_unlock_irqrestore(&info->lock, flags);
		read_len = kernel_recvmsg(info->hdl, &read_msg, &iov, 1,
					  pkt_len, MSG_DONTWAIT);
		pr_debug("%s : %s drop total bytes: %d\n", __func__,
			info->name, read_len);
	}
	vfree(temp);
}

static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
{
	int err = 0;
@@ -693,8 +732,8 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
	int qrtr_ctrl_recd = 0;
	uint8_t buf_full = 0;
	unsigned char *temp = NULL;
	struct kvec iov = {0};
	struct msghdr read_msg = {0};
	struct kvec iov;
	struct msghdr read_msg = {NULL, 0};
	struct sockaddr_qrtr src_addr = {0};
	struct diag_socket_info *info;
	struct mutex *channel_mutex;