.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2007 Jens Axboe <jens.axboe@oracle.com> |
---|
3 | 4 | * |
---|
4 | 5 | * Scatterlist handling helpers. |
---|
5 | | - * |
---|
6 | | - * This source code is licensed under the GNU General Public License, |
---|
7 | | - * Version 2. See the file COPYING for more details. |
---|
8 | 6 | */ |
---|
9 | 7 | #include <linux/export.h> |
---|
10 | 8 | #include <linux/slab.h> |
---|
.. | .. |
---|
181 | 179 | * __sg_free_table - Free a previously mapped sg table |
---|
182 | 180 | * @table: The sg table header to use |
---|
183 | 181 | * @max_ents: The maximum number of entries per single scatterlist |
---|
184 | | - * @skip_first_chunk: don't free the (preallocated) first scatterlist chunk |
---|
| 182 | + * @nents_first_chunk: Number of entries int the (preallocated) first |
---|
| 183 | + * scatterlist chunk, 0 means no such preallocated first chunk |
---|
185 | 184 | * @free_fn: Free function |
---|
186 | 185 | * |
---|
187 | 186 | * Description: |
---|
.. | .. |
---|
191 | 190 | * |
---|
192 | 191 | **/ |
---|
193 | 192 | void __sg_free_table(struct sg_table *table, unsigned int max_ents, |
---|
194 | | - bool skip_first_chunk, sg_free_fn *free_fn) |
---|
| 193 | + unsigned int nents_first_chunk, sg_free_fn *free_fn) |
---|
195 | 194 | { |
---|
196 | 195 | struct scatterlist *sgl, *next; |
---|
| 196 | + unsigned curr_max_ents = nents_first_chunk ?: max_ents; |
---|
197 | 197 | |
---|
198 | 198 | if (unlikely(!table->sgl)) |
---|
199 | 199 | return; |
---|
.. | .. |
---|
209 | 209 | * sg_size is then one less than alloc size, since the last |
---|
210 | 210 | * element is the chain pointer. |
---|
211 | 211 | */ |
---|
212 | | - if (alloc_size > max_ents) { |
---|
213 | | - next = sg_chain_ptr(&sgl[max_ents - 1]); |
---|
214 | | - alloc_size = max_ents; |
---|
| 212 | + if (alloc_size > curr_max_ents) { |
---|
| 213 | + next = sg_chain_ptr(&sgl[curr_max_ents - 1]); |
---|
| 214 | + alloc_size = curr_max_ents; |
---|
215 | 215 | sg_size = alloc_size - 1; |
---|
216 | 216 | } else { |
---|
217 | 217 | sg_size = alloc_size; |
---|
.. | .. |
---|
219 | 219 | } |
---|
220 | 220 | |
---|
221 | 221 | table->orig_nents -= sg_size; |
---|
222 | | - if (skip_first_chunk) |
---|
223 | | - skip_first_chunk = false; |
---|
| 222 | + if (nents_first_chunk) |
---|
| 223 | + nents_first_chunk = 0; |
---|
224 | 224 | else |
---|
225 | 225 | free_fn(sgl, alloc_size); |
---|
226 | 226 | sgl = next; |
---|
| 227 | + curr_max_ents = max_ents; |
---|
227 | 228 | } |
---|
228 | 229 | |
---|
229 | 230 | table->sgl = NULL; |
---|
.. | .. |
---|
246 | 247 | * @table: The sg table header to use |
---|
247 | 248 | * @nents: Number of entries in sg list |
---|
248 | 249 | * @max_ents: The maximum number of entries the allocator returns per call |
---|
| 250 | + * @nents_first_chunk: Number of entries int the (preallocated) first |
---|
| 251 | + * scatterlist chunk, 0 means no such preallocated chunk provided by user |
---|
249 | 252 | * @gfp_mask: GFP allocation mask |
---|
250 | 253 | * @alloc_fn: Allocator to use |
---|
251 | 254 | * |
---|
.. | .. |
---|
262 | 265 | **/ |
---|
263 | 266 | int __sg_alloc_table(struct sg_table *table, unsigned int nents, |
---|
264 | 267 | unsigned int max_ents, struct scatterlist *first_chunk, |
---|
265 | | - gfp_t gfp_mask, sg_alloc_fn *alloc_fn) |
---|
| 268 | + unsigned int nents_first_chunk, gfp_t gfp_mask, |
---|
| 269 | + sg_alloc_fn *alloc_fn) |
---|
266 | 270 | { |
---|
267 | 271 | struct scatterlist *sg, *prv; |
---|
268 | 272 | unsigned int left; |
---|
| 273 | + unsigned curr_max_ents = nents_first_chunk ?: max_ents; |
---|
| 274 | + unsigned prv_max_ents; |
---|
269 | 275 | |
---|
270 | 276 | memset(table, 0, sizeof(*table)); |
---|
271 | 277 | |
---|
272 | 278 | if (nents == 0) |
---|
273 | 279 | return -EINVAL; |
---|
274 | | -#ifndef CONFIG_ARCH_HAS_SG_CHAIN |
---|
| 280 | +#ifdef CONFIG_ARCH_NO_SG_CHAIN |
---|
275 | 281 | if (WARN_ON_ONCE(nents > max_ents)) |
---|
276 | 282 | return -EINVAL; |
---|
277 | 283 | #endif |
---|
.. | .. |
---|
281 | 287 | do { |
---|
282 | 288 | unsigned int sg_size, alloc_size = left; |
---|
283 | 289 | |
---|
284 | | - if (alloc_size > max_ents) { |
---|
285 | | - alloc_size = max_ents; |
---|
| 290 | + if (alloc_size > curr_max_ents) { |
---|
| 291 | + alloc_size = curr_max_ents; |
---|
286 | 292 | sg_size = alloc_size - 1; |
---|
287 | 293 | } else |
---|
288 | 294 | sg_size = alloc_size; |
---|
.. | .. |
---|
316 | 322 | * If this is not the first mapping, chain previous part. |
---|
317 | 323 | */ |
---|
318 | 324 | if (prv) |
---|
319 | | - sg_chain(prv, max_ents, sg); |
---|
| 325 | + sg_chain(prv, prv_max_ents, sg); |
---|
320 | 326 | else |
---|
321 | 327 | table->sgl = sg; |
---|
322 | 328 | |
---|
.. | .. |
---|
327 | 333 | sg_mark_end(&sg[sg_size - 1]); |
---|
328 | 334 | |
---|
329 | 335 | prv = sg; |
---|
| 336 | + prv_max_ents = curr_max_ents; |
---|
| 337 | + curr_max_ents = max_ents; |
---|
330 | 338 | } while (left); |
---|
331 | 339 | |
---|
332 | 340 | return 0; |
---|
.. | .. |
---|
349 | 357 | int ret; |
---|
350 | 358 | |
---|
351 | 359 | ret = __sg_alloc_table(table, nents, SG_MAX_SINGLE_ALLOC, |
---|
352 | | - NULL, gfp_mask, sg_kmalloc); |
---|
| 360 | + NULL, 0, gfp_mask, sg_kmalloc); |
---|
353 | 361 | if (unlikely(ret)) |
---|
354 | | - __sg_free_table(table, SG_MAX_SINGLE_ALLOC, false, sg_kfree); |
---|
| 362 | + __sg_free_table(table, SG_MAX_SINGLE_ALLOC, 0, sg_kfree); |
---|
355 | 363 | |
---|
356 | 364 | return ret; |
---|
357 | 365 | } |
---|
358 | 366 | EXPORT_SYMBOL(sg_alloc_table); |
---|
| 367 | + |
---|
| 368 | +static struct scatterlist *get_next_sg(struct sg_table *table, |
---|
| 369 | + struct scatterlist *cur, |
---|
| 370 | + unsigned long needed_sges, |
---|
| 371 | + gfp_t gfp_mask) |
---|
| 372 | +{ |
---|
| 373 | + struct scatterlist *new_sg, *next_sg; |
---|
| 374 | + unsigned int alloc_size; |
---|
| 375 | + |
---|
| 376 | + if (cur) { |
---|
| 377 | + next_sg = sg_next(cur); |
---|
| 378 | + /* Check if last entry should be keeped for chainning */ |
---|
| 379 | + if (!sg_is_last(next_sg) || needed_sges == 1) |
---|
| 380 | + return next_sg; |
---|
| 381 | + } |
---|
| 382 | + |
---|
| 383 | + alloc_size = min_t(unsigned long, needed_sges, SG_MAX_SINGLE_ALLOC); |
---|
| 384 | + new_sg = sg_kmalloc(alloc_size, gfp_mask); |
---|
| 385 | + if (!new_sg) |
---|
| 386 | + return ERR_PTR(-ENOMEM); |
---|
| 387 | + sg_init_table(new_sg, alloc_size); |
---|
| 388 | + if (cur) { |
---|
| 389 | + __sg_chain(next_sg, new_sg); |
---|
| 390 | + table->orig_nents += alloc_size - 1; |
---|
| 391 | + } else { |
---|
| 392 | + table->sgl = new_sg; |
---|
| 393 | + table->orig_nents = alloc_size; |
---|
| 394 | + table->nents = 0; |
---|
| 395 | + } |
---|
| 396 | + return new_sg; |
---|
| 397 | +} |
---|
359 | 398 | |
---|
360 | 399 | /** |
---|
361 | 400 | * __sg_alloc_table_from_pages - Allocate and initialize an sg table from |
---|
.. | .. |
---|
365 | 404 | * @n_pages: Number of pages in the pages array |
---|
366 | 405 | * @offset: Offset from start of the first page to the start of a buffer |
---|
367 | 406 | * @size: Number of valid bytes in the buffer (after offset) |
---|
368 | | - * @max_segment: Maximum size of a scatterlist node in bytes (page aligned) |
---|
| 407 | + * @max_segment: Maximum size of a scatterlist element in bytes |
---|
| 408 | + * @prv: Last populated sge in sgt |
---|
| 409 | + * @left_pages: Left pages caller have to set after this call |
---|
369 | 410 | * @gfp_mask: GFP allocation mask |
---|
370 | 411 | * |
---|
371 | | - * Description: |
---|
372 | | - * Allocate and initialize an sg table from a list of pages. Contiguous |
---|
373 | | - * ranges of the pages are squashed into a single scatterlist node up to the |
---|
374 | | - * maximum size specified in @max_segment. An user may provide an offset at a |
---|
375 | | - * start and a size of valid data in a buffer specified by the page array. |
---|
376 | | - * The returned sg table is released by sg_free_table. |
---|
| 412 | + * Description: |
---|
| 413 | + * If @prv is NULL, allocate and initialize an sg table from a list of pages, |
---|
| 414 | + * else reuse the scatterlist passed in at @prv. |
---|
| 415 | + * Contiguous ranges of the pages are squashed into a single scatterlist |
---|
| 416 | + * entry up to the maximum size specified in @max_segment. A user may |
---|
| 417 | + * provide an offset at a start and a size of valid data in a buffer |
---|
| 418 | + * specified by the page array. |
---|
377 | 419 | * |
---|
378 | 420 | * Returns: |
---|
379 | | - * 0 on success, negative error on failure |
---|
| 421 | + * Last SGE in sgt on success, PTR_ERR on otherwise. |
---|
| 422 | + * The allocation in @sgt must be released by sg_free_table. |
---|
| 423 | + * |
---|
| 424 | + * Notes: |
---|
| 425 | + * If this function returns non-0 (eg failure), the caller must call |
---|
| 426 | + * sg_free_table() to cleanup any leftover allocations. |
---|
380 | 427 | */ |
---|
381 | | -int __sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages, |
---|
382 | | - unsigned int n_pages, unsigned int offset, |
---|
383 | | - unsigned long size, unsigned int max_segment, |
---|
384 | | - gfp_t gfp_mask) |
---|
| 428 | +struct scatterlist *__sg_alloc_table_from_pages(struct sg_table *sgt, |
---|
| 429 | + struct page **pages, unsigned int n_pages, unsigned int offset, |
---|
| 430 | + unsigned long size, unsigned int max_segment, |
---|
| 431 | + struct scatterlist *prv, unsigned int left_pages, |
---|
| 432 | + gfp_t gfp_mask) |
---|
385 | 433 | { |
---|
386 | | - unsigned int chunks, cur_page, seg_len, i; |
---|
387 | | - int ret; |
---|
388 | | - struct scatterlist *s; |
---|
| 434 | + unsigned int chunks, cur_page, seg_len, i, prv_len = 0; |
---|
| 435 | + unsigned int added_nents = 0; |
---|
| 436 | + struct scatterlist *s = prv; |
---|
389 | 437 | |
---|
390 | | - if (WARN_ON(!max_segment || offset_in_page(max_segment))) |
---|
391 | | - return -EINVAL; |
---|
| 438 | + /* |
---|
| 439 | + * The algorithm below requires max_segment to be aligned to PAGE_SIZE |
---|
| 440 | + * otherwise it can overshoot. |
---|
| 441 | + */ |
---|
| 442 | + max_segment = ALIGN_DOWN(max_segment, PAGE_SIZE); |
---|
| 443 | + if (WARN_ON(max_segment < PAGE_SIZE)) |
---|
| 444 | + return ERR_PTR(-EINVAL); |
---|
| 445 | + |
---|
| 446 | + if (IS_ENABLED(CONFIG_ARCH_NO_SG_CHAIN) && prv) |
---|
| 447 | + return ERR_PTR(-EOPNOTSUPP); |
---|
| 448 | + |
---|
| 449 | + if (prv) { |
---|
| 450 | + unsigned long paddr = (page_to_pfn(sg_page(prv)) * PAGE_SIZE + |
---|
| 451 | + prv->offset + prv->length) / |
---|
| 452 | + PAGE_SIZE; |
---|
| 453 | + |
---|
| 454 | + if (WARN_ON(offset)) |
---|
| 455 | + return ERR_PTR(-EINVAL); |
---|
| 456 | + |
---|
| 457 | + /* Merge contiguous pages into the last SG */ |
---|
| 458 | + prv_len = prv->length; |
---|
| 459 | + while (n_pages && page_to_pfn(pages[0]) == paddr) { |
---|
| 460 | + if (prv->length + PAGE_SIZE > max_segment) |
---|
| 461 | + break; |
---|
| 462 | + prv->length += PAGE_SIZE; |
---|
| 463 | + paddr++; |
---|
| 464 | + pages++; |
---|
| 465 | + n_pages--; |
---|
| 466 | + } |
---|
| 467 | + if (!n_pages) |
---|
| 468 | + goto out; |
---|
| 469 | + } |
---|
392 | 470 | |
---|
393 | 471 | /* compute number of contiguous chunks */ |
---|
394 | 472 | chunks = 1; |
---|
.. | .. |
---|
402 | 480 | } |
---|
403 | 481 | } |
---|
404 | 482 | |
---|
405 | | - ret = sg_alloc_table(sgt, chunks, gfp_mask); |
---|
406 | | - if (unlikely(ret)) |
---|
407 | | - return ret; |
---|
408 | | - |
---|
409 | 483 | /* merging chunks and putting them into the scatterlist */ |
---|
410 | 484 | cur_page = 0; |
---|
411 | | - for_each_sg(sgt->sgl, s, sgt->orig_nents, i) { |
---|
| 485 | + for (i = 0; i < chunks; i++) { |
---|
412 | 486 | unsigned int j, chunk_size; |
---|
413 | 487 | |
---|
414 | 488 | /* look for the end of the current chunk */ |
---|
.. | .. |
---|
421 | 495 | break; |
---|
422 | 496 | } |
---|
423 | 497 | |
---|
| 498 | + /* Pass how many chunks might be left */ |
---|
| 499 | + s = get_next_sg(sgt, s, chunks - i + left_pages, gfp_mask); |
---|
| 500 | + if (IS_ERR(s)) { |
---|
| 501 | + /* |
---|
| 502 | + * Adjust entry length to be as before function was |
---|
| 503 | + * called. |
---|
| 504 | + */ |
---|
| 505 | + if (prv) |
---|
| 506 | + prv->length = prv_len; |
---|
| 507 | + return s; |
---|
| 508 | + } |
---|
424 | 509 | chunk_size = ((j - cur_page) << PAGE_SHIFT) - offset; |
---|
425 | 510 | sg_set_page(s, pages[cur_page], |
---|
426 | 511 | min_t(unsigned long, size, chunk_size), offset); |
---|
| 512 | + added_nents++; |
---|
427 | 513 | size -= chunk_size; |
---|
428 | 514 | offset = 0; |
---|
429 | 515 | cur_page = j; |
---|
430 | 516 | } |
---|
431 | | - |
---|
432 | | - return 0; |
---|
| 517 | + sgt->nents += added_nents; |
---|
| 518 | +out: |
---|
| 519 | + if (!left_pages) |
---|
| 520 | + sg_mark_end(s); |
---|
| 521 | + return s; |
---|
433 | 522 | } |
---|
434 | 523 | EXPORT_SYMBOL(__sg_alloc_table_from_pages); |
---|
435 | 524 | |
---|
.. | .. |
---|
457 | 546 | unsigned int n_pages, unsigned int offset, |
---|
458 | 547 | unsigned long size, gfp_t gfp_mask) |
---|
459 | 548 | { |
---|
460 | | - return __sg_alloc_table_from_pages(sgt, pages, n_pages, offset, size, |
---|
461 | | - SCATTERLIST_MAX_SEGMENT, gfp_mask); |
---|
| 549 | + return PTR_ERR_OR_ZERO(__sg_alloc_table_from_pages(sgt, pages, n_pages, |
---|
| 550 | + offset, size, UINT_MAX, NULL, 0, gfp_mask)); |
---|
462 | 551 | } |
---|
463 | 552 | EXPORT_SYMBOL(sg_alloc_table_from_pages); |
---|
464 | 553 | |
---|
.. | .. |
---|
496 | 585 | nalloc++; |
---|
497 | 586 | } |
---|
498 | 587 | sgl = kmalloc_array(nalloc, sizeof(struct scatterlist), |
---|
499 | | - (gfp & ~GFP_DMA) | __GFP_ZERO); |
---|
| 588 | + gfp & ~GFP_DMA); |
---|
500 | 589 | if (!sgl) |
---|
501 | 590 | return NULL; |
---|
502 | 591 | |
---|
.. | .. |
---|
624 | 713 | return true; |
---|
625 | 714 | } |
---|
626 | 715 | EXPORT_SYMBOL(__sg_page_iter_next); |
---|
| 716 | + |
---|
| 717 | +static int sg_dma_page_count(struct scatterlist *sg) |
---|
| 718 | +{ |
---|
| 719 | + return PAGE_ALIGN(sg->offset + sg_dma_len(sg)) >> PAGE_SHIFT; |
---|
| 720 | +} |
---|
| 721 | + |
---|
| 722 | +bool __sg_page_iter_dma_next(struct sg_dma_page_iter *dma_iter) |
---|
| 723 | +{ |
---|
| 724 | + struct sg_page_iter *piter = &dma_iter->base; |
---|
| 725 | + |
---|
| 726 | + if (!piter->__nents || !piter->sg) |
---|
| 727 | + return false; |
---|
| 728 | + |
---|
| 729 | + piter->sg_pgoffset += piter->__pg_advance; |
---|
| 730 | + piter->__pg_advance = 1; |
---|
| 731 | + |
---|
| 732 | + while (piter->sg_pgoffset >= sg_dma_page_count(piter->sg)) { |
---|
| 733 | + piter->sg_pgoffset -= sg_dma_page_count(piter->sg); |
---|
| 734 | + piter->sg = sg_next(piter->sg); |
---|
| 735 | + if (!--piter->__nents || !piter->sg) |
---|
| 736 | + return false; |
---|
| 737 | + } |
---|
| 738 | + |
---|
| 739 | + return true; |
---|
| 740 | +} |
---|
| 741 | +EXPORT_SYMBOL(__sg_page_iter_dma_next); |
---|
627 | 742 | |
---|
628 | 743 | /** |
---|
629 | 744 | * sg_miter_start - start mapping iteration over a sg list |
---|
.. | .. |
---|
777 | 892 | flush_kernel_dcache_page(miter->page); |
---|
778 | 893 | |
---|
779 | 894 | if (miter->__flags & SG_MITER_ATOMIC) { |
---|
780 | | - WARN_ON_ONCE(preemptible()); |
---|
| 895 | + WARN_ON_ONCE(!pagefault_disabled()); |
---|
781 | 896 | kunmap_atomic(miter->addr); |
---|
782 | 897 | } else |
---|
783 | 898 | kunmap(miter->page); |
---|
.. | .. |
---|
798 | 913 | * @buflen: The number of bytes to copy |
---|
799 | 914 | * @skip: Number of bytes to skip before copying |
---|
800 | 915 | * @to_buffer: transfer direction (true == from an sg list to a |
---|
801 | | - * buffer, false == from a buffer to an sg list |
---|
| 916 | + * buffer, false == from a buffer to an sg list) |
---|
802 | 917 | * |
---|
803 | 918 | * Returns the number of copied bytes. |
---|
804 | 919 | * |
---|
.. | .. |
---|
818 | 933 | sg_miter_start(&miter, sgl, nents, sg_flags); |
---|
819 | 934 | |
---|
820 | 935 | if (!sg_miter_skip(&miter, skip)) |
---|
821 | | - return false; |
---|
| 936 | + return 0; |
---|
822 | 937 | |
---|
823 | 938 | while ((offset < buflen) && sg_miter_next(&miter)) { |
---|
824 | 939 | unsigned int len; |
---|