Skip to content

Commit 64f95f8

Browse files
Sricharan Randersson
authored andcommitted
rpmsg: glink: Use the local intents when receiving data
So previously on request from remote side, we allocated local intent buffers and passed the ids to the remote. Now when we receive data buffers from remote directed to that intent id, copy the data to the corresponding preallocated intent buffer. Acked-by: Arun Kumar Neelakantam <aneela@codeaurora.org> Signed-off-by: Sricharan R <sricharan@codeaurora.org> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
1 parent 933b45d commit 64f95f8

File tree

1 file changed

+50
-25
lines changed

1 file changed

+50
-25
lines changed

drivers/rpmsg/qcom_glink_native.c

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ struct glink_channel {
162162
spinlock_t intent_lock;
163163
struct idr liids;
164164

165-
void *buf;
165+
struct glink_core_rx_intent *buf;
166166
int buf_offset;
167167
int buf_size;
168168

@@ -614,6 +614,7 @@ static int qcom_glink_rx_defer(struct qcom_glink *glink, size_t extra)
614614

615615
static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
616616
{
617+
struct glink_core_rx_intent *intent;
617618
struct glink_channel *channel;
618619
struct {
619620
struct glink_msg msg;
@@ -623,6 +624,8 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
623624
unsigned int chunk_size;
624625
unsigned int left_size;
625626
unsigned int rcid;
627+
unsigned int liid;
628+
int ret = 0;
626629
unsigned long flags;
627630

628631
if (avail < sizeof(hdr)) {
@@ -650,56 +653,78 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
650653
dev_dbg(glink->dev, "Data on non-existing channel\n");
651654

652655
/* Drop the message */
653-
qcom_glink_rx_advance(glink,
654-
ALIGN(sizeof(hdr) + chunk_size, 8));
655-
return 0;
656+
goto advance_rx;
656657
}
657658

658-
/* Might have an ongoing, fragmented, message to append */
659-
if (!channel->buf) {
660-
channel->buf = kmalloc(chunk_size + left_size, GFP_ATOMIC);
661-
if (!channel->buf)
662-
return -ENOMEM;
659+
if (glink->intentless) {
660+
/* Might have an ongoing, fragmented, message to append */
661+
if (!channel->buf) {
662+
intent = kzalloc(sizeof(*intent), GFP_ATOMIC);
663+
if (!intent)
664+
return -ENOMEM;
665+
666+
intent->data = kmalloc(chunk_size + left_size,
667+
GFP_ATOMIC);
668+
if (!intent->data) {
669+
kfree(intent);
670+
return -ENOMEM;
671+
}
672+
673+
intent->id = 0xbabababa;
674+
intent->size = chunk_size + left_size;
675+
intent->offset = 0;
676+
677+
channel->buf = intent;
678+
} else {
679+
intent = channel->buf;
680+
}
681+
} else {
682+
liid = le32_to_cpu(hdr.msg.param2);
663683

664-
channel->buf_size = chunk_size + left_size;
665-
channel->buf_offset = 0;
666-
}
684+
spin_lock_irqsave(&channel->intent_lock, flags);
685+
intent = idr_find(&channel->liids, liid);
686+
spin_unlock_irqrestore(&channel->intent_lock, flags);
667687

668-
qcom_glink_rx_advance(glink, sizeof(hdr));
688+
if (!intent) {
689+
dev_err(glink->dev,
690+
"no intent found for channel %s intent %d",
691+
channel->name, liid);
692+
goto advance_rx;
693+
}
694+
}
669695

670-
if (channel->buf_size - channel->buf_offset < chunk_size) {
671-
dev_err(glink->dev, "Insufficient space in input buffer\n");
696+
if (intent->size - intent->offset < chunk_size) {
697+
dev_err(glink->dev, "Insufficient space in intent\n");
672698

673699
/* The packet header lied, drop payload */
674-
qcom_glink_rx_advance(glink, chunk_size);
675-
return -ENOMEM;
700+
goto advance_rx;
676701
}
677702

678-
qcom_glink_rx_peak(glink, channel->buf + channel->buf_offset,
703+
qcom_glink_rx_advance(glink, ALIGN(sizeof(hdr), 8));
704+
qcom_glink_rx_peak(glink, intent->data + intent->offset,
679705
chunk_size);
680-
channel->buf_offset += chunk_size;
706+
intent->offset += chunk_size;
681707

682708
/* Handle message when no fragments remain to be received */
683709
if (!left_size) {
684710
spin_lock(&channel->recv_lock);
685711
if (channel->ept.cb) {
686712
channel->ept.cb(channel->ept.rpdev,
687-
channel->buf,
688-
channel->buf_offset,
713+
intent->data,
714+
intent->offset,
689715
channel->ept.priv,
690716
RPMSG_ADDR_ANY);
691717
}
692718
spin_unlock(&channel->recv_lock);
693719

694-
kfree(channel->buf);
720+
intent->offset = 0;
695721
channel->buf = NULL;
696-
channel->buf_size = 0;
697722
}
698723

699-
/* Each message starts at 8 byte aligned address */
724+
advance_rx:
700725
qcom_glink_rx_advance(glink, ALIGN(chunk_size, 8));
701726

702-
return 0;
727+
return ret;
703728
}
704729

705730
static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid)

0 commit comments

Comments
 (0)