| /* SPDX-License-Identifier: GPL-2.0 */ |
| #ifndef _LINUX_NETDEV_RX_QUEUE_H |
| #define _LINUX_NETDEV_RX_QUEUE_H |
| |
| #include <linux/dma-buf.h> |
| #include <linux/kobject.h> |
| #include <linux/netdevice.h> |
| #include <linux/sysfs.h> |
| #include <net/xdp.h> |
| |
| /* This structure contains an instance of an RX queue. */ |
| struct netdev_rx_queue { |
| struct xdp_rxq_info xdp_rxq; |
| #ifdef CONFIG_RPS |
| struct rps_map __rcu *rps_map; |
| struct rps_dev_flow_table __rcu *rps_flow_table; |
| #endif |
| struct kobject kobj; |
| struct net_device *dev; |
| netdevice_tracker dev_tracker; |
| |
| #ifdef CONFIG_XDP_SOCKETS |
| struct xsk_buff_pool *pool; |
| #endif |
| struct file __rcu *dmabuf_pages; |
| } ____cacheline_aligned_in_smp; |
| |
| struct page * |
| __netdev_rxq_alloc_page_from_dmabuf_pool(struct netdev_rx_queue *rxq, |
| unsigned int order); |
| |
| static inline struct page *netdev_rxq_alloc_dma_buf_page(struct netdev_rx_queue *rxq, |
| unsigned int order) |
| { |
| |
| /* Return NULL if we can't allocate a dma_buf page, instead of trying |
| * to fallback to alloc_page(). The reason we do this is because we |
| * don't want to confuse the caller with respect to whether the page |
| * they are getting is a dma_buf page or otherwise. dma_buf pages and |
| * devmem skbs require special handling, so the distinction is |
| * important. Let the caller fall back to allocating a non-dma_buf page |
| * if they know what they're doing. |
| */ |
| if (unlikely(!rcu_access_pointer(rxq->dmabuf_pages))) |
| return NULL; |
| |
| return __netdev_rxq_alloc_page_from_dmabuf_pool(rxq, order); |
| } |
| |
| static inline void netdev_rxq_free_page(struct page *pg) |
| { |
| if (is_dma_buf_page(pg)) { |
| put_page(pg); |
| return; |
| } |
| |
| __free_page(pg); |
| } |
| |
| /* |
| * RX queue sysfs structures and functions. |
| */ |
| struct rx_queue_attribute { |
| struct attribute attr; |
| ssize_t (*show)(struct netdev_rx_queue *queue, char *buf); |
| ssize_t (*store)(struct netdev_rx_queue *queue, |
| const char *buf, size_t len); |
| }; |
| |
| static inline struct netdev_rx_queue * |
| __netif_get_rx_queue(struct net_device *dev, unsigned int rxq) |
| { |
| return dev->_rx + rxq; |
| } |
| |
| #ifdef CONFIG_SYSFS |
| static inline unsigned int |
| get_netdev_rx_queue_index(struct netdev_rx_queue *queue) |
| { |
| struct net_device *dev = queue->dev; |
| int index = queue - dev->_rx; |
| |
| BUG_ON(index >= dev->num_rx_queues); |
| return index; |
| } |
| #endif |
| #endif |