mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
page_pool: place frag_* fields in one cacheline
On x86_64, frag_* fields of struct page_pool are scattered across two cachelines despite the summary size of 24 bytes. All three fields are used in pretty much the same places, but the last field, ::frag_users, is pushed out to the next CL, provoking unwanted false-sharing on hotpath (frags allocation code). There are some holes and cold members to move around. Move frag_* one block up, placing them right after &page_pool_params perfectly at the beginning of CL2. This doesn't do any meaningful to the second block, as those are some destroy-path cold structures, and doesn't do anything to ::alloc_stats, which still starts at 200-byte offset, 8 bytes after CL3 (still fitting into 1 cacheline). On my setup, this yields 1-2% of Mpps when using PP frags actively. When it comes to 32-bit architectures with 32-byte CL: &page_pool_params plus ::pad is 44 bytes, the block taken care of is 16 bytes within one CL, so there should be at least no regressions from the actual change. ::pages_state_hold_cnt is not related directly to that triple, but is paired currently with ::frags_offset and decoupling them would mean either two 4-byte holes or more invasive layout changes. Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com> Reviewed-by: Alexander Duyck <alexanderduyck@fb.com> Link: https://lore.kernel.org/r/20230804180529.2483231-4-aleksander.lobakin@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
75eaf63ea7
commit
06d0fbdad6
1 changed files with 5 additions and 5 deletions
|
@ -123,16 +123,16 @@ struct page_pool_stats {
|
||||||
struct page_pool {
|
struct page_pool {
|
||||||
struct page_pool_params p;
|
struct page_pool_params p;
|
||||||
|
|
||||||
|
long frag_users;
|
||||||
|
struct page *frag_page;
|
||||||
|
unsigned int frag_offset;
|
||||||
|
u32 pages_state_hold_cnt;
|
||||||
|
|
||||||
struct delayed_work release_dw;
|
struct delayed_work release_dw;
|
||||||
void (*disconnect)(void *pool);
|
void (*disconnect)(void *pool);
|
||||||
unsigned long defer_start;
|
unsigned long defer_start;
|
||||||
unsigned long defer_warn;
|
unsigned long defer_warn;
|
||||||
|
|
||||||
u32 pages_state_hold_cnt;
|
|
||||||
unsigned int frag_offset;
|
|
||||||
struct page *frag_page;
|
|
||||||
long frag_users;
|
|
||||||
|
|
||||||
#ifdef CONFIG_PAGE_POOL_STATS
|
#ifdef CONFIG_PAGE_POOL_STATS
|
||||||
/* these stats are incremented while in softirq context */
|
/* these stats are incremented while in softirq context */
|
||||||
struct page_pool_alloc_stats alloc_stats;
|
struct page_pool_alloc_stats alloc_stats;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue