How to handle P2P DMA with only {physaddr,len} in bio_vec?

From: David Howells
Date: Mon Jun 23 2025 - 06:52:49 EST


Hi Christoph,

Looking at the DMA address mapping infrastructure, it makes use of the page
struct to access the physical address (which obviously shouldn't be a problem)
and to find out if the page is involved in P2P DMA.

dma_direct_map_page() calls is_pci_p2pdma_page():

static inline bool is_pci_p2pdma_page(const struct page *page)
{
return IS_ENABLED(CONFIG_PCI_P2PDMA) &&
is_zone_device_page(page) &&
page_pgmap(page)->type == MEMORY_DEVICE_PCI_P2PDMA;
}

What's the best way to manage this without having to go back to the page
struct for every DMA mapping we want to make? Do we need to have
iov_extract_user_pages() note this in the bio_vec?

struct bio_vec {
physaddr_t bv_base_addr; /* 64-bits */
size_t bv_len:56; /* Maybe just u32 */
bool p2pdma:1; /* Region is involved in P2P */
unsigned int spare:7;
};

I'm guessing that only folio-type pages can be involved in this:

static inline struct dev_pagemap *page_pgmap(const struct page *page)
{
VM_WARN_ON_ONCE_PAGE(!is_zone_device_page(page), page);
return page_folio(page)->pgmap;
}

as only struct folio has a pointer to dev_pagemap? And I assume this is going
to get removed from struct page itself at some point soonish.

David