Commit 9dd59727 authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Mike Snitzer

dm integrity: fix inefficient allocation of journal space

When using a block size greater than 512 bytes, the dm-integrity target
allocates journal space inefficiently.  It allocates one journal entry
for each 512-byte chunk of data, fills an entry for each block of data
and leaves the remaining entries unused.

This issue doesn't cause data corruption, but all the unused journal
entries degrade performance severely.

For example, with 4k blocks and an 8k bio, it would allocate 16 journal
entries but only use 2 entries.  The remaining 14 entries were left
unused.

Fix this by adding the missing 'log2_sectors_per_block' shifts that are
required to have each journal entry map to a full block.
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org
Fixes: 7eada909 ("dm: add integrity target")
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 5771a8c0
...@@ -1587,16 +1587,18 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map ...@@ -1587,16 +1587,18 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map
if (likely(ic->mode == 'J')) { if (likely(ic->mode == 'J')) {
if (dio->write) { if (dio->write) {
unsigned next_entry, i, pos; unsigned next_entry, i, pos;
unsigned ws, we; unsigned ws, we, range_sectors;
dio->range.n_sectors = min(dio->range.n_sectors, ic->free_sectors); dio->range.n_sectors = min(dio->range.n_sectors,
ic->free_sectors << ic->sb->log2_sectors_per_block);
if (unlikely(!dio->range.n_sectors)) if (unlikely(!dio->range.n_sectors))
goto sleep; goto sleep;
ic->free_sectors -= dio->range.n_sectors; range_sectors = dio->range.n_sectors >> ic->sb->log2_sectors_per_block;
ic->free_sectors -= range_sectors;
journal_section = ic->free_section; journal_section = ic->free_section;
journal_entry = ic->free_section_entry; journal_entry = ic->free_section_entry;
next_entry = ic->free_section_entry + dio->range.n_sectors; next_entry = ic->free_section_entry + range_sectors;
ic->free_section_entry = next_entry % ic->journal_section_entries; ic->free_section_entry = next_entry % ic->journal_section_entries;
ic->free_section += next_entry / ic->journal_section_entries; ic->free_section += next_entry / ic->journal_section_entries;
ic->n_uncommitted_sections += next_entry / ic->journal_section_entries; ic->n_uncommitted_sections += next_entry / ic->journal_section_entries;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment