mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
netdev: netdevice devmem allocator
Implement netdev devmem allocator. The allocator takes a given struct netdev_dmabuf_binding as input and allocates net_iov from that binding. The allocation simply delegates to the binding's genpool for the allocation logic and wraps the returned memory region in a net_iov struct. Signed-off-by: Willem de Bruijn <willemb@google.com> Signed-off-by: Kaiyuan Zhang <kaiyuanz@google.com> Signed-off-by: Mina Almasry <almasrymina@google.com> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> Reviewed-by: Jakub Kicinski <kuba@kernel.org> Link: https://patch.msgid.link/20240910171458.219195-5-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
170aafe35c
commit
28c5c74eea
@ -34,6 +34,14 @@ static void net_devmem_dmabuf_free_chunk_owner(struct gen_pool *genpool,
|
||||
kfree(owner);
|
||||
}
|
||||
|
||||
static dma_addr_t net_devmem_get_dma_addr(const struct net_iov *niov)
|
||||
{
|
||||
struct dmabuf_genpool_chunk_owner *owner = net_iov_owner(niov);
|
||||
|
||||
return owner->base_dma_addr +
|
||||
((dma_addr_t)net_iov_idx(niov) << PAGE_SHIFT);
|
||||
}
|
||||
|
||||
void __net_devmem_dmabuf_binding_free(struct net_devmem_dmabuf_binding *binding)
|
||||
{
|
||||
size_t size, avail;
|
||||
@ -56,6 +64,39 @@ void __net_devmem_dmabuf_binding_free(struct net_devmem_dmabuf_binding *binding)
|
||||
kfree(binding);
|
||||
}
|
||||
|
||||
struct net_iov *
|
||||
net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding)
|
||||
{
|
||||
struct dmabuf_genpool_chunk_owner *owner;
|
||||
unsigned long dma_addr;
|
||||
struct net_iov *niov;
|
||||
ssize_t offset;
|
||||
ssize_t index;
|
||||
|
||||
dma_addr = gen_pool_alloc_owner(binding->chunk_pool, PAGE_SIZE,
|
||||
(void **)&owner);
|
||||
if (!dma_addr)
|
||||
return NULL;
|
||||
|
||||
offset = dma_addr - owner->base_dma_addr;
|
||||
index = offset / PAGE_SIZE;
|
||||
niov = &owner->niovs[index];
|
||||
|
||||
return niov;
|
||||
}
|
||||
|
||||
void net_devmem_free_dmabuf(struct net_iov *niov)
|
||||
{
|
||||
struct net_devmem_dmabuf_binding *binding = net_iov_binding(niov);
|
||||
unsigned long dma_addr = net_devmem_get_dma_addr(niov);
|
||||
|
||||
if (WARN_ON(!gen_pool_has_addr(binding->chunk_pool, dma_addr,
|
||||
PAGE_SIZE)))
|
||||
return;
|
||||
|
||||
gen_pool_free(binding->chunk_pool, dma_addr, PAGE_SIZE);
|
||||
}
|
||||
|
||||
void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding)
|
||||
{
|
||||
struct netdev_rx_queue *rxq;
|
||||
|
@ -74,6 +74,23 @@ int net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
|
||||
struct netlink_ext_ack *extack);
|
||||
void dev_dmabuf_uninstall(struct net_device *dev);
|
||||
|
||||
static inline struct dmabuf_genpool_chunk_owner *
|
||||
net_iov_owner(const struct net_iov *niov)
|
||||
{
|
||||
return niov->owner;
|
||||
}
|
||||
|
||||
static inline unsigned int net_iov_idx(const struct net_iov *niov)
|
||||
{
|
||||
return niov - net_iov_owner(niov)->niovs;
|
||||
}
|
||||
|
||||
static inline struct net_devmem_dmabuf_binding *
|
||||
net_iov_binding(const struct net_iov *niov)
|
||||
{
|
||||
return net_iov_owner(niov)->binding;
|
||||
}
|
||||
|
||||
static inline void
|
||||
net_devmem_dmabuf_binding_get(struct net_devmem_dmabuf_binding *binding)
|
||||
{
|
||||
@ -89,7 +106,13 @@ net_devmem_dmabuf_binding_put(struct net_devmem_dmabuf_binding *binding)
|
||||
__net_devmem_dmabuf_binding_free(binding);
|
||||
}
|
||||
|
||||
struct net_iov *
|
||||
net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding);
|
||||
void net_devmem_free_dmabuf(struct net_iov *ppiov);
|
||||
|
||||
#else
|
||||
struct net_devmem_dmabuf_binding;
|
||||
|
||||
static inline void
|
||||
__net_devmem_dmabuf_binding_free(struct net_devmem_dmabuf_binding *binding)
|
||||
{
|
||||
@ -119,6 +142,17 @@ net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
|
||||
static inline void dev_dmabuf_uninstall(struct net_device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct net_iov *
|
||||
net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void net_devmem_free_dmabuf(struct net_iov *ppiov)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _NET_DEVMEM_H */
|
||||
|
Loading…
Reference in New Issue
Block a user