Merge tag 'ntb-5.11' of git://github.com/jonmason/ntb
[linux-2.6-microblaze.git] / Documentation / networking / page_pool.rst
1 .. SPDX-License-Identifier: GPL-2.0
2
3 =============
4 Page Pool API
5 =============
6
7 The page_pool allocator is optimized for the XDP mode that uses one frame
8 per-page, but it can fallback on the regular page allocator APIs.
9
10 Basic use involves replacing alloc_pages() calls with the
11 page_pool_alloc_pages() call.  Drivers should use page_pool_dev_alloc_pages()
12 replacing dev_alloc_pages().
13
14 API keeps track of inflight pages, in order to let API user know
15 when it is safe to free a page_pool object.  Thus, API users
16 must run page_pool_release_page() when a page is leaving the page_pool or
17 call page_pool_put_page() where appropriate in order to maintain correct
18 accounting.
19
20 API user must call page_pool_put_page() once on a page, as it
21 will either recycle the page, or in case of refcnt > 1, it will
22 release the DMA mapping and inflight state accounting.
23
24 Architecture overview
25 =====================
26
27 .. code-block:: none
28
29     +------------------+
30     |       Driver     |
31     +------------------+
32             ^
33             |
34             |
35             |
36             v
37     +--------------------------------------------+
38     |                request memory              |
39     +--------------------------------------------+
40         ^                                  ^
41         |                                  |
42         | Pool empty                       | Pool has entries
43         |                                  |
44         v                                  v
45     +-----------------------+     +------------------------+
46     | alloc (and map) pages |     |  get page from cache   |
47     +-----------------------+     +------------------------+
48                                     ^                    ^
49                                     |                    |
50                                     | cache available    | No entries, refill
51                                     |                    | from ptr-ring
52                                     |                    |
53                                     v                    v
54                           +-----------------+     +------------------+
55                           |   Fast cache    |     |  ptr-ring cache  |
56                           +-----------------+     +------------------+
57
58 API interface
59 =============
60 The number of pools created **must** match the number of hardware queues
61 unless hardware restrictions make that impossible. This would otherwise beat the
62 purpose of page pool, which is allocate pages fast from cache without locking.
63 This lockless guarantee naturally comes from running under a NAPI softirq.
64 The protection doesn't strictly have to be NAPI, any guarantee that allocating
65 a page will cause no race conditions is enough.
66
67 * page_pool_create(): Create a pool.
68     * flags:      PP_FLAG_DMA_MAP, PP_FLAG_DMA_SYNC_DEV
69     * order:      2^order pages on allocation
70     * pool_size:  size of the ptr_ring
71     * nid:        preferred NUMA node for allocation
72     * dev:        struct device. Used on DMA operations
73     * dma_dir:    DMA direction
74     * max_len:    max DMA sync memory size
75     * offset:     DMA address offset
76
77 * page_pool_put_page(): The outcome of this depends on the page refcnt. If the
78   driver bumps the refcnt > 1 this will unmap the page. If the page refcnt is 1
79   the allocator owns the page and will try to recycle it in one of the pool
80   caches. If PP_FLAG_DMA_SYNC_DEV is set, the page will be synced for_device
81   using dma_sync_single_range_for_device().
82
83 * page_pool_put_full_page(): Similar to page_pool_put_page(), but will DMA sync
84   for the entire memory area configured in area pool->max_len.
85
86 * page_pool_recycle_direct(): Similar to page_pool_put_full_page() but caller
87   must guarantee safe context (e.g NAPI), since it will recycle the page
88   directly into the pool fast cache.
89
90 * page_pool_release_page(): Unmap the page (if mapped) and account for it on
91   inflight counters.
92
93 * page_pool_dev_alloc_pages(): Get a page from the page allocator or page_pool
94   caches.
95
96 * page_pool_get_dma_addr(): Retrieve the stored DMA address.
97
98 * page_pool_get_dma_dir(): Retrieve the stored DMA direction.
99
100 * page_pool_put_page_bulk(): Tries to refill a number of pages into the
101   ptr_ring cache holding ptr_ring producer lock. If the ptr_ring is full,
102   page_pool_put_page_bulk() will release leftover pages to the page allocator.
103   page_pool_put_page_bulk() is suitable to be run inside the driver NAPI tx
104   completion loop for the XDP_REDIRECT use case.
105   Please note the caller must not use data area after running
106   page_pool_put_page_bulk(), as this function overwrites it.
107
108 Coding examples
109 ===============
110
111 Registration
112 ------------
113
114 .. code-block:: c
115
116     /* Page pool registration */
117     struct page_pool_params pp_params = { 0 };
118     struct xdp_rxq_info xdp_rxq;
119     int err;
120
121     pp_params.order = 0;
122     /* internal DMA mapping in page_pool */
123     pp_params.flags = PP_FLAG_DMA_MAP;
124     pp_params.pool_size = DESC_NUM;
125     pp_params.nid = NUMA_NO_NODE;
126     pp_params.dev = priv->dev;
127     pp_params.dma_dir = xdp_prog ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE;
128     page_pool = page_pool_create(&pp_params);
129
130     err = xdp_rxq_info_reg(&xdp_rxq, ndev, 0);
131     if (err)
132         goto err_out;
133
134     err = xdp_rxq_info_reg_mem_model(&xdp_rxq, MEM_TYPE_PAGE_POOL, page_pool);
135     if (err)
136         goto err_out;
137
138 NAPI poller
139 -----------
140
141
142 .. code-block:: c
143
144     /* NAPI Rx poller */
145     enum dma_data_direction dma_dir;
146
147     dma_dir = page_pool_get_dma_dir(dring->page_pool);
148     while (done < budget) {
149         if (some error)
150             page_pool_recycle_direct(page_pool, page);
151         if (packet_is_xdp) {
152             if XDP_DROP:
153                 page_pool_recycle_direct(page_pool, page);
154         } else (packet_is_skb) {
155             page_pool_release_page(page_pool, page);
156             new_page = page_pool_dev_alloc_pages(page_pool);
157         }
158     }
159
160 Driver unload
161 -------------
162
163 .. code-block:: c
164
165     /* Driver unload */
166     page_pool_put_full_page(page_pool, page, false);
167     xdp_rxq_info_unreg(&xdp_rxq);