Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752963AbbLCWYc (ORCPT ); Thu, 3 Dec 2015 17:24:32 -0500 Received: from smtprelay0076.hostedemail.com ([216.40.44.76]:37792 "EHLO smtprelay.hostedemail.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751967AbbLCWYa (ORCPT ); Thu, 3 Dec 2015 17:24:30 -0500 X-Session-Marker: 726F737465647440676F6F646D69732E6F7267 X-Spam-Summary: 2,0,0,,d41d8cd98f00b204,rostedt@goodmis.org,:::::::::::::,RULES_HIT:41:355:379:541:800:960:966:968:973:988:989:1260:1277:1311:1313:1314:1345:1437:1515:1516:1518:1534:1542:1593:1594:1711:1730:1747:1777:1792:2194:2196:2198:2199:2200:2201:2393:2553:2559:2562:2693:2731:2741:3138:3139:3140:3141:3142:3165:3354:3865:3866:3867:3868:3870:3871:3872:3874:4321:4385:4605:5007:6120:6261:7901:7903:10004:10400:10848:11026:11473:11658:11914:12043:12114:12438:12517:12519:12555:14096:14097:14659:21080:30012:30054:30070:30090,0,RBL:none,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fn,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:2,LUA_SUMMARY:none X-HE-Tag: join91_444a2b580b241 X-Filterd-Recvd-Size: 3519 Date: Thu, 3 Dec 2015 17:24:28 -0500 From: Steven Rostedt To: LKML Cc: Ingo Molnar , Peter Zijlstra , Andrew Morton , Rusty Russell , Sergey Senozhatsky , Xunlei Pang Subject: [RFC][PATCH] Add __GFP_ZERO to alloc_cpumask_var_node() if ptr is zero Message-ID: <20151203172428.600f380a@gandalf.local.home> X-Mailer: Claws Mail 3.13.0 (GTK+ 2.24.28; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2807 Lines: 65 Xunlei Pang reported a bug in the scheduler code when CONFIG_CPUMASK_OFFSTACK is set, several of the cpumasks used by the root domains can contain garbage. The code does the following: memset(rd, 0, sizeof(*rd)); if (!alloc_cpumask_var(&rd->span, GFP_KERNEL)) goto out; if (!alloc_cpumask_var(&rd->online, GFP_KERNEL)) goto free_span; if (!alloc_cpumask_var(&rd->dlo_mask, GFP_KERNEL)) goto free_online; if (!alloc_cpumask_var(&rd->rto_mask, GFP_KERNEL)) goto free_dlo_mask; When CONFIG_CPUMASK_OFFSTACK is not defined, the four cpumasks are part of the 'rd' structure, and the memset() will zero them all out. But when CONFIG_CPUMASK_OFFSTACK is enabled, those cpumasks are no longer set by the memset() but are allocated independently. That allocation may contain garbage. In order to make alloc_cpumask_var() and friends behave the same with respect to being zero or not whether or not CONFIG_CPUMASK_OFFSTACK is defined, a check is made to the contents of the mask pointer. If the contents of the mask pointer is zero, it is assumed that the value was zeroed out before and __GFP_ZERO is added to the flags for allocation to make the returned cpumasks already zeroed. Calls to alloc_cpumask_var() are not done in performance critical paths, and even if they are, zeroing them out shouldn't add much overhead to it. The up side to this change is that we remove subtle bugs when enabling CONFIG_CPUMASK_OFFSTACK with cpumask logic that worked fined when that config was not enabled. Signed-off-by: Steven Rostedt --- diff --git a/lib/cpumask.c b/lib/cpumask.c index 5a70f6196f57..c0d68752a8b9 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c @@ -60,6 +60,19 @@ int cpumask_any_but(const struct cpumask *mask, unsigned int cpu) */ bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node) { + /* + * When CONFIG_CPUMASK_OFFSTACK is not set, the cpumask may + * be zeroed by a memset of the structure that contains the + * mask. But if CONFIG_CPUMASK_OFFSTACK is then enabled, + * the mask may end up containing garbage. By checking + * if the pointer of the mask is already zero, we can assume + * that the mask itself should be allocated to contain all + * zeros as well. This will prevent subtle bugs by the + * inconsistency of the config being set or not. + */ + if ((long)*mask == 0) + flags |= __GFP_ZERO; + *mask = kmalloc_node(cpumask_size(), flags, node); #ifdef CONFIG_DEBUG_PER_CPU_MAPS -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/