From patchwork Wed May 22 11:55:11 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 2601441 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) by patchwork2.kernel.org (Postfix) with ESMTP id 2588CDF215 for ; Wed, 22 May 2013 11:56:00 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Uf7e8-0007BU-Kk; Wed, 22 May 2013 11:55:56 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Uf7e5-0006ac-TK; Wed, 22 May 2013 11:55:53 +0000 Received: from mail-pb0-x22e.google.com ([2607:f8b0:400e:c01::22e]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Uf7e2-0006a7-Km for linux-arm-kernel@lists.infradead.org; Wed, 22 May 2013 11:55:51 +0000 Received: by mail-pb0-f46.google.com with SMTP id rq2so1614825pbb.33 for ; Wed, 22 May 2013 04:55:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer; bh=+sCMOChxrmfAor7aND/iEuvtIAnsZVDzX7HLfTL6xkY=; b=pL9nsSjVkatyUVpDVtrE72RJniv9xwATKoKbiUDcWuLvluwlYBZg4LylOiO9QJkcrf ClfzCDtKmD6vztr0zijyTVQ+0SaRxGNAtVL0HLsgK0THTkPfyeE1eAW0+apaheZ4IHI+ MTZDr1uxrQzd6dYH7hA4Vm4J5EZeZ4IYDLM1jSZuEAEU39Jj5fNEWEU6oA++IRdOuIrX PFyMvT4Fq0x2znvxb261RjNfl9iRfo+xm9eD/8L24ZGyR9E14MgQMv4RZe6yog4EWpcJ MnLVjjnyEKFPjWiIqAAgmdeEtHrYVQlz6qF85SujRaXWtX9EsLtUPSzuT8HGl9nZ73dE /hLg== X-Received: by 10.68.191.167 with SMTP id gz7mr7605422pbc.16.1369223727744; Wed, 22 May 2013 04:55:27 -0700 (PDT) Received: from localhost ([183.37.214.135]) by mx.google.com with ESMTPSA id rn7sm6992248pbc.12.2013.05.22.04.55.21 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 22 May 2013 04:55:26 -0700 (PDT) From: Ming Lei To: linux-arm-kernel@lists.infradead.org Subject: [RFC PATCH] ARM: mm: lazy cache flushing on non-mapped pages Date: Wed, 22 May 2013 19:55:11 +0800 Message-Id: <1369223711-2995-1-git-send-email-ming.lei@canonical.com> X-Mailer: git-send-email 1.7.9.5 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130522_075550_778878_70D8A046 X-CRM114-Status: GOOD ( 15.12 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (tom.leiming[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.0 TO_NO_BRKTS_PCNT To: misformatted + percentage Cc: Nicolas Pitre , Russell King , Catalin Marinas , Ming Lei , Will Deacon , Andrew Morton , Michel Lespinasse X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Currently flush_dcache_page() thinks pages as non-mapped if mapping_mapped(mapping) return false. This approach is very coase: - mmap on part of file may cause all pages backed on the file being thought as mmaped - file-backed pages aren't mapped into user space actually if the memory mmaped on the file isn't accessed This patch also uses page_mapcount() to decide if the page has been mapped. From the attached test code, we can see there is much performance improvement(>25%) when accessing page caches via read under this situations, so memcpy benefits a lot from not flushing cache under this situations. Seq. read time without the patch Seq. read time with the patch ================================================================ No. 0, time 22615636 us No. 0, time 22014717 us No. 1, time 4387851 us No. 1, time 3113184 us No. 2, time 4276535 us No. 2, time 3005244 us No. 3, time 4259821 us No. 3, time 3001565 us No. 4, time 4263811 us No. 4, time 3002748 us No. 5, time 4258486 us No. 5, time 3004104 us No. 6, time 4253009 us No. 6, time 3002188 us No. 7, time 4262809 us No. 7, time 2998196 us No. 8, time 4264525 us No. 8, time 3007255 us No. 9, time 4267795 us No. 9, time 3005094 us 1), No.0. is to read the file from storage device, and others are to read the file from page caches basically. 2), file size is 512M, and is on ext4 over usb mass storage. 3), the test is done on Pandaboard. unsigned int sum = 0; unsigned long sum_val = 0; static unsigned long tv_diff(struct timeval *tv1, struct timeval *tv2) { return (tv2->tv_sec - tv1->tv_sec) * 1000000 + (tv2->tv_usec - tv1->tv_usec); } int main(int argc, char *argv[]) { char *mbuf, fbuf; int fd; int i; unsigned long page_size, size; struct stat stat; struct timeval t1, t2; unsigned char *rbuf = malloc(32 * page_size); if (!rbuf) { printf(" %s\n", "malloc failed"); exit(-1); } page_size = getpagesize(); fd = open(argv[1], O_RDWR); assert(fd >= 0); fstat(fd, &stat); size = stat.st_size; printf("%s: file %s, size %lu, page size %lu\n", argv[0], argv[1], size, page_size); gettimeofday(&t1, NULL); mbuf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (!mbuf) { printf(" %s\n", "mmap failed"); exit(-1); } for (i = 0 ; i < size ; i += (page_size * 32)) { int rcnt; lseek(fd, i, SEEK_SET); rcnt = read(fd, rbuf, page_size * 32); if (rcnt != page_size * 32) { printf("%s: read faild\n", __func__); exit(-1); } } free(rbuf); munmap(mbuf, size); gettimeofday(&t2, NULL); printf("\tread mmaped time: %luus\n", tv_diff(&t1, &t2)); close(fd); } Cc: Michel Lespinasse Cc: Andrew Morton Cc: Will Deacon Cc: Nicolas Pitre Cc: Catalin Marinas Cc: Russell King Signed-off-by: Ming Lei --- arch/arm/mm/flush.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 9251d56..1d0e8d5 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -283,8 +283,8 @@ void flush_dcache_page(struct page *page) mapping = page_mapping(page); - if (!cache_ops_need_broadcast() && - mapping && !mapping_mapped(mapping)) + if (!cache_ops_need_broadcast() && mapping && + (!mapping_mapped(mapping) || !page_mapcount(page))) clear_bit(PG_dcache_clean, &page->flags); else { __flush_dcache_page(mapping, page);