Skip to content

Commit 35d8ba2

Browse files
rleonkawasaki
authored andcommitted
PCI/P2PDMA: Introduce p2pdma_provider structure for cleaner abstraction
Extract the core P2PDMA provider information (device owner and bus offset) from the dev_pagemap into a dedicated p2pdma_provider structure. This creates a cleaner separation between the memory management layer and the P2PDMA functionality. The new p2pdma_provider structure contains: - owner: pointer to the providing device - bus_offset: computed offset for non-host transactions This refactoring simplifies the P2PDMA state management by removing the need to access pgmap internals directly. The pci_p2pdma_map_state now stores a pointer to the provider instead of the pgmap, making the API more explicit and easier to understand. Signed-off-by: Jason Gunthorpe <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]>
1 parent ac93cfa commit 35d8ba2

2 files changed

Lines changed: 37 additions & 23 deletions

File tree

drivers/pci/p2pdma.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ struct pci_p2pdma {
2828
};
2929

3030
struct pci_p2pdma_pagemap {
31-
struct pci_dev *provider;
32-
u64 bus_offset;
3331
struct dev_pagemap pgmap;
32+
struct p2pdma_provider mem;
3433
};
3534

3635
static struct pci_p2pdma_pagemap *to_p2p_pgmap(struct dev_pagemap *pgmap)
@@ -204,8 +203,8 @@ static void p2pdma_page_free(struct page *page)
204203
{
205204
struct pci_p2pdma_pagemap *pgmap = to_p2p_pgmap(page_pgmap(page));
206205
/* safe to dereference while a reference is held to the percpu ref */
207-
struct pci_p2pdma *p2pdma =
208-
rcu_dereference_protected(pgmap->provider->p2pdma, 1);
206+
struct pci_p2pdma *p2pdma = rcu_dereference_protected(
207+
to_pci_dev(pgmap->mem.owner)->p2pdma, 1);
209208
struct percpu_ref *ref;
210209

211210
gen_pool_free_owner(p2pdma->pool, (uintptr_t)page_to_virt(page),
@@ -270,14 +269,15 @@ static int pci_p2pdma_setup(struct pci_dev *pdev)
270269

271270
static void pci_p2pdma_unmap_mappings(void *data)
272271
{
273-
struct pci_dev *pdev = data;
272+
struct pci_p2pdma_pagemap *p2p_pgmap = data;
274273

275274
/*
276275
* Removing the alloc attribute from sysfs will call
277276
* unmap_mapping_range() on the inode, teardown any existing userspace
278277
* mappings and prevent new ones from being created.
279278
*/
280-
sysfs_remove_file_from_group(&pdev->dev.kobj, &p2pmem_alloc_attr.attr,
279+
sysfs_remove_file_from_group(&p2p_pgmap->mem.owner->kobj,
280+
&p2pmem_alloc_attr.attr,
281281
p2pmem_group.name);
282282
}
283283

@@ -328,10 +328,9 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
328328
pgmap->nr_range = 1;
329329
pgmap->type = MEMORY_DEVICE_PCI_P2PDMA;
330330
pgmap->ops = &p2pdma_pgmap_ops;
331-
332-
p2p_pgmap->provider = pdev;
333-
p2p_pgmap->bus_offset = pci_bus_address(pdev, bar) -
334-
pci_resource_start(pdev, bar);
331+
p2p_pgmap->mem.owner = &pdev->dev;
332+
p2p_pgmap->mem.bus_offset =
333+
pci_bus_address(pdev, bar) - pci_resource_start(pdev, bar);
335334

336335
addr = devm_memremap_pages(&pdev->dev, pgmap);
337336
if (IS_ERR(addr)) {
@@ -340,7 +339,7 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
340339
}
341340

342341
error = devm_add_action_or_reset(&pdev->dev, pci_p2pdma_unmap_mappings,
343-
pdev);
342+
p2p_pgmap);
344343
if (error)
345344
goto pages_free;
346345

@@ -973,16 +972,16 @@ void pci_p2pmem_publish(struct pci_dev *pdev, bool publish)
973972
}
974973
EXPORT_SYMBOL_GPL(pci_p2pmem_publish);
975974

976-
static enum pci_p2pdma_map_type pci_p2pdma_map_type(struct dev_pagemap *pgmap,
977-
struct device *dev)
975+
static enum pci_p2pdma_map_type
976+
pci_p2pdma_map_type(struct p2pdma_provider *provider, struct device *dev)
978977
{
979978
enum pci_p2pdma_map_type type = PCI_P2PDMA_MAP_NOT_SUPPORTED;
980-
struct pci_dev *provider = to_p2p_pgmap(pgmap)->provider;
979+
struct pci_dev *pdev = to_pci_dev(provider->owner);
981980
struct pci_dev *client;
982981
struct pci_p2pdma *p2pdma;
983982
int dist;
984983

985-
if (!provider->p2pdma)
984+
if (!pdev->p2pdma)
986985
return PCI_P2PDMA_MAP_NOT_SUPPORTED;
987986

988987
if (!dev_is_pci(dev))
@@ -991,24 +990,29 @@ static enum pci_p2pdma_map_type pci_p2pdma_map_type(struct dev_pagemap *pgmap,
991990
client = to_pci_dev(dev);
992991

993992
rcu_read_lock();
994-
p2pdma = rcu_dereference(provider->p2pdma);
993+
p2pdma = rcu_dereference(pdev->p2pdma);
995994

996995
if (p2pdma)
997996
type = xa_to_value(xa_load(&p2pdma->map_types,
998997
map_types_idx(client)));
999998
rcu_read_unlock();
1000999

10011000
if (type == PCI_P2PDMA_MAP_UNKNOWN)
1002-
return calc_map_type_and_dist(provider, client, &dist, true);
1001+
return calc_map_type_and_dist(pdev, client, &dist, true);
10031002

10041003
return type;
10051004
}
10061005

10071006
void __pci_p2pdma_update_state(struct pci_p2pdma_map_state *state,
10081007
struct device *dev, struct page *page)
10091008
{
1010-
state->pgmap = page_pgmap(page);
1011-
state->map = pci_p2pdma_map_type(state->pgmap, dev);
1009+
struct pci_p2pdma_pagemap *p2p_pgmap = to_p2p_pgmap(page_pgmap(page));
1010+
1011+
if (state->mem == &p2p_pgmap->mem)
1012+
return;
1013+
1014+
state->mem = &p2p_pgmap->mem;
1015+
state->map = pci_p2pdma_map_type(&p2p_pgmap->mem, dev);
10121016
}
10131017

10141018
/**

include/linux/pci-p2pdma.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@
1616
struct block_device;
1717
struct scatterlist;
1818

19+
/**
20+
* struct p2pdma_provider
21+
*
22+
* A p2pdma provider is a range of MMIO address space available to the CPU.
23+
*/
24+
struct p2pdma_provider {
25+
struct device *owner;
26+
u64 bus_offset;
27+
};
28+
1929
#ifdef CONFIG_PCI_P2PDMA
2030
int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
2131
u64 offset);
@@ -144,10 +154,11 @@ enum pci_p2pdma_map_type {
144154
};
145155

146156
struct pci_p2pdma_map_state {
147-
struct dev_pagemap *pgmap;
157+
struct p2pdma_provider *mem;
148158
enum pci_p2pdma_map_type map;
149159
};
150160

161+
151162
/* helper for pci_p2pdma_state(), do not use directly */
152163
void __pci_p2pdma_update_state(struct pci_p2pdma_map_state *state,
153164
struct device *dev, struct page *page);
@@ -166,8 +177,7 @@ pci_p2pdma_state(struct pci_p2pdma_map_state *state, struct device *dev,
166177
struct page *page)
167178
{
168179
if (IS_ENABLED(CONFIG_PCI_P2PDMA) && is_pci_p2pdma_page(page)) {
169-
if (state->pgmap != page_pgmap(page))
170-
__pci_p2pdma_update_state(state, dev, page);
180+
__pci_p2pdma_update_state(state, dev, page);
171181
return state->map;
172182
}
173183
return PCI_P2PDMA_MAP_NONE;
@@ -185,7 +195,7 @@ static inline dma_addr_t
185195
pci_p2pdma_bus_addr_map(struct pci_p2pdma_map_state *state, phys_addr_t paddr)
186196
{
187197
WARN_ON_ONCE(state->map != PCI_P2PDMA_MAP_BUS_ADDR);
188-
return paddr + to_p2p_pgmap(state->pgmap)->bus_offsetf;
198+
return paddr + state->mem->bus_offset;
189199
}
190200

191201
#endif /* _LINUX_PCI_P2P_H */

0 commit comments

Comments
 (0)