Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754511AbbEOK45 (ORCPT ); Fri, 15 May 2015 06:56:57 -0400 Received: from mta-out1.inet.fi ([62.71.2.195]:40636 "EHLO kirsi1.inet.fi" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752739AbbEOK4z (ORCPT ); Fri, 15 May 2015 06:56:55 -0400 Date: Fri, 15 May 2015 13:56:21 +0300 From: "Kirill A. Shutemov" To: Vlastimil Babka Cc: "Kirill A. Shutemov" , Andrew Morton , Andrea Arcangeli , Hugh Dickins , Dave Hansen , Mel Gorman , Rik van Riel , Christoph Lameter , Naoya Horiguchi , Steve Capper , "Aneesh Kumar K.V" , Johannes Weiner , Michal Hocko , Jerome Marchand , Sasha Levin , linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: Re: [PATCHv5 01/28] mm, proc: adjust PSS calculation Message-ID: <20150515105621.GA6250@node.dhcp.inet.fi> References: <1429823043-157133-1-git-send-email-kirill.shutemov@linux.intel.com> <1429823043-157133-2-git-send-email-kirill.shutemov@linux.intel.com> <5554AD4D.9040000@suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5554AD4D.9040000@suse.cz> User-Agent: Mutt/1.5.23.1 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3616 Lines: 106 On Thu, May 14, 2015 at 04:12:29PM +0200, Vlastimil Babka wrote: > On 04/23/2015 11:03 PM, Kirill A. Shutemov wrote: > >With new refcounting all subpages of the compound page are not nessessary > >have the same mapcount. We need to take into account mapcount of every > >sub-page. > > > >Signed-off-by: Kirill A. Shutemov > >Tested-by: Sasha Levin > > Acked-by: Vlastimil Babka > > (some nitpicks below) > > >--- > > fs/proc/task_mmu.c | 43 ++++++++++++++++++++++--------------------- > > 1 file changed, 22 insertions(+), 21 deletions(-) > > > >diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c > >index 956b75d61809..95bc384ee3f7 100644 > >--- a/fs/proc/task_mmu.c > >+++ b/fs/proc/task_mmu.c > >@@ -449,9 +449,10 @@ struct mem_size_stats { > > }; > > > > static void smaps_account(struct mem_size_stats *mss, struct page *page, > >- unsigned long size, bool young, bool dirty) > >+ bool compound, bool young, bool dirty) > > { > >- int mapcount; > >+ int i, nr = compound ? hpage_nr_pages(page) : 1; > > Why not just HPAGE_PMD_NR instead of hpage_nr_pages(page)? Okay, makes sense. Compiler is smart enough to optimize away HPAGE_PMD_NR for THP=n. (HPAGE_PMD_NR is BUILD_BUG() for THP=n) > We already came here through a pmd mapping. Even if the page stopped > being a hugepage meanwhile (I'm not sure if any locking prevents that or > not?), We're under ptl here. PMD will not go away under us. > it would be more accurate to continue assuming it's a hugepage, > otherwise we account only the base page (formerly head) and skip the 511 > formerly tail pages? > > Also, is there some shortcut way to tell us that we are the only one mapping > the whole compound page, and nobody has any base pages, so we don't need to > loop on each tail page? I guess not under the new design, right... No, we don't have shortcut here. > >+ unsigned long size = nr * PAGE_SIZE; > > > > if (PageAnon(page)) > > mss->anonymous += size; > >@@ -460,23 +461,23 @@ static void smaps_account(struct mem_size_stats *mss, struct page *page, > > /* Accumulate the size in pages that have been accessed. */ > > if (young || PageReferenced(page)) > > mss->referenced += size; > >- mapcount = page_mapcount(page); > >- if (mapcount >= 2) { > >- u64 pss_delta; > > > >- if (dirty || PageDirty(page)) > >- mss->shared_dirty += size; > >- else > >- mss->shared_clean += size; > >- pss_delta = (u64)size << PSS_SHIFT; > >- do_div(pss_delta, mapcount); > >- mss->pss += pss_delta; > >- } else { > >- if (dirty || PageDirty(page)) > >- mss->private_dirty += size; > >- else > >- mss->private_clean += size; > >- mss->pss += (u64)size << PSS_SHIFT; > >+ for (i = 0; i < nr; i++) { > >+ int mapcount = page_mapcount(page + i); > >+ > >+ if (mapcount >= 2) { > >+ if (dirty || PageDirty(page + i)) > >+ mss->shared_dirty += PAGE_SIZE; > >+ else > >+ mss->shared_clean += PAGE_SIZE; > >+ mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount; > >+ } else { > >+ if (dirty || PageDirty(page + i)) > >+ mss->private_dirty += PAGE_SIZE; > >+ else > >+ mss->private_clean += PAGE_SIZE; > >+ mss->pss += PAGE_SIZE << PSS_SHIFT; > >+ } > > That's 3 instances of "page + i", why not just use page and do a page++ in > the for loop? Okay. -- Kirill A. Shutemov -- 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/