From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E336BC4CC65 for ; Tue, 6 Jul 2021 11:39:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D8A1161D79 for ; Tue, 6 Jul 2021 11:39:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237470AbhGFLmD (ORCPT ); Tue, 6 Jul 2021 07:42:03 -0400 Received: from mail.kernel.org ([198.145.29.99]:35430 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233910AbhGFL0c (ORCPT ); Tue, 6 Jul 2021 07:26:32 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id F35B961D2D; Tue, 6 Jul 2021 11:19:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1625570389; bh=d3lS5lOLbe7KkQbtTlkkBsmYKP4rS81QrK1hK406CxM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Cz5C/QAwMda/o+pYgcjkdHGmirx7ejPVFykMftJKWSgDQXZKr9P9OlY2U1UaY8I9a 2KaTlvRDfwqfTw05ONbhNPio+S28r9iaEXbbgxZueNkXJxFECNOXC6cXhVgW5U30Fm WiYh1xvABHK7d+6kGS3H+Rpwo5tBXhi6Q3u38e0pUzUyyEvzS+N56+TjnOmntYrXcs Hdt6gQkBUCKeEd5uAA9TGkLRnXCjcJLQNGM1l17uf3IPpOE+z0Y+bcui7+FDhQvGrN tYvo1fT9Gvmk4jhmGV8XqG4jRc/hxt2xbpjMzaMhiyQn6ILncZ07Ai4spV9RhTbBln VE3BEhx/oeDtw== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Mikulas Patocka , Mike Snitzer , Sasha Levin , dm-devel@redhat.com Subject: [PATCH AUTOSEL 5.12 062/160] dm writecache: don't split bios when overwriting contiguous cache content Date: Tue, 6 Jul 2021 07:16:48 -0400 Message-Id: <20210706111827.2060499-62-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210706111827.2060499-1-sashal@kernel.org> References: <20210706111827.2060499-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Mikulas Patocka [ Upstream commit ee50cc19d80e9b9a8283d1fb517a778faf2f6899 ] If dm-writecache overwrites existing cached data, it splits the incoming bio into many block-sized bios. The I/O scheduler does merge these bios into one large request but this needless splitting and merging causes performance degradation. Fix this by avoiding bio splitting if the cache target area that is being overwritten is contiguous. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Sasha Levin --- drivers/md/dm-writecache.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c index 4f72b6f66c3a..7bb4d83e90cc 100644 --- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -1360,14 +1360,18 @@ static int writecache_map(struct dm_target *ti, struct bio *bio) } else { do { bool found_entry = false; + bool search_used = false; if (writecache_has_error(wc)) goto unlock_error; e = writecache_find_entry(wc, bio->bi_iter.bi_sector, 0); if (e) { - if (!writecache_entry_is_committed(wc, e)) + if (!writecache_entry_is_committed(wc, e)) { + search_used = true; goto bio_copy; + } if (!WC_MODE_PMEM(wc) && !e->write_in_progress) { wc->overwrote_committed = true; + search_used = true; goto bio_copy; } found_entry = true; @@ -1404,13 +1408,31 @@ static int writecache_map(struct dm_target *ti, struct bio *bio) sector_t current_cache_sec = start_cache_sec + (bio_size >> SECTOR_SHIFT); while (bio_size < bio->bi_iter.bi_size) { - struct wc_entry *f = writecache_pop_from_freelist(wc, current_cache_sec); - if (!f) - break; - write_original_sector_seq_count(wc, f, bio->bi_iter.bi_sector + - (bio_size >> SECTOR_SHIFT), wc->seq_count); - writecache_insert_entry(wc, f); - wc->uncommitted_blocks++; + if (!search_used) { + struct wc_entry *f = writecache_pop_from_freelist(wc, current_cache_sec); + if (!f) + break; + write_original_sector_seq_count(wc, f, bio->bi_iter.bi_sector + + (bio_size >> SECTOR_SHIFT), wc->seq_count); + writecache_insert_entry(wc, f); + wc->uncommitted_blocks++; + } else { + struct wc_entry *f; + struct rb_node *next = rb_next(&e->rb_node); + if (!next) + break; + f = container_of(next, struct wc_entry, rb_node); + if (f != e + 1) + break; + if (read_original_sector(wc, f) != + read_original_sector(wc, e) + (wc->block_size >> SECTOR_SHIFT)) + break; + if (unlikely(f->write_in_progress)) + break; + if (writecache_entry_is_committed(wc, f)) + wc->overwrote_committed = true; + e = f; + } bio_size += wc->block_size; current_cache_sec += wc->block_size >> SECTOR_SHIFT; } -- 2.30.2