* [dhowells-fs:netfs-next-3 13/26] fs/netfs/bvecq.c:79:22: error: implicit declaration of function 'mempool_alloc_noreserve'
@ 2026-09-26 17:59 kernel test robot
0 siblings, 0 replies; only message in thread
From: kernel test robot @ 2026-09-26 17:59 UTC (permalink / raw)
To: David Howells; +Cc: oe-kbuild-all
tree: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git netfs-next-3
head: 65d1ffcb408ea16b3a4a497269da871c62b7faa3
commit: 217cce19dbecd925c96842bf3b15c0b45e19a930 [13/26] netfs: Add some tools for managing bvecq chains
config: parisc-defconfig (https://download.01.org/0day-ci/archive/20260927/202609270101.Fe684goD-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 16.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260927/202609270101.Fe684goD-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202609270101.Fe684goD-lkp@intel.com/
All errors (new ones prefixed by >>):
fs/netfs/bvecq.c: In function 'bvecq_alloc_one':
>> fs/netfs/bvecq.c:79:22: error: implicit declaration of function 'mempool_alloc_noreserve' [-Wimplicit-function-declaration]
79 | bq = mempool_alloc_noreserve(&netfs_bvecq_pool, gfp);
| ^~~~~~~~~~~~~~~~~~~~~~~
fs/netfs/bvecq.c:79:20: error: assignment to 'struct bvecq *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
79 | bq = mempool_alloc_noreserve(&netfs_bvecq_pool, gfp);
| ^
fs/netfs/bvecq.c: In function 'bvecq_put':
>> fs/netfs/bvecq.c:277:25: error: implicit declaration of function 'mempool_free' [-Wimplicit-function-declaration]
277 | mempool_free(bq, &netfs_bvecq_pool);
| ^~~~~~~~~~~~
vim +/mempool_alloc_noreserve +79 fs/netfs/bvecq.c
38
39 /**
40 * bvecq_alloc_one - Allocate a single bvecq node with unpopulated slots
41 * @nr_slots: Number of slots to allocate
42 * @gfp: The allocation constraints.
43 * @for_writeback: True if allocating for writeback
44 *
45 * Allocate a single bvecq node and initialise the header. The allocation is
46 * rounded up to the size of the smallest slab granule that will accommodate it
47 * and all the remaining space is set as an inline slot array with max_slots
48 * set to the number of slots. The slot array is not initialised.
49 *
50 * If @for_writeback is set, then the emergency mempool may be used for
51 * allocation. If it does allocate from that pool, the maximum number of slots
52 * available will be BVECQ_POOL_SLOTS which may be less than requested. Also,
53 * if @for_writeback is set, the function will not fail - though it may have to
54 * wait.
55 *
56 * Return: The node pointer or NULL on allocation failure.
57 */
58 struct bvecq *bvecq_alloc_one(size_t nr_slots, gfp_t gfp, bool for_writeback)
59 {
60 struct bvecq *bq;
61 const size_t pool_size = struct_size_t(struct bvecq, __bv, BVECQ_POOL_SLOTS);
62 size_t size;
63 bool from_pool = false;
64
65 size = kmalloc_size_roundup(struct_size(bq, __bv, nr_slots));
66 gfp &= ~(GFP_ZONEMASK | __GFP_THISNODE);
67
68 if (for_writeback) {
69 if (size != pool_size) {
70 gfp_t gfp_temp = gfp;
71
72 gfp_temp |= __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN;
73 gfp_temp &= ~(__GFP_DIRECT_RECLAIM | __GFP_IO);
74 bq = kmalloc(size, gfp_temp);
75 if (bq)
76 goto success;
77 }
78
> 79 bq = mempool_alloc_noreserve(&netfs_bvecq_pool, gfp);
80 if (!bq)
81 return bq;
82 from_pool = true;
83 size = pool_size;
84 } else {
85 bq = kmalloc(size, gfp);
86 if (!bq)
87 return bq;
88 }
89
90 success:
91 *bq = (struct bvecq) {
92 .ref = REFCOUNT_INIT(1),
93 .bv = bq->__bv,
94 .inline_bv = true,
95 .max_slots = (size - sizeof(*bq)) / sizeof(bq->__bv[0]),
96 .from_pool = from_pool,
97 };
98 netfs_stat(&netfs_n_bvecq);
99 return bq;
100 }
101 EXPORT_SYMBOL(bvecq_alloc_one);
102
103 /**
104 * bvecq_alloc_chain - Allocate an unpopulated bvecq chain
105 * @nr_slots: Number of slots to allocate
106 * @gfp: The allocation constraints.
107 * @for_writeback: True if allocating for writeback
108 *
109 * Allocate a chain of bvecq nodes providing at least the requested cumulative
110 * number of slots. Each node is a maximum of 4KiB in size.
111 *
112 * Return: The first node pointer or NULL on allocation failure.
113 */
114 struct bvecq *bvecq_alloc_chain(size_t nr_slots, gfp_t gfp, bool for_writeback)
115 {
116 struct bvecq *head = NULL, *tail = NULL;
117
118 _enter("%zu", nr_slots);
119
120 for (;;) {
121 struct bvecq *bq;
122
123 bq = bvecq_alloc_one(min(nr_slots, BVECQ_4KB_SLOTS), gfp, for_writeback);
124 if (!bq)
125 goto oom;
126
127 if (tail)
128 bvecq_append(tail, bq);
129 else
130 head = bq;
131 tail = bq;
132 if (tail->max_slots >= nr_slots)
133 break;
134 nr_slots -= tail->max_slots;
135 }
136
137 return head;
138 oom:
139 bvecq_put(head);
140 return NULL;
141 }
142 EXPORT_SYMBOL(bvecq_alloc_chain);
143
144 /**
145 * bvecq_alloc_buffer2 - Allocate a bvecq chain and populate with buffers
146 * @size: Target size of the buffer (can be 0 for an empty buffer)
147 * @pre_slots: Number of preamble slots to set aside
148 * @gfp: The allocation constraints.
149 * @for_writeback: True if allocating for writeback
150 *
151 * Allocate a chain of bvecq nodes and populate the slots with sufficient pages
152 * to provide at least the requested amount of space, leaving the first
153 * @pre_slots slots unset. The pre-slots must all fit into the the first
154 * bvecq.
155 *
156 * The pages allocated may be compound pages larger than PAGE_SIZE and thus
157 * occupy fewer slots. The pages have their refcounts set to 1 and can be
158 * passed to MSG_SPLICE_PAGES.
159 *
160 * Return: The first node pointer or NULL on allocation failure.
161 */
162 struct bvecq *bvecq_alloc_buffer2(size_t size, unsigned int pre_slots, gfp_t gfp,
163 bool for_writeback)
164 {
165 struct bvecq *head = NULL, *p = NULL;
166 size_t nr_per_bq = BVECQ_POOL_SLOTS;
167 size_t count = pre_slots + DIV_ROUND_UP(size, PAGE_SIZE);
168
169 _enter("%zx,%zx,%u", size, count, pre_slots);
170
171 if (WARN_ON_ONCE(pre_slots > nr_per_bq))
172 return NULL;
173
174 head = bvecq_alloc_chain(count, gfp, for_writeback);
175 if (!head)
176 return NULL;
177
178 p = head;
179 do {
180 struct page **pages;
181 size_t unused, want, got, slot;
182
183 if (!count)
184 break;
185 if (WARN_ON_ONCE(!p))
186 goto oom;
187
188 if (p->nr_slots == 0) {
189 /* Need to clear pre slots and pages[], so just clear all. */
190 memset(p->bv, 0, p->max_slots * sizeof(p->bv[0]));
191 p->mem_type = BVECQ_MEM_ALLOCED;
192 p->nr_slots = pre_slots;
193 count -= pre_slots;
194 pre_slots = 0;
195 if (!count)
196 break;
197 }
198
199 if (p->nr_slots >= p->max_slots) {
200 p = p->next;
201 continue;
202 }
203 unused = p->max_slots - p->nr_slots;
204
205 pages = (struct page **)&p->bv[p->max_slots];
206 pages -= unused;
207
208 want = min(count, unused);
209 got = alloc_pages_bulk(gfp, want, pages);
210 if (!got)
211 goto oom;
212
213 slot = p->nr_slots;
214 for (int i = 0; i < got; i++) {
215 set_page_count(pages[i], 1);
216 bvec_set_page(&p->bv[slot++], pages[i], PAGE_SIZE, 0);
217 }
218
219 bvecq_filled_to(p, slot);
220 count -= got;
221 } while (count > 0);
222
223 return head;
224 oom:
225 bvecq_put(head);
226 return NULL;
227 }
228 EXPORT_SYMBOL(bvecq_alloc_buffer2);
229
230 /*
231 * Free the page pointed to by a slot as necessary.
232 */
233 static void bvecq_free_slot(struct bvecq *bq, unsigned int slot)
234 {
235 struct page *page = bq->bv[slot].bv_page;
236
237 if (!page)
238 return;
239
240 switch (bq->mem_type) {
241 case BVECQ_MEM_EXTERNAL:
242 break;
243 case BVECQ_MEM_PAGECACHE:
244 put_page(page);
245 break;
246 case BVECQ_MEM_GUP:
247 unpin_user_page(page);
248 break;
249 case BVECQ_MEM_ALLOCED:
250 __free_pages(page, compound_order(page));
251 break;
252 default:
253 WARN_ON_ONCE(1);
254 break;
255 }
256 }
257
258 /**
259 * bvecq_put - Put a ref on a bvec queue
260 * @bq: The start of the folio queue to free
261 *
262 * Put the ref(s) on the nodes in a bvec queue, freeing up the node and the
263 * page fragments it points to as the refcounts become zero.
264 */
265 void bvecq_put(struct bvecq *bq)
266 {
267 struct bvecq *next;
268
269 for (; bq; bq = next) {
270 if (!refcount_dec_and_test(&bq->ref))
271 break;
272 for (int slot = 0; slot < bq->nr_slots; slot++)
273 bvecq_free_slot(bq, slot);
274 next = bq->next;
275 netfs_stat_d(&netfs_n_bvecq);
276 if (bq->from_pool)
> 277 mempool_free(bq, &netfs_bvecq_pool);
278 else
279 kfree(bq);
280 }
281 }
282 EXPORT_SYMBOL(bvecq_put);
283
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-26 17:59 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-26 17:59 [dhowells-fs:netfs-next-3 13/26] fs/netfs/bvecq.c:79:22: error: implicit declaration of function 'mempool_alloc_noreserve' kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.