Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755110AbbLJRan (ORCPT ); Thu, 10 Dec 2015 12:30:43 -0500 Received: from mx1.redhat.com ([209.132.183.28]:45617 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754378AbbLJRai (ORCPT ); Thu, 10 Dec 2015 12:30:38 -0500 Date: Thu, 10 Dec 2015 12:30:37 -0500 (EST) From: Mikulas Patocka X-X-Sender: mpatocka@file01.intranet.prod.int.rdu2.redhat.com To: "James E.J. Bottomley" , "Martin K. Petersen" , Jens Axboe , Mike Snitzer , Jonathan Brassow cc: dm-devel@redhat.com, linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH 7/15] scsi xcopy: keep cache of failures In-Reply-To: Message-ID: References: User-Agent: Alpine 2.02 (LRH 1266 2009-07-14) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3414 Lines: 88 If xcopy between two devices fails, it is pointless to send more xcopy command between there two devices because they take time and they will likely also fail. This patch keeps a cache of (source_device,destination_device) pairs where copying failed and makes sure that no xcopy command is sooner than 30 seconds after the last failure. Signed-off-by: Mikulas Patocka --- drivers/scsi/sd.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) Index: linux-4.4-rc4/drivers/scsi/sd.c =================================================================== --- linux-4.4-rc4.orig/drivers/scsi/sd.c 2015-12-07 16:59:09.000000000 +0100 +++ linux-4.4-rc4/drivers/scsi/sd.c 2015-12-07 16:59:12.000000000 +0100 @@ -939,6 +939,26 @@ static void sd_config_copy(struct scsi_d (logical_block_size >> 9)); } +#define SD_COPY_DISABLED_CACHE_TIME (HZ * 30) +#define SD_COPY_DISABLED_CACHE_HASH_BITS 6 +#define SD_COPY_DISABLED_CACHE_HASH (1 << SD_COPY_DISABLED_CACHE_HASH_BITS) + +struct sd_copy_disabled_cache_entry { + struct scsi_device *src; + struct scsi_device *dst; + unsigned long jiffies; +}; + +static struct sd_copy_disabled_cache_entry sd_copy_disabled_cache[SD_COPY_DISABLED_CACHE_HASH]; + +static struct sd_copy_disabled_cache_entry *sd_copy_disabled_cache_hash( + struct scsi_device *src, struct scsi_device *dst) +{ + return &sd_copy_disabled_cache[ + hash_long((unsigned long)src + ((unsigned long)dst >> 1), SD_COPY_DISABLED_CACHE_HASH_BITS) + ]; +} + static int sd_setup_copy_cmnd(struct scsi_cmnd *cmd) { struct request *rq = cmd->request; @@ -951,6 +971,7 @@ static int sd_setup_copy_cmnd(struct scs struct bio *bio = rq->bio; struct page *page; unsigned char *buf; + struct sd_copy_disabled_cache_entry *e; dst_sdp = scsi_disk(rq->rq_disk)->device; dst_queue = rq->rq_disk->queue; @@ -970,6 +991,12 @@ static int sd_setup_copy_cmnd(struct scs if (src_sdp->sector_size != dst_sdp->sector_size) return BLKPREP_KILL; + /* The copy failed in the past, so do not retry it for some time */ + e = sd_copy_disabled_cache_hash(src_sdp, dst_sdp); + if (unlikely(jiffies - ACCESS_ONCE(e->jiffies) < SD_COPY_DISABLED_CACHE_TIME) && + likely(ACCESS_ONCE(e->src) == src_sdp) && likely(ACCESS_ONCE(e->dst) == dst_sdp)) + return BLKPREP_KILL; + dst_lba = blk_rq_pos(rq) >> (ilog2(dst_sdp->sector_size) - 9); src_lba = bio->bi_copy->pair[0]->bi_iter.bi_sector >> (ilog2(src_sdp->sector_size) - 9); nr_blocks = blk_rq_sectors(rq) >> (ilog2(dst_sdp->sector_size) - 9); @@ -2003,6 +2030,16 @@ static int sd_done(struct scsi_cmnd *SCp */ case EXTENDED_COPY: if ((SCpnt->cmnd[1] & 0x1f) == 0) { + struct sd_copy_disabled_cache_entry *e; + struct scsi_device *src_sdp, *dst_sdp; + + dst_sdp = sdkp->device; + src_sdp = scsi_disk(req->bio->bi_copy->pair[0]->bi_bdev->bd_disk)->device; + e = sd_copy_disabled_cache_hash(src_sdp, dst_sdp); + ACCESS_ONCE(e->src) = src_sdp; + ACCESS_ONCE(e->dst) = dst_sdp; + ACCESS_ONCE(e->jiffies) = jiffies; + good_bytes = 0; req->__data_len = blk_rq_bytes(req); req->cmd_flags |= REQ_QUIET; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/