1. 24 Oct, 2023 5 commits
    • Yunsheng Lin's avatar
      net: veth: use newly added page pool API for veth with xdp · 2d0de67d
      Yunsheng Lin authored
      Use page_pool_alloc() API to allocate memory with least
      memory utilization and performance penalty.
      Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
      CC: Lorenzo Bianconi <lorenzo@kernel.org>
      CC: Alexander Duyck <alexander.duyck@gmail.com>
      CC: Liang Chen <liangchen.linux@gmail.com>
      CC: Alexander Lobakin <aleksander.lobakin@intel.com>
      Link: https://lore.kernel.org/r/20231020095952.11055-6-linyunsheng@huawei.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      2d0de67d
    • Yunsheng Lin's avatar
      page_pool: update document about fragment API · 8ab32fa1
      Yunsheng Lin authored
      As more drivers begin to use the fragment API, update the
      document about how to decide which API to use for the
      driver author.
      Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
      CC: Lorenzo Bianconi <lorenzo@kernel.org>
      CC: Alexander Duyck <alexander.duyck@gmail.com>
      CC: Liang Chen <liangchen.linux@gmail.com>
      CC: Alexander Lobakin <aleksander.lobakin@intel.com>
      CC: Dima Tisnek <dimaqq@gmail.com>
      Link: https://lore.kernel.org/r/20231020095952.11055-5-linyunsheng@huawei.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      8ab32fa1
    • Yunsheng Lin's avatar
      page_pool: introduce page_pool_alloc() API · de97502e
      Yunsheng Lin authored
      Currently page pool supports the below use cases:
      use case 1: allocate page without page splitting using
                  page_pool_alloc_pages() API if the driver knows
                  that the memory it need is always bigger than
                  half of the page allocated from page pool.
      use case 2: allocate page frag with page splitting using
                  page_pool_alloc_frag() API if the driver knows
                  that the memory it need is always smaller than
                  or equal to the half of the page allocated from
                  page pool.
      
      There is emerging use case [1] & [2] that is a mix of the
      above two case: the driver doesn't know the size of memory it
      need beforehand, so the driver may use something like below to
      allocate memory with least memory utilization and performance
      penalty:
      
      if (size << 1 > max_size)
      	page = page_pool_alloc_pages();
      else
      	page = page_pool_alloc_frag();
      
      To avoid the driver doing something like above, add the
      page_pool_alloc() API to support the above use case, and update
      the true size of memory that is acctually allocated by updating
      '*size' back to the driver in order to avoid exacerbating
      truesize underestimate problem.
      
      Rename page_pool_free() which is used in the destroy process to
      __page_pool_destroy() to avoid confusion with the newly added
      API.
      
      1. https://lore.kernel.org/all/d3ae6bd3537fbce379382ac6a42f67e22f27ece2.1683896626.git.lorenzo@kernel.org/
      2. https://lore.kernel.org/all/20230526054621.18371-3-liangchen.linux@gmail.com/Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
      CC: Lorenzo Bianconi <lorenzo@kernel.org>
      CC: Alexander Duyck <alexander.duyck@gmail.com>
      CC: Liang Chen <liangchen.linux@gmail.com>
      CC: Alexander Lobakin <aleksander.lobakin@intel.com>
      Link: https://lore.kernel.org/r/20231020095952.11055-4-linyunsheng@huawei.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      de97502e
    • Yunsheng Lin's avatar
      page_pool: remove PP_FLAG_PAGE_FRAG · 09d96ee5
      Yunsheng Lin authored
      PP_FLAG_PAGE_FRAG is not really needed after pp_frag_count
      handling is unified and page_pool_alloc_frag() is supported
      in 32-bit arch with 64-bit DMA, so remove it.
      Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
      CC: Lorenzo Bianconi <lorenzo@kernel.org>
      CC: Alexander Duyck <alexander.duyck@gmail.com>
      CC: Liang Chen <liangchen.linux@gmail.com>
      CC: Alexander Lobakin <aleksander.lobakin@intel.com>
      Link: https://lore.kernel.org/r/20231020095952.11055-3-linyunsheng@huawei.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      09d96ee5
    • Yunsheng Lin's avatar
      page_pool: unify frag_count handling in page_pool_is_last_frag() · 58d53d8f
      Yunsheng Lin authored
      Currently when page_pool_create() is called with
      PP_FLAG_PAGE_FRAG flag, page_pool_alloc_pages() is only
      allowed to be called under the below constraints:
      1. page_pool_fragment_page() need to be called to setup
         page->pp_frag_count immediately.
      2. page_pool_defrag_page() often need to be called to drain
         the page->pp_frag_count when there is no more user will
         be holding on to that page.
      
      Those constraints exist in order to support a page to be
      split into multi fragments.
      
      And those constraints have some overhead because of the
      cache line dirtying/bouncing and atomic update.
      
      Those constraints are unavoidable for case when we need a
      page to be split into more than one fragment, but there is
      also case that we want to avoid the above constraints and
      their overhead when a page can't be split as it can only
      hold a fragment as requested by user, depending on different
      use cases:
      use case 1: allocate page without page splitting.
      use case 2: allocate page with page splitting.
      use case 3: allocate page with or without page splitting
                  depending on the fragment size.
      
      Currently page pool only provide page_pool_alloc_pages() and
      page_pool_alloc_frag() API to enable the 1 & 2 separately,
      so we can not use a combination of 1 & 2 to enable 3, it is
      not possible yet because of the per page_pool flag
      PP_FLAG_PAGE_FRAG.
      
      So in order to allow allocating unsplit page without the
      overhead of split page while still allow allocating split
      page we need to remove the per page_pool flag in
      page_pool_is_last_frag(), as best as I can think of, it seems
      there are two methods as below:
      1. Add per page flag/bit to indicate a page is split or
         not, which means we might need to update that flag/bit
         everytime the page is recycled, dirtying the cache line
         of 'struct page' for use case 1.
      2. Unify the page->pp_frag_count handling for both split and
         unsplit page by assuming all pages in the page pool is split
         into a big fragment initially.
      
      As page pool already supports use case 1 without dirtying the
      cache line of 'struct page' whenever a page is recyclable, we
      need to support the above use case 3 with minimal overhead,
      especially not adding any noticeable overhead for use case 1,
      and we are already doing an optimization by not updating
      pp_frag_count in page_pool_defrag_page() for the last fragment
      user, this patch chooses to unify the pp_frag_count handling
      to support the above use case 3.
      
      There is no noticeable performance degradation and some
      justification for unifying the frag_count handling with this
      patch applied using a micro-benchmark testing in [1].
      
      1. https://lore.kernel.org/all/bf2591f8-7b3c-4480-bb2c-31dc9da1d6ac@huawei.com/Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
      CC: Lorenzo Bianconi <lorenzo@kernel.org>
      CC: Alexander Duyck <alexander.duyck@gmail.com>
      CC: Liang Chen <liangchen.linux@gmail.com>
      CC: Alexander Lobakin <aleksander.lobakin@intel.com>
      Link: https://lore.kernel.org/r/20231020095952.11055-2-linyunsheng@huawei.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      58d53d8f
  2. 23 Oct, 2023 35 commits