Thread (21 messages) flat view 21 messages, 2 authors, 2017-07-28
STALE3304d REVIEWED: 2 (1M)

Revision v2 of 3 in this series; 2 review trailers.

Revisions (3)
  1. v1 [diff vs current]
  2. v2 current
  3. v3 [diff vs current]

[PATCH v2 5/7] mailbox: Make message send queue size dynamic in Linux mailbox

From: Anup Patel <hidden>
Date: 2017-07-21 06:56:46
Also in: linux-devicetree, lkml
Subsystem: mailbox api, the rest · Maintainers: Jassi Brar, Linus Torvalds

Currently, the message send queue size in Linux mailbox framework
is hard-coded to MBOX_TX_QUEUE_LEN which is defined as 20.

This message send queue can easily overflow if mbox_send_message()
is called for same mailbox channel several times. The size of message
send queue should not be hard-coded in Linux mailbox framework and
instead mailbox controller driver should have a mechanism to specify
message send queue size for each mailbox channel.

This patch makes message send queue size dynamic in Linux mailbox
framework and provides a mechanism to set message send queue size
for each mailbox channel. If mailbox controller driver does not set
message send queue size then we assume the hard-coded value of 20.

Signed-off-by: Anup Patel <redacted>
Reviewed-by: Jonathan Richardson <redacted>
Reviewed-by: Scott Branden <scott.branden@broadcom.com>
---
 drivers/mailbox/mailbox.c          | 15 ++++++++++++---
 include/linux/mailbox_controller.h |  5 +++--
 2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index 537f4f6..ccc2aea 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -34,7 +34,7 @@ static int add_to_rbuf(struct mbox_chan *chan, void *mssg)
 	spin_lock_irqsave(&chan->lock, flags);
 
 	/* See if there is any space left */
-	if (chan->msg_count == MBOX_TX_QUEUE_LEN) {
+	if (chan->msg_count == chan->msg_queue_len) {
 		spin_unlock_irqrestore(&chan->lock, flags);
 		return -ENOBUFS;
 	}
@@ -43,7 +43,7 @@ static int add_to_rbuf(struct mbox_chan *chan, void *mssg)
 	chan->msg_data[idx] = mssg;
 	chan->msg_count++;
 
-	if (idx == MBOX_TX_QUEUE_LEN - 1)
+	if (idx == chan->msg_queue_len - 1)
 		chan->msg_free = 0;
 	else
 		chan->msg_free++;
@@ -70,7 +70,7 @@ static void msg_submit(struct mbox_chan *chan)
 	if (idx >= count)
 		idx -= count;
 	else
-		idx += MBOX_TX_QUEUE_LEN - count;
+		idx += chan->msg_queue_len - count;
 
 	data = chan->msg_data[idx];
 
@@ -346,6 +346,12 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
 	spin_lock_irqsave(&chan->lock, flags);
 	chan->msg_free = 0;
 	chan->msg_count = 0;
+	chan->msg_data = kcalloc(chan->msg_queue_len,
+				 sizeof(void *), GFP_ATOMIC);
+	if (!chan->msg_data) {
+		spin_unlock_irqrestore(&chan->lock, flags);
+		return ERR_PTR(-ENOMEM);
+	}
 	chan->active_req = NULL;
 	chan->cl = cl;
 	init_completion(&chan->tx_complete);
@@ -420,6 +426,7 @@ void mbox_free_channel(struct mbox_chan *chan)
 	chan->active_req = NULL;
 	if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK))
 		chan->txdone_method = TXDONE_BY_POLL;
+	kfree(chan->msg_data);
 
 	module_put(chan->mbox->dev->driver->owner);
 	spin_unlock_irqrestore(&chan->lock, flags);
@@ -477,6 +484,8 @@ int mbox_controller_register(struct mbox_controller *mbox)
 		chan->cl = NULL;
 		chan->mbox = mbox;
 		chan->txdone_method = txdone;
+		if (chan->msg_queue_len < MBOX_TX_QUEUE_LEN)
+			chan->msg_queue_len = MBOX_TX_QUEUE_LEN;
 		spin_lock_init(&chan->lock);
 	}
 
diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h
index 74deadb..eba3fed 100644
--- a/include/linux/mailbox_controller.h
+++ b/include/linux/mailbox_controller.h
@@ -110,6 +110,7 @@ struct mbox_controller {
  * @active_req:		Currently active request hook
  * @msg_count:		No. of mssg currently queued
  * @msg_free:		Index of next available mssg slot
+ * @msg_queue_len:	Max number of mssg which can be queued
  * @msg_data:		Hook for data packet
  * @lock:		Serialise access to the channel
  * @con_priv:		Hook for controller driver to attach private data
@@ -120,8 +121,8 @@ struct mbox_chan {
 	struct mbox_client *cl;
 	struct completion tx_complete;
 	void *active_req;
-	unsigned msg_count, msg_free;
-	void *msg_data[MBOX_TX_QUEUE_LEN];
+	unsigned int msg_count, msg_free, msg_queue_len;
+	void **msg_data;
 	spinlock_t lock; /* Serialise access to the channel */
 	void *con_priv;
 };
-- 
2.7.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help