From patchwork Wed May 29 14:56:56 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 2630671 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 F15ADDF24C for ; Wed, 29 May 2013 14:57:41 +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 1Uhhoq-0003Va-7w; Wed, 29 May 2013 14:57:40 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Uhhon-0000Rh-Ev; Wed, 29 May 2013 14:57:37 +0000 Received: from mail-pa0-f44.google.com ([209.85.220.44]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Uhhol-0000RM-CL for linux-arm-kernel@lists.infradead.org; Wed, 29 May 2013 14:57:36 +0000 Received: by mail-pa0-f44.google.com with SMTP id wp1so6803322pac.17 for ; Wed, 29 May 2013 07:57:12 -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=IPB7DBi8OMkq5NJhkMgpxVWl8D7yLrSopJTU4QVluds=; b=fs/IzK7FgM8RsX0uPvTctYFT8HSRpIuKjwPwzPXTODliJQH9EgKp2RaYyy/sBWRj7J 99jVQQy1zz2b6TT8iotfA+WSMrcQnxeCDSDcnkVAH4ae4TxlcRHpkSGTdKKVJuGIZ7sf P1oSWtJ9XNrfLIFclZaFh8X1DpoaUHzorXzrfilMcNMNZ5Ewpp0065667YY1TBHAknMW Nt0W10/qZsQ0W6QxQkcPgXYBxQzH9taNy+8e0J6yiuqOQMy6oW7tTRjS9xHVTThvXxlz WxHwwyiGSmcpiaNPf+H6cTWw9x2ug6Q+CIGJ1drLkQI97iwNVqznVPC5O0GGOthA75TI kWdw== X-Received: by 10.66.248.228 with SMTP id yp4mr3735378pac.158.1369839432221; Wed, 29 May 2013 07:57:12 -0700 (PDT) Received: from localhost ([183.37.208.72]) by mx.google.com with ESMTPSA id sg4sm37657032pbc.7.2013.05.29.07.57.05 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 29 May 2013 07:57:11 -0700 (PDT) From: Ming Lei To: linux-arm-kernel@lists.infradead.org Subject: [PATCH V1] ARM: mm: lazy cache flushing on non-mapped pages Date: Wed, 29 May 2013 22:56:56 +0800 Message-Id: <1369839416-27817-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-20130529_105735_492068_5CC37A7C X-CRM114-Status: GOOD ( 16.23 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (tom.leiming[at]gmail.com) -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.220.44 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 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 uses page_mapped() to decide if the page has been mapped. From the attached test code, I find 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 situation. No. read time without the patch No. 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 --- V1: - take Catalin's suggestion to use page_mapped() 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 0d473cc..008af99 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -286,8 +286,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_mapped(page))) clear_bit(PG_dcache_clean, &page->flags); else { __flush_dcache_page(mapping, page);