From patchwork Tue May 1 13:26:21 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Vorontsov X-Patchwork-Id: 8318 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 35E9923E9A for ; Tue, 1 May 2012 13:27:44 +0000 (UTC) Received: from mail-yx0-f180.google.com (mail-yx0-f180.google.com [209.85.213.180]) by fiordland.canonical.com (Postfix) with ESMTP id E3BFDA1829D for ; Tue, 1 May 2012 13:27:43 +0000 (UTC) Received: by yenl4 with SMTP id l4so2232764yen.11 for ; Tue, 01 May 2012 06:27:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:date:from :to:cc:subject:message-id:references:mime-version:content-type :content-disposition:in-reply-to:user-agent:x-gm-message-state; bh=3b8C187Dg6K44jK2zjmJVF1FUe+2bgx2FNSub9cXn8E=; b=nLTCSe+qeWntZeM4s8AGnTCTMW8Dmis6yLCgrMIhvytOE82TzQefCiDbOajtIYJIiU NpNI93I+EQEyT56WrRaPAbpax8Iku+Z0Qy8NpOrMz/AX93I4S+RvwMe7bZBohLplMWz7 bPq4NhKSWtJiWZZlyUqYCs4wnv486qd3L4JuK0B2HgoKauBK3byV6TAht4nkIJ10vkZM qrpojtD/C2S75hKVtyFOCo8Fs/jVVyqb7Bsh1NnNSL9zHYv5KG7BTTm1P+UGFITNjh8Z wKKyDnNUOlL5xGooM+MjjfjlGye0sUbODJ6hr9WpQI/rlCZt//Mpjmr9vP9PHNNGOG// YyAg== Received: by 10.50.57.129 with SMTP id i1mr1806692igq.33.1335878863214; Tue, 01 May 2012 06:27:43 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.137.198 with SMTP id x6csp180810ibt; Tue, 1 May 2012 06:27:42 -0700 (PDT) Received: by 10.68.191.228 with SMTP id hb4mr262214pbc.97.1335878862509; Tue, 01 May 2012 06:27:42 -0700 (PDT) Received: from mail-pb0-f50.google.com (mail-pb0-f50.google.com [209.85.160.50]) by mx.google.com with ESMTPS id p7si18305037pbk.314.2012.05.01.06.27.42 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 01 May 2012 06:27:42 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.160.50 is neither permitted nor denied by best guess record for domain of anton.vorontsov@linaro.org) client-ip=209.85.160.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.160.50 is neither permitted nor denied by best guess record for domain of anton.vorontsov@linaro.org) smtp.mail=anton.vorontsov@linaro.org Received: by mail-pb0-f50.google.com with SMTP id xa12so5766477pbc.37 for ; Tue, 01 May 2012 06:27:42 -0700 (PDT) Received: by 10.68.216.101 with SMTP id op5mr8668918pbc.10.1335878862288; Tue, 01 May 2012 06:27:42 -0700 (PDT) Received: from localhost (c-71-204-165-222.hsd1.ca.comcast.net. [71.204.165.222]) by mx.google.com with ESMTPS id ux5sm19306656pbc.4.2012.05.01.06.27.40 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 01 May 2012 06:27:41 -0700 (PDT) Date: Tue, 1 May 2012 06:26:21 -0700 From: Anton Vorontsov To: Pekka Enberg Cc: Leonid Moiseichuk , John Stultz , linux-mm@kvack.org, linux-kernel@vger.kernel.org, linaro-kernel@lists.linaro.org, patches@linaro.org, kernel-team@android.com Subject: [PATCH 3/3] vmevent: Implement special low-memory attribute Message-ID: <20120501132620.GC24226@lizard> References: <20120501132409.GA22894@lizard> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20120501132409.GA22894@lizard> User-Agent: Mutt/1.5.21 (2010-09-15) X-Gm-Message-State: ALoCoQlVmO+sSLXAzQOI7GZmwkyZ2s5pTcG4wPBEr1cb1+06YDt4Q5IOjr7aUNZb/grFVAn4tAbz This is specially "blended" attribute, the event triggers when kernel decides that we're close to the low memory threshold. Userspace should not expect very precise meaning of low memory situation, mostly, it's just a guess on the kernel's side. Well, this is the same as userland should not know or care how exactly kernel manages the memory, or assume that memory management behaviour is a part of the "ABI". So, all the 'low memory' is just guessing, but we're trying to do our best. It might be that we will end up with two or three variations of 'low memory' thresholds, and all of them would be useful for different use cases. For this implementation, we assume that there's a low memory situation for the N pages threshold when we have neither N pages of completely free pages, nor we have N reclaimable pages in the cache. This effectively means, that if userland expects to allocate N pages, it would consume all the free pages, and any further allocations (above N) would start draining caches. In the worst case, prior to hitting the threshold, we might have only N pages in cache, and nearly no memory as free pages. The same 'low memory' meaning is used in the current Android Low Memory Killer driver. Signed-off-by: Anton Vorontsov --- include/linux/vmevent.h | 7 ++++++ mm/vmevent.c | 40 ++++++++++++++++++++++++++++++++++ tools/testing/vmevent/vmevent-test.c | 12 +++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/include/linux/vmevent.h b/include/linux/vmevent.h index aae0d24..9bfa244 100644 --- a/include/linux/vmevent.h +++ b/include/linux/vmevent.h @@ -10,6 +10,13 @@ enum { VMEVENT_ATTR_NR_AVAIL_PAGES = 1UL, VMEVENT_ATTR_NR_FREE_PAGES = 2UL, VMEVENT_ATTR_NR_SWAP_PAGES = 3UL, + /* + * This is specially blended attribute, the event triggers + * when kernel decides that we're close to the low memory threshold. + * Don't expect very precise meaning of low memory situation, mostly, + * it's just a guess on the kernel's side. + */ + VMEVENT_ATTR_LOWMEM_PAGES = 4UL, VMEVENT_ATTR_MAX /* non-ABI */ }; diff --git a/mm/vmevent.c b/mm/vmevent.c index b312236..d278a25 100644 --- a/mm/vmevent.c +++ b/mm/vmevent.c @@ -68,10 +68,50 @@ static u64 vmevent_attr_avail_pages(struct vmevent_watch *watch, return totalram_pages; } +/* + * Here's some implementation details for the "low memory" meaning. + * + * (The explanation is not in the header file as userland should not + * know these details, nor it should assume that the meaning will + * always be the same. As well as it should not know how exactly kernel + * manages the memory, or assume that memory management behaviour is a + * part of the "ABI". So, all the 'low memory' is just guessing, but + * we're trying to do our best.) + * + * For this implementation, we assume that there's a low memory situation + * for the N pages threshold when we have neither N pages of completely + * free pages, nor we have N reclaimable pages in the cache. This + * effectively means, that if userland expects to allocate N pages, it + * would consume all the free pages, and any further allocations (above + * N) would start draining caches. + * + * In the worst case, prior hitting the threshold, we might have only + * N pages in cache, and nearly no memory as free pages. + */ +static u64 vmevent_attr_lowmem_pages(struct vmevent_watch *watch, + struct vmevent_attr *attr) +{ + int free = global_page_state(NR_FREE_PAGES); + int file = global_page_state(NR_FILE_PAGES) - + global_page_state(NR_SHMEM); /* TODO: account locked pages */ + int val = attr->value; + + /* + * For convenience we return 0 or attr value (instead of 0/1), it + * makes it easier for vmevent_match() to cope with blended + * attributes, plus userland might use the value to find out which + * threshold triggered. + */ + if (free < val && file < val) + return val; + return 0; +} + static vmevent_attr_sample_fn attr_samplers[] = { [VMEVENT_ATTR_NR_AVAIL_PAGES] = vmevent_attr_avail_pages, [VMEVENT_ATTR_NR_FREE_PAGES] = vmevent_attr_free_pages, [VMEVENT_ATTR_NR_SWAP_PAGES] = vmevent_attr_swap_pages, + [VMEVENT_ATTR_LOWMEM_PAGES] = vmevent_attr_lowmem_pages, }; static u64 vmevent_sample_attr(struct vmevent_watch *watch, struct vmevent_attr *attr) diff --git a/tools/testing/vmevent/vmevent-test.c b/tools/testing/vmevent/vmevent-test.c index fd9a174..c61aed7 100644 --- a/tools/testing/vmevent/vmevent-test.c +++ b/tools/testing/vmevent/vmevent-test.c @@ -33,7 +33,7 @@ int main(int argc, char *argv[]) config = (struct vmevent_config) { .sample_period_ns = 1000000000L, - .counter = 6, + .counter = 7, .attrs = { { .type = VMEVENT_ATTR_NR_FREE_PAGES, @@ -59,6 +59,13 @@ int main(int argc, char *argv[]) .type = VMEVENT_ATTR_NR_SWAP_PAGES, }, { + .type = VMEVENT_ATTR_LOWMEM_PAGES, + .state = VMEVENT_ATTR_STATE_VALUE_LT | + VMEVENT_ATTR_STATE_VALUE_EQ | + VMEVENT_ATTR_STATE_ONE_SHOT, + .value = phys_pages / 2, + }, + { .type = 0xffff, /* invalid */ }, }, @@ -108,6 +115,9 @@ int main(int argc, char *argv[]) case VMEVENT_ATTR_NR_SWAP_PAGES: printf(" VMEVENT_ATTR_NR_SWAP_PAGES: %Lu\n", attr->value); break; + case VMEVENT_ATTR_LOWMEM_PAGES: + printf(" VMEVENT_ATTR_LOWMEM_PAGES: %Lu\n", attr->value); + break; default: printf(" Unknown attribute: %Lu\n", attr->value); }