page_pool: Refactor page_pool to enable fragmenting after allocation
authorAlexander Duyck <alexanderduyck@fb.com>
Mon, 31 Jan 2022 16:40:01 +0000 (08:40 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 3 Feb 2022 11:49:03 +0000 (11:49 +0000)
commit52cc6ffc0ab2c61a76127b9347567fc97c15582f
tree90a1729f5ae2dd3d78bfa8937cdfc36d0a32c29d
parent33f7a32dd4b6d3c2b4d003582ccdd1a4c765b1e9
page_pool: Refactor page_pool to enable fragmenting after allocation

This change is meant to permit a driver to perform "fragmenting" of the
page from within the driver instead of the current model which requires
pre-partitioning the page. The main motivation behind this is to support
use cases where the page will be split up by the driver after DMA instead
of before.

With this change it becomes possible to start using page pool to replace
some of the existing use cases where multiple references were being used
for a single page, but the number needed was unknown as the size could be
dynamic.

For example, with this code it would be possible to do something like
the following to handle allocation:
  page = page_pool_alloc_pages();
  if (!page)
    return NULL;
  page_pool_fragment_page(page, DRIVER_PAGECNT_BIAS_MAX);
  rx_buf->page = page;
  rx_buf->pagecnt_bias = DRIVER_PAGECNT_BIAS_MAX;

Then we would process a received buffer by handling it with:
  rx_buf->pagecnt_bias--;

Once the page has been fully consumed we could then flush the remaining
instances with:
  if (page_pool_defrag_page(page, rx_buf->pagecnt_bias))
    continue;
  page_pool_put_defragged_page(pool, page -1, !!budget);

The general idea is that we want to have the ability to allocate a page
with excess fragment count and then trim off the unneeded fragments.

Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/page_pool.h
net/core/page_pool.c