Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp4570485pxv; Tue, 6 Jul 2021 04:19:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzPWGV7j6459WNos1s6VAB0nTCbTdCjx8eGgS0VsuRsOlRVCXECvzceKI0/4Ufv9Lq+Eaj4 X-Received: by 2002:a6b:4f10:: with SMTP id d16mr11726168iob.58.1625570357509; Tue, 06 Jul 2021 04:19:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625570357; cv=none; d=google.com; s=arc-20160816; b=rYoJybIM08pbYq8bGQTELvV+okZe9l9UWC9+tK+iUlSTwf1elWuS8OMXF8gTvEsI6q 3xqtdbi+HSbeLwebFhspJw+epmmrabqRGrqYCrzUt2Y9arm8A1StS5z+q8sMzvEuV+jT MLxvT//vu7DefMSQFbqgSbuNatKiIU6wWLqiv1DZRXRoEnmnYVh+loutAzteX4EocTjq 5xCSOzrgGwM42wVJoRT/dudbrZcd1gEaeHAkjaTuvu3H9s7oLqBJqRHbhsXNUI+taCPu sqG1+G9rJS/nacoG16miMiEEoNN/tBkiYWptyYXPfzPQnw28S5HyykUwDusAlNSkwKJs 8wyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=TRNi+GOwMSID11xoLnD8qqkaz1j7q9ktrNlsLM4hH3A=; b=PrIJCqcQaemggysYTb3w4FanRdy45jrr/UrjG4nqyMu2nxPILgsDtb70i7AB3v5pIo NuxZyeTKPffDUyQrWoklGawn5r9wEONofmtCgy0432dnSkidf+u+nRQ0G3/r67GxHxxb jm600XT6atGr+owXA+W5zwJ9lLBNcVcB0U0TsLAxlv2KOwyB6FFEuBjz6alYoeEt9KTJ hzklY1pmohcOdYxzTpuSbXF8R485gly1vjCoy6jdyyTuYzra7lzOy97oRdvSCf9Zxvlw 6fFJZhondM3TUDtKVfcWlGdnqw5uefy/wm1cBq2b+1lA1LIGHCxcFLIJbju4OG+XL3rk mHuQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ez1ij4Pz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w23si17197063jaq.102.2021.07.06.04.19.05; Tue, 06 Jul 2021 04:19:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ez1ij4Pz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233517AbhGFLVQ (ORCPT + 99 others); Tue, 6 Jul 2021 07:21:16 -0400 Received: from mail.kernel.org ([198.145.29.99]:54502 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232548AbhGFLSb (ORCPT ); Tue, 6 Jul 2021 07:18:31 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 04A8F61A14; Tue, 6 Jul 2021 11:15:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1625570152; bh=OZVZebsjwdl1JxRsp/zcRmFGerLEwI0om/fVkc0q93U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ez1ij4PznlRxb/a2xK2rPUDkBLSmDt6NNwBGwZ5xmVSA66OBE52s8lH/q8GWECsRP cZTupCOWJq9uWPncfodiDTqQ22vU5Igrb6tU+Ee2k7qUpJv4K/Vo9e8aqO0tw+AwP0 tQUd8NrGwLHY9EA1LHOG0Ni/BRQS6fjVLlPPT8E/MYfyqY5b4TFHVpp6tnBnr5Kf9n 3uEgEPDEyzuLM+XIKcOho8vGu31Mgce67Z2HtTu0j4hab41Fm84sciftGTW24tC1tJ 8X8BbI/rHtWUuCcPQmzqaE20RZJ0LEa1Ml2vQWToQ81iczmM5FzWT1CTVu5vzn6BK+ wz/XqoKlNzqhw== 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.13 075/189] dm writecache: don't split bios when overwriting contiguous cache content Date: Tue, 6 Jul 2021 07:12:15 -0400 Message-Id: <20210706111409.2058071-75-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210706111409.2058071-1-sashal@kernel.org> References: <20210706111409.2058071-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 aecc246ade26..a44007297e63 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