mbox series

[v2,net-next,0/4] net: consolidate page_is_pfmemalloc() usage

Message ID 20210127201031.98544-1-alobakin@pm.me
Headers show
Series net: consolidate page_is_pfmemalloc() usage | expand

Message

Alexander Lobakin Jan. 27, 2021, 8:10 p.m. UTC
page_is_pfmemalloc() is used mostly by networking drivers to test
if a page can be considered for reusing/recycling.
It doesn't write anything to the struct page itself, so its sole
argument can be constified, as well as the first argument of
skb_propagate_pfmemalloc().
In Page Pool core code, it can be simply inlined instead.
Most of the callers from NIC drivers were just doppelgangers of
the same condition tests. Derive them into a new common function
do deduplicate the code.

Since v1 [0]:
 - new: reduce code duplication by introducing a new common function
   to test if a page can be reused/recycled (David Rientjes);
 - collect autographs for Page Pool bits (Jesper Dangaard Brouer,
   Ilias Apalodimas).

[0] https://lore.kernel.org/netdev/20210125164612.243838-1-alobakin@pm.me

Alexander Lobakin (4):
  mm: constify page_is_pfmemalloc() argument
  skbuff: constify skb_propagate_pfmemalloc() "page" argument
  net: introduce common dev_page_is_reserved()
  net: page_pool: simplify page recycling condition tests

 .../net/ethernet/hisilicon/hns3/hns3_enet.c   | 10 ++--------
 drivers/net/ethernet/intel/fm10k/fm10k_main.c |  9 ++-------
 drivers/net/ethernet/intel/i40e/i40e_txrx.c   | 15 +--------------
 drivers/net/ethernet/intel/iavf/iavf_txrx.c   | 15 +--------------
 drivers/net/ethernet/intel/ice/ice_txrx.c     | 11 +----------
 drivers/net/ethernet/intel/igb/igb_main.c     |  7 +------
 drivers/net/ethernet/intel/igc/igc_main.c     |  7 +------
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  7 +------
 .../net/ethernet/intel/ixgbevf/ixgbevf_main.c |  7 +------
 .../net/ethernet/mellanox/mlx5/core/en_rx.c   |  7 +------
 include/linux/mm.h                            |  2 +-
 include/linux/skbuff.h                        | 19 +++++++++++++++++--
 net/core/page_pool.c                          | 14 ++++----------
 13 files changed, 34 insertions(+), 96 deletions(-)

Comments

Jesse Brandeburg Jan. 27, 2021, 9:47 p.m. UTC | #1
Alexander Lobakin wrote:

> A bunch of drivers test the page before reusing/recycling for two
> common conditions:
>  - if a page was allocated under memory pressure (pfmemalloc page);
>  - if a page was allocated at a distant memory node (to exclude
>    slowdowns).
> 
> Introduce and use a new common function for doing this and eliminate
> all functions-duplicates from drivers.
> 
> Suggested-by: David Rientjes <rientjes@google.com>
> Signed-off-by: Alexander Lobakin <alobakin@pm.me>
> ---
>  drivers/net/ethernet/hisilicon/hns3/hns3_enet.c   | 10 ++--------
>  drivers/net/ethernet/intel/fm10k/fm10k_main.c     |  9 ++-------
>  drivers/net/ethernet/intel/i40e/i40e_txrx.c       | 15 +--------------
>  drivers/net/ethernet/intel/iavf/iavf_txrx.c       | 15 +--------------
>  drivers/net/ethernet/intel/ice/ice_txrx.c         | 11 +----------
>  drivers/net/ethernet/intel/igb/igb_main.c         |  7 +------
>  drivers/net/ethernet/intel/igc/igc_main.c         |  7 +------
>  drivers/net/ethernet/intel/ixgbe/ixgbe_main.c     |  7 +------
>  drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |  7 +------
>  drivers/net/ethernet/mellanox/mlx5/core/en_rx.c   |  7 +------
>  include/linux/skbuff.h                            | 15 +++++++++++++++
>  11 files changed, 27 insertions(+), 83 deletions(-)

For the patch, and esp. for the Intel drivers:
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
David Rientjes Jan. 28, 2021, 10:44 p.m. UTC | #2
On Wed, 27 Jan 2021, Alexander Lobakin wrote:

> The function only tests for page->index, so its argument should be

> const.

> 

> Signed-off-by: Alexander Lobakin <alobakin@pm.me>


Acked-by: David Rientjes <rientjes@google.com>
David Rientjes Jan. 28, 2021, 10:48 p.m. UTC | #3
On Wed, 27 Jan 2021, Alexander Lobakin wrote:

> A bunch of drivers test the page before reusing/recycling for two

> common conditions:

>  - if a page was allocated under memory pressure (pfmemalloc page);

>  - if a page was allocated at a distant memory node (to exclude

>    slowdowns).

> 

> Introduce and use a new common function for doing this and eliminate

> all functions-duplicates from drivers.

> 

> Suggested-by: David Rientjes <rientjes@google.com>

> Signed-off-by: Alexander Lobakin <alobakin@pm.me>


Looks even better than I thought!

(Since all of the changes are in drivers/net/ethernet/, I assume 
everything directly or indirectly includes skbuff.h already.)

Acked-by: David Rientjes <rientjes@google.com>


Thanks for doing this.
Jakub Kicinski Jan. 30, 2021, 2:30 a.m. UTC | #4
On Wed, 27 Jan 2021 20:11:01 +0000 Alexander Lobakin wrote:
> The function only tests for page->index, so its argument should be

> const.

> 

> Signed-off-by: Alexander Lobakin <alobakin@pm.me>

> ---

>  include/linux/mm.h | 2 +-

>  1 file changed, 1 insertion(+), 1 deletion(-)

> 

> diff --git a/include/linux/mm.h b/include/linux/mm.h

> index ecdf8a8cd6ae..078633d43af9 100644

> --- a/include/linux/mm.h

> +++ b/include/linux/mm.h

> @@ -1584,7 +1584,7 @@ struct address_space *page_mapping_file(struct page *page);

>   * ALLOC_NO_WATERMARKS and the low watermark was not

>   * met implying that the system is under some pressure.

>   */

> -static inline bool page_is_pfmemalloc(struct page *page)

> +static inline bool page_is_pfmemalloc(const struct page *page)

>  {

>  	/*

>  	 * Page index cannot be this large so this must be


No objections for this going via net-next?
Jakub Kicinski Jan. 30, 2021, 2:39 a.m. UTC | #5
On Wed, 27 Jan 2021 20:11:23 +0000 Alexander Lobakin wrote:
> + * dev_page_is_reserved - check whether a page can be reused for network Rx

> + * @page: the page to test

> + *

> + * A page shouldn't be considered for reusing/recycling if it was allocated

> + * under memory pressure or at a distant memory node.

> + *

> + * Returns true if this page should be returned to page allocator, false

> + * otherwise.

> + */

> +static inline bool dev_page_is_reserved(const struct page *page)


Am I the only one who feels like "reusable" is a better term than
"reserved".
Alexander Lobakin Jan. 30, 2021, 3:42 p.m. UTC | #6
From: Jakub Kicinski <kuba@kernel.org>

Date: Fri, 29 Jan 2021 18:39:07 -0800

> On Wed, 27 Jan 2021 20:11:23 +0000 Alexander Lobakin wrote:

> > + * dev_page_is_reserved - check whether a page can be reused for network Rx

> > + * @page: the page to test

> > + *

> > + * A page shouldn't be considered for reusing/recycling if it was allocated

> > + * under memory pressure or at a distant memory node.

> > + *

> > + * Returns true if this page should be returned to page allocator, false

> > + * otherwise.

> > + */

> > +static inline bool dev_page_is_reserved(const struct page *page)

> 

> Am I the only one who feels like "reusable" is a better term than

> "reserved".


I thought about it, but this will need to inverse the conditions in
most of the drivers. I decided to keep it as it is.
I can redo if "reusable" is preferred.

Regarding "no objectives to take patch 1 through net-next": patches
2-3 depend on it, so I can't put it in a separate series.

Thanks,
Al
Jakub Kicinski Jan. 30, 2021, 7:07 p.m. UTC | #7
On Sat, 30 Jan 2021 15:42:29 +0000 Alexander Lobakin wrote:
> > On Wed, 27 Jan 2021 20:11:23 +0000 Alexander Lobakin wrote:  

> > > + * dev_page_is_reserved - check whether a page can be reused for network Rx

> > > + * @page: the page to test

> > > + *

> > > + * A page shouldn't be considered for reusing/recycling if it was allocated

> > > + * under memory pressure or at a distant memory node.

> > > + *

> > > + * Returns true if this page should be returned to page allocator, false

> > > + * otherwise.

> > > + */

> > > +static inline bool dev_page_is_reserved(const struct page *page)  

> > 

> > Am I the only one who feels like "reusable" is a better term than

> > "reserved".  

> 

> I thought about it, but this will need to inverse the conditions in

> most of the drivers. I decided to keep it as it is.

> I can redo if "reusable" is preferred.


Naming is hard. As long as the condition is not a double negative it
reads fine to me, but that's probably personal preference.
The thing that doesn't sit well is the fact that there is nothing
"reserved" about a page from another NUMA node.. But again, if nobody
+1s this it's whatever...

That said can we move the likely()/unlikely() into the helper itself?
People on the internet may say otherwise but according to my tests 
using __builtin_expect() on a return value of a static inline helper
works just fine.
Alexander Lobakin Jan. 30, 2021, 7:45 p.m. UTC | #8
From: Jakub Kicinski <kuba@kernel.org>

Date: Sat, 30 Jan 2021 11:07:07 -0800

> On Sat, 30 Jan 2021 15:42:29 +0000 Alexander Lobakin wrote:

> > > On Wed, 27 Jan 2021 20:11:23 +0000 Alexander Lobakin wrote:

> > > > + * dev_page_is_reserved - check whether a page can be reused for network Rx

> > > > + * @page: the page to test

> > > > + *

> > > > + * A page shouldn't be considered for reusing/recycling if it was allocated

> > > > + * under memory pressure or at a distant memory node.

> > > > + *

> > > > + * Returns true if this page should be returned to page allocator, false

> > > > + * otherwise.

> > > > + */

> > > > +static inline bool dev_page_is_reserved(const struct page *page)

> > >

> > > Am I the only one who feels like "reusable" is a better term than

> > > "reserved".

> >

> > I thought about it, but this will need to inverse the conditions in

> > most of the drivers. I decided to keep it as it is.

> > I can redo if "reusable" is preferred.

> 

> Naming is hard. As long as the condition is not a double negative it

> reads fine to me, but that's probably personal preference.

> The thing that doesn't sit well is the fact that there is nothing

> "reserved" about a page from another NUMA node.. But again, if nobody

> +1s this it's whatever...


Agree on NUMA and naming. I'm a bit surprised that 95% of drivers
have this helper called "reserved" (one of the reasons why I finished
with this variant).
Let's say, if anybody else will vote for "reusable", I'll pick it for
v3.

> That said can we move the likely()/unlikely() into the helper itself?

> People on the internet may say otherwise but according to my tests

> using __builtin_expect() on a return value of a static inline helper

> works just fine.


Sounds fine, this will make code more elegant. Will publish v3 soon.

Thanks,
Al
John Hubbard Jan. 30, 2021, 9:23 p.m. UTC | #9
On 1/30/21 11:45 AM, Alexander Lobakin wrote:
> From: Jakub Kicinski <kuba@kernel.org>

> Date: Sat, 30 Jan 2021 11:07:07 -0800

> 

>> On Sat, 30 Jan 2021 15:42:29 +0000 Alexander Lobakin wrote:

>>>> On Wed, 27 Jan 2021 20:11:23 +0000 Alexander Lobakin wrote:

>>>>> + * dev_page_is_reserved - check whether a page can be reused for network Rx

>>>>> + * @page: the page to test

>>>>> + *

>>>>> + * A page shouldn't be considered for reusing/recycling if it was allocated

>>>>> + * under memory pressure or at a distant memory node.

>>>>> + *

>>>>> + * Returns true if this page should be returned to page allocator, false

>>>>> + * otherwise.

>>>>> + */

>>>>> +static inline bool dev_page_is_reserved(const struct page *page)

>>>>

>>>> Am I the only one who feels like "reusable" is a better term than

>>>> "reserved".

>>>

>>> I thought about it, but this will need to inverse the conditions in

>>> most of the drivers. I decided to keep it as it is.

>>> I can redo if "reusable" is preferred.

>>

>> Naming is hard. As long as the condition is not a double negative it

>> reads fine to me, but that's probably personal preference.

>> The thing that doesn't sit well is the fact that there is nothing

>> "reserved" about a page from another NUMA node.. But again, if nobody

>> +1s this it's whatever...

> 

> Agree on NUMA and naming. I'm a bit surprised that 95% of drivers

> have this helper called "reserved" (one of the reasons why I finished

> with this variant).

> Let's say, if anybody else will vote for "reusable", I'll pick it for

> v3.


Definitely "reusable" seems better to me, and especially anything *other*
than "reserved" is a good idea, IMHO.


thanks,
-- 
John Hubbard
NVIDIA