3 ms·
I'm not sure how the current vm system tracks dirty pages, so I wouldn't know where to start suggesting realistic solutions. But yes, assuming the dirty pages a
by tremon 3y ago
I'm not sure how the current vm system tracks dirty pages, so I wouldn't know where to start suggesting realistic solutions. But yes, assuming the dirty pages are organized in some sort of specialized data structure (queue or otherwise), you could do this without needing new barriers: it would suffice to create a new dirty-page root structure before starting writeout, and redirect freshly dirtied pages to the new root. The writer process can then take its leisurely time committing the pending writes to disk without obstructing other processes issuing new writes. New writes to pending pages can be reparented to the new root via an RCU mechanism (to not violate previous write barriers), and incomplete writes can be reparented by the writer process in a similar way. When the writeout process completes, the old root can be completely discarded; the writer could even consume and free the old structure while traversing it.
But really, this is all fantasy given that I know nothing about the virtual memory internal data structures.
- afr0ck 3y agoThe kernel page cache is an XArray [1] (data structure here [2]) and dirty page pointers are annotated with the dirty tag when the page is dirtied [3]. There is a per-filesystem callback that usually always ends up here [4], where you can see the the above data structure [2] entry for that page is being tagged as dirty. Edit: fixed typo [1] https://docs.kernel.org/core-api/xarray.html https://docs.kernel.org/core-api/xarray.html [2] https://elixir.bootlin.com/linux/latest/source/include/linux/fs.h#L472 https://elixir.bootlin.com/linux/latest/source/include/linux... [3] https://elixir.bootlin.com/linux/latest/source/mm/page-writeback.c#L2763 https://elixir.bootlin.com/linux/latest/source/mm/page-write... [4] https://elixir.bootlin.com/linux/latest/source/mm/page-writeback.c#L2670 https://elixir.bootlin.com/linux/latest/source/mm/page-write...
- tremon 3y agoThanks. So there is no "specialized data structure" for tracking dirty pages, the page dirty status is tracked within the regular page cache hierarchy. And the obvious in-line solution (use a wraparound counter for tracking dirty state, increase dirty values for new pages while writing out lower values) isn't easy because the tag is a bitfield. So the easiest solution would be to have two separate dirty markers (e.g. dirty_a and dirty_b), and have the writeout process toggle the new-dirty marker from A to B so it can safely write dirty_a pages without interference. And vice-versa for the next writeout. There is just one caveat with regards to the previous solution: pages that are already pending writeout still need to be locked. In the previous design, a write to a page already pending writeout could be duplicated into the new dirty queue. But since it seems that a page can exist only once in the page cache, it cannot be written to without possibly violating write barriers. So the write must block until the writeout process has un-dirtied the page. Armchair programming is fun, isn't it? :)