Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp3222725imm; Sun, 10 Jun 2018 11:07:33 -0700 (PDT) X-Google-Smtp-Source: ADUXVKKHBgjHqQLeEt4qHqRb598aWiYpZu85itKMC1AzzBR2SzQd55DX4BluZzGuQNomkg2dupPZ X-Received: by 2002:a62:1013:: with SMTP id y19-v6mr14305036pfi.166.1528654053173; Sun, 10 Jun 2018 11:07:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528654053; cv=none; d=google.com; s=arc-20160816; b=Mt45cSJeAk5OGPt9vDLSQsUg4Ym74airEmLlZRp3QjrWJq4PPw85lUZ50gxMah/2J0 nTvYqJoJdQn5LDi2b9D1WsQHoXNVfCr4Kg3jw+E6j3ty2np6I4hMuY96yLft2H4+6w3R waf2A34/xmI88I+onwshERKOfuQz66e+ikqTZuMk8q2niaaaB8GLxeSt3IrrHrUS0183 ZRu1s9WBFG0L7fvyKKOlpco+zlOcTiX4KFz3ukP9BnSNj8saLXQqJJkH5lQZaTVl6Mo/ 4naVAflEqX3osDqK7dZAEqSR/VytMjhTb6bO73hMli0N3H1gRW3+uK16+c2M0TT4kqpV 1a1g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :message-id:in-reply-to:subject:cc:to:from:date:dkim-signature :arc-authentication-results; bh=WjEvthiFiuZgBjvWCHDOWrHW4PoRFuIWNG3Pd4GhuEo=; b=iLbqPzaUrIIjCUhmnTyUkPhxTQbAivkncx+94CDVQRFmj44UM0OBhmqbmklMbCPTAH wYmqYDxUwsr+DfWPZ9E6At/UXNDrMD4h7+yChxYOnNoU1rFgdjQmkzq1LeBFKjRfM/cO yULLB3txjBJMVx67MuEVcsDAiRPMS/jCGG0FiOtMcpImvhu10YKbV25B8/Ckd6D6lN2e hHoZvv/Nxui0nEOoDqGxUehFr/mXHCKuU8F3GDYp/Mocx9nhJ182GeaQyoZ6wNSmhjBs 2qfMpsrr74Tj9KQdwf1cuQdHE1wL7UOELuFK+iWw+Hm79noHvLFU1pAhN0ed+QSGXfd8 X01A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=IHs95GWW; 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; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g4-v6si11678829pfm.365.2018.06.10.11.07.04; Sun, 10 Jun 2018 11:07:33 -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; dkim=pass header.i=@google.com header.s=20161025 header.b=IHs95GWW; 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; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753680AbeFJSGc (ORCPT + 99 others); Sun, 10 Jun 2018 14:06:32 -0400 Received: from mail-oi0-f67.google.com ([209.85.218.67]:38551 "EHLO mail-oi0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753507AbeFJSGa (ORCPT ); Sun, 10 Jun 2018 14:06:30 -0400 Received: by mail-oi0-f67.google.com with SMTP id d5-v6so16000230oib.5 for ; Sun, 10 Jun 2018 11:06:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:from:to:cc:subject:in-reply-to:message-id:references :user-agent:mime-version; bh=WjEvthiFiuZgBjvWCHDOWrHW4PoRFuIWNG3Pd4GhuEo=; b=IHs95GWWpaGs7S2rtEOBIaf/MWDgWYfqeQ/hTkJdsLcT0qpC6eF6lqj/WsU7dL5GtZ Sei3DAob6C/+n27kNNzxrhTFpEd+OCF0fZVivxCYaqW6plR4/g5APKQc6gCcIvgpqI3E 6nDkRQqLqkphlvwnsk8uHdeMXgm0pUpiaPmPy+YKE2oxeA6qTnmGj18aV9gJKTAlKT3Z 9CL4pxbrGQixgJoWoP7ogHtq/YQpTxYt3j81qo0YcFc2YqsVAF0DU9deR+AIph3mI8nC 0yQCWQufLwlhX2K1thO4tOFVKnG44hMMYSegJssXZ4+y4csTUU3EIV1uiheYUQZNI4Jp XzhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:in-reply-to:message-id :references:user-agent:mime-version; bh=WjEvthiFiuZgBjvWCHDOWrHW4PoRFuIWNG3Pd4GhuEo=; b=kGRxfJ9BpwgSt+zRpkkvJFm8QffzuGzbIcagFoIpukfmmU3slvnUj/4KMhCcCnDb8W KubK4W8A2zrAc56mHcWmD6pdTnWm9wNyUCZDgFjJgiG3yqe4NJ9xaB3xSIMXR+4NiSUo GUufy5RXjhx+l6ytI8LqS/fKYTrHthc6ZLgmAooeQtMmosCbkTOseXHXK3RgBQCJm/M6 ahLaADB6z0/UtmUctaMcY9WWrq0QK2fGG3AMBirfypLZdKTNwCHFFpEjVwbJZJ+/Q1jk BM0UzswQsxz73RJU7LM165LPNr0YKr13hCOH2hou2ZSsw1mWS7GRqo45SmSAbQDYftfr J0ng== X-Gm-Message-State: APt69E1tMi500VKfXrB1R2WSzw8PtpYVPDMLpJ3HoRGUOko913WYH7Zu qrAiPto1zhlPTLUbxIeZK6CroA4ClBQ= X-Received: by 2002:aca:5116:: with SMTP id f22-v6mr7494926oib.78.1528653989022; Sun, 10 Jun 2018 11:06:29 -0700 (PDT) Received: from eggly.attlocal.net (172-10-233-147.lightspeed.sntcca.sbcglobal.net. [172.10.233.147]) by smtp.gmail.com with ESMTPSA id w88-v6sm20970391ota.48.2018.06.10.11.06.27 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 10 Jun 2018 11:06:28 -0700 (PDT) Date: Sun, 10 Jun 2018 11:06:15 -0700 (PDT) From: Hugh Dickins X-X-Sender: hugh@eggly.anvils To: Ben Hutchings cc: linux-kernel@vger.kernel.org, stable@vger.kernel.org, akpm@linux-foundation.org, Linus Torvalds , Mel Gorman , Jan Kara , Minchan Kim , "Huang, Ying" , Ivan Kalvachev , Hugh Dickins Subject: Re: [PATCH 3.16 183/410] mm: pin address_space before dereferencing it while isolating an LRU page In-Reply-To: Message-ID: References: User-Agent: Alpine 2.11 (LSU 23 2013-08-11) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 7 Jun 2018, Ben Hutchings wrote: > 3.16.57-rc1 review patch. If anyone has any objections, please let me know. Not an objection as such, but if you're including this one, please be sure to add 145e1a71e090575c74969e3daa8136d1e5b99fc8 "mm: fix the NULL mapping case in __isolate_lru_page()" Thanks, Hugh > > ------------------ > > From: Mel Gorman > > commit 69d763fc6d3aee787a3e8c8c35092b4f4960fa5d upstream. > > Minchan Kim asked the following question -- what locks protects > address_space destroying when race happens between inode trauncation and > __isolate_lru_page? Jan Kara clarified by describing the race as follows > > CPU1 CPU2 > > truncate(inode) __isolate_lru_page() > ... > truncate_inode_page(mapping, page); > delete_from_page_cache(page) > spin_lock_irqsave(&mapping->tree_lock, flags); > __delete_from_page_cache(page, NULL) > page_cache_tree_delete(..) > ... mapping = page_mapping(page); > page->mapping = NULL; > ... > spin_unlock_irqrestore(&mapping->tree_lock, flags); > page_cache_free_page(mapping, page) > put_page(page) > if (put_page_testzero(page)) -> false > - inode now has no pages and can be freed including embedded address_space > > if (mapping && !mapping->a_ops->migratepage) > - we've dereferenced mapping which is potentially already free. > > The race is theoretically possible but unlikely. Before the > delete_from_page_cache, truncate_cleanup_page is called so the page is > likely to be !PageDirty or PageWriteback which gets skipped by the only > caller that checks the mappping in __isolate_lru_page. Even if the race > occurs, a substantial amount of work has to happen during a tiny window > with no preemption but it could potentially be done using a virtual > machine to artifically slow one CPU or halt it during the critical > window. > > This patch should eliminate the race with truncation by try-locking the > page before derefencing mapping and aborting if the lock was not > acquired. There was a suggestion from Huang Ying to use RCU as a > side-effect to prevent mapping being freed. However, I do not like the > solution as it's an unconventional means of preserving a mapping and > it's not a context where rcu_read_lock is obviously protecting rcu data. > > Link: http://lkml.kernel.org/r/20180104102512.2qos3h5vqzeisrek@techsingularity.net > Fixes: c82449352854 ("mm: compaction: make isolate_lru_page() filter-aware again") > Signed-off-by: Mel Gorman > Acked-by: Minchan Kim > Cc: "Huang, Ying" > Cc: Jan Kara > Signed-off-by: Andrew Morton > Signed-off-by: Linus Torvalds > [bwh: Backported to 3.16: adjust context] > Signed-off-by: Ben Hutchings > --- > mm/vmscan.c | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > > --- a/mm/vmscan.c > +++ b/mm/vmscan.c > @@ -1206,6 +1206,7 @@ int __isolate_lru_page(struct page *page > > if (PageDirty(page)) { > struct address_space *mapping; > + bool migrate_dirty; > > /* ISOLATE_CLEAN means only clean pages */ > if (mode & ISOLATE_CLEAN) > @@ -1214,10 +1215,19 @@ int __isolate_lru_page(struct page *page > /* > * Only pages without mappings or that have a > * ->migratepage callback are possible to migrate > - * without blocking > + * without blocking. However, we can be racing with > + * truncation so it's necessary to lock the page > + * to stabilise the mapping as truncation holds > + * the page lock until after the page is removed > + * from the page cache. > */ > + if (!trylock_page(page)) > + return ret; > + > mapping = page_mapping(page); > - if (mapping && !mapping->a_ops->migratepage) > + migrate_dirty = mapping && mapping->a_ops->migratepage; > + unlock_page(page); > + if (!migrate_dirty) > return ret; > } > } > >