From patchwork Fri Aug 2 14:19:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda Delgado X-Patchwork-Id: 2837951 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 632289F492 for ; Fri, 2 Aug 2013 14:20:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 325B42042C for ; Fri, 2 Aug 2013 14:20:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 478632042A for ; Fri, 2 Aug 2013 14:20:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753692Ab3HBOUM (ORCPT ); Fri, 2 Aug 2013 10:20:12 -0400 Received: from mail-lb0-f181.google.com ([209.85.217.181]:34722 "EHLO mail-lb0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753674Ab3HBOUJ (ORCPT ); Fri, 2 Aug 2013 10:20:09 -0400 Received: by mail-lb0-f181.google.com with SMTP id o10so494746lbi.12 for ; Fri, 02 Aug 2013 07:20:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=KmHCRmCNggRaRcMKW/CoKuTCG4Pkd9zNAhy8BLnAqaY=; b=FmAqjSQ8eQKbHpQ0WlA5+f2fhvdih4IdqYN4odq+mupXH3i+DDRDZSITaYVTi7gm15 HJgXtjBs+sP+3BosLtuaVkPOVYG6/OmwD0pIHghv3fDmdCLh1xP1PvlkTWqBnGX+rxf4 vyqsp1Noxbf1JBRAbh9x/xCz5GW3GSkSrby5dq/WHrK/RrtlatqeNpYdaz8mH2yl60bk 7B5djFxTNDuM3U0snwfOMiBfZ9VBUmW9Rq+GszZ8jn84GapAIGpKvy7Yds4AdALwWRMV SKO4SdFF2GIFF7DSdg8Jjmqt09jx3zrRG5WEAao/Cx/N2RRJ3rC1YRUg/U6Spm0OLqOn 5QbA== X-Received: by 10.112.130.6 with SMTP id oa6mr3607638lbb.62.1375453208330; Fri, 02 Aug 2013 07:20:08 -0700 (PDT) Received: from localhost (0x4dd4aed9.adsl.cybercity.dk. [77.212.174.217]) by mx.google.com with ESMTPSA id w9sm3381977lbk.7.2013.08.02.07.20.06 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 02 Aug 2013 07:20:07 -0700 (PDT) From: Ricardo Ribalda Delgado To: Jonathan Corbet , Mauro Carvalho Chehab , Pawel Osciak , Marek Szyprowski , Kyungmin Park , Ismael Luceno , Greg Kroah-Hartman , linux-media@vger.kernel.org, Sylwester Nawrocki Cc: Ricardo Ribalda Delgado Subject: [PATCH v4 1/2] videobuf2-dma-sg: Allocate pages as contiguous as possible Date: Fri, 2 Aug 2013 16:19:59 +0200 Message-Id: <1375453200-28459-2-git-send-email-ricardo.ribalda@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1375453200-28459-1-git-send-email-ricardo.ribalda@gmail.com> References: <1375453200-28459-1-git-send-email-ricardo.ribalda@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-8.2 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Most DMA engines have limitations regarding the number of DMA segments (sg-buffers) that they can handle. Videobuffers can easily spread through hundreds of pages. In the previous aproach, the pages were allocated individually, this could led to the creation houndreds of dma segments (sg-buffers) that could not be handled by some DMA engines. This patch tries to minimize the number of DMA segments by using alloc_pages. In the worst case it will behave as before, but most of the times it will reduce the number of dma segments Acked-by: Marek Szyprowski Reviewed-by: Andre Heider Signed-off-by: Ricardo Ribalda Delgado --- drivers/media/v4l2-core/videobuf2-dma-sg.c | 60 +++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 16ae3dc..4999c48 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -42,10 +42,55 @@ struct vb2_dma_sg_buf { static void vb2_dma_sg_put(void *buf_priv); +static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf, + gfp_t gfp_flags) +{ + unsigned int last_page = 0; + int size = buf->sg_desc.size; + + while (size > 0) { + struct page *pages; + int order; + int i; + + order = get_order(size); + /* Dont over allocate*/ + if ((PAGE_SIZE << order) > size) + order--; + + pages = NULL; + while (!pages) { + pages = alloc_pages(GFP_KERNEL | __GFP_ZERO | + __GFP_NOWARN | gfp_flags, order); + if (pages) + break; + + if (order == 0) { + while (last_page--) + __free_page(buf->pages[last_page]); + return -ENOMEM; + } + order--; + } + + split_page(pages, order); + for (i = 0; i < (1 << order); i++) { + buf->pages[last_page] = &pages[i]; + sg_set_page(&buf->sg_desc.sglist[last_page], + buf->pages[last_page], PAGE_SIZE, 0); + last_page++; + } + + size -= PAGE_SIZE << order; + } + + return 0; +} + static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_flags) { struct vb2_dma_sg_buf *buf; - int i; + int ret; buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) @@ -69,14 +114,9 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_fla if (!buf->pages) goto fail_pages_array_alloc; - for (i = 0; i < buf->sg_desc.num_pages; ++i) { - buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO | - __GFP_NOWARN | gfp_flags); - if (NULL == buf->pages[i]) - goto fail_pages_alloc; - sg_set_page(&buf->sg_desc.sglist[i], - buf->pages[i], PAGE_SIZE, 0); - } + ret = vb2_dma_sg_alloc_compacted(buf, gfp_flags); + if (ret) + goto fail_pages_alloc; buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_dma_sg_put; @@ -89,8 +129,6 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_fla return buf; fail_pages_alloc: - while (--i >= 0) - __free_page(buf->pages[i]); kfree(buf->pages); fail_pages_array_alloc: