xdp: introduce bulking for page_pool tx return path
Subsystems (6)
cover xdp: introduce bulking for page_pool tx return path
xdp_return_frame/xdp_return_frame_napi and page_pool_put_page are usually run inside the driver NAPI tx completion loop so it is possible batch them. Introduce bulking capability in xdp tx return path (XDP_TX and XDP_REDIRECT). Convert mvneta driver to xdp_return_frame_bulk APIs.
mvneta upstream code:XDP_TX: ~296KppsXDP_REDIRECT: ~273Kpps
mvneta + xdp_return_frame_bulk APIs:XDP_TX: ~303KppsXDP_REDIRECT: ~287Kpps
Lorenzo Bianconi (2):
net: xdp: introduce bulking for xdp tx return path
net: page_pool: add bulk support for ptr_ring
drivers/net/ethernet/marvell/mvneta.c | 8 ++--- include/net/page_pool.h | 21 ++++++++++++ include/net/xdp.h | 11 ++++++ net/core/page_pool.c | 37 ++++++++++++++++++++ net/core/xdp.c | 49 +++++++++++++++++++++++++++ 5 files changed, 122 insertions(+), 4 deletions(-)
Signature · 1 line
2.26.2
RFC 1/2 net: xdp: introduce bulking for xdp tx return path
Introduce bulking capability in xdp tx return path (XDP_TX and XDP_REDIRECT). xdp_return_frame and xdp_return_frame_napi are usually run inside the driver NAPI tx completion loop so it is possible batch them.
Current implementation considers only page_pool memory model. Convert mvneta driver to xdp_return_frame_bulk APIs.
--- drivers/net/ethernet/marvell/mvneta.c | 8 ++--- include/net/xdp.h | 11 ++++++ net/core/xdp.c | 50 +++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 4 deletions(-)
drivers/net/ethernet/marvell/mvneta.c +4 -4
@@ -663,6 +663,8 @@ struct mvneta_tx_queue {/* Affinity mask for CPUs*/ cpumask_t affinity_mask; + +struct xdp_frame_bulk bq; };struct mvneta_rx_queue {
@@ -1854,12 +1856,10 @@ static void mvneta_txq_bufs_free(struct mvneta_port *pp,dev_kfree_skb_any (buf->skb); }else if (buf->type ==MVNETA_TYPE_XDP_TX || buf->type ==MVNETA_TYPE_XDP_NDO ) { -if (napi && buf->type ==MVNETA_TYPE_XDP_TX ) -xdp_return_frame_rx_napi (buf->xdpf); -else -xdp_return_frame (buf->xdpf); +xdp_return_frame_bulk (buf->xdpf, &txq->bq, napi); } } +xdp_flush_frame_bulk (&txq->bq, napi);netdev_tx_completed_queue (nq, pkts_compl, bytes_compl); }
include/net/xdp.h +11 -0
@@ -104,6 +104,12 @@ struct xdp_frame {struct net_device *dev_rx;/* used by cpumap */ }; +#define XDP_BULK_QUEUE_SIZE 16 +struct xdp_frame_bulk { +void *q[XDP_BULK_QUEUE_SIZE ]; +int count; +void *xa; +};static inline struct skb_shared_info *xdp_get_shared_info_from_frame (struct xdp_frame *frame)
@@ -194,6 +200,11 @@ struct xdp_frame *xdp_convert_buff_to_frame(struct xdp_buff *xdp)void xdp_return_frame (struct xdp_frame *xdpf);void xdp_return_frame_rx_napi (struct xdp_frame *xdpf);void xdp_return_buff (struct xdp_buff *xdp); +void xdp_flush_frame_bulk (struct xdp_frame_bulk *bq, +bool napi_direct); +void xdp_return_frame_bulk (struct xdp_frame *xdpf, +struct xdp_frame_bulk *bq, +bool napi_direct);/* When sending xdp_frame into the network stack, then there is no * return point callback, which is needed to release e.g. DMA-mapping
net/core/xdp.c +50 -0
56 lines not on this page · raw message
Signature · 1 line
2.26.2
Re: [RFC 1/2] net: xdp: introduce bulking for xdp tx return path
Quoted 14 lines · On Tue, 20 Oct 2020 11:33:37 +0200 Lorenzo Bianconi <[email protected]> wrote:
drivers/net/ethernet/marvell/mvneta.c +2
-0@@ -663,6 +663,8 @@ struct mvneta_tx_queue {/* Affinity mask for CPUs*/ cpumask_t affinity_mask; + +struct xdp_frame_bulk bq; };struct mvneta_rx_queue {
drivers/net/ethernet/marvell/mvneta.c static void mvneta_txq_bufs_free(struct mvneta_port *pp, · line 1859
Quoted 8 lines
drivers/net/ethernet/marvell/mvneta.c +1
-4@@ -1854,12 +1856,10 @@ static void mvneta_txq_bufs_free(struct mvneta_port *pp,dev_kfree_skb_any (buf->skb); }else if (buf->type ==MVNETA_TYPE_XDP_TX || buf->type ==MVNETA_TYPE_XDP_NDO ) { -if (napi && buf->type ==MVNETA_TYPE_XDP_TX ) -xdp_return_frame_rx_napi (buf->xdpf); -else -xdp_return_frame (buf->xdpf); +xdp_return_frame_bulk (buf->xdpf, &txq->bq, napi);
Hmm, I don't think you can use 'napi' directly here.
You are circumventing check (buf->type == MVNETA_TYPE_XDP_TX), and will now also allow XDP_NDO (XDP_REDIRECT) to basically use xdp_return_frame_rx_napi().
Quoted 6 lines
drivers/net/ethernet/marvell/mvneta.c +1
-0} } +xdp_flush_frame_bulk (&txq->bq, napi);netdev_tx_completed_queue (nq, pkts_compl, bytes_compl); }
Signature · 4 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
Re: [RFC 1/2] net: xdp: introduce bulking for xdp tx return path
Quoted 28 lines
Quoted 14 lines · On Tue, 20 Oct 2020 11:33:37 +0200 Lorenzo Bianconi <[email protected]> wrote:
drivers/net/ethernet/marvell/mvneta.c +2
-0@@ -663,6 +663,8 @@ struct mvneta_tx_queue {/* Affinity mask for CPUs*/ cpumask_t affinity_mask; + +struct xdp_frame_bulk bq; };struct mvneta_rx_queue {drivers/net/ethernet/marvell/mvneta.c static void mvneta_txq_bufs_free(struct mvneta_port *pp, · line 1859
Quoted 8 lines
drivers/net/ethernet/marvell/mvneta.c +1
-4@@ -1854,12 +1856,10 @@ static void mvneta_txq_bufs_free(struct mvneta_port *pp,dev_kfree_skb_any (buf->skb); }else if (buf->type ==MVNETA_TYPE_XDP_TX || buf->type ==MVNETA_TYPE_XDP_NDO ) { -if (napi && buf->type ==MVNETA_TYPE_XDP_TX ) -xdp_return_frame_rx_napi (buf->xdpf); -else -xdp_return_frame (buf->xdpf); +xdp_return_frame_bulk (buf->xdpf, &txq->bq, napi);Hmm, I don't think you can use 'napi' directly here.
Quoted 2 lines
You are circumventing check (
buf->type==MVNETA_TYPE_XDP_TX), and will now also allowXDP_NDO(XDP_REDIRECT) to basically usexdp_return_frame_rx_napi().
ack, right. I will fix it.
Regards,
Lorenzo
Quoted 17 lines
Quoted 8 lines
drivers/net/ethernet/marvell/mvneta.c +1
-0} } +xdp_flush_frame_bulk (&txq->bq, napi);netdev_tx_completed_queue (nq, pkts_compl, bytes_compl); }Signature · 4 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
RFC 2/2 net: page_pool: add bulk support for ptr_ring
In reply to Lorenzo BianconiIntroduce the capability to batch page_pool ptr_ring refill since it is usually run inside the driver NAPI tx completion loop.
--- include/net/page_pool.h | 21 +++++++++++++++++++++ net/core/page_pool.c | 37 +++++++++++++++++++++++++++++++++++++ net/core/xdp.c | 13 ++++++------- 3 files changed, 64 insertions(+), 7 deletions(-)
include/net/page_pool.h +21 -0
@@ -169,6 +169,8 @@ static inline void page_pool_release_page(struct page_pool *pool,void page_pool_put_page (struct page_pool *pool,struct page *page,unsigned int dma_sync_size,bool allow_direct); +void page_pool_put_page_bulk (struct page_pool *pool,void **data,int count, +bool allow_direct);/* Same as above but will try to sync the entire area pool->max_len */ static inline void page_pool_put_full_page(struct page_pool *pool,
@@ -215,4 +217,23 @@ static inline void page_pool_nid_changed(struct page_pool *pool, int new_nid)if (unlikely (pool->p.nid != new_nid))page_pool_update_nid (pool, new_nid); } + +static inline void page_pool_ring_lock(struct page_pool *pool) + __acquires(&pool->ring.producer_lock) +{ +if (in_serving_softirq ()) +spin_lock (&pool->ring.producer_lock); +else +spin_lock_bh (&pool->ring.producer_lock); +} + +static inline void page_pool_ring_unlock (struct page_pool *pool) + __releases(&pool->ring.producer_lock) +{ +if (in_serving_softirq ()) +spin_unlock (&pool->ring.producer_lock); +else +spin_unlock_bh (&pool->ring.producer_lock); +} +#endif /* _NET_PAGE_POOL_H */
net/core/page_pool.c +37 -0
@@ -11,6 +11,8 @@#include <linux/device.h> #include <net/page_pool.h> +#include <net/xdp.h> +#include <linux/dma-direction.h> #include <linux/dma-mapping.h> #include <linux/page-flags.h>
@@ -408,6 +410,41 @@ void page_pool_put_page(struct page_pool *pool, struct page *page, }EXPORT_SYMBOL (page_pool_put_page); +void page_pool_put_page_bulk (struct page_pool *pool,void **data,int count, +bool allow_direct) +{ +struct page *page_ring[XDP_BULK_QUEUE_SIZE ]; +int i, len =0 ; + +for (i =0 ; i < count; i++) { +struct page *page =virt_to_head_page (data[i]); + +if (unlikely (page_ref_count (page) !=1 || + !pool_page_reusable (pool, page))) { +page_pool_release_page (pool, page); +put_page (page); +continue ; + } + +if (pool->p.flags &PP_FLAG_DMA_SYNC_DEV ) +page_pool_dma_sync_for_device (pool, page,-1 ); + +if (allow_direct &&in_serving_softirq () && +page_pool_recycle_in_cache (page, pool)) +continue ; + + page_ring[len++] = page; + } + +page_pool_ring_lock (pool); +for (i =0 ; i < len; i++) { +if (__ptr_ring_produce (&pool->ring, page_ring[i])) +page_pool_return_page (pool, page_ring[i]); + } +page_pool_ring_unlock (pool); +} +EXPORT_SYMBOL (page_pool_put_page_bulk); +static void page_pool_empty_ring (struct page_pool *pool) {struct page *page;
net/core/xdp.c +6 -7
@@ -384,14 +384,13 @@ void xdp_flush_frame_bulk(struct xdp_frame_bulk *bq, bool napi_direct) {struct xdp_mem_allocator *xa = bq->xa; -int i; -for (i =0 ; i < bq->count; i++) { - napi_direct &= !xdp_return_frame_no_direct (); -page_pool_put_full_page (xa->page_pool, -virt_to_head_page (bq->q[i]), - napi_direct); - } +if (unlikely (!bq->count)) +return ; + + napi_direct &= !xdp_return_frame_no_direct (); +page_pool_put_page_bulk (xa->page_pool, bq->q, bq->count, + napi_direct); bq->count =0 ; }EXPORT_SYMBOL_GPL (xdp_flush_frame_bulk);
Signature · 1 line
2.26.2
kernel test robot
build botRe: [RFC 2/2] net: page_pool: add bulk support for ptr_ring
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch]
Hi Lorenzo,
[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on net/master]
[also build test ERROR on net-next/master linus/master next-20201016] [cannot apply to ipvs/master v5.9]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Lorenzo-Bianconi/xdp-introduce-bulking-for-page_pool-tx-return-path/20201020-173429 base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git df6afe2f7c19349de2ee560dc62ea4d9ad3ff889 config: microblaze-nommu_defconfig (attached as .config) compiler: microblaze-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/2f929a681db7cecf34421d870697eaca69856d3c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Lorenzo-Bianconi/xdp-introduce-bulking-for-page_pool-tx-return-path/20201020-173429 git checkout 2f929a681db7cecf34421d870697eaca69856d3c
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=microblaze
If you fix the issue, kindly add following tag as appropriate
All errors (new ones prefixed by >>):
microblaze-linux-ld: net/core/xdp.o: in function `xdp_flush_frame_bulk':
>> (.text+0xc8): undefined reference to `page_pool_put_page_bulk'
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org