5 ms·
The 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
by afr0ck 3y ago
The 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? :)