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

Commit b5b6007d authored by Deepak Kumar Singh's avatar Deepak Kumar Singh
Browse files

rpmsg: glink: do not serve intent request if no callback present



Sometime remote may try to send packet before receive callback is
assigned. Which can result in dropping of packets on apps.

Acknowledge intent request but queue the intent only when receive
callback assignment is complete.

Change-Id: Ie366c24e204db7f1609e2345ee3324cb00f56f3e
Signed-off-by: default avatarDeepak Kumar Singh <deesin@codeaurora.org>
parent 460ba7df
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ struct glink_core_rx_intent {
	size_t size;
	bool reuse;
	bool in_use;
	bool advertised;
	u32 offset;

	struct list_head node;
@@ -768,6 +769,15 @@ static int qcom_glink_advertise_intent(struct qcom_glink *glink,
		__le32 liid;
	} __packed;
	struct command cmd;
	unsigned long flags;

	spin_lock_irqsave(&channel->intent_lock, flags);
	if (intent->advertised) {
		spin_unlock_irqrestore(&channel->intent_lock, flags);
		return 0;
	}
	intent->advertised = true;
	spin_unlock_irqrestore(&channel->intent_lock, flags);

	cmd.id = cpu_to_le16(RPM_CMD_INTENT);
	cmd.lcid = cpu_to_le16(channel->lcid);
@@ -873,6 +883,7 @@ static void qcom_glink_handle_intent_req(struct qcom_glink *glink,
	struct glink_core_rx_intent *intent = NULL;
	struct glink_core_rx_intent *tmp;
	struct glink_channel *channel;
	struct rpmsg_endpoint *ept;
	unsigned long flags;
	int iid;

@@ -898,8 +909,9 @@ static void qcom_glink_handle_intent_req(struct qcom_glink *glink,
		return;
	}

	ept = &channel->ept;
	intent = qcom_glink_alloc_intent(glink, channel, size, false);
	if (intent)
	if (intent && ept->cb)
		qcom_glink_advertise_intent(glink, channel, intent);

	qcom_glink_send_intent_req_ack(glink, channel, !!intent);
@@ -1399,16 +1411,31 @@ static int qcom_glink_announce_create(struct rpmsg_device *rpdev)
	struct device_node *np = rpdev->dev.of_node;
	struct qcom_glink *glink = channel->glink;
	struct glink_core_rx_intent *intent;
	struct glink_core_rx_intent *tmp;
	const struct property *prop = NULL;
	__be32 defaults[] = { cpu_to_be32(SZ_1K), cpu_to_be32(5) };
	int num_intents;
	int num_groups = 1;
	__be32 *val = defaults;
	unsigned long flags;
	int iid;
	int size;

	if (glink->intentless || !completion_done(&channel->open_ack))
		return 0;

	/*Serve any pending intent request*/
	spin_lock_irqsave(&channel->intent_lock, flags);
	idr_for_each_entry(&channel->liids, tmp, iid) {
		if (!tmp->reuse && !tmp->advertised) {
			intent = tmp;
			spin_unlock_irqrestore(&channel->intent_lock, flags);
			qcom_glink_advertise_intent(glink, channel, intent);
			spin_lock_irqsave(&channel->intent_lock, flags);
		}
	}
	spin_unlock_irqrestore(&channel->intent_lock, flags);

	prop = of_find_property(np, "qcom,intents", NULL);
	if (prop) {
		val = prop->value;