From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751971Ab2KPLXm (ORCPT ); Fri, 16 Nov 2012 06:23:42 -0500 Received: from cantor2.suse.de ([195.135.220.15]:33127 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751883Ab2KPLXh (ORCPT ); Fri, 16 Nov 2012 06:23:37 -0500 From: Mel Gorman To: Peter Zijlstra , Andrea Arcangeli , Ingo Molnar Cc: Rik van Riel , Johannes Weiner , Hugh Dickins , Thomas Gleixner , Linus Torvalds , Andrew Morton , Linux-MM , LKML , Mel Gorman Subject: [PATCH 28/43] mm: numa: Rate limit the amount of memory that is migrated between nodes Date: Fri, 16 Nov 2012 11:22:38 +0000 Message-Id: <1353064973-26082-29-git-send-email-mgorman@suse.de> X-Mailer: git-send-email 1.7.9.2 In-Reply-To: <1353064973-26082-1-git-send-email-mgorman@suse.de> References: <1353064973-26082-1-git-send-email-mgorman@suse.de> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org NOTE: This is very heavily based on similar logic in autonuma. It should be signed off by Andrea but because there was no standalone patch and it's sufficiently different from what he did that the signed-off is omitted. Will be added back if requested. If a large number of pages are misplaced then the memory bus can be saturated just migrating pages between nodes. This patch rate-limits the amount of memory that can be migrating between nodes. Signed-off-by: Mel Gorman --- mm/migrate.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/mm/migrate.c b/mm/migrate.c index 88b9a7e..dac5a43 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1464,12 +1464,21 @@ static struct page *alloc_misplaced_dst_page(struct page *page, } /* + * page migration rate limiting control. + * Do not migrate more than @pages_to_migrate in a @migrate_interval_millisecs + * window of time. Default here says do not migrate more than 1280M per second. + */ +static unsigned int migrate_interval_millisecs __read_mostly = 100; +static unsigned int ratelimit_pages __read_mostly = 128 << (20 - PAGE_SHIFT); + +/* * Attempt to migrate a misplaced page to the specified destination * node. Caller is expected to have an elevated reference count on * the page that will be dropped by this function before returning. */ struct page *migrate_misplaced_page(struct page *page, int node) { + pg_data_t *pgdat = NODE_DATA(node); struct misplaced_request req = { .nid = node, .newpage = NULL, @@ -1484,8 +1493,26 @@ struct page *migrate_misplaced_page(struct page *page, int node) if (page_mapcount(page) != 1) goto out; + /* + * Rate-limit the amount of data that is being migrated to a node. + * Optimal placement is no good if the memory bus is saturated and + * all the time is being spent migrating! + */ + spin_lock(&pgdat->balancenuma_migrate_lock); + if (time_after(jiffies, pgdat->balancenuma_migrate_next_window)) { + pgdat->balancenuma_migrate_nr_pages = 0; + pgdat->balancenuma_migrate_next_window = jiffies + + msecs_to_jiffies(migrate_interval_millisecs); + } + if (pgdat->balancenuma_migrate_nr_pages > ratelimit_pages) { + spin_unlock(&pgdat->balancenuma_migrate_lock); + goto out; + } + pgdat->balancenuma_migrate_nr_pages++; + spin_unlock(&pgdat->balancenuma_migrate_lock); + /* Avoid migrating to a node that is nearly full */ - if (migrate_balanced_pgdat(NODE_DATA(node), 1)) { + if (migrate_balanced_pgdat(pgdat, 1)) { int page_lru; if (isolate_lru_page(page)) { @@ -1521,6 +1548,7 @@ struct page *migrate_misplaced_page(struct page *page, int node) count_vm_numa_event(NUMA_PAGE_MIGRATE); } BUG_ON(!list_empty(&migratepages)); + out: return req.newpage; } -- 1.7.9.2