diff mbox series

[v9,3/9] block: add empty account cookie type

Message ID 20190906160120.70239-4-anton.nefedov@virtuozzo.com (mailing list archive)
State New, archived
Headers show
Series discard blockstats | expand

Commit Message

Anton Nefedov Sept. 6, 2019, 4:01 p.m. UTC
This adds some protection from accounting uninitialized cookie.
That is, block_acct_failed/done without previous block_acct_start;
in that case, cookie probably holds values from previous operation.

(Note: it might also be uninitialized holding garbage value and there is
 still "< BLOCK_MAX_IOTYPE" assertion for that.
 So block_acct_failed/done without previous block_acct_start should be used
 with caution.)

Currently this is particularly useful in ide code where it's hard to
keep track whether the request started accounting or not. For example,
trim requests do the accounting separately.

Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 include/block/accounting.h | 1 +
 block/accounting.c         | 6 ++++++
 2 files changed, 7 insertions(+)

Comments

Alberto Garcia Sept. 9, 2019, 2:54 p.m. UTC | #1
On Fri 06 Sep 2019 06:01:14 PM CEST, Anton Nefedov wrote:
> This adds some protection from accounting uninitialized cookie.
> That is, block_acct_failed/done without previous block_acct_start;
> in that case, cookie probably holds values from previous operation.
>
> (Note: it might also be uninitialized holding garbage value and there
> is still "< BLOCK_MAX_IOTYPE" assertion for that.  So
> block_acct_failed/done without previous block_acct_start should be
> used with caution.)
>
> Currently this is particularly useful in ide code where it's hard to
> keep track whether the request started accounting or not. For example,
> trim requests do the accounting separately.

Sorry if I'm understanding it wrong, but it sounds like you know that
there's a bug in the ide code (where you call block_acct_done() without
having it initialized it first), and the purpose of the this patch is to
hide the bug ?

Berto
Anton Nefedov Sept. 10, 2019, 3:23 p.m. UTC | #2
On 9/9/2019 5:54 PM, Alberto Garcia wrote:
> On Fri 06 Sep 2019 06:01:14 PM CEST, Anton Nefedov wrote:
>> This adds some protection from accounting uninitialized cookie.
>> That is, block_acct_failed/done without previous block_acct_start;
>> in that case, cookie probably holds values from previous operation.
>>
>> (Note: it might also be uninitialized holding garbage value and there
>> is still "< BLOCK_MAX_IOTYPE" assertion for that.  So
>> block_acct_failed/done without previous block_acct_start should be
>> used with caution.)
>>
>> Currently this is particularly useful in ide code where it's hard to
>> keep track whether the request started accounting or not. For example,
>> trim requests do the accounting separately.
> 
> Sorry if I'm understanding it wrong, but it sounds like you know that
> there's a bug in the ide code (where you call block_acct_done() without
> having it initialized it first), and the purpose of the this patch is to
> hide the bug ?
> 

hi,

not really; in the existing code, I can't see block_acct_done() without
block_acct_start(), but there might be double-accounting though;
e.g. ide_atapi_cmd_read_dma_cb(): it can account the same operation
twice like
   ide_handle_rw_error();
   goto eot;
   block_acct_failed();

The patch should solve it.

The commit message is misleading, sorry. I'll change to:

 > Each block_acct_done/failed call is designed to correspond to a
 > previous block_acct_start call, which initializes the stats cookie.
 > However sometimes it is not the case, e.g. some error paths might
 > report the same cookie twice because it is hard to accurately track if
 > the cookie was reported yet or not.

 > This patch cleans the cookie after report.
 > (Note: block_acct_failed/done without a previous block_acct_start at
 > all should be avoided. Uninitialized cookie might hold a garbage value
 > and there is still "< BLOCK_MAX_IOTYPE" assertion for that)

 > It will be particularly useful in ide code where it's hard to
 > keep track whether the request done its accounting or not: in the
 > following patch of the series, trim requests will do the accounting
 > separately.

/Anton
diff mbox series

Patch

diff --git a/include/block/accounting.h b/include/block/accounting.h
index ba8b04d572..878b4c3581 100644
--- a/include/block/accounting.h
+++ b/include/block/accounting.h
@@ -33,6 +33,7 @@  typedef struct BlockAcctTimedStats BlockAcctTimedStats;
 typedef struct BlockAcctStats BlockAcctStats;
 
 enum BlockAcctType {
+    BLOCK_ACCT_NONE = 0,
     BLOCK_ACCT_READ,
     BLOCK_ACCT_WRITE,
     BLOCK_ACCT_FLUSH,
diff --git a/block/accounting.c b/block/accounting.c
index 70a3d9a426..8d41c8a83a 100644
--- a/block/accounting.c
+++ b/block/accounting.c
@@ -195,6 +195,10 @@  static void block_account_one_io(BlockAcctStats *stats, BlockAcctCookie *cookie,
 
     assert(cookie->type < BLOCK_MAX_IOTYPE);
 
+    if (cookie->type == BLOCK_ACCT_NONE) {
+        return;
+    }
+
     qemu_mutex_lock(&stats->lock);
 
     if (failed) {
@@ -217,6 +221,8 @@  static void block_account_one_io(BlockAcctStats *stats, BlockAcctCookie *cookie,
     }
 
     qemu_mutex_unlock(&stats->lock);
+
+    cookie->type = BLOCK_ACCT_NONE;
 }
 
 void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie)