bcachefs: bch2_account_io_completion()
We need to start accounting successes for every IO, not just failures, so introduce a unified hook for io completion accounting and convert io_read.c. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
@@ -216,6 +216,26 @@ void bch2_io_error_work(struct work_struct *);
|
||||
/* Does the error handling without logging a message */
|
||||
void bch2_io_error(struct bch_dev *, enum bch_member_error_type);
|
||||
|
||||
#ifndef CONFIG_BCACHEFS_NO_LATENCY_ACCT
|
||||
void bch2_latency_acct(struct bch_dev *, u64, int);
|
||||
#else
|
||||
static inline void bch2_latency_acct(struct bch_dev *ca, u64 submit_time, int rw) {}
|
||||
#endif
|
||||
|
||||
static inline void bch2_account_io_completion(struct bch_dev *ca,
|
||||
enum bch_member_error_type type,
|
||||
u64 submit_time, bool success)
|
||||
{
|
||||
if (unlikely(!ca))
|
||||
return;
|
||||
|
||||
if (type != BCH_MEMBER_ERROR_checksum)
|
||||
bch2_latency_acct(ca, submit_time, type);
|
||||
|
||||
if (!success)
|
||||
bch2_io_error(ca, type);
|
||||
}
|
||||
|
||||
#define bch2_dev_io_err_on(cond, ca, _type, ...) \
|
||||
({ \
|
||||
bool _ret = (cond); \
|
||||
|
||||
+23
-22
@@ -524,12 +524,10 @@ static void bch2_read_io_err(struct work_struct *work)
|
||||
bch2_read_err_msg(c, &buf, rbio, rbio->read_pos);
|
||||
prt_printf(&buf, "data read error: %s", bch2_blk_status_to_str(bio->bi_status));
|
||||
|
||||
if (ca) {
|
||||
bch2_io_error(ca, BCH_MEMBER_ERROR_read);
|
||||
if (ca)
|
||||
bch_err_ratelimited(ca, "%s", buf.buf);
|
||||
} else {
|
||||
else
|
||||
bch_err_ratelimited(c, "%s", buf.buf);
|
||||
}
|
||||
|
||||
printbuf_exit(&buf);
|
||||
bch2_rbio_error(rbio, READ_RETRY_AVOID, bio->bi_status);
|
||||
@@ -614,12 +612,10 @@ static void bch2_read_csum_err(struct work_struct *work)
|
||||
bch2_csum_err_msg(&buf, crc.csum_type, rbio->pick.crc.csum, csum);
|
||||
|
||||
struct bch_dev *ca = rbio->have_ioref ? bch2_dev_have_ref(c, rbio->pick.ptr.dev) : NULL;
|
||||
if (ca) {
|
||||
bch2_io_error(ca, BCH_MEMBER_ERROR_checksum);
|
||||
if (ca)
|
||||
bch_err_ratelimited(ca, "%s", buf.buf);
|
||||
} else {
|
||||
else
|
||||
bch_err_ratelimited(c, "%s", buf.buf);
|
||||
}
|
||||
|
||||
bch2_rbio_error(rbio, READ_RETRY_AVOID, BLK_STS_IOERR);
|
||||
printbuf_exit(&buf);
|
||||
@@ -671,6 +667,7 @@ static void __bch2_read_endio(struct work_struct *work)
|
||||
struct bch_read_bio *rbio =
|
||||
container_of(work, struct bch_read_bio, work);
|
||||
struct bch_fs *c = rbio->c;
|
||||
struct bch_dev *ca = rbio->have_ioref ? bch2_dev_have_ref(c, rbio->pick.ptr.dev) : NULL;
|
||||
struct bio *src = &rbio->bio;
|
||||
struct bio *dst = &bch2_rbio_parent(rbio)->bio;
|
||||
struct bvec_iter dst_iter = rbio->bvec_iter;
|
||||
@@ -692,7 +689,22 @@ static void __bch2_read_endio(struct work_struct *work)
|
||||
}
|
||||
|
||||
csum = bch2_checksum_bio(c, crc.csum_type, nonce, src);
|
||||
if (bch2_crc_cmp(csum, rbio->pick.crc.csum) && !c->opts.no_data_io)
|
||||
bool csum_good = !bch2_crc_cmp(csum, rbio->pick.crc.csum) || c->opts.no_data_io;
|
||||
|
||||
/*
|
||||
* Checksum error: if the bio wasn't bounced, we may have been
|
||||
* reading into buffers owned by userspace (that userspace can
|
||||
* scribble over) - retry the read, bouncing it this time:
|
||||
*/
|
||||
if (!csum_good && !rbio->bounce && (rbio->flags & BCH_READ_user_mapped)) {
|
||||
rbio->flags |= BCH_READ_must_bounce;
|
||||
bch2_rbio_error(rbio, READ_RETRY, BLK_STS_IOERR);
|
||||
goto out;
|
||||
}
|
||||
|
||||
bch2_account_io_completion(ca, BCH_MEMBER_ERROR_checksum, 0, csum_good);
|
||||
|
||||
if (!csum_good)
|
||||
goto csum_err;
|
||||
|
||||
/*
|
||||
@@ -765,17 +777,6 @@ out:
|
||||
memalloc_nofs_restore(nofs_flags);
|
||||
return;
|
||||
csum_err:
|
||||
/*
|
||||
* Checksum error: if the bio wasn't bounced, we may have been
|
||||
* reading into buffers owned by userspace (that userspace can
|
||||
* scribble over) - retry the read, bouncing it this time:
|
||||
*/
|
||||
if (!rbio->bounce && (rbio->flags & BCH_READ_user_mapped)) {
|
||||
rbio->flags |= BCH_READ_must_bounce;
|
||||
bch2_rbio_error(rbio, READ_RETRY, BLK_STS_IOERR);
|
||||
goto out;
|
||||
}
|
||||
|
||||
bch2_rbio_punt(rbio, bch2_read_csum_err, RBIO_CONTEXT_UNBOUND, system_unbound_wq);
|
||||
goto out;
|
||||
decompression_err:
|
||||
@@ -795,8 +796,8 @@ static void bch2_read_endio(struct bio *bio)
|
||||
struct workqueue_struct *wq = NULL;
|
||||
enum rbio_context context = RBIO_CONTEXT_NULL;
|
||||
|
||||
if (ca)
|
||||
bch2_latency_acct(ca, rbio->submit_time, READ);
|
||||
bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read,
|
||||
rbio->submit_time, !bio->bi_status);
|
||||
|
||||
if (!rbio->split)
|
||||
rbio->bio.bi_end_io = rbio->end_io;
|
||||
|
||||
@@ -11,12 +11,6 @@
|
||||
void bch2_bio_free_pages_pool(struct bch_fs *, struct bio *);
|
||||
void bch2_bio_alloc_pages_pool(struct bch_fs *, struct bio *, size_t);
|
||||
|
||||
#ifndef CONFIG_BCACHEFS_NO_LATENCY_ACCT
|
||||
void bch2_latency_acct(struct bch_dev *, u64, int);
|
||||
#else
|
||||
static inline void bch2_latency_acct(struct bch_dev *ca, u64 submit_time, int rw) {}
|
||||
#endif
|
||||
|
||||
void bch2_submit_wbio_replicas(struct bch_write_bio *, struct bch_fs *,
|
||||
enum bch_data_type, const struct bkey_i *, bool);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user