From patchwork Thu Jun 9 11:41:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias Reichl X-Patchwork-Id: 9166759 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id ED3D2604DB for ; Thu, 9 Jun 2016 11:46:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DCE4E2823D for ; Thu, 9 Jun 2016 11:46:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D19AF28340; Thu, 9 Jun 2016 11:46:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3B7712823D for ; Thu, 9 Jun 2016 11:46:23 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1bAyLv-0005kn-TB; Thu, 09 Jun 2016 11:42:23 +0000 Received: from mail.horus.com ([78.46.148.228]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1bAyLj-0005fv-Eo; Thu, 09 Jun 2016 11:42:15 +0000 Received: from [192.168.1.20] (85-127-114-243.dynamic.xdsl-line.inode.at [85.127.114.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "E-Mail Matthias Reichl", Issuer "HiassofT CA 2014" (verified OK)) by mail.horus.com (Postfix) with ESMTPS id 6E56B64094; Thu, 9 Jun 2016 13:41:45 +0200 (CEST) Received: by camel2.lan (Postfix, from userid 1000) id EE94F1C730A; Thu, 9 Jun 2016 13:41:44 +0200 (CEST) From: Matthias Reichl To: Vinod Koul , Stephen Warren , Lee Jones , Eric Anholt Subject: [PATCH 2/2] dmaengine: bcm2835: Avoid splitting periods into very small chunks Date: Thu, 9 Jun 2016 13:41:44 +0200 Message-Id: <1465472504-10191-3-git-send-email-hias@horus.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1465472504-10191-1-git-send-email-hias@horus.com> References: <1465472504-10191-1-git-send-email-hias@horus.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160609_044211_701721_D7958A2E X-CRM114-Status: GOOD ( 14.26 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-kernel@vger.kernel.org, Clive Messer , linux-rpi-kernel@lists.infradead.org, dmaengine@vger.kernel.org, Martin Sperl , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The current cyclic DMA period splitting implementation can generate very small chunks at the end of each period. For example a 65536 byte period will be split into a 65532 byte chunk and a 4 byte chunk on the "lite" DMA channels. This increases pressure on the RAM controller as the DMA controller needs to fetch two control blocks from RAM in quick succession and could potentially cause latency issues if the RAM is tied up by other devices. We can easily avoid these situations by distributing the remaining length evenly between the last-but-one and the last chunk, making sure that split chunks will be at least half the maximum length the DMA controller can handle. This patch checks if the last chunk would be less than half of the maximum DMA length and if yes distributes the max len+4...max_len*1.5 bytes evenly between the last 2 chunks. This results in chunk sizes between max_len/2 and max_len*0.75 bytes. Signed-off-by: Matthias Reichl Signed-off-by: Martin Sperl Tested-by: Clive Messer Acked-by: Eric Anholt --- drivers/dma/bcm2835-dma.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index 344bcf92..36b998d 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -252,6 +252,20 @@ static void bcm2835_dma_create_cb_set_length( /* have we filled in period_length yet? */ if (*total_len + control_block->length < period_len) { + /* + * If the next control block is the last in the period + * and it's length would be less than half of max_len + * change it so that both control blocks are (almost) + * equally long. This avoids generating very short + * control blocks (worst case would be 4 bytes) which + * might be problematic. We also have to make sure the + * new length is a multiple of 4 bytes. + */ + if (*total_len + control_block->length + max_len / 2 > + period_len) { + control_block->length = + DIV_ROUND_UP(period_len - *total_len, 8) * 4; + } /* update number of bytes in this period so far */ *total_len += control_block->length; return;