Skip to content

Commit

Permalink
{hmp, hw/pvrdma}: Expose device internals via monitor interface
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Dr. David Alan Gilbert <[email protected]>
Acked-by: Markus Armbruster <[email protected]>
Message-Id: <[email protected]>
Reviewed-by: Marcel Apfelbaum <[email protected]>
Signed-off-by: Marcel Apfelbaum <[email protected]>
  • Loading branch information
Yuval Shaia authored and marcel-apf committed Mar 16, 2019
1 parent c2dd117 commit f4b2c02
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 1 deletion.
14 changes: 14 additions & 0 deletions hmp-commands-info.hx
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,20 @@ STEXI
@item info pic
@findex info pic
Show PIC state.
ETEXI

{
.name = "rdma",
.args_type = "",
.params = "",
.help = "show RDMA state",
.cmd = hmp_info_rdma,
},

STEXI
@item info rdma
@findex info rdma
Show RDMA state.
ETEXI

{
Expand Down
27 changes: 27 additions & 0 deletions hmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include "qemu/error-report.h"
#include "exec/ramlist.h"
#include "hw/intc/intc.h"
#include "hw/rdma/rdma.h"
#include "migration/snapshot.h"
#include "migration/misc.h"

Expand Down Expand Up @@ -1013,6 +1014,32 @@ void hmp_info_pic(Monitor *mon, const QDict *qdict)
hmp_info_pic_foreach, mon);
}

static int hmp_info_rdma_foreach(Object *obj, void *opaque)
{
RdmaProvider *rdma;
RdmaProviderClass *k;
Monitor *mon = opaque;

if (object_dynamic_cast(obj, INTERFACE_RDMA_PROVIDER)) {
rdma = RDMA_PROVIDER(obj);
k = RDMA_PROVIDER_GET_CLASS(obj);
if (k->print_statistics) {
k->print_statistics(mon, rdma);
} else {
monitor_printf(mon, "RDMA statistics not available for %s.\n",
object_get_typename(obj));
}
}

return 0;
}

void hmp_info_rdma(Monitor *mon, const QDict *qdict)
{
object_child_foreach_recursive(object_get_root(),
hmp_info_rdma_foreach, mon);
}

void hmp_info_pci(Monitor *mon, const QDict *qdict)
{
PciInfoList *info_list, *info;
Expand Down
1 change: 1 addition & 0 deletions hmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict);
void hmp_info_balloon(Monitor *mon, const QDict *qdict);
void hmp_info_irq(Monitor *mon, const QDict *qdict);
void hmp_info_pic(Monitor *mon, const QDict *qdict);
void hmp_info_rdma(Monitor *mon, const QDict *qdict);
void hmp_info_pci(Monitor *mon, const QDict *qdict);
void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
void hmp_info_tpm(Monitor *mon, const QDict *qdict);
Expand Down
2 changes: 1 addition & 1 deletion hw/rdma/Makefile.objs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ifeq ($(CONFIG_PVRDMA),y)
obj-$(CONFIG_PCI) += rdma_utils.o rdma_backend.o rdma_rm.o
obj-$(CONFIG_PCI) += rdma_utils.o rdma_backend.o rdma_rm.o rdma.o
obj-$(CONFIG_PCI) += vmw/pvrdma_dev_ring.o vmw/pvrdma_cmd.o \
vmw/pvrdma_qp_ops.o vmw/pvrdma_main.o
endif
30 changes: 30 additions & 0 deletions hw/rdma/rdma.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* RDMA device interface
*
* Copyright (C) 2018 Oracle
* Copyright (C) 2018 Red Hat Inc
*
* Authors:
* Yuval Shaia <[email protected]>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/

#include "qemu/osdep.h"
#include "hw/rdma/rdma.h"
#include "qemu/module.h"

static const TypeInfo rdma_hmp_info = {
.name = INTERFACE_RDMA_PROVIDER,
.parent = TYPE_INTERFACE,
.class_size = sizeof(RdmaProviderClass),
};

static void rdma_register_types(void)
{
type_register_static(&rdma_hmp_info);
}

type_init(rdma_register_types)
53 changes: 53 additions & 0 deletions hw/rdma/rdma_rm.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "cpu.h"
#include "monitor/monitor.h"

#include "trace.h"
#include "rdma_utils.h"
Expand All @@ -26,6 +27,58 @@
#define PG_DIR_SZ { TARGET_PAGE_SIZE / sizeof(__u64) }
#define PG_TBL_SZ { TARGET_PAGE_SIZE / sizeof(__u64) }

void rdma_dump_device_counters(Monitor *mon, RdmaDeviceResources *dev_res)
{
monitor_printf(mon, "\ttx : %" PRId64 "\n",
dev_res->stats.tx);
monitor_printf(mon, "\ttx_len : %" PRId64 "\n",
dev_res->stats.tx_len);
monitor_printf(mon, "\ttx_err : %" PRId64 "\n",
dev_res->stats.tx_err);
monitor_printf(mon, "\trx_bufs : %" PRId64 "\n",
dev_res->stats.rx_bufs);
monitor_printf(mon, "\trx_bufs_len : %" PRId64 "\n",
dev_res->stats.rx_bufs_len);
monitor_printf(mon, "\trx_bufs_err : %" PRId64 "\n",
dev_res->stats.rx_bufs_err);
monitor_printf(mon, "\tcomps : %" PRId64 "\n",
dev_res->stats.completions);
monitor_printf(mon, "\tmissing_comps : %" PRId32 "\n",
dev_res->stats.missing_cqe);
monitor_printf(mon, "\tpoll_cq (bk) : %" PRId64 "\n",
dev_res->stats.poll_cq_from_bk);
monitor_printf(mon, "\tpoll_cq_ppoll_to : %" PRId64 "\n",
dev_res->stats.poll_cq_ppoll_to);
monitor_printf(mon, "\tpoll_cq (fe) : %" PRId64 "\n",
dev_res->stats.poll_cq_from_guest);
monitor_printf(mon, "\tpoll_cq_empty : %" PRId64 "\n",
dev_res->stats.poll_cq_from_guest_empty);
monitor_printf(mon, "\tmad_tx : %" PRId64 "\n",
dev_res->stats.mad_tx);
monitor_printf(mon, "\tmad_tx_err : %" PRId64 "\n",
dev_res->stats.mad_tx_err);
monitor_printf(mon, "\tmad_rx : %" PRId64 "\n",
dev_res->stats.mad_rx);
monitor_printf(mon, "\tmad_rx_err : %" PRId64 "\n",
dev_res->stats.mad_rx_err);
monitor_printf(mon, "\tmad_rx_bufs : %" PRId64 "\n",
dev_res->stats.mad_rx_bufs);
monitor_printf(mon, "\tmad_rx_bufs_err : %" PRId64 "\n",
dev_res->stats.mad_rx_bufs_err);
monitor_printf(mon, "\tPDs : %" PRId32 "\n",
dev_res->pd_tbl.used);
monitor_printf(mon, "\tMRs : %" PRId32 "\n",
dev_res->mr_tbl.used);
monitor_printf(mon, "\tUCs : %" PRId32 "\n",
dev_res->uc_tbl.used);
monitor_printf(mon, "\tQPs : %" PRId32 "\n",
dev_res->qp_tbl.used);
monitor_printf(mon, "\tCQs : %" PRId32 "\n",
dev_res->cq_tbl.used);
monitor_printf(mon, "\tCEQ_CTXs : %" PRId32 "\n",
dev_res->cqe_ctx_tbl.used);
}

static inline void res_tbl_init(const char *name, RdmaRmResTbl *tbl,
uint32_t tbl_sz, uint32_t res_sz)
{
Expand Down
1 change: 1 addition & 0 deletions hw/rdma/rdma_rm.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,6 @@ static inline union ibv_gid *rdma_rm_get_gid(RdmaDeviceResources *dev_res,
{
return &dev_res->port.gid_tbl[sgid_idx].gid;
}
void rdma_dump_device_counters(Monitor *mon, RdmaDeviceResources *dev_res);

#endif
26 changes: 26 additions & 0 deletions hw/rdma/vmw/pvrdma_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "cpu.h"
#include "trace.h"
#include "sysemu/sysemu.h"
#include "monitor/monitor.h"
#include "hw/rdma/rdma.h"

#include "../rdma_rm.h"
#include "../rdma_backend.h"
Expand Down Expand Up @@ -55,6 +57,26 @@ static Property pvrdma_dev_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};

static void pvrdma_print_statistics(Monitor *mon, RdmaProvider *obj)
{
PVRDMADev *dev = PVRDMA_DEV(obj);
PCIDevice *pdev = PCI_DEVICE(dev);

monitor_printf(mon, "%s, %x.%x\n", pdev->name, PCI_SLOT(pdev->devfn),
PCI_FUNC(pdev->devfn));
monitor_printf(mon, "\tcommands : %" PRId64 "\n",
dev->stats.commands);
monitor_printf(mon, "\tregs_reads : %" PRId64 "\n",
dev->stats.regs_reads);
monitor_printf(mon, "\tregs_writes : %" PRId64 "\n",
dev->stats.regs_writes);
monitor_printf(mon, "\tuar_writes : %" PRId64 "\n",
dev->stats.uar_writes);
monitor_printf(mon, "\tinterrupts : %" PRId64 "\n",
dev->stats.interrupts);
rdma_dump_device_counters(mon, &dev->rdma_dev_res);
}

static void free_dev_ring(PCIDevice *pci_dev, PvrdmaRing *ring,
void *ring_state)
{
Expand Down Expand Up @@ -639,6 +661,7 @@ static void pvrdma_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
RdmaProviderClass *ir = INTERFACE_RDMA_PROVIDER_CLASS(klass);

k->realize = pvrdma_realize;
k->exit = pvrdma_exit;
Expand All @@ -650,6 +673,8 @@ static void pvrdma_class_init(ObjectClass *klass, void *data)
dc->desc = "RDMA Device";
dc->props = pvrdma_dev_properties;
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);

ir->print_statistics = pvrdma_print_statistics;
}

static const TypeInfo pvrdma_info = {
Expand All @@ -659,6 +684,7 @@ static const TypeInfo pvrdma_info = {
.class_init = pvrdma_class_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ INTERFACE_RDMA_PROVIDER },
{ }
}
};
Expand Down
40 changes: 40 additions & 0 deletions include/hw/rdma/rdma.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* RDMA device interface
*
* Copyright (C) 2019 Oracle
* Copyright (C) 2019 Red Hat Inc
*
* Authors:
* Yuval Shaia <[email protected]>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/

#ifndef RDMA_H
#define RDMA_H

#include "qom/object.h"

#define INTERFACE_RDMA_PROVIDER "rdma"

#define INTERFACE_RDMA_PROVIDER_CLASS(klass) \
OBJECT_CLASS_CHECK(RdmaProviderClass, (klass), \
INTERFACE_RDMA_PROVIDER)
#define RDMA_PROVIDER_GET_CLASS(obj) \
OBJECT_GET_CLASS(RdmaProviderClass, (obj), \
INTERFACE_RDMA_PROVIDER)
#define RDMA_PROVIDER(obj) \
INTERFACE_CHECK(RdmaProvider, (obj), \
INTERFACE_RDMA_PROVIDER)

typedef struct RdmaProvider RdmaProvider;

typedef struct RdmaProviderClass {
InterfaceClass parent;

void (*print_statistics)(Monitor *mon, RdmaProvider *obj);
} RdmaProviderClass;

#endif

0 comments on commit f4b2c02

Please sign in to comment.