From: "Damien Riégel" <damien.riegel@silabs.com>
To: greybus-dev@lists.linaro.org, Johan Hovold <johan@kernel.org>,
Alex Elder <elder@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
linux-kernel@vger.kernel.org
Cc: "Silicon Labs Kernel Team" <linux-devel@silabs.com>,
"Damien Riégel" <damien.riegel@silabs.com>
Subject: [PATCH v3 10/14] greybus: cpc: use holding queue instead of sending out immediately
Date: Thu, 12 Feb 2026 09:43:48 -0500 [thread overview]
Message-ID: <20260212144352.93043-11-damien.riegel@silabs.com> (raw)
In-Reply-To: <20260212144352.93043-1-damien.riegel@silabs.com>
A feature of CPC is the RX window. This value, advertised in every
packet, indicates to the remote peer how many reception buffers are
available for that CPort. The remote peer must not send more messages
than advertised, as these extra messages are almost guaranteed to be
dropped by the receiver. This is a bit similar to TCP's receive window,
but expressed in a number of messages instead of bytes.
As the first step to handle remote's RX window, store the skb in a
sk_buff_head list, instead of sending a message immediately when pushed
by Greybus. skbs are still sent out straight away for now, but a future
commit will make sure they stay in the holding queue instead of being
sent out immediately if the remote's RX window is too small.
Signed-off-by: Damien Riégel <damien.riegel@silabs.com>
---
drivers/greybus/cpc/cpc.h | 10 ++++++----
drivers/greybus/cpc/cport.c | 21 ++++++++++++---------
drivers/greybus/cpc/host.c | 4 +++-
drivers/greybus/cpc/protocol.c | 25 ++++++++++++++++++++++++-
4 files changed, 45 insertions(+), 15 deletions(-)
diff --git a/drivers/greybus/cpc/cpc.h b/drivers/greybus/cpc/cpc.h
index 725fd7f4afc..f1669585c45 100644
--- a/drivers/greybus/cpc/cpc.h
+++ b/drivers/greybus/cpc/cpc.h
@@ -9,15 +9,15 @@
#include <linux/device.h>
#include <linux/greybus.h>
#include <linux/mutex.h>
+#include <linux/skbuff.h>
#include <linux/types.h>
-struct sk_buff;
-
/**
* struct cpc_cport - CPC cport
* @id: cport ID
* @cpc_hd: pointer to the CPC host device this cport belongs to
* @lock: mutex to synchronize accesses to tcb and other attributes
+ * @holding_queue: list of frames queued to be sent
* @tcb: Transmission Control Block
*/
struct cpc_cport {
@@ -26,6 +26,8 @@ struct cpc_cport {
struct cpc_host_device *cpc_hd;
struct mutex lock; /* Synchronize access to state variables */
+ struct sk_buff_head holding_queue;
+
/*
* @ack: current acknowledge number
* @seq: current sequence number
@@ -42,7 +44,7 @@ void cpc_cport_release(struct cpc_cport *cport);
void cpc_cport_pack(struct gb_operation_msg_hdr *gb_hdr, u16 cport_id);
u16 cpc_cport_unpack(struct gb_operation_msg_hdr *gb_hdr);
-int cpc_cport_transmit(struct cpc_cport *cport, struct sk_buff *skb);
+void cpc_cport_transmit(struct cpc_cport *cport, struct sk_buff *skb);
struct cpc_skb_cb {
struct cpc_cport *cport;
@@ -58,7 +60,7 @@ struct cpc_skb_cb {
#define CPC_SKB_CB(__skb) ((struct cpc_skb_cb *)&((__skb)->cb[0]))
-void cpc_protocol_prepare_header(struct sk_buff *skb, u8 ack);
void cpc_protocol_on_data(struct cpc_cport *cport, struct sk_buff *skb);
+void __cpc_protocol_write_head(struct cpc_cport *cport);
#endif
diff --git a/drivers/greybus/cpc/cport.c b/drivers/greybus/cpc/cport.c
index 847cc8ebe41..91c39856e22 100644
--- a/drivers/greybus/cpc/cport.c
+++ b/drivers/greybus/cpc/cport.c
@@ -7,7 +7,6 @@
#include <linux/skbuff.h>
#include "cpc.h"
-#include "host.h"
/**
* cpc_cport_tcb_reset() - Reset cport's TCB to initial values.
@@ -38,15 +37,23 @@ struct cpc_cport *cpc_cport_alloc(u16 cport_id, gfp_t gfp_mask)
cpc_cport_tcb_reset(cport);
mutex_init(&cport->lock);
+ skb_queue_head_init(&cport->holding_queue);
return cport;
}
void cpc_cport_release(struct cpc_cport *cport)
{
+ skb_queue_purge(&cport->holding_queue);
kfree(cport);
}
+static void cpc_cport_queue_skb(struct cpc_cport *cport, struct sk_buff *skb)
+{
+ __skb_header_release(skb);
+ __skb_queue_tail(&cport->holding_queue, skb);
+}
+
/**
* cpc_cport_pack() - Pack CPort ID into Greybus Operation Message header.
* @gb_hdr: Greybus operation message header.
@@ -78,11 +85,9 @@ u16 cpc_cport_unpack(struct gb_operation_msg_hdr *gb_hdr)
* @cport: cport.
* @skb: skb to be transmitted.
*/
-int cpc_cport_transmit(struct cpc_cport *cport, struct sk_buff *skb)
+void cpc_cport_transmit(struct cpc_cport *cport, struct sk_buff *skb)
{
- struct cpc_host_device *cpc_hd = cport->cpc_hd;
struct gb_operation_msg_hdr *gb_hdr;
- u8 ack;
/* Inject cport ID in Greybus header */
gb_hdr = (struct gb_operation_msg_hdr *)skb->data;
@@ -94,11 +99,9 @@ int cpc_cport_transmit(struct cpc_cport *cport, struct sk_buff *skb)
CPC_SKB_CB(skb)->cpc_flags = CPC_SKB_FLAG_REQ_ACK;
cport->tcb.seq++;
- ack = cport->tcb.ack;
+
+ cpc_cport_queue_skb(cport, skb);
+ __cpc_protocol_write_head(cport);
mutex_unlock(&cport->lock);
-
- cpc_protocol_prepare_header(skb, ack);
-
- return cpc_hd_send_skb(cpc_hd, skb);
}
diff --git a/drivers/greybus/cpc/host.c b/drivers/greybus/cpc/host.c
index 2c1b5d02ec2..225f9342cd2 100644
--- a/drivers/greybus/cpc/host.c
+++ b/drivers/greybus/cpc/host.c
@@ -62,7 +62,9 @@ static int cpc_hd_message_send(struct cpc_host_device *cpc_hd, u16 cport_id,
CPC_SKB_CB(skb)->cport = cport;
CPC_SKB_CB(skb)->gb_message = message;
- return cpc_cport_transmit(cport, skb);
+ cpc_cport_transmit(cport, skb);
+
+ return 0;
}
static int cpc_hd_cport_allocate(struct cpc_host_device *cpc_hd, int cport_id, unsigned long flags)
diff --git a/drivers/greybus/cpc/protocol.c b/drivers/greybus/cpc/protocol.c
index 97db70a53b0..4cda71994d8 100644
--- a/drivers/greybus/cpc/protocol.c
+++ b/drivers/greybus/cpc/protocol.c
@@ -14,7 +14,7 @@ static bool cpc_skb_is_sequenced(struct sk_buff *skb)
return CPC_SKB_CB(skb)->cpc_flags & CPC_SKB_FLAG_REQ_ACK;
}
-void cpc_protocol_prepare_header(struct sk_buff *skb, u8 ack)
+static void cpc_protocol_prepare_header(struct sk_buff *skb, u8 ack)
{
struct cpc_header *hdr;
@@ -86,3 +86,26 @@ void cpc_protocol_on_data(struct cpc_cport *cport, struct sk_buff *skb)
greybus_data_rcvd(cport->cpc_hd->gb_hd, cport->id, skb->data, skb->len);
}
}
+
+static void __cpc_protocol_write_skb(struct cpc_cport *cport, struct sk_buff *skb, u8 ack)
+{
+ cpc_protocol_prepare_header(skb, ack);
+
+ cpc_hd_send_skb(cport->cpc_hd, skb);
+}
+
+/* Write skbs at the head of holding queue */
+void __cpc_protocol_write_head(struct cpc_cport *cport)
+{
+ struct sk_buff *skb;
+ u8 ack;
+
+ ack = cport->tcb.ack;
+
+ /* For each SKB in the holding queue, clone it and pass it to lower layer */
+ while ((skb = skb_peek(&cport->holding_queue))) {
+ skb_unlink(skb, &cport->holding_queue);
+
+ __cpc_protocol_write_skb(cport, skb, ack);
+ }
+}
--
2.52.0
next prev parent reply other threads:[~2026-02-12 14:44 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-12 14:43 [PATCH v3 00/14] greybus: introduce CPC as transport layer Damien Riégel
2026-02-12 14:43 ` [PATCH v3 01/14] greybus: cpc: add minimal CPC Host Device infrastructure Damien Riégel
2026-02-12 14:43 ` [PATCH v3 02/14] greybus: cpc: introduce CPC cport structure Damien Riégel
2026-02-12 14:43 ` [PATCH v3 03/14] greybus: cpc: use socket buffers instead of gb_message in TX path Damien Riégel
2026-02-12 14:43 ` [PATCH v3 04/14] greybus: cpc: pack cport ID in Greybus header Damien Riégel
2026-02-12 14:43 ` [PATCH v3 05/14] greybus: cpc: switch RX path to socket buffers Damien Riégel
2026-02-12 14:43 ` [PATCH v3 06/14] greybus: cpc: introduce CPC header structure Damien Riégel
2026-02-12 14:43 ` [PATCH v3 07/14] greybus: cpc: account for CPC header size in RX and TX path Damien Riégel
2026-02-12 14:43 ` [PATCH v3 08/14] greybus: cpc: add and validate sequence numbers Damien Riégel
2026-02-12 14:43 ` [PATCH v3 09/14] greybus: cpc: acknowledge all incoming messages Damien Riégel
2026-02-12 14:43 ` Damien Riégel [this message]
2026-02-13 6:44 ` [PATCH v3 10/14] greybus: cpc: use holding queue instead of sending out immediately kernel test robot
2026-02-12 14:43 ` [PATCH v3 11/14] greybus: cpc: honour remote's RX window Damien Riégel
2026-02-13 21:56 ` kernel test robot
2026-02-12 14:43 ` [PATCH v3 12/14] greybus: cpc: let host device drivers dequeue TX frames Damien Riégel
2026-02-12 14:43 ` [PATCH v3 13/14] greybus: cpc: add private data pointer in CPC Host Device Damien Riégel
2026-02-12 14:43 ` [PATCH v3 14/14] greybus: cpc: add CPC SDIO host driver Damien Riégel
2026-02-13 0:31 ` kernel test robot
2026-02-13 9:35 ` Jérôme Pouiller
2026-02-13 16:00 ` Damien Riégel
2026-02-19 14:38 ` Damien Riégel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260212144352.93043-11-damien.riegel@silabs.com \
--to=damien.riegel@silabs.com \
--cc=elder@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=greybus-dev@lists.linaro.org \
--cc=johan@kernel.org \
--cc=linux-devel@silabs.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®