From patchwork Tue Jun 30 14:36:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Petazzoni X-Patchwork-Id: 6696681 Return-Path: X-Original-To: patchwork-dmaengine@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CEB93C05AC for ; Tue, 30 Jun 2015 14:37:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 634D720623 for ; Tue, 30 Jun 2015 14:37:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6002320626 for ; Tue, 30 Jun 2015 14:37:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752597AbbF3OhL (ORCPT ); Tue, 30 Jun 2015 10:37:11 -0400 Received: from down.free-electrons.com ([37.187.137.238]:47186 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752321AbbF3OhJ (ORCPT ); Tue, 30 Jun 2015 10:37:09 -0400 Received: by mail.free-electrons.com (Postfix, from userid 106) id 25EF11F46; Tue, 30 Jun 2015 16:37:09 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from localhost (AToulouse-657-1-1071-25.w92-134.abo.wanadoo.fr [92.134.77.25]) by mail.free-electrons.com (Postfix) with ESMTPSA id DC48093; Tue, 30 Jun 2015 16:37:08 +0200 (CEST) From: Thomas Petazzoni To: Vinod Koul , dmaengine@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, Jason Cooper , Andrew Lunn , Sebastian Hesselbarth , Gregory Clement , Tawfik Bayouk , Nadav Haklai , Lior Amsalem , Maxime Ripard , Thomas Petazzoni Subject: [PATCH v3 6/6] dmaengine: mv_xor: optimize performance by using a subset of the XOR channels Date: Tue, 30 Jun 2015 16:36:57 +0200 Message-Id: <1435675017-875-7-git-send-email-thomas.petazzoni@free-electrons.com> X-Mailer: git-send-email 2.4.5 In-Reply-To: <1435675017-875-1-git-send-email-thomas.petazzoni@free-electrons.com> References: <1435675017-875-1-git-send-email-thomas.petazzoni@free-electrons.com> Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Due to how async_tx behaves internally, having more XOR channels than CPUs is actually hurting performance more than it improves it, because memcpy requests get scheduled on a different channel than the XOR requests, but async_tx will still wait for the completion of the memcpy requests before scheduling the XOR requests. It is in fact more efficient to have at most one channel per CPU, which this patch implements by limiting the number of channels per engine, and the number of engines registered depending on the number of availables CPUs. Marvell platforms are currently available in one CPU, two CPUs and four CPUs configurations: - in the configurations with one CPU, only one channel from one engine is used. - in the configurations with two CPUs, only one channel from each engine is used (they are two XOR engines) - in the configurations with four CPUs, both channels of both engines are used. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 6e09d59..2cdfca7 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "dmaengine.h" @@ -1137,12 +1138,15 @@ static const struct of_device_id mv_xor_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, mv_xor_dt_ids); +static unsigned int mv_xor_engine_count; + static int mv_xor_probe(struct platform_device *pdev) { const struct mbus_dram_target_info *dram; struct mv_xor_device *xordev; struct mv_xor_platform_data *pdata = dev_get_platdata(&pdev->dev); struct resource *res; + unsigned int max_engines, max_channels; int i, ret; int op_in_desc; @@ -1186,6 +1190,21 @@ static int mv_xor_probe(struct platform_device *pdev) if (!IS_ERR(xordev->clk)) clk_prepare_enable(xordev->clk); + /* + * We don't want to have more than one channel per CPU in + * order for async_tx to perform well. So we limit the number + * of engines and channels so that we take into account this + * constraint. Note that we also want to use channels from + * separate engines when possible. + */ + max_engines = num_present_cpus(); + max_channels = min_t(unsigned int, + MV_XOR_MAX_CHANNELS, + DIV_ROUND_UP(num_present_cpus(), 2)); + + if (mv_xor_engine_count >= max_engines) + return 0; + if (pdev->dev.of_node) { struct device_node *np; int i = 0; @@ -1199,6 +1218,9 @@ static int mv_xor_probe(struct platform_device *pdev) int irq; op_in_desc = (int)of_id->data; + if (i >= max_channels) + continue; + dma_cap_zero(cap_mask); dma_cap_set(DMA_MEMCPY, cap_mask); dma_cap_set(DMA_XOR, cap_mask); @@ -1222,7 +1244,7 @@ static int mv_xor_probe(struct platform_device *pdev) i++; } } else if (pdata && pdata->channels) { - for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) { + for (i = 0; i < max_channels; i++) { struct mv_xor_channel_data *cd; struct mv_xor_chan *chan; int irq;