Skip to content

Commit ed9178f

Browse files
Steve Sistarejgunthorpe
authored andcommitted
iommufd: Folio subroutines
Add subroutines for copying folios to a batch. Link: https://patch.msgid.link/r/[email protected] Signed-off-by: Steve Sistare <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent c27f0a6 commit ed9178f

File tree

1 file changed

+64
-15
lines changed

1 file changed

+64
-15
lines changed

drivers/iommu/iommufd/pages.c

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -346,27 +346,41 @@ static void batch_destroy(struct pfn_batch *batch, void *backup)
346346
kfree(batch->pfns);
347347
}
348348

349-
/* true if the pfn was added, false otherwise */
350-
static bool batch_add_pfn(struct pfn_batch *batch, unsigned long pfn)
349+
static bool batch_add_pfn_num(struct pfn_batch *batch, unsigned long pfn,
350+
u32 nr)
351351
{
352352
const unsigned int MAX_NPFNS = type_max(typeof(*batch->npfns));
353-
354-
if (batch->end &&
355-
pfn == batch->pfns[batch->end - 1] + batch->npfns[batch->end - 1] &&
356-
batch->npfns[batch->end - 1] != MAX_NPFNS) {
357-
batch->npfns[batch->end - 1]++;
358-
batch->total_pfns++;
359-
return true;
360-
}
361-
if (batch->end == batch->array_size)
353+
unsigned int end = batch->end;
354+
355+
if (end && pfn == batch->pfns[end - 1] + batch->npfns[end - 1] &&
356+
nr <= MAX_NPFNS - batch->npfns[end - 1]) {
357+
batch->npfns[end - 1] += nr;
358+
} else if (end < batch->array_size) {
359+
batch->pfns[end] = pfn;
360+
batch->npfns[end] = nr;
361+
batch->end++;
362+
} else {
362363
return false;
363-
batch->total_pfns++;
364-
batch->pfns[batch->end] = pfn;
365-
batch->npfns[batch->end] = 1;
366-
batch->end++;
364+
}
365+
366+
batch->total_pfns += nr;
367367
return true;
368368
}
369369

370+
static void batch_remove_pfn_num(struct pfn_batch *batch, unsigned long nr)
371+
{
372+
batch->npfns[batch->end - 1] -= nr;
373+
if (batch->npfns[batch->end - 1] == 0)
374+
batch->end--;
375+
batch->total_pfns -= nr;
376+
}
377+
378+
/* true if the pfn was added, false otherwise */
379+
static bool batch_add_pfn(struct pfn_batch *batch, unsigned long pfn)
380+
{
381+
return batch_add_pfn_num(batch, pfn, 1);
382+
}
383+
370384
/*
371385
* Fill the batch with pfns from the domain. When the batch is full, or it
372386
* reaches last_index, the function will return. The caller should use
@@ -622,6 +636,41 @@ static void batch_from_pages(struct pfn_batch *batch, struct page **pages,
622636
break;
623637
}
624638

639+
static int batch_from_folios(struct pfn_batch *batch, struct folio ***folios_p,
640+
unsigned long *offset_p, unsigned long npages)
641+
{
642+
int rc = 0;
643+
struct folio **folios = *folios_p;
644+
unsigned long offset = *offset_p;
645+
646+
while (npages) {
647+
struct folio *folio = *folios;
648+
unsigned long nr = folio_nr_pages(folio) - offset;
649+
unsigned long pfn = page_to_pfn(folio_page(folio, offset));
650+
651+
nr = min(nr, npages);
652+
npages -= nr;
653+
654+
if (!batch_add_pfn_num(batch, pfn, nr))
655+
break;
656+
if (nr > 1) {
657+
rc = folio_add_pins(folio, nr - 1);
658+
if (rc) {
659+
batch_remove_pfn_num(batch, nr);
660+
goto out;
661+
}
662+
}
663+
664+
folios++;
665+
offset = 0;
666+
}
667+
668+
out:
669+
*folios_p = folios;
670+
*offset_p = offset;
671+
return rc;
672+
}
673+
625674
static void batch_unpin(struct pfn_batch *batch, struct iopt_pages *pages,
626675
unsigned int first_page_off, size_t npages)
627676
{

0 commit comments

Comments
 (0)