On Thu, Apr 11, 2024 at 10:51 AM Xuan Zhuo <xuanzhuo@xxxxxxxxxxxxxxxxx> wrote: > > Now, we chain the pages of big mode by the page's private variable. > But a subsequent patch aims to make the big mode to support > premapped mode. This requires additional space to store the dma addr. > > Within the sub-struct that contains the 'private', there is no suitable > variable for storing the DMA addr. > > struct { /* Page cache and anonymous pages */ > /** > * @lru: Pageout list, eg. active_list protected by > * lruvec->lru_lock. Sometimes used as a generic list > * by the page owner. > */ > union { > struct list_head lru; > > /* Or, for the Unevictable "LRU list" slot */ > struct { > /* Always even, to negate PageTail */ > void *__filler; > /* Count page's or folio's mlocks */ > unsigned int mlock_count; > }; > > /* Or, free page */ > struct list_head buddy_list; > struct list_head pcp_list; > }; > /* See page-flags.h for PAGE_MAPPING_FLAGS */ > struct address_space *mapping; > union { > pgoff_t index; /* Our offset within mapping. */ > unsigned long share; /* share count for fsdax */ > }; > /** > * @private: Mapping-private opaque data. > * Usually used for buffer_heads if PagePrivate. > * Used for swp_entry_t if PageSwapCache. > * Indicates order in the buddy system if PageBuddy. > */ > unsigned long private; > }; > > But within the page pool struct, we have a variable called > dma_addr that is appropriate for storing dma addr. > And that struct is used by netstack. That works to our advantage. > > struct { /* page_pool used by netstack */ > /** > * @pp_magic: magic value to avoid recycling non > * page_pool allocated pages. > */ > unsigned long pp_magic; > struct page_pool *pp; > unsigned long _pp_mapping_pad; > unsigned long dma_addr; > atomic_long_t pp_ref_count; > }; > > On the other side, we should use variables from the same sub-struct. > So this patch replaces the "private" with "pp". > > Signed-off-by: Xuan Zhuo <xuanzhuo@xxxxxxxxxxxxxxxxx> > --- > drivers/net/virtio_net.c | 27 +++++++++++++++------------ > 1 file changed, 15 insertions(+), 12 deletions(-) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index c22d1118a133..4446fb54de6d 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -48,6 +48,9 @@ module_param(napi_tx, bool, 0644); > > #define VIRTIO_XDP_FLAG BIT(0) > > +#define page_chain_next(p) ((struct page *)((p)->pp)) > +#define page_chain_add(p, n) ((p)->pp = (void *)n) > + > /* RX packet size EWMA. The average packet size is used to determine the packet > * buffer size when refilling RX rings. As the entire RX ring may be refilled > * at once, the weight is chosen so that the EWMA will be insensitive to short- > @@ -191,7 +194,7 @@ struct receive_queue { > > struct virtnet_interrupt_coalesce intr_coal; > > - /* Chain pages by the private ptr. */ > + /* Chain pages by the page's pp struct. */ > struct page *pages; > > /* Average packet length for mergeable receive buffers. */ > @@ -432,16 +435,16 @@ skb_vnet_common_hdr(struct sk_buff *skb) > } > > /* > - * private is used to chain pages for big packets, put the whole > - * most recent used list in the beginning for reuse > + * put the whole most recent used list in the beginning for reuse > */ While at this, let's explain the pp is used to chain pages or we can do it on the definition of page_chain_add(). Others look good. Acked-by: Jason Wang <jasowang@xxxxxxxxxx> Thanks