From: Matthew Wilcox <willy@xxxxxxxxxxxxx> > Sent: 15 April 2021 19:22 > > On Thu, Apr 15, 2021 at 08:08:32PM +0200, Jesper Dangaard Brouer wrote: > > +static inline > > +dma_addr_t page_pool_dma_addr_read(dma_addr_t dma_addr) > > +{ > > + /* Workaround for storing 64-bit DMA-addr on 32-bit machines in struct > > + * page. The page->dma_addr share area with page->compound_head which > > + * use bit zero to mark compound pages. This is okay, as DMA-addr are > > + * aligned pointers which have bit zero cleared. > > + * > > + * In the 32-bit case, page->compound_head is 32-bit. Thus, when > > + * dma_addr_t is 64-bit it will be located in top 32-bit. Solve by > > + * swapping dma_addr 32-bit segments. > > + */ > > +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT > > #if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) && defined(__BIG_ENDIAN) > otherwise you'll create the problem on ARM that you're avoiding on PPC ... > > I think you want to delete the word '_read' from this function name because > you're using it for both read and write. I think I'd use explicit dma_addr_hi and dma_addr_lo and separate read/write functions just to make absolutely sure nothing picks up the swapped value. Isn't it possible to move the field down one long? This might require an explicit zero - but this is not a common code path - the extra write will be noise. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)