-
Notifications
You must be signed in to change notification settings - Fork 20
Read caching implementation
Akira Hayakawa edited this page Sep 4, 2016
·
5 revisions
Writeboost implements read-caching using write-caching.
The algorithm is:
- Only caches 4KB (full-sized) read requests
- Hold read data into the read-cache cells in the endio callback (
read_cache_cell_copy_data
). There are 2048 cells preallocated by default.reserve_read_cache_cell
is called when the read request result in cache miss, will be read from the backing store, and the function reserves a new cell. In endio, the read data payload is copied to the cell. - Once all cells are occupied writeboost injects the read data in the cells into the write-caching routine. (
inject_read_cache
) This is something like read-requests turn into writers. But the code path is simpler than the real write path because the data is assured to be 4KB (not partial) and there is no chance of overwriting the existing cache block because the cell data should have been cancelled if other thread in write-caching wrote the same address. (might_cancel_read_cache_cell
)
struct read_cache_cell {
sector_t sector;
void *data; /* 4KB data read */
bool cancelled; /* Don't include this */
struct rb_node rb_node;
};
With the tunable parameter read_cache_threshold
set, read-caching detects sequentiality within the 2048 cells and cancels the cells included in the sequentiality. read_cache_cell
is maintained in the rb tree because taking the cells out of the tree is sorted in ascending order which helps detect sequentiality.
The struct dirtiness
indicates the dirtiness of a cache block. is_dirty
is set false if it's read-caching, otherwise true, and no need to write back. data_bits
is the bit mask of valid sectors in the 4KB cache block. Therefore all read-cached blocks are set is_dirty=false
and data_bits=255
. This way, we can mix write-caching and read-caching in unified manner.
struct dirtiness {
bool is_dirty;
u8 data_bits;
};