diff options
author | Bob Liu <bob.liu@oracle.com> | 2015-12-08 18:44:02 -0500 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2016-01-04 12:21:25 -0500 |
commit | db6fbc106786f26d95889c50c18b1f28aa543a17 (patch) | |
tree | 21d9bed91528e2477d4a318556de7afb326dbb6f | |
parent | 6cc5683390472c450fd69975d1283db79202667f (diff) |
xen/blkback: make st_ statistics per ring
Make st_* statistics per ring and the VBD sysfs would iterate over all the
rings.
Note: xenvbd_sysfs_delif() is called in xen_blkbk_remove() before all rings
are torn down, so it's safe.
Signed-off-by: Bob Liu <bob.liu@oracle.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
v2: Aligned the variables on the same column.
-rw-r--r-- | drivers/block/xen-blkback/blkback.c | 34 | ||||
-rw-r--r-- | drivers/block/xen-blkback/common.h | 20 | ||||
-rw-r--r-- | drivers/block/xen-blkback/xenbus.c | 45 |
3 files changed, 61 insertions, 38 deletions
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 99b479f330af..148930c8c121 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c | |||
@@ -587,20 +587,18 @@ irqreturn_t xen_blkif_be_int(int irq, void *dev_id) | |||
587 | 587 | ||
588 | static void print_stats(struct xen_blkif_ring *ring) | 588 | static void print_stats(struct xen_blkif_ring *ring) |
589 | { | 589 | { |
590 | struct xen_blkif *blkif = ring->blkif; | ||
591 | |||
592 | pr_info("(%s): oo %3llu | rd %4llu | wr %4llu | f %4llu" | 590 | pr_info("(%s): oo %3llu | rd %4llu | wr %4llu | f %4llu" |
593 | " | ds %4llu | pg: %4u/%4d\n", | 591 | " | ds %4llu | pg: %4u/%4d\n", |
594 | current->comm, blkif->st_oo_req, | 592 | current->comm, ring->st_oo_req, |
595 | blkif->st_rd_req, blkif->st_wr_req, | 593 | ring->st_rd_req, ring->st_wr_req, |
596 | blkif->st_f_req, blkif->st_ds_req, | 594 | ring->st_f_req, ring->st_ds_req, |
597 | ring->persistent_gnt_c, | 595 | ring->persistent_gnt_c, |
598 | xen_blkif_max_pgrants); | 596 | xen_blkif_max_pgrants); |
599 | blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000); | 597 | ring->st_print = jiffies + msecs_to_jiffies(10 * 1000); |
600 | blkif->st_rd_req = 0; | 598 | ring->st_rd_req = 0; |
601 | blkif->st_wr_req = 0; | 599 | ring->st_wr_req = 0; |
602 | blkif->st_oo_req = 0; | 600 | ring->st_oo_req = 0; |
603 | blkif->st_ds_req = 0; | 601 | ring->st_ds_req = 0; |
604 | } | 602 | } |
605 | 603 | ||
606 | int xen_blkif_schedule(void *arg) | 604 | int xen_blkif_schedule(void *arg) |
@@ -656,7 +654,7 @@ purge_gnt_list: | |||
656 | /* Shrink if we have more than xen_blkif_max_buffer_pages */ | 654 | /* Shrink if we have more than xen_blkif_max_buffer_pages */ |
657 | shrink_free_pagepool(ring, xen_blkif_max_buffer_pages); | 655 | shrink_free_pagepool(ring, xen_blkif_max_buffer_pages); |
658 | 656 | ||
659 | if (log_stats && time_after(jiffies, ring->blkif->st_print)) | 657 | if (log_stats && time_after(jiffies, ring->st_print)) |
660 | print_stats(ring); | 658 | print_stats(ring); |
661 | } | 659 | } |
662 | 660 | ||
@@ -1018,7 +1016,7 @@ static int dispatch_discard_io(struct xen_blkif_ring *ring, | |||
1018 | preq.sector_number + preq.nr_sects, blkif->vbd.pdevice); | 1016 | preq.sector_number + preq.nr_sects, blkif->vbd.pdevice); |
1019 | goto fail_response; | 1017 | goto fail_response; |
1020 | } | 1018 | } |
1021 | blkif->st_ds_req++; | 1019 | ring->st_ds_req++; |
1022 | 1020 | ||
1023 | secure = (blkif->vbd.discard_secure && | 1021 | secure = (blkif->vbd.discard_secure && |
1024 | (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ? | 1022 | (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ? |
@@ -1145,7 +1143,7 @@ __do_block_io_op(struct xen_blkif_ring *ring) | |||
1145 | 1143 | ||
1146 | pending_req = alloc_req(ring); | 1144 | pending_req = alloc_req(ring); |
1147 | if (NULL == pending_req) { | 1145 | if (NULL == pending_req) { |
1148 | ring->blkif->st_oo_req++; | 1146 | ring->st_oo_req++; |
1149 | more_to_do = 1; | 1147 | more_to_do = 1; |
1150 | break; | 1148 | break; |
1151 | } | 1149 | } |
@@ -1243,17 +1241,17 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring, | |||
1243 | 1241 | ||
1244 | switch (req_operation) { | 1242 | switch (req_operation) { |
1245 | case BLKIF_OP_READ: | 1243 | case BLKIF_OP_READ: |
1246 | ring->blkif->st_rd_req++; | 1244 | ring->st_rd_req++; |
1247 | operation = READ; | 1245 | operation = READ; |
1248 | break; | 1246 | break; |
1249 | case BLKIF_OP_WRITE: | 1247 | case BLKIF_OP_WRITE: |
1250 | ring->blkif->st_wr_req++; | 1248 | ring->st_wr_req++; |
1251 | operation = WRITE_ODIRECT; | 1249 | operation = WRITE_ODIRECT; |
1252 | break; | 1250 | break; |
1253 | case BLKIF_OP_WRITE_BARRIER: | 1251 | case BLKIF_OP_WRITE_BARRIER: |
1254 | drain = true; | 1252 | drain = true; |
1255 | case BLKIF_OP_FLUSH_DISKCACHE: | 1253 | case BLKIF_OP_FLUSH_DISKCACHE: |
1256 | ring->blkif->st_f_req++; | 1254 | ring->st_f_req++; |
1257 | operation = WRITE_FLUSH; | 1255 | operation = WRITE_FLUSH; |
1258 | break; | 1256 | break; |
1259 | default: | 1257 | default: |
@@ -1395,9 +1393,9 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring, | |||
1395 | blk_finish_plug(&plug); | 1393 | blk_finish_plug(&plug); |
1396 | 1394 | ||
1397 | if (operation == READ) | 1395 | if (operation == READ) |
1398 | ring->blkif->st_rd_sect += preq.nr_sects; | 1396 | ring->st_rd_sect += preq.nr_sects; |
1399 | else if (operation & WRITE) | 1397 | else if (operation & WRITE) |
1400 | ring->blkif->st_wr_sect += preq.nr_sects; | 1398 | ring->st_wr_sect += preq.nr_sects; |
1401 | 1399 | ||
1402 | return 0; | 1400 | return 0; |
1403 | 1401 | ||
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 3c244ecf22a4..b27c5ba15600 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h | |||
@@ -298,6 +298,16 @@ struct xen_blkif_ring { | |||
298 | atomic_t persistent_gnt_in_use; | 298 | atomic_t persistent_gnt_in_use; |
299 | unsigned long next_lru; | 299 | unsigned long next_lru; |
300 | 300 | ||
301 | /* Statistics. */ | ||
302 | unsigned long st_print; | ||
303 | unsigned long long st_rd_req; | ||
304 | unsigned long long st_wr_req; | ||
305 | unsigned long long st_oo_req; | ||
306 | unsigned long long st_f_req; | ||
307 | unsigned long long st_ds_req; | ||
308 | unsigned long long st_rd_sect; | ||
309 | unsigned long long st_wr_sect; | ||
310 | |||
301 | /* Used by the kworker that offload work from the persistent purge. */ | 311 | /* Used by the kworker that offload work from the persistent purge. */ |
302 | struct list_head persistent_purge_list; | 312 | struct list_head persistent_purge_list; |
303 | struct work_struct persistent_purge_work; | 313 | struct work_struct persistent_purge_work; |
@@ -328,16 +338,6 @@ struct xen_blkif { | |||
328 | struct completion drain_complete; | 338 | struct completion drain_complete; |
329 | atomic_t drain; | 339 | atomic_t drain; |
330 | 340 | ||
331 | /* statistics */ | ||
332 | unsigned long st_print; | ||
333 | unsigned long long st_rd_req; | ||
334 | unsigned long long st_wr_req; | ||
335 | unsigned long long st_oo_req; | ||
336 | unsigned long long st_f_req; | ||
337 | unsigned long long st_ds_req; | ||
338 | unsigned long long st_rd_sect; | ||
339 | unsigned long long st_wr_sect; | ||
340 | |||
341 | struct work_struct free_work; | 341 | struct work_struct free_work; |
342 | unsigned int nr_ring_pages; | 342 | unsigned int nr_ring_pages; |
343 | /* All rings for this device. */ | 343 | /* All rings for this device. */ |
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index c92b35882720..44396b8a0cb2 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c | |||
@@ -159,6 +159,7 @@ static int xen_blkif_alloc_rings(struct xen_blkif *blkif) | |||
159 | init_waitqueue_head(&ring->pending_free_wq); | 159 | init_waitqueue_head(&ring->pending_free_wq); |
160 | init_waitqueue_head(&ring->shutdown_wq); | 160 | init_waitqueue_head(&ring->shutdown_wq); |
161 | ring->blkif = blkif; | 161 | ring->blkif = blkif; |
162 | ring->st_print = jiffies; | ||
162 | xen_blkif_get(blkif); | 163 | xen_blkif_get(blkif); |
163 | } | 164 | } |
164 | 165 | ||
@@ -179,7 +180,6 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) | |||
179 | atomic_set(&blkif->refcnt, 1); | 180 | atomic_set(&blkif->refcnt, 1); |
180 | init_completion(&blkif->drain_complete); | 181 | init_completion(&blkif->drain_complete); |
181 | INIT_WORK(&blkif->free_work, xen_blkif_deferred_free); | 182 | INIT_WORK(&blkif->free_work, xen_blkif_deferred_free); |
182 | blkif->st_print = jiffies; | ||
183 | 183 | ||
184 | return blkif; | 184 | return blkif; |
185 | } | 185 | } |
@@ -329,25 +329,38 @@ int __init xen_blkif_interface_init(void) | |||
329 | * sysfs interface for VBD I/O requests | 329 | * sysfs interface for VBD I/O requests |
330 | */ | 330 | */ |
331 | 331 | ||
332 | #define VBD_SHOW(name, format, args...) \ | 332 | #define VBD_SHOW_ALLRING(name, format) \ |
333 | static ssize_t show_##name(struct device *_dev, \ | 333 | static ssize_t show_##name(struct device *_dev, \ |
334 | struct device_attribute *attr, \ | 334 | struct device_attribute *attr, \ |
335 | char *buf) \ | 335 | char *buf) \ |
336 | { \ | 336 | { \ |
337 | struct xenbus_device *dev = to_xenbus_device(_dev); \ | 337 | struct xenbus_device *dev = to_xenbus_device(_dev); \ |
338 | struct backend_info *be = dev_get_drvdata(&dev->dev); \ | 338 | struct backend_info *be = dev_get_drvdata(&dev->dev); \ |
339 | struct xen_blkif *blkif = be->blkif; \ | ||
340 | unsigned int i; \ | ||
341 | unsigned long long result = 0; \ | ||
339 | \ | 342 | \ |
340 | return sprintf(buf, format, ##args); \ | 343 | if (!blkif->rings) \ |
344 | goto out; \ | ||
345 | \ | ||
346 | for (i = 0; i < blkif->nr_rings; i++) { \ | ||
347 | struct xen_blkif_ring *ring = &blkif->rings[i]; \ | ||
348 | \ | ||
349 | result += ring->st_##name; \ | ||
350 | } \ | ||
351 | \ | ||
352 | out: \ | ||
353 | return sprintf(buf, format, result); \ | ||
341 | } \ | 354 | } \ |
342 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) | 355 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) |
343 | 356 | ||
344 | VBD_SHOW(oo_req, "%llu\n", be->blkif->st_oo_req); | 357 | VBD_SHOW_ALLRING(oo_req, "%llu\n"); |
345 | VBD_SHOW(rd_req, "%llu\n", be->blkif->st_rd_req); | 358 | VBD_SHOW_ALLRING(rd_req, "%llu\n"); |
346 | VBD_SHOW(wr_req, "%llu\n", be->blkif->st_wr_req); | 359 | VBD_SHOW_ALLRING(wr_req, "%llu\n"); |
347 | VBD_SHOW(f_req, "%llu\n", be->blkif->st_f_req); | 360 | VBD_SHOW_ALLRING(f_req, "%llu\n"); |
348 | VBD_SHOW(ds_req, "%llu\n", be->blkif->st_ds_req); | 361 | VBD_SHOW_ALLRING(ds_req, "%llu\n"); |
349 | VBD_SHOW(rd_sect, "%llu\n", be->blkif->st_rd_sect); | 362 | VBD_SHOW_ALLRING(rd_sect, "%llu\n"); |
350 | VBD_SHOW(wr_sect, "%llu\n", be->blkif->st_wr_sect); | 363 | VBD_SHOW_ALLRING(wr_sect, "%llu\n"); |
351 | 364 | ||
352 | static struct attribute *xen_vbdstat_attrs[] = { | 365 | static struct attribute *xen_vbdstat_attrs[] = { |
353 | &dev_attr_oo_req.attr, | 366 | &dev_attr_oo_req.attr, |
@@ -365,6 +378,18 @@ static struct attribute_group xen_vbdstat_group = { | |||
365 | .attrs = xen_vbdstat_attrs, | 378 | .attrs = xen_vbdstat_attrs, |
366 | }; | 379 | }; |
367 | 380 | ||
381 | #define VBD_SHOW(name, format, args...) \ | ||
382 | static ssize_t show_##name(struct device *_dev, \ | ||
383 | struct device_attribute *attr, \ | ||
384 | char *buf) \ | ||
385 | { \ | ||
386 | struct xenbus_device *dev = to_xenbus_device(_dev); \ | ||
387 | struct backend_info *be = dev_get_drvdata(&dev->dev); \ | ||
388 | \ | ||
389 | return sprintf(buf, format, ##args); \ | ||
390 | } \ | ||
391 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) | ||
392 | |||
368 | VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor); | 393 | VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor); |
369 | VBD_SHOW(mode, "%s\n", be->mode); | 394 | VBD_SHOW(mode, "%s\n", be->mode); |
370 | 395 | ||