From patchwork Thu Jun 23 10:05:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 102112 Delivered-To: patch@linaro.org Received: by 10.140.28.4 with SMTP id 4csp346790qgy; Thu, 23 Jun 2016 03:04:35 -0700 (PDT) X-Received: by 10.98.26.148 with SMTP id a142mr41183065pfa.46.1466676275781; Thu, 23 Jun 2016 03:04:35 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w69si6059094pfd.81.2016.06.23.03.04.35; Thu, 23 Jun 2016 03:04:35 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751872AbcFWKEd (ORCPT + 30 others); Thu, 23 Jun 2016 06:04:33 -0400 Received: from mout.kundenserver.de ([212.227.17.10]:56049 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750960AbcFWKEc (ORCPT ); Thu, 23 Jun 2016 06:04:32 -0400 Received: from wuerfel.lan. ([78.42.132.4]) by mrelayeu.kundenserver.de (mreue101) with ESMTPA (Nemesis) id 0MOAtg-1bLVf50skO-005YoG; Thu, 23 Jun 2016 12:03:15 +0200 From: Arnd Bergmann To: Mel Gorman Cc: Vlastimil Babka , Johannes Weiner , Rik van Riel , Andrew Morton , linux-mm@kvack.org, linux-kernel@vger.kernel.org, Arnd Bergmann Subject: [RFC, DEBUGGING 2/2] mm: add type checking for page state functions Date: Thu, 23 Jun 2016 12:05:18 +0200 Message-Id: <20160623100518.156662-2-arnd@arndb.de> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20160623100518.156662-1-arnd@arndb.de> References: <20160623100518.156662-1-arnd@arndb.de> X-Provags-ID: V03:K0:mRerk8gP7bbFfs3YWa8iiWunLqpofeGe3Xzz+Ybp/UXa+mrEcBE gq5kyvDHi2qDI+wVULTSW1nSzXn/v6i80oaqwaW7qn9nlzvXdtgspmzEY1RZoxvbOjs+Vf5 yV+v/UMLQsg4QkEeprseS5YlkX+fU36guj4oDwRzOLKBadfj4Facwth/Cz9rH9acHEM28By IeheYq+Zwg+C0ZQMLXhaA== X-UI-Out-Filterresults: notjunk:1; V01:K0:LrEGeCGlcZU=:/V9TMK+z8HHB3zunhbWpVc NDrN3utgpmaBZqk5YRPL1sByL2TSmSXDzl4VW27Itb4w56rV6RoetJ2o+NcUo4fXwgjYC3ZMr orJOYjyt2cJgoR1LO4Q68EfpyYUkFmR6mZu2Rt50cHIRIrDhmrfP9SiNuD3tKQTZqCbxghYyN QmYqe4DqwTE0TsWDxL9zlJdc93VTabwM6cSaauKLzVMYqwH2e3X4VCBzvVmxJ5auK0Vilwg2O gm+kpmPVb7IxiUVaCMXQUf+31wOFnood78g6BNEIni5D2MCgk7OMi3vpZgYWjBG4zpkLboufL Sj9SNSIJnmca7H5F2DgZko6v4c0oTuMooPeSoIOaNssXZ7cePI2JwOG5rNvBnjIOocX6VTSsL vGUeR7l9YkiEAawDcukxrFcIgowZ+xcK8SN16E+inNgiMDN8Cl+vdrGhYbkbnA1+pbWamoq8n ZN55WZ51PU+S8/asGQWOAmrkn3p8OMG1IC+fYoAHl02UaVnoIz+zQh+ZrppfpUJ15Ec8EvFLu /vqGBbzm2CVb1aq1s52kIcjOZk+cMJVZucKaT29v71wv0LJjLX6LE1V5zT1gDe2wylUsiIHc3 4P4ZyzaMKMpukTbaVGoAN8XRY+nw/JI0AEem0Q9zHMp1VYpwBj1KVvU5FoqDOeR/thlAhOLNC lG5ytMqGVhPzvPjsnD8E3Zgu7vb6qDBJpQlDwDaebbzTkanF1frIZQbNr8lb1Pd7/8iE= Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We had a couple of bugs where we pass the incorrect 'enum' into one of the statistics functions, and unfortunately gcc can only warn about comparing distinct enum types rather than warning about passing an enum of the wrong type into a function. This wraps all the stats calls inside of macros that add the type checking using a comparison. This is a fairly crude method, but it helped uncover some issues for me. Signed-off-by: Arnd Bergmann --- include/linux/vmstat.h | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) -- 2.9.0 diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index c799073fe1c4..0328858894a5 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -116,6 +116,8 @@ static inline void zone_page_state_add(long x, struct zone *zone, atomic_long_add(x, &zone->vm_stat[item]); atomic_long_add(x, &vm_zone_stat[item]); } +#define zone_page_state_add(x, zone, item) \ + zone_page_state_add(x, zone, ((item) == (enum zone_stat_item )0) ? (item) : (item)) static inline void node_page_state_add(long x, struct pglist_data *pgdat, enum node_stat_item item) @@ -123,6 +125,8 @@ static inline void node_page_state_add(long x, struct pglist_data *pgdat, atomic_long_add(x, &pgdat->vm_stat[item]); atomic_long_add(x, &vm_node_stat[item]); } +#define node_page_state_add(x, node, item) \ + node_page_state_add(x, node, ((item) == (enum node_stat_item )0) ? (item) : (item)) static inline unsigned long global_page_state(enum zone_stat_item item) { @@ -133,6 +137,8 @@ static inline unsigned long global_page_state(enum zone_stat_item item) #endif return x; } +#define global_page_state(item) \ + global_page_state(((item) == (enum zone_stat_item )0) ? (item) : (item)) static inline unsigned long global_node_page_state(enum node_stat_item item) { @@ -143,6 +149,8 @@ static inline unsigned long global_node_page_state(enum node_stat_item item) #endif return x; } +#define global_node_page_state(item) \ + global_node_page_state(((item) == (enum node_stat_item )0) ? (item) : (item)) static inline unsigned long zone_page_state(struct zone *zone, enum zone_stat_item item) @@ -154,6 +162,8 @@ static inline unsigned long zone_page_state(struct zone *zone, #endif return x; } +#define zone_page_state(zone, item) \ + zone_page_state(zone, ((item) == (enum zone_stat_item )0) ? (item) : (item)) /* * More accurate version that also considers the currently pending @@ -176,6 +186,8 @@ static inline unsigned long zone_page_state_snapshot(struct zone *zone, #endif return x; } +#define zone_page_state_snapshot(zone, item) \ + zone_page_state_snapshot(zone, ((item) == (enum zone_stat_item )0) ? (item) : (item)) static inline unsigned long node_page_state_snapshot(pg_data_t *pgdat, enum zone_stat_item item) @@ -192,7 +204,8 @@ static inline unsigned long node_page_state_snapshot(pg_data_t *pgdat, #endif return x; } - +#define node_page_state_snapshot(zone, item) \ + node_page_state_snapshot(zone, ((item) == (enum node_stat_item )0) ? (item) : (item)) #ifdef CONFIG_NUMA extern unsigned long sum_zone_node_page_state(int node, @@ -341,6 +354,27 @@ static inline void drain_zonestat(struct zone *zone, struct per_cpu_pageset *pset) { } #endif /* CONFIG_SMP */ +#define __mod_zone_page_state(zone, item, delta) \ + __mod_zone_page_state(zone, ((item) == (enum zone_stat_item )0) ? (item) : (item), delta) +#define __mod_node_page_state(pgdat, item, delta) \ + __mod_node_page_state(pgdat, ((item) == (enum node_stat_item )0) ? (item) : (item), delta) +#define __inc_zone_state(zone, item) \ + __inc_zone_state(zone, ((item) == (enum zone_stat_item )0) ? (item) : (item)) +#define __inc_node_state(pgdat, item) \ + __inc_node_state(pgdat, ((item) == (enum node_stat_item )0) ? (item) : (item)) +#define __dec_zone_state(zone, item) \ + __dec_zone_state(zone, ((item) == (enum zone_stat_item )0) ? (item) : (item)) +#define __dec_node_state(pgdat, item) \ + __dec_node_state(pgdat, ((item) == (enum node_stat_item )0) ? (item) : (item)) +#define __inc_zone_page_state(page, item) \ + __inc_zone_page_state(page, ((item) == (enum zone_stat_item )0) ? (item) : (item)) +#define __inc_node_page_state(page, item) \ + __inc_node_page_state(page, ((item) == (enum node_stat_item )0) ? (item) : (item)) +#define __dec_zone_page_state(page, item) \ + __dec_zone_page_state(page, ((item) == (enum zone_stat_item )0) ? (item) : (item)) +#define __dec_node_page_state(page, item) \ + __dec_node_page_state(page, ((item) == (enum node_stat_item )0) ? (item) : (item)) + static inline void __mod_zone_freepage_state(struct zone *zone, int nr_pages, int migratetype) {