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: Deepak Kumar Singh <deesin@codeaurora.org>
This commit is contained in:
Deepak Kumar Singh
2020-07-24 15:12:10 +05:30
parent 460ba7dfb1
commit b5b6007d15

View File

@@ -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;