From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 40EEBEE4993 for ; Tue, 22 Aug 2023 17:12:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231938AbjHVRMT (ORCPT ); Tue, 22 Aug 2023 13:12:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49966 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229668AbjHVRMR (ORCPT ); Tue, 22 Aug 2023 13:12:17 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D1689CFF for ; Tue, 22 Aug 2023 10:12:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=In-Reply-To:Content-Type:MIME-Version: References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=pAvdzBr8xJbkKP9oGhwJOhkcjpuEd8zfm5pqt9FtdRs=; b=Ekgm6EikmR6wKxMWvcB5lAVHZ/ zawmmDfz/wu1BrkzlQ8UHJuvsLyQtemb2FLLRSqAE2KClRiAuT/k0scuv438iGVvV8L1mQTRuHRWO Shsqm2mDcbzwB30feJKklUNzNbpwc8jrgvxcv0QCRlVxDY4v1bzeBmmewrsd7tnEQXONbsmXunzLQ su8FI2nZL7i61j+44TosPFs9DXpjd4bLTTXKiscLeV2oDz0TiWHSylDwNgEbiaTNyUfXMg5Zl5JK0 vsZ1ob2lV0EdArVXGwa0aNNxXD2xuTOXm8ylHBj+yDppn2CgYsz5gtfEaWNzAcnIL90w2RpPTvMq3 EwYSaX8A==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1qYUvK-00HVGo-83; Tue, 22 Aug 2023 17:12:10 +0000 Date: Tue, 22 Aug 2023 18:12:10 +0100 From: Matthew Wilcox To: "Russell King (Oracle)" Cc: Marek Szyprowski , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Andrew Morton , Mike Rapoport Subject: Re: [PATCH] arm: dma-mapping: don't call folio_next() beyond the requested region Message-ID: References: <20230810091955.3579004-1-m.szyprowski@samsung.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Aug 10, 2023 at 12:06:09PM +0100, Russell King (Oracle) wrote: > However, consider what happens with the above when offset is larger > than the first folio size. To show this, let's rewrite it: Hmm. I thought 'off' had to be smaller than PAGE_SIZE. > So, in all, to me it looks like this conversion is basically wrong, and it > needs to be something like: > > size_t left = size; > > while (off >= folio_size(folio)) { > off -= folio_size(folio); > folio = folio_next(folio); > } We can jump straight to the first folio without iterating over the folios in between. Like so: static void __dma_page_dev_to_cpu(struct page *page, unsigned long off, size_t size, enum dma_data_direction dir) { phys_addr_t paddr = page_to_phys(page) + off; ... if (dir != DMA_TO_DEVICE && size >= PAGE_SIZE) { struct folio *folio = pfn_folio(paddr / PAGE_SIZE); size_t offset = offset_in_folio(folio, paddr); for (;;) { size_t sz = folio_size(folio) - offset; if (size < sz) break; if (!offset) set_bit(PG_dcache_clean, &folio->flags); offset = 0; size -= sz; if (!size) break; folio = folio_next(folio); } } Advantages: * No more signed arithmetic * Not even an intended arithmetic overflow * Only one call to folio_size() per loop * Folded the first conditional into the loop Disadvantages: * Some maintainers don't like a for (;;) loop, or a two-exit loop. (we could remove the for (;;) by moving 'sz' outside the loop and recalculating it at the end of the loop)