aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Liu <bob.liu@oracle.com>2015-12-08 18:44:02 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2016-01-04 12:21:25 -0500
commitdb6fbc106786f26d95889c50c18b1f28aa543a17 (patch)
tree21d9bed91528e2477d4a318556de7afb326dbb6f
parent6cc5683390472c450fd69975d1283db79202667f (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.c34
-rw-r--r--drivers/block/xen-blkback/common.h20
-rw-r--r--drivers/block/xen-blkback/xenbus.c45
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
588static void print_stats(struct xen_blkif_ring *ring) 588static 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
606int xen_blkif_schedule(void *arg) 604int 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 \
352out: \
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
344VBD_SHOW(oo_req, "%llu\n", be->blkif->st_oo_req); 357VBD_SHOW_ALLRING(oo_req, "%llu\n");
345VBD_SHOW(rd_req, "%llu\n", be->blkif->st_rd_req); 358VBD_SHOW_ALLRING(rd_req, "%llu\n");
346VBD_SHOW(wr_req, "%llu\n", be->blkif->st_wr_req); 359VBD_SHOW_ALLRING(wr_req, "%llu\n");
347VBD_SHOW(f_req, "%llu\n", be->blkif->st_f_req); 360VBD_SHOW_ALLRING(f_req, "%llu\n");
348VBD_SHOW(ds_req, "%llu\n", be->blkif->st_ds_req); 361VBD_SHOW_ALLRING(ds_req, "%llu\n");
349VBD_SHOW(rd_sect, "%llu\n", be->blkif->st_rd_sect); 362VBD_SHOW_ALLRING(rd_sect, "%llu\n");
350VBD_SHOW(wr_sect, "%llu\n", be->blkif->st_wr_sect); 363VBD_SHOW_ALLRING(wr_sect, "%llu\n");
351 364
352static struct attribute *xen_vbdstat_attrs[] = { 365static 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
368VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor); 393VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor);
369VBD_SHOW(mode, "%s\n", be->mode); 394VBD_SHOW(mode, "%s\n", be->mode);
370 395