lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1479147965-29662-6-git-send-email-rob.rice@broadcom.com>
Date:   Mon, 14 Nov 2016 13:25:59 -0500
From:   Rob Rice <rob.rice@...adcom.com>
To:     Jassi Brar <jassisinghbrar@...il.com>
Cc:     bcm-kernel-feedback-list@...adcom.com,
        linux-kernel@...r.kernel.org, Steve Lin <steven.lin1@...adcom.com>,
        Rob Rice <rob.rice@...adcom.com>
Subject: [PATCH 05/11] mailbox: bcm-pdc: streamline rx code

Remove the unnecessary rmb() from the receive path.

If the rx ring has multiple messages ready, avoid reading
last_rx_curr multiple times from the register.

Signed-off-by: Rob Rice <rob.rice@...adcom.com>
Reviewed-by: Andy Gospodarek <gospo@...adcom.com>
---
 drivers/mailbox/bcm-pdc-mailbox.c | 108 +++++++++++++++++---------------------
 1 file changed, 48 insertions(+), 60 deletions(-)

diff --git a/drivers/mailbox/bcm-pdc-mailbox.c b/drivers/mailbox/bcm-pdc-mailbox.c
index fa3f484..2195760 100644
--- a/drivers/mailbox/bcm-pdc-mailbox.c
+++ b/drivers/mailbox/bcm-pdc-mailbox.c
@@ -570,27 +570,23 @@ pdc_build_txd(struct pdc_state *pdcs, dma_addr_t dma_addr, u32 buf_len,
 }
 
 /**
- * pdc_receive() - Receive a response message from a given SPU.
+ * pdc_receive_one() - Receive a response message from a given SPU.
  * @pdcs:    PDC state for the SPU to receive from
- * @mssg:    mailbox message to be returned to client
  *
  * When the return code indicates success, the response message is available in
  * the receive buffers provided prior to submission of the request.
  *
- * Input:
- *   pdcs - PDC state structure for the SPU to be polled
- *   mssg - mailbox message to be returned to client. This function sets the
- *	    context pointer on the message to help the client associate the
- *	    response with a request.
- *
  * Return:  PDC_SUCCESS if one or more receive descriptors was processed
  *          -EAGAIN indicates that no response message is available
  *          -EIO an error occurred
  */
 static int
-pdc_receive(struct pdc_state *pdcs, struct brcm_message *mssg)
+pdc_receive_one(struct pdc_state *pdcs)
 {
 	struct device *dev = &pdcs->pdev->dev;
+	struct mbox_controller *mbc;
+	struct mbox_chan *chan;
+	struct brcm_message mssg;
 	u32 len, rx_status;
 	u32 num_frags;
 	int i;
@@ -599,29 +595,23 @@ pdc_receive(struct pdc_state *pdcs, struct brcm_message *mssg)
 	u32 rx_idx;      /* ring index of start of receive frame */
 	dma_addr_t resp_hdr_daddr;
 
+	mbc = &pdcs->mbc;
+	chan = &mbc->chans[0];
+	mssg.type = BRCM_MESSAGE_SPU;
+
 	/*
 	 * return if a complete response message is not yet ready.
 	 * rxin_numd[rxin] is the number of fragments in the next msg
 	 * to read.
 	 */
 	frags_rdy = NRXDACTIVE(pdcs->rxin, pdcs->last_rx_curr, pdcs->nrxpost);
-	if ((frags_rdy == 0) || (frags_rdy < pdcs->rxin_numd[pdcs->rxin])) {
-		/* See if the hw has written more fragments than we know */
-		pdcs->last_rx_curr =
-		    (ioread32((void *)&pdcs->rxregs_64->status0) &
-		     CRYPTO_D64_RS0_CD_MASK) / RING_ENTRY_SIZE;
-		frags_rdy = NRXDACTIVE(pdcs->rxin, pdcs->last_rx_curr,
-				       pdcs->nrxpost);
-		if ((frags_rdy == 0) ||
-		    (frags_rdy < pdcs->rxin_numd[pdcs->rxin])) {
-			/* No response ready */
-			return -EAGAIN;
-		}
-		/* can't read descriptors/data until write index is read */
-		rmb();
-	}
+	if ((frags_rdy == 0) || (frags_rdy < pdcs->rxin_numd[pdcs->rxin]))
+		/* No response ready */
+		return -EAGAIN;
 
 	num_frags = pdcs->txin_numd[pdcs->txin];
+	WARN_ON(num_frags == 0);
+
 	dma_unmap_sg(dev, pdcs->src_sg[pdcs->txin],
 		     sg_nents(pdcs->src_sg[pdcs->txin]), DMA_TO_DEVICE);
 
@@ -634,7 +624,7 @@ pdc_receive(struct pdc_state *pdcs, struct brcm_message *mssg)
 	rx_idx = pdcs->rxin;
 	num_frags = pdcs->rxin_numd[rx_idx];
 	/* Return opaque context with result */
-	mssg->ctx = pdcs->rxp_ctx[rx_idx];
+	mssg.ctx = pdcs->rxp_ctx[rx_idx];
 	pdcs->rxp_ctx[rx_idx] = NULL;
 	resp_hdr = pdcs->resp_hdr[rx_idx];
 	resp_hdr_daddr = pdcs->resp_hdr_daddr[rx_idx];
@@ -674,12 +664,35 @@ pdc_receive(struct pdc_state *pdcs, struct brcm_message *mssg)
 
 	dma_pool_free(pdcs->rx_buf_pool, resp_hdr, resp_hdr_daddr);
 
+	mbox_chan_received_data(chan, &mssg);
+
 	pdcs->pdc_replies++;
-	/* if we read one or more rx descriptors, claim success */
-	if (num_frags > 0)
-		return PDC_SUCCESS;
-	else
-		return -EIO;
+	return PDC_SUCCESS;
+}
+
+/**
+ * pdc_receive() - Process as many responses as are available in the rx ring.
+ * @pdcs:  PDC state
+ *
+ * Called within the hard IRQ.
+ * Return:
+ */
+static int
+pdc_receive(struct pdc_state *pdcs)
+{
+	int rx_status;
+
+	/* read last_rx_curr from register once */
+	pdcs->last_rx_curr =
+	    (ioread32((void *)&pdcs->rxregs_64->status0) &
+	     CRYPTO_D64_RS0_CD_MASK) / RING_ENTRY_SIZE;
+
+	do {
+		/* Could be many frames ready */
+		rx_status = pdc_receive_one(pdcs);
+	} while (rx_status == PDC_SUCCESS);
+
+	return 0;
 }
 
 /**
@@ -946,14 +959,13 @@ static irqreturn_t pdc_irq_handler(int irq, void *cookie)
 }
 
 /**
- * pdc_irq_thread() - Function invoked on deferred thread when a DMA tx has
- * completed or data is available to receive.
+ * pdc_irq_thread() - Function invoked on deferred thread when data is available
+ * to receive.
  * @irq:    Interrupt number
  * @cookie: PDC state for PDC that generated the interrupt
  *
- * On DMA tx complete, notify the mailbox client. On DMA rx complete, process
- * as many SPU response messages as are available and send each to the mailbox
- * client.
+ * On DMA rx complete, process as many SPU response messages as are available
+ * and send each to the mailbox client.
  *
  * Return: IRQ_HANDLED if we recognized and handled the interrupt
  *         IRQ_NONE otherwise
@@ -961,39 +973,15 @@ static irqreturn_t pdc_irq_handler(int irq, void *cookie)
 static irqreturn_t pdc_irq_thread(int irq, void *cookie)
 {
 	struct pdc_state *pdcs = cookie;
-	struct mbox_controller *mbc;
-	struct mbox_chan *chan;
 	bool rx_int;
-	int rx_status;
-	struct brcm_message mssg;
 
 	rx_int = test_and_clear_bit(PDC_RCVINT_0, &pdcs->intstatus);
-
 	if (pdcs && rx_int) {
 		dev_dbg(&pdcs->pdev->dev,
 			"%s() got irq %d with rx_int %s",
 			__func__, irq, rx_int ? "set" : "clear");
 
-		mbc = &pdcs->mbc;
-		chan = &mbc->chans[0];
-
-		while (1) {
-			/* Could be many frames ready */
-			memset(&mssg, 0, sizeof(mssg));
-			mssg.type = BRCM_MESSAGE_SPU;
-			rx_status = pdc_receive(pdcs, &mssg);
-			if (rx_status >= 0) {
-				dev_dbg(&pdcs->pdev->dev,
-					"%s(): invoking client rx cb",
-					__func__);
-				mbox_chan_received_data(chan, &mssg);
-			} else {
-				dev_dbg(&pdcs->pdev->dev,
-					"%s(): no SPU response available",
-					__func__);
-				break;
-			}
-		}
+		pdc_receive(pdcs);
 		return IRQ_HANDLED;
 	}
 	return IRQ_NONE;
-- 
2.1.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ