Skip to content

Commit 7ba0d83

Browse files
Coly Liaxboe
authored andcommitted
bcache: set error_limit correctly
Struct cache uses io_errors for two purposes, - Error decay: when cache set error_decay is set, io_errors is used to generate a small piece of delay when I/O error happens. - I/O errors counter: in order to generate big enough value for error decay, I/O errors counter value is stored by left shifting 20 bits (a.k.a IO_ERROR_SHIFT). In function bch_count_io_errors(), if I/O errors counter reaches cache set error limit, bch_cache_set_error() will be called to retire the whold cache set. But current code is problematic when checking the error limit, see the following code piece from bch_count_io_errors(), 90 if (error) { 91 char buf[BDEVNAME_SIZE]; 92 unsigned errors = atomic_add_return(1 << IO_ERROR_SHIFT, 93 &ca->io_errors); 94 errors >>= IO_ERROR_SHIFT; 95 96 if (errors < ca->set->error_limit) 97 pr_err("%s: IO error on %s, recovering", 98 bdevname(ca->bdev, buf), m); 99 else 100 bch_cache_set_error(ca->set, 101 "%s: too many IO errors %s", 102 bdevname(ca->bdev, buf), m); 103 } At line 94, errors is right shifting IO_ERROR_SHIFT bits, now it is real errors counter to compare at line 96. But ca->set->error_limit is initia- lized with an amplified value in bch_cache_set_alloc(), 1545 c->error_limit = 8 << IO_ERROR_SHIFT; It means by default, in bch_count_io_errors(), before 8<<20 errors happened bch_cache_set_error() won't be called to retire the problematic cache device. If the average request size is 64KB, it means bcache won't handle failed device until 512GB data is requested. This is too large to be an I/O threashold. So I believe the correct error limit should be much less. This patch sets default cache set error limit to 8, then in bch_count_io_errors() when errors counter reaches 8 (if it is default value), function bch_cache_set_error() will be called to retire the whole cache set. This patch also removes bits shifting when store or show io_error_limit value via sysfs interface. Nowadays most of SSDs handle internal flash failure automatically by LBA address re-indirect mapping. If an I/O error can be observed by upper layer code, it will be a notable error because that SSD can not re-indirect map the problematic LBA address to an available flash block. This situation indicates the whole SSD will be failed very soon. Therefore setting 8 as the default io error limit value makes sense, it is enough for most of cache devices. Changelog: v2: add reviewed-by from Hannes. v1: initial version for review. Signed-off-by: Coly Li <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Reviewed-by: Tang Junhui <[email protected]> Reviewed-by: Michael Lyle <[email protected]> Cc: Junhui Tang <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 99361bb commit 7ba0d83

File tree

3 files changed

+4
-3
lines changed

3 files changed

+4
-3
lines changed

drivers/md/bcache/bcache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ struct cache_set {
666666
ON_ERROR_UNREGISTER,
667667
ON_ERROR_PANIC,
668668
} on_error;
669+
#define DEFAULT_IO_ERROR_LIMIT 8
669670
unsigned error_limit;
670671
unsigned error_decay;
671672

drivers/md/bcache/super.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1553,7 +1553,7 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb)
15531553

15541554
c->congested_read_threshold_us = 2000;
15551555
c->congested_write_threshold_us = 20000;
1556-
c->error_limit = 8 << IO_ERROR_SHIFT;
1556+
c->error_limit = DEFAULT_IO_ERROR_LIMIT;
15571557

15581558
return c;
15591559
err:

drivers/md/bcache/sysfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ SHOW(__bch_cache_set)
568568

569569
/* See count_io_errors for why 88 */
570570
sysfs_print(io_error_halflife, c->error_decay * 88);
571-
sysfs_print(io_error_limit, c->error_limit >> IO_ERROR_SHIFT);
571+
sysfs_print(io_error_limit, c->error_limit);
572572

573573
sysfs_hprint(congested,
574574
((uint64_t) bch_get_congested(c)) << 9);
@@ -668,7 +668,7 @@ STORE(__bch_cache_set)
668668
}
669669

670670
if (attr == &sysfs_io_error_limit)
671-
c->error_limit = strtoul_or_return(buf) << IO_ERROR_SHIFT;
671+
c->error_limit = strtoul_or_return(buf);
672672

673673
/* See count_io_errors() for why 88 */
674674
if (attr == &sysfs_io_error_halflife)

0 commit comments

Comments
 (0)