Browse Source

{hmp, hw/pvrdma}: Expose device internals via monitor interface

Allow interrogating device internals through HMP interface.
The exposed indicators can be used for troubleshooting by developers or
sysadmin.
There is no need to expose these attributes to a management system (e.x.
libvirt) because (1) most of them are not "device-management' related
info and (2) there is no guarantee the interface is stable.

Signed-off-by: Yuval Shaia <yuval.shaia@oracle.com>
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1552300155-25216-6-git-send-email-yuval.shaia@oracle.com>
Reviewed-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
tags/v4.0.0-rc0
Yuval Shaia 3 months ago
parent
commit
f4b2c02a29
9 changed files with 193 additions and 1 deletions
  1. 14
    0
      hmp-commands-info.hx
  2. 27
    0
      hmp.c
  3. 1
    0
      hmp.h
  4. 1
    1
      hw/rdma/Makefile.objs
  5. 30
    0
      hw/rdma/rdma.c
  6. 53
    0
      hw/rdma/rdma_rm.c
  7. 1
    0
      hw/rdma/rdma_rm.h
  8. 26
    0
      hw/rdma/vmw/pvrdma_main.c
  9. 40
    0
      include/hw/rdma/rdma.h

+ 14
- 0
hmp-commands-info.hx View File

@@ -202,6 +202,20 @@ STEXI
202 202
 @item info pic
203 203
 @findex info pic
204 204
 Show PIC state.
205
+ETEXI
206
+
207
+    {
208
+        .name       = "rdma",
209
+        .args_type  = "",
210
+        .params     = "",
211
+        .help       = "show RDMA state",
212
+        .cmd        = hmp_info_rdma,
213
+    },
214
+
215
+STEXI
216
+@item info rdma
217
+@findex info rdma
218
+Show RDMA state.
205 219
 ETEXI
206 220
 
207 221
     {

+ 27
- 0
hmp.c View File

@@ -51,6 +51,7 @@
51 51
 #include "qemu/error-report.h"
52 52
 #include "exec/ramlist.h"
53 53
 #include "hw/intc/intc.h"
54
+#include "hw/rdma/rdma.h"
54 55
 #include "migration/snapshot.h"
55 56
 #include "migration/misc.h"
56 57
 
@@ -1013,6 +1014,32 @@ void hmp_info_pic(Monitor *mon, const QDict *qdict)
1013 1014
                                    hmp_info_pic_foreach, mon);
1014 1015
 }
1015 1016
 
1017
+static int hmp_info_rdma_foreach(Object *obj, void *opaque)
1018
+{
1019
+    RdmaProvider *rdma;
1020
+    RdmaProviderClass *k;
1021
+    Monitor *mon = opaque;
1022
+
1023
+    if (object_dynamic_cast(obj, INTERFACE_RDMA_PROVIDER)) {
1024
+        rdma = RDMA_PROVIDER(obj);
1025
+        k = RDMA_PROVIDER_GET_CLASS(obj);
1026
+        if (k->print_statistics) {
1027
+            k->print_statistics(mon, rdma);
1028
+        } else {
1029
+            monitor_printf(mon, "RDMA statistics not available for %s.\n",
1030
+                           object_get_typename(obj));
1031
+        }
1032
+    }
1033
+
1034
+    return 0;
1035
+}
1036
+
1037
+void hmp_info_rdma(Monitor *mon, const QDict *qdict)
1038
+{
1039
+    object_child_foreach_recursive(object_get_root(),
1040
+                                   hmp_info_rdma_foreach, mon);
1041
+}
1042
+
1016 1043
 void hmp_info_pci(Monitor *mon, const QDict *qdict)
1017 1044
 {
1018 1045
     PciInfoList *info_list, *info;

+ 1
- 0
hmp.h View File

@@ -36,6 +36,7 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict);
36 36
 void hmp_info_balloon(Monitor *mon, const QDict *qdict);
37 37
 void hmp_info_irq(Monitor *mon, const QDict *qdict);
38 38
 void hmp_info_pic(Monitor *mon, const QDict *qdict);
39
+void hmp_info_rdma(Monitor *mon, const QDict *qdict);
39 40
 void hmp_info_pci(Monitor *mon, const QDict *qdict);
40 41
 void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
41 42
 void hmp_info_tpm(Monitor *mon, const QDict *qdict);

+ 1
- 1
hw/rdma/Makefile.objs View File

@@ -1,5 +1,5 @@
1 1
 ifeq ($(CONFIG_PVRDMA),y)
2
-obj-$(CONFIG_PCI) += rdma_utils.o rdma_backend.o rdma_rm.o
2
+obj-$(CONFIG_PCI) += rdma_utils.o rdma_backend.o rdma_rm.o rdma.o
3 3
 obj-$(CONFIG_PCI) += vmw/pvrdma_dev_ring.o vmw/pvrdma_cmd.o \
4 4
                      vmw/pvrdma_qp_ops.o vmw/pvrdma_main.o
5 5
 endif

+ 30
- 0
hw/rdma/rdma.c View File

@@ -0,0 +1,30 @@
1
+/*
2
+ * RDMA device interface
3
+ *
4
+ * Copyright (C) 2018 Oracle
5
+ * Copyright (C) 2018 Red Hat Inc
6
+ *
7
+ * Authors:
8
+ *     Yuval Shaia <yuval.shaia@oracle.com>
9
+ *
10
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
11
+ * See the COPYING file in the top-level directory.
12
+ *
13
+ */
14
+
15
+#include "qemu/osdep.h"
16
+#include "hw/rdma/rdma.h"
17
+#include "qemu/module.h"
18
+
19
+static const TypeInfo rdma_hmp_info = {
20
+    .name = INTERFACE_RDMA_PROVIDER,
21
+    .parent = TYPE_INTERFACE,
22
+    .class_size = sizeof(RdmaProviderClass),
23
+};
24
+
25
+static void rdma_register_types(void)
26
+{
27
+    type_register_static(&rdma_hmp_info);
28
+}
29
+
30
+type_init(rdma_register_types)

+ 53
- 0
hw/rdma/rdma_rm.c View File

@@ -16,6 +16,7 @@
16 16
 #include "qemu/osdep.h"
17 17
 #include "qapi/error.h"
18 18
 #include "cpu.h"
19
+#include "monitor/monitor.h"
19 20
 
20 21
 #include "trace.h"
21 22
 #include "rdma_utils.h"
@@ -26,6 +27,58 @@
26 27
 #define PG_DIR_SZ { TARGET_PAGE_SIZE / sizeof(__u64) }
27 28
 #define PG_TBL_SZ { TARGET_PAGE_SIZE / sizeof(__u64) }
28 29
 
30
+void rdma_dump_device_counters(Monitor *mon, RdmaDeviceResources *dev_res)
31
+{
32
+    monitor_printf(mon, "\ttx               : %" PRId64 "\n",
33
+                   dev_res->stats.tx);
34
+    monitor_printf(mon, "\ttx_len           : %" PRId64 "\n",
35
+                   dev_res->stats.tx_len);
36
+    monitor_printf(mon, "\ttx_err           : %" PRId64 "\n",
37
+                   dev_res->stats.tx_err);
38
+    monitor_printf(mon, "\trx_bufs          : %" PRId64 "\n",
39
+                   dev_res->stats.rx_bufs);
40
+    monitor_printf(mon, "\trx_bufs_len      : %" PRId64 "\n",
41
+                   dev_res->stats.rx_bufs_len);
42
+    monitor_printf(mon, "\trx_bufs_err      : %" PRId64 "\n",
43
+                   dev_res->stats.rx_bufs_err);
44
+    monitor_printf(mon, "\tcomps            : %" PRId64 "\n",
45
+                   dev_res->stats.completions);
46
+    monitor_printf(mon, "\tmissing_comps    : %" PRId32 "\n",
47
+                   dev_res->stats.missing_cqe);
48
+    monitor_printf(mon, "\tpoll_cq (bk)     : %" PRId64 "\n",
49
+                   dev_res->stats.poll_cq_from_bk);
50
+    monitor_printf(mon, "\tpoll_cq_ppoll_to : %" PRId64 "\n",
51
+                   dev_res->stats.poll_cq_ppoll_to);
52
+    monitor_printf(mon, "\tpoll_cq (fe)     : %" PRId64 "\n",
53
+                   dev_res->stats.poll_cq_from_guest);
54
+    monitor_printf(mon, "\tpoll_cq_empty    : %" PRId64 "\n",
55
+                   dev_res->stats.poll_cq_from_guest_empty);
56
+    monitor_printf(mon, "\tmad_tx           : %" PRId64 "\n",
57
+                   dev_res->stats.mad_tx);
58
+    monitor_printf(mon, "\tmad_tx_err       : %" PRId64 "\n",
59
+                   dev_res->stats.mad_tx_err);
60
+    monitor_printf(mon, "\tmad_rx           : %" PRId64 "\n",
61
+                   dev_res->stats.mad_rx);
62
+    monitor_printf(mon, "\tmad_rx_err       : %" PRId64 "\n",
63
+                   dev_res->stats.mad_rx_err);
64
+    monitor_printf(mon, "\tmad_rx_bufs      : %" PRId64 "\n",
65
+                   dev_res->stats.mad_rx_bufs);
66
+    monitor_printf(mon, "\tmad_rx_bufs_err  : %" PRId64 "\n",
67
+                   dev_res->stats.mad_rx_bufs_err);
68
+    monitor_printf(mon, "\tPDs              : %" PRId32 "\n",
69
+                   dev_res->pd_tbl.used);
70
+    monitor_printf(mon, "\tMRs              : %" PRId32 "\n",
71
+                   dev_res->mr_tbl.used);
72
+    monitor_printf(mon, "\tUCs              : %" PRId32 "\n",
73
+                   dev_res->uc_tbl.used);
74
+    monitor_printf(mon, "\tQPs              : %" PRId32 "\n",
75
+                   dev_res->qp_tbl.used);
76
+    monitor_printf(mon, "\tCQs              : %" PRId32 "\n",
77
+                   dev_res->cq_tbl.used);
78
+    monitor_printf(mon, "\tCEQ_CTXs         : %" PRId32 "\n",
79
+                   dev_res->cqe_ctx_tbl.used);
80
+}
81
+
29 82
 static inline void res_tbl_init(const char *name, RdmaRmResTbl *tbl,
30 83
                                 uint32_t tbl_sz, uint32_t res_sz)
31 84
 {

+ 1
- 0
hw/rdma/rdma_rm.h View File

@@ -81,5 +81,6 @@ static inline union ibv_gid *rdma_rm_get_gid(RdmaDeviceResources *dev_res,
81 81
 {
82 82
     return &dev_res->port.gid_tbl[sgid_idx].gid;
83 83
 }
84
+void rdma_dump_device_counters(Monitor *mon, RdmaDeviceResources *dev_res);
84 85
 
85 86
 #endif

+ 26
- 0
hw/rdma/vmw/pvrdma_main.c View File

@@ -25,6 +25,8 @@
25 25
 #include "cpu.h"
26 26
 #include "trace.h"
27 27
 #include "sysemu/sysemu.h"
28
+#include "monitor/monitor.h"
29
+#include "hw/rdma/rdma.h"
28 30
 
29 31
 #include "../rdma_rm.h"
30 32
 #include "../rdma_backend.h"
@@ -55,6 +57,26 @@ static Property pvrdma_dev_properties[] = {
55 57
     DEFINE_PROP_END_OF_LIST(),
56 58
 };
57 59
 
60
+static void pvrdma_print_statistics(Monitor *mon, RdmaProvider *obj)
61
+{
62
+    PVRDMADev *dev = PVRDMA_DEV(obj);
63
+    PCIDevice *pdev = PCI_DEVICE(dev);
64
+
65
+    monitor_printf(mon, "%s, %x.%x\n", pdev->name, PCI_SLOT(pdev->devfn),
66
+                   PCI_FUNC(pdev->devfn));
67
+    monitor_printf(mon, "\tcommands         : %" PRId64 "\n",
68
+                   dev->stats.commands);
69
+    monitor_printf(mon, "\tregs_reads       : %" PRId64 "\n",
70
+                   dev->stats.regs_reads);
71
+    monitor_printf(mon, "\tregs_writes      : %" PRId64 "\n",
72
+                   dev->stats.regs_writes);
73
+    monitor_printf(mon, "\tuar_writes       : %" PRId64 "\n",
74
+                   dev->stats.uar_writes);
75
+    monitor_printf(mon, "\tinterrupts       : %" PRId64 "\n",
76
+                   dev->stats.interrupts);
77
+    rdma_dump_device_counters(mon, &dev->rdma_dev_res);
78
+}
79
+
58 80
 static void free_dev_ring(PCIDevice *pci_dev, PvrdmaRing *ring,
59 81
                           void *ring_state)
60 82
 {
@@ -639,6 +661,7 @@ static void pvrdma_class_init(ObjectClass *klass, void *data)
639 661
 {
640 662
     DeviceClass *dc = DEVICE_CLASS(klass);
641 663
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
664
+    RdmaProviderClass *ir = INTERFACE_RDMA_PROVIDER_CLASS(klass);
642 665
 
643 666
     k->realize = pvrdma_realize;
644 667
     k->exit = pvrdma_exit;
@@ -650,6 +673,8 @@ static void pvrdma_class_init(ObjectClass *klass, void *data)
650 673
     dc->desc = "RDMA Device";
651 674
     dc->props = pvrdma_dev_properties;
652 675
     set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
676
+
677
+    ir->print_statistics = pvrdma_print_statistics;
653 678
 }
654 679
 
655 680
 static const TypeInfo pvrdma_info = {
@@ -659,6 +684,7 @@ static const TypeInfo pvrdma_info = {
659 684
     .class_init = pvrdma_class_init,
660 685
     .interfaces = (InterfaceInfo[]) {
661 686
         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
687
+        { INTERFACE_RDMA_PROVIDER },
662 688
         { }
663 689
     }
664 690
 };

+ 40
- 0
include/hw/rdma/rdma.h View File

@@ -0,0 +1,40 @@
1
+/*
2
+ * RDMA device interface
3
+ *
4
+ * Copyright (C) 2019 Oracle
5
+ * Copyright (C) 2019 Red Hat Inc
6
+ *
7
+ * Authors:
8
+ *     Yuval Shaia <yuval.shaia@oracle.com>
9
+ *
10
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
11
+ * See the COPYING file in the top-level directory.
12
+ *
13
+ */
14
+
15
+#ifndef RDMA_H
16
+#define RDMA_H
17
+
18
+#include "qom/object.h"
19
+
20
+#define INTERFACE_RDMA_PROVIDER "rdma"
21
+
22
+#define INTERFACE_RDMA_PROVIDER_CLASS(klass) \
23
+    OBJECT_CLASS_CHECK(RdmaProviderClass, (klass), \
24
+                       INTERFACE_RDMA_PROVIDER)
25
+#define RDMA_PROVIDER_GET_CLASS(obj) \
26
+    OBJECT_GET_CLASS(RdmaProviderClass, (obj), \
27
+                     INTERFACE_RDMA_PROVIDER)
28
+#define RDMA_PROVIDER(obj) \
29
+    INTERFACE_CHECK(RdmaProvider, (obj), \
30
+                    INTERFACE_RDMA_PROVIDER)
31
+
32
+typedef struct RdmaProvider RdmaProvider;
33
+
34
+typedef struct RdmaProviderClass {
35
+    InterfaceClass parent;
36
+
37
+    void (*print_statistics)(Monitor *mon, RdmaProvider *obj);
38
+} RdmaProviderClass;
39
+
40
+#endif

Loading…
Cancel
Save