{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>
This commit is contained in:
Yuval Shaia 2019-03-11 03:29:09 -07:00 committed by Marcel Apfelbaum
parent c2dd117b38
commit f4b2c02a29
9 changed files with 193 additions and 1 deletions

View file

@ -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
hw/rdma/rdma.c Normal file
View file

@ -0,0 +1,30 @@
/*
* RDMA device interface
*
* Copyright (C) 2018 Oracle
* Copyright (C) 2018 Red Hat Inc
*
* Authors:
* Yuval Shaia <yuval.shaia@oracle.com>
*
* 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)

View file

@ -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"
@ -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)
{

View file

@ -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

View file

@ -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"
@ -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)
{
@ -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;
@ -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 = {
@ -659,6 +684,7 @@ static const TypeInfo pvrdma_info = {
.class_init = pvrdma_class_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ INTERFACE_RDMA_PROVIDER },
{ }
}
};