On Sun, May 16, 2021 at 11:27:10AM -0700, Linus Torvalds wrote: > On Sun, May 16, 2021 at 11:22 AM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > > > > Nobody's been willing to guarantee that all 32-bit architectures keep the > > top 20 bits clear for their DMA addresses. I've certainly seen hardware > > (maybe PA-RISC? MIPS?) which uses the top few bits of the DMA address to > > indicate things like "coherent" or "bypasses IOMMU". Rather than trying > > to find out, I thought this was the safer option. > > Fair enough. I just find it somewhat odd. > > But I still find this a bit ugly. Maybe we could just have made that > one sub-structure "__aligned(4)", and avoided this all, and let the > compiler generate the split load (or, more likely, just let the > compiler generate a regular load from an unaligned location). > > IOW, just > > struct { /* page_pool used by netstack */ > /** > * @dma_addr: might require a 64-bit value even on > * 32-bit architectures. > */ > dma_addr_t dma_addr; > } __aligned((4)); > > without the magic shifting games? That was the other problem fixed by this patch -- on big-endian 32-bit platforms with 64-bit dma_addr_t (mips, ppc), a DMA address with bit 32 set inadvertently sets the PageTail bit. So we need to store the low bits in the first word, even on big-endian platforms. There's an upcoming patch to move dma_addr out of the union with compound_head, but that requires changing page_is_pfmemalloc() to use an indicator other than page->index == -1. Once we do that, we can have fun with __aligned(). Since we knew it would have to be backported, this felt like the least risky patch to start with.