On Thu, Aug 10, 2023 at 11:33:32AM +0100, Ryan Roberts wrote:
+void folios_put_refs(struct folio_range *folios, int nr)
+{
+ int i;
+ LIST_HEAD(pages_to_free);
+ struct lruvec *lruvec = NULL;
+ unsigned long flags = 0;
+ unsigned int lock_batch;
+
+ for (i = 0; i < nr; i++) {
+ struct folio *folio = page_folio(folios[i].start);
+ int refs = folios[i].end - folios[i].start;
+
+ /*
+ * Make sure the IRQ-safe lock-holding time does not get
+ * excessive with a continuous string of pages from the
+ * same lruvec. The lock is held only if lruvec != NULL.
+ */
+ if (lruvec && ++lock_batch == SWAP_CLUSTER_MAX) {
+ unlock_page_lruvec_irqrestore(lruvec, flags);
+ lruvec = NULL;
+ }
+
+ if (is_huge_zero_page(&folio->page))
+ continue;
+
+ if (folio_is_zone_device(folio)) {
+ if (lruvec) {
+ unlock_page_lruvec_irqrestore(lruvec, flags);
+ lruvec = NULL;
+ }
+ if (put_devmap_managed_page(&folio->page))
+ continue;
+ if (folio_put_testzero(folio))
We're only putting one ref for the zone_device folios? Surely
this should be ref_sub_and_test like below?