From patchwork Mon Jun 3 14:44:39 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 2653051 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 B3B60DF24C for ; Mon, 3 Jun 2013 14:46:14 +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 1UjW0x-0000gX-Rv; Mon, 03 Jun 2013 14:45: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 1UjW0f-0001yC-50; Mon, 03 Jun 2013 14:45:21 +0000 Received: from mail-pd0-f182.google.com ([209.85.192.182]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UjW0c-0001xX-4P for linux-arm-kernel@lists.infradead.org; Mon, 03 Jun 2013 14:45:19 +0000 Received: by mail-pd0-f182.google.com with SMTP id g10so5743735pdj.41 for ; Mon, 03 Jun 2013 07:44:56 -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=mbkqo7rvUkFqUF8UrAQB4Bg+o16pKXHlrbvxtB35gck=; b=APvCzr6t4NPdzOE0bHLzzHUA55jVjeFT4VWEVfWyuSSr6uEmC+VWpJRrzrLOe7vRAZ dMMs+UuOlPNM+ftjY0orXmp55WpzWDiD68EBOB84Qs2kNqs5y5RRv+AIlwe2jF23Y5io M7eXqj3H6OKJHt/VHTEFioIDZKwvynbGfC3lO+e5di3qjzCpfJeFBNHYU2TRiKfltOZC KrGOehsG/LhDClXxZWfB7V9z8h0EZw+XLypnAqLhviIDHgv+KDjt6dzZXdUwpYjGzRqO wkFRiuktr3e4QI3T8qa/fIpj178rT1kTRKetRchaWe03AbFzqhjXDj0TlHEux2IHyMOU z74w== X-Received: by 10.68.76.67 with SMTP id i3mr24083314pbw.20.1370270696243; Mon, 03 Jun 2013 07:44:56 -0700 (PDT) Received: from localhost ([183.37.203.73]) by mx.google.com with ESMTPSA id dc3sm20990082pbc.9.2013.06.03.07.44.50 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 03 Jun 2013 07:44:54 -0700 (PDT) From: Ming Lei To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v2] ARM: mm: lazy cache flushing on non-mapped pages Date: Mon, 3 Jun 2013 22:44:39 +0800 Message-Id: <1370270680-729-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-20130603_104518_270679_1DBD01C5 X-CRM114-Status: GOOD ( 15.86 ) X-Spam-Score: 0.3 (/) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (0.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (tom.leiming[at]gmail.com) -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [209.85.192.182 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] 2.2 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 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 Acked-by: Catalin Marinas ================================================================ 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 --- V2: - take Will's suggestion to remove check on !mapping_mapped(mapping) because mapcount of file-backed page always repsents the correct mapping count of the page V1: - take Catalin's suggestion to use page_mapped() arch/arm/mm/flush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 0d473cc..2ff66eb 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -287,7 +287,7 @@ void flush_dcache_page(struct page *page) mapping = page_mapping(page); if (!cache_ops_need_broadcast() && - mapping && !mapping_mapped(mapping)) + mapping && !page_mapped(page)) clear_bit(PG_dcache_clean, &page->flags); else { __flush_dcache_page(mapping, page);