From patchwork Wed Jun 1 13:30:11 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 840152 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.3) with ESMTP id p51DUUvZ002974 for ; Wed, 1 Jun 2011 13:30:31 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756806Ab1FANaU (ORCPT ); Wed, 1 Jun 2011 09:30:20 -0400 Received: from perceval.ideasonboard.com ([95.142.166.194]:50554 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755438Ab1FANaQ (ORCPT ); Wed, 1 Jun 2011 09:30:16 -0400 Received: from localhost.localdomain (unknown [91.178.85.245]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 56A9835998; Wed, 1 Jun 2011 13:30:15 +0000 (UTC) From: Laurent Pinchart To: linux-omap@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Subject: [PATCH v3 1/2] omap3: iovmm: Work around sg_alloc_table size limitation in IOMMU Date: Wed, 1 Jun 2011 15:30:11 +0200 Message-Id: <1306935012-12406-1-git-send-email-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <20110601131744.GH11352@atomide.com> References: <20110601131744.GH11352@atomide.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Wed, 01 Jun 2011 13:30:31 +0000 (UTC) sg_alloc_table can only allocate multi-page scatter-gather list tables if the architecture supports scatter-gather lists chaining. ARM doesn't fit in that category. The IOMMU driver abuses the sg table structure only to hold page addresses without ever passing the table to the device. Use __sg_alloc_table instead of sg_alloc_table and allocate all entries in one go. Otherwise trying to use a large userspace buffers to capture video will hit a BUG_ON in __sg_alloc_table. Signed-off-by: Laurent Pinchart Acked-by: Hiroshi DOYU --- arch/arm/plat-omap/iovmm.c | 14 ++++++++++++-- 1 files changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 51ef43e..b82cef4 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -121,6 +121,16 @@ static unsigned sgtable_nents(size_t bytes, u32 da, u32 pa) return nr_entries; } +static struct scatterlist *sg_alloc(unsigned int nents, gfp_t gfp_mask) +{ + return kmalloc(nents * sizeof(struct scatterlist), gfp_mask); +} + +static void sg_free(struct scatterlist *sg, unsigned int nents) +{ + kfree(sg); +} + /* allocate and initialize sg_table header(a kind of 'superblock') */ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags, u32 da, u32 pa) @@ -146,7 +156,7 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags, if (!sgt) return ERR_PTR(-ENOMEM); - err = sg_alloc_table(sgt, nr_entries, GFP_KERNEL); + err = __sg_alloc_table(sgt, nr_entries, -1, GFP_KERNEL, sg_alloc); if (err) { kfree(sgt); return ERR_PTR(err); @@ -163,7 +173,7 @@ static void sgtable_free(struct sg_table *sgt) if (!sgt) return; - sg_free_table(sgt); + __sg_free_table(sgt, -1, sg_free); kfree(sgt); pr_debug("%s: sgt:%p\n", __func__, sgt);