@@ -206,6 +206,19 @@ struct dm_writecache {
206
206
207
207
struct bio_set bio_set ;
208
208
mempool_t copy_pool ;
209
+
210
+ struct {
211
+ unsigned long long reads ;
212
+ unsigned long long read_hits ;
213
+ unsigned long long writes ;
214
+ unsigned long long write_hits_uncommitted ;
215
+ unsigned long long write_hits_committed ;
216
+ unsigned long long writes_around ;
217
+ unsigned long long writes_allocate ;
218
+ unsigned long long writes_blocked_on_freelist ;
219
+ unsigned long long flushes ;
220
+ unsigned long long discards ;
221
+ } stats ;
209
222
};
210
223
211
224
#define WB_LIST_INLINE 16
@@ -1157,6 +1170,18 @@ static int process_cleaner_mesg(unsigned argc, char **argv, struct dm_writecache
1157
1170
return 0 ;
1158
1171
}
1159
1172
1173
+ static int process_clear_stats_mesg (unsigned argc , char * * argv , struct dm_writecache * wc )
1174
+ {
1175
+ if (argc != 1 )
1176
+ return - EINVAL ;
1177
+
1178
+ wc_lock (wc );
1179
+ memset (& wc -> stats , 0 , sizeof wc -> stats );
1180
+ wc_unlock (wc );
1181
+
1182
+ return 0 ;
1183
+ }
1184
+
1160
1185
static int writecache_message (struct dm_target * ti , unsigned argc , char * * argv ,
1161
1186
char * result , unsigned maxlen )
1162
1187
{
@@ -1169,6 +1194,8 @@ static int writecache_message(struct dm_target *ti, unsigned argc, char **argv,
1169
1194
r = process_flush_on_suspend_mesg (argc , argv , wc );
1170
1195
else if (!strcasecmp (argv [0 ], "cleaner" ))
1171
1196
r = process_cleaner_mesg (argc , argv , wc );
1197
+ else if (!strcasecmp (argv [0 ], "clear_stats" ))
1198
+ r = process_clear_stats_mesg (argc , argv , wc );
1172
1199
else
1173
1200
DMERR ("unrecognised message received: %s" , argv [0 ]);
1174
1201
@@ -1320,8 +1347,10 @@ static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio *
1320
1347
struct wc_entry * e ;
1321
1348
1322
1349
read_next_block :
1350
+ wc -> stats .reads ++ ;
1323
1351
e = writecache_find_entry (wc , bio -> bi_iter .bi_sector , WFE_RETURN_FOLLOWING );
1324
1352
if (e && read_original_sector (wc , e ) == bio -> bi_iter .bi_sector ) {
1353
+ wc -> stats .read_hits ++ ;
1325
1354
if (WC_MODE_PMEM (wc )) {
1326
1355
bio_copy_block (wc , bio , memory_data (wc , e ));
1327
1356
if (bio -> bi_iter .bi_size )
@@ -1400,14 +1429,17 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
1400
1429
do {
1401
1430
bool found_entry = false;
1402
1431
bool search_used = false;
1432
+ wc -> stats .writes ++ ;
1403
1433
if (writecache_has_error (wc ))
1404
1434
return WC_MAP_ERROR ;
1405
1435
e = writecache_find_entry (wc , bio -> bi_iter .bi_sector , 0 );
1406
1436
if (e ) {
1407
1437
if (!writecache_entry_is_committed (wc , e )) {
1438
+ wc -> stats .write_hits_uncommitted ++ ;
1408
1439
search_used = true;
1409
1440
goto bio_copy ;
1410
1441
}
1442
+ wc -> stats .write_hits_committed ++ ;
1411
1443
if (!WC_MODE_PMEM (wc ) && !e -> write_in_progress ) {
1412
1444
wc -> overwrote_committed = true;
1413
1445
search_used = true;
@@ -1423,15 +1455,18 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
1423
1455
if (unlikely (!e )) {
1424
1456
if (!WC_MODE_PMEM (wc ) && !found_entry ) {
1425
1457
direct_write :
1458
+ wc -> stats .writes_around ++ ;
1426
1459
e = writecache_find_entry (wc , bio -> bi_iter .bi_sector , WFE_RETURN_FOLLOWING );
1427
1460
return writecache_map_remap_origin (wc , bio , e );
1428
1461
}
1462
+ wc -> stats .writes_blocked_on_freelist ++ ;
1429
1463
writecache_wait_on_freelist (wc );
1430
1464
continue ;
1431
1465
}
1432
1466
write_original_sector_seq_count (wc , e , bio -> bi_iter .bi_sector , wc -> seq_count );
1433
1467
writecache_insert_entry (wc , e );
1434
1468
wc -> uncommitted_blocks ++ ;
1469
+ wc -> stats .writes_allocate ++ ;
1435
1470
bio_copy :
1436
1471
if (WC_MODE_PMEM (wc ))
1437
1472
bio_copy_block (wc , bio , memory_data (wc , e ));
@@ -1453,6 +1488,7 @@ static enum wc_map_op writecache_map_flush(struct dm_writecache *wc, struct bio
1453
1488
return WC_MAP_ERROR ;
1454
1489
1455
1490
if (WC_MODE_PMEM (wc )) {
1491
+ wc -> stats .flushes ++ ;
1456
1492
writecache_flush (wc );
1457
1493
if (writecache_has_error (wc ))
1458
1494
return WC_MAP_ERROR ;
@@ -1463,12 +1499,15 @@ static enum wc_map_op writecache_map_flush(struct dm_writecache *wc, struct bio
1463
1499
/* SSD: */
1464
1500
if (dm_bio_get_target_bio_nr (bio ))
1465
1501
return WC_MAP_REMAP_ORIGIN ;
1502
+ wc -> stats .flushes ++ ;
1466
1503
writecache_offload_bio (wc , bio );
1467
1504
return WC_MAP_RETURN ;
1468
1505
}
1469
1506
1470
1507
static enum wc_map_op writecache_map_discard (struct dm_writecache * wc , struct bio * bio )
1471
1508
{
1509
+ wc -> stats .discards ++ ;
1510
+
1472
1511
if (writecache_has_error (wc ))
1473
1512
return WC_MAP_ERROR ;
1474
1513
@@ -2618,9 +2657,20 @@ static void writecache_status(struct dm_target *ti, status_type_t type,
2618
2657
2619
2658
switch (type ) {
2620
2659
case STATUSTYPE_INFO :
2621
- DMEMIT ("%ld %llu %llu %llu" , writecache_has_error (wc ),
2660
+ DMEMIT ("%ld %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu" ,
2661
+ writecache_has_error (wc ),
2622
2662
(unsigned long long )wc -> n_blocks , (unsigned long long )wc -> freelist_size ,
2623
- (unsigned long long )wc -> writeback_size );
2663
+ (unsigned long long )wc -> writeback_size ,
2664
+ wc -> stats .reads ,
2665
+ wc -> stats .read_hits ,
2666
+ wc -> stats .writes ,
2667
+ wc -> stats .write_hits_uncommitted ,
2668
+ wc -> stats .write_hits_committed ,
2669
+ wc -> stats .writes_around ,
2670
+ wc -> stats .writes_allocate ,
2671
+ wc -> stats .writes_blocked_on_freelist ,
2672
+ wc -> stats .flushes ,
2673
+ wc -> stats .discards );
2624
2674
break ;
2625
2675
case STATUSTYPE_TABLE :
2626
2676
DMEMIT ("%c %s %s %u " , WC_MODE_PMEM (wc ) ? 'p' : 's' ,
@@ -2678,7 +2728,7 @@ static void writecache_status(struct dm_target *ti, status_type_t type,
2678
2728
2679
2729
static struct target_type writecache_target = {
2680
2730
.name = "writecache" ,
2681
- .version = {1 , 5 , 0 },
2731
+ .version = {1 , 6 , 0 },
2682
2732
.module = THIS_MODULE ,
2683
2733
.ctr = writecache_ctr ,
2684
2734
.dtr = writecache_dtr ,
0 commit comments