Re: [PATCH v3 2/3] mm: swap: drop dropbehind swap cache folios on writeback completion
Barry Song <[email protected]>
| Newsgroups | org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <CAGsJ_4zC+wAuevG+i5y23rLPGXn0P=D7JpMECnZ1OuP1BsyYkw@mail.gmail.com> |
On Wed, Aug 19, 2026 at 12:34 AM Alexandre Ghiti <[email protected]> wrote: > > A PG_dropbehind folio is dropped from its cache once writeback completes > rather than left for reclaim to find later; this is implemented for file > folios in folio_end_dropbehind(). Extend it to swap cache folios. > > The drop needs the folio and swap cluster locks and may sleep, but > writeback can complete in interrupt context, so defer the work to a > workqueue that runs once writeback has completed and frees the folios in > batches. > > Suggested-by: Yosry Ahmed <[email protected]> > Suggested-by: Johannes Weiner <[email protected]> > Suggested-by: Nhat Pham <[email protected]> > Signed-off-by: Alexandre Ghiti <[email protected]> > --- [...] > > +static DEFINE_PER_CPU(struct llist_head, swap_dropbehind_llist); > + > +static bool swap_dropbehind_drop_folio(struct folio *folio) > +{ > + struct mem_cgroup *memcg; > + bool dropped = false; > + > + folio_lock(folio); > + > + /* The folio was allocated off the LRU and nothing re-adds it here. */ > + VM_WARN_ON_ONCE_FOLIO(folio_test_lru(folio), folio); Hi Alexandre, Thanks very much for your patch! I don't quite understand why we only support NON-LRU folios. Does this restriction prevent potential optimizations for madv_pageout? Also, zram might benefit from your patch in the future with asynchronous hardware compression and software compression such as kcompressd[1]. [1] https://lore.kernel.org/linux-mm/[email protected]/ [...] > + > +/** > + * swap_dropbehind_free_batch_folio - free a dropbehind swap cache folio into a batch > + * @folio: the off-LRU folio whose writeback has completed > + * @fbatch: batch of folios to free, flushed when full > + */ > +static void swap_dropbehind_free_batch_folio(struct folio *folio, > + struct folio_batch *fbatch) > +{ > + if (swap_dropbehind_drop_folio(folio) && !folio_batch_add(fbatch, folio)) > + folios_put(fbatch); > +} > + > +static void swap_dropbehind_workfn(struct work_struct *work) > +{ > + struct folio_batch fbatch; > + struct llist_node *pos, *next; > + int cpu; > + > + folio_batch_init(&fbatch); > + for_each_possible_cpu(cpu) { > + pos = llist_del_all(per_cpu_ptr(&swap_dropbehind_llist, cpu)); > + llist_for_each_safe(pos, next, pos) { > + struct folio *folio = container_of((struct list_head *)pos, > + struct folio, lru); > + swap_dropbehind_free_batch_folio(folio, &fbatch); > + } > + } > + if (fbatch.nr) > + folios_put(&fbatch); > +} > + > +static DECLARE_WORK(swap_dropbehind_work, swap_dropbehind_workfn); > +static struct workqueue_struct *swap_dropbehind_wq; > + > +void swap_writeback_dropbehind_folio(struct folio *folio) > +{ > + llist_add((struct llist_node *)&folio->lru, > + raw_cpu_ptr(&swap_dropbehind_llist)); > + queue_work(swap_dropbehind_wq, &swap_dropbehind_work); > +} > + This is good. For file dropbehind, I see both F2FS [1] and block devices [2] reinventing workqueues in their own filesystems or drivers, while folio_end_dropbehind() simply benefits from its safe, sleepable context. This seems a bit odd. So I'm really curious whether this could be extended to file-backed folios as well, so that those filesystems and device drivers don't have to deal with this themselves. [1] https://lore.kernel.org/all/[email protected]/ [2] https://lore.kernel.org/all/[email protected]/ Thanks Barry