Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753992AbcKRX1V (ORCPT ); Fri, 18 Nov 2016 18:27:21 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:42388 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752336AbcKRX1R (ORCPT ); Fri, 18 Nov 2016 18:27:17 -0500 Date: Fri, 18 Nov 2016 15:27:16 -0800 From: Andrew Morton To: Alexander Duyck Cc: linux-mm@kvack.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [mm PATCH v3 21/23] mm: Add support for releasing multiple instances of a page Message-Id: <20161118152716.3f7acf6e25f142846909b2f6@linux-foundation.org> In-Reply-To: <20161110113606.76501.70752.stgit@ahduyck-blue-test.jf.intel.com> References: <20161110113027.76501.63030.stgit@ahduyck-blue-test.jf.intel.com> <20161110113606.76501.70752.stgit@ahduyck-blue-test.jf.intel.com> X-Mailer: Sylpheed 3.4.1 (GTK+ 2.24.23; 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: 2105 Lines: 56 On Thu, 10 Nov 2016 06:36:06 -0500 Alexander Duyck wrote: > This patch adds a function that allows us to batch free a page that has > multiple references outstanding. Specifically this function can be used to > drop a page being used in the page frag alloc cache. With this drivers can > make use of functionality similar to the page frag alloc cache without > having to do any workarounds for the fact that there is no function that > frees multiple references. > > ... > > --- a/include/linux/gfp.h > +++ b/include/linux/gfp.h > @@ -506,6 +506,8 @@ extern void free_hot_cold_page(struct page *page, bool cold); > extern void free_hot_cold_page_list(struct list_head *list, bool cold); > > struct page_frag_cache; > +extern void __page_frag_drain(struct page *page, unsigned int order, > + unsigned int count); > extern void *__alloc_page_frag(struct page_frag_cache *nc, > unsigned int fragsz, gfp_t gfp_mask); > extern void __free_page_frag(void *addr); > diff --git a/mm/page_alloc.c b/mm/page_alloc.c > index 0fbfead..54fea40 100644 > --- a/mm/page_alloc.c > +++ b/mm/page_alloc.c > @@ -3912,6 +3912,20 @@ static struct page *__page_frag_refill(struct page_frag_cache *nc, > return page; > } > > +void __page_frag_drain(struct page *page, unsigned int order, > + unsigned int count) > +{ > + VM_BUG_ON_PAGE(page_ref_count(page) == 0, page); > + > + if (page_ref_sub_and_test(page, count)) { > + if (order == 0) > + free_hot_cold_page(page, false); > + else > + __free_pages_ok(page, order); > + } > +} > +EXPORT_SYMBOL(__page_frag_drain); It's an exported-to-modules library function. It should be documented, please? The page-frag API is only partially documented, but that's no excuse. And perhaps documentation will help explain the naming choice. Why "drain"? I'd have expected "put"? And why the leading underscores. The page-frag API is pretty weird :( And inconsistent. __alloc_page_frag -> page_frag_alloc, __free_page_frag -> page_frag_free(), etc. I must have been asleep when I let that lot through.