hw/s390x/s390-pci-bus.c | 3 +- hw/s390x/s390-pci-bus.h | 25 ++++++++++ hw/s390x/s390-pci-inst.c | 105 +++++++++++++++++++++++++++++++++++++-- hw/s390x/s390-pci-inst.h | 1 + 4 files changed, 130 insertions(+), 4 deletions(-)
Common function measurement block is used to report counters of
successfully issued pcilg/stg/stb and rpcit instructions. This patch
introduces a new struct ZpciFmb and schedules a timer callback to
copy fmb to the guest memory at a interval time which is set to
4s by default. While attemping to update fmb failed, an event error
would be generated. After pcilg/stg/stb and rpcit interception
handlers issue successfully, increase the related counter. The guest
could pass null address to switch off FMB and stop corresponding
timer.
Signed-off-by: Yi Min Zhao <zyimin@linux.ibm.com>
Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
---
Change Log:
v2:
1. Use QEMU_BUILD_BUG_MSG for ZpciFmb struct instead of QEMU_PACKED.
---
hw/s390x/s390-pci-bus.c | 3 +-
hw/s390x/s390-pci-bus.h | 25 ++++++++++
hw/s390x/s390-pci-inst.c | 105 +++++++++++++++++++++++++++++++++++++--
hw/s390x/s390-pci-inst.h | 1 +
4 files changed, 130 insertions(+), 4 deletions(-)
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index e42e1b80d6..6cd23175cd 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -976,6 +976,7 @@ static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
bus = pci_get_bus(pci_dev);
devfn = pci_dev->devfn;
object_unparent(OBJECT(pci_dev));
+ fmb_timer_free(pbdev);
s390_pci_msix_free(pbdev);
s390_pci_iommu_free(s, bus, devfn);
pbdev->pdev = NULL;
@@ -1147,7 +1148,7 @@ static void s390_pci_device_reset(DeviceState *dev)
pci_dereg_ioat(pbdev->iommu);
}
- pbdev->fmb_addr = 0;
+ fmb_timer_free(pbdev);
}
static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index 1f7f9b5814..bfbbaca26c 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -286,6 +286,29 @@ typedef struct S390PCIIOMMUTable {
S390PCIIOMMU *iommu[PCI_SLOT_MAX];
} S390PCIIOMMUTable;
+/* Function Measurement Block */
+#define DEFAULT_MUI 4000
+#define UPDATE_U_BIT 0x1ULL
+#define FMBK_MASK 0xfULL
+
+typedef struct ZpciFmbFmt0 {
+ uint64_t dma_rbytes;
+ uint64_t dma_wbytes;
+} ZpciFmbFmt0;
+
+typedef struct ZpciFmb {
+ uint8_t format;
+ uint8_t fmt_ind[3];
+ uint32_t sample;
+ uint64_t last_update;
+ uint64_t ld_ops;
+ uint64_t st_ops;
+ uint64_t stb_ops;
+ uint64_t rpcit_ops;
+ ZpciFmbFmt0 fmt0;
+} ZpciFmb;
+QEMU_BUILD_BUG_MSG(offsetof(ZpciFmb, fmt0) != 48, "padding in ZpciFmb");
+
struct S390PCIBusDevice {
DeviceState qdev;
PCIDevice *pdev;
@@ -297,6 +320,8 @@ struct S390PCIBusDevice {
uint32_t fid;
bool fid_defined;
uint64_t fmb_addr;
+ ZpciFmb fmb;
+ QEMUTimer *fmb_timer;
uint8_t isc;
uint16_t noi;
uint16_t maxstbl;
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 7b61367ee3..1ed5cb91d0 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -19,6 +19,7 @@
#include "exec/memory-internal.h"
#include "qemu/error-report.h"
#include "sysemu/hw_accel.h"
+#include "hw/s390x/tod.h"
#ifndef DEBUG_S390PCI_INST
#define DEBUG_S390PCI_INST 0
@@ -293,7 +294,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
resgrp->fr = 1;
stq_p(&resgrp->dasm, 0);
stq_p(&resgrp->msia, ZPCI_MSI_ADDR);
- stw_p(&resgrp->mui, 0);
+ stw_p(&resgrp->mui, DEFAULT_MUI);
stw_p(&resgrp->i, 128);
stw_p(&resgrp->maxstbl, 128);
resgrp->version = 0;
@@ -456,6 +457,10 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
return 0;
}
+ if (pbdev->fmb_addr) {
+ pbdev->fmb.ld_ops++;
+ }
+
env->regs[r1] = data;
setcc(cpu, ZPCI_PCI_LS_OK);
return 0;
@@ -561,6 +566,10 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
return 0;
}
+ if (pbdev->fmb_addr) {
+ pbdev->fmb.st_ops++;
+ }
+
setcc(cpu, ZPCI_PCI_LS_OK);
return 0;
}
@@ -681,6 +690,9 @@ err:
s390_set_status_code(env, r1, ZPCI_PCI_ST_FUNC_IN_ERR);
s390_pci_generate_error_event(error, pbdev->fh, pbdev->fid, start, 0);
} else {
+ if (pbdev->fmb_addr) {
+ pbdev->fmb.rpcit_ops++;
+ }
setcc(cpu, ZPCI_PCI_LS_OK);
}
return 0;
@@ -783,6 +795,10 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
}
}
+ if (pbdev->fmb_addr) {
+ pbdev->fmb.stb_ops++;
+ }
+
setcc(cpu, ZPCI_PCI_LS_OK);
return 0;
@@ -889,6 +905,63 @@ void pci_dereg_ioat(S390PCIIOMMU *iommu)
iommu->g_iota = 0;
}
+void fmb_timer_free(S390PCIBusDevice *pbdev)
+{
+ if (pbdev->fmb_timer) {
+ timer_del(pbdev->fmb_timer);
+ timer_free(pbdev->fmb_timer);
+ pbdev->fmb_timer = NULL;
+ }
+ pbdev->fmb_addr = 0;
+ memset(&pbdev->fmb, 0, sizeof(ZpciFmb));
+}
+
+static int fmb_do_update(S390PCIBusDevice *pbdev, uint8_t offset, int len)
+{
+ MemTxResult ret;
+
+ ret = address_space_write(&address_space_memory,
+ pbdev->fmb_addr + (uint64_t)offset,
+ MEMTXATTRS_UNSPECIFIED,
+ (uint8_t *)&pbdev->fmb + offset,
+ len);
+ if (ret) {
+ s390_pci_generate_error_event(ERR_EVENT_FMBA, pbdev->fh, pbdev->fid,
+ pbdev->fmb_addr, 0);
+ fmb_timer_free(pbdev);
+ }
+
+ return ret;
+}
+
+static void fmb_update(void *opaque)
+{
+ S390PCIBusDevice *pbdev = opaque;
+ int64_t t = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
+ uint8_t offset = offsetof(ZpciFmb, last_update);
+
+ /* Update U bit */
+ pbdev->fmb.last_update |= UPDATE_U_BIT;
+ if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) {
+ return;
+ }
+
+ /* Update FMB counters */
+ pbdev->fmb.sample++;
+ if (fmb_do_update(pbdev, 0, sizeof(ZpciFmb))) {
+ return;
+ }
+
+ /* Clear U bit and update the time */
+ pbdev->fmb.last_update = time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+ pbdev->fmb.last_update &= ~UPDATE_U_BIT;
+ if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) {
+ return;
+ }
+
+ timer_mod(pbdev->fmb_timer, t + DEFAULT_MUI);
+}
+
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
uintptr_t ra)
{
@@ -1018,9 +1091,35 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
}
break;
- case ZPCI_MOD_FC_SET_MEASURE:
- pbdev->fmb_addr = ldq_p(&fib.fmb_addr);
+ case ZPCI_MOD_FC_SET_MEASURE: {
+ uint64_t fmb_addr = ldq_p(&fib.fmb_addr);
+
+ if (fmb_addr & FMBK_MASK) {
+ cc = ZPCI_PCI_LS_ERR;
+ s390_pci_generate_error_event(ERR_EVENT_FMBPRO, pbdev->fh,
+ pbdev->fid, fmb_addr, 0);
+ fmb_timer_free(pbdev);
+ break;
+ }
+
+ if (!fmb_addr) {
+ /* Stop updating FMB. */
+ fmb_timer_free(pbdev);
+ break;
+ }
+
+ pbdev->fmb_addr = fmb_addr;
+ if (!pbdev->fmb_timer) {
+ pbdev->fmb_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
+ fmb_update, pbdev);
+ } else if (timer_pending(pbdev->fmb_timer)) {
+ /* Remove pending timer to update FMB address. */
+ timer_del(pbdev->fmb_timer);
+ }
+ timer_mod(pbdev->fmb_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + DEFAULT_MUI);
break;
+ }
default:
s390_program_interrupt(&cpu->env, PGM_OPERAND, 6, ra);
cc = ZPCI_PCI_LS_ERR;
diff --git a/hw/s390x/s390-pci-inst.h b/hw/s390x/s390-pci-inst.h
index 91c3d61f2a..fa3bf8b5aa 100644
--- a/hw/s390x/s390-pci-inst.h
+++ b/hw/s390x/s390-pci-inst.h
@@ -303,6 +303,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
uintptr_t ra);
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
uintptr_t ra);
+void fmb_timer_free(S390PCIBusDevice *pbdev);
#define ZPCI_IO_BAR_MIN 0
#define ZPCI_IO_BAR_MAX 5
--
Yi Min
On 2018-10-22 10:02, Yi Min Zhao wrote:
> Common function measurement block is used to report counters of
> successfully issued pcilg/stg/stb and rpcit instructions. This patch
> introduces a new struct ZpciFmb and schedules a timer callback to
> copy fmb to the guest memory at a interval time which is set to
> 4s by default. While attemping to update fmb failed, an event error
> would be generated. After pcilg/stg/stb and rpcit interception
> handlers issue successfully, increase the related counter. The guest
> could pass null address to switch off FMB and stop corresponding
> timer.
>
> Signed-off-by: Yi Min Zhao <zyimin@linux.ibm.com>
> Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
> ---
[...]
> +static int fmb_do_update(S390PCIBusDevice *pbdev, uint8_t offset, int len)
> +{
> + MemTxResult ret;
> +
> + ret = address_space_write(&address_space_memory,
> + pbdev->fmb_addr + (uint64_t)offset,
> + MEMTXATTRS_UNSPECIFIED,
> + (uint8_t *)&pbdev->fmb + offset,
> + len);
> + if (ret) {
> + s390_pci_generate_error_event(ERR_EVENT_FMBA, pbdev->fh, pbdev->fid,
> + pbdev->fmb_addr, 0);
> + fmb_timer_free(pbdev);
> + }
> +
> + return ret;
> +}
> +
> +static void fmb_update(void *opaque)
> +{
> + S390PCIBusDevice *pbdev = opaque;
> + int64_t t = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
> + uint8_t offset = offsetof(ZpciFmb, last_update);
> +
> + /* Update U bit */
> + pbdev->fmb.last_update |= UPDATE_U_BIT;
> + if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) {
> + return;
> + }
> +
> + /* Update FMB counters */
> + pbdev->fmb.sample++;
> + if (fmb_do_update(pbdev, 0, sizeof(ZpciFmb))) {
> + return;
> + }
> +
> + /* Clear U bit and update the time */
> + pbdev->fmb.last_update = time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
> + pbdev->fmb.last_update &= ~UPDATE_U_BIT;
> + if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) {
> + return;
> + }
> +
> + timer_mod(pbdev->fmb_timer, t + DEFAULT_MUI);
> +}
Sorry for noticing this in v1 already, but is this code endianess-safe?
I.e. can this also work with qemu-system-s390x running with TCG on a x86
host? I think you might have to use something like this here instead:
pbdev->fmb.sample = cpu_to_be32(be32_to_cpu(pbdev->fmb.sample) + 1);
etc.
Thomas
在 2018/10/22 下午8:17, Thomas Huth 写道:
> On 2018-10-22 10:02, Yi Min Zhao wrote:
>> Common function measurement block is used to report counters of
>> successfully issued pcilg/stg/stb and rpcit instructions. This patch
>> introduces a new struct ZpciFmb and schedules a timer callback to
>> copy fmb to the guest memory at a interval time which is set to
>> 4s by default. While attemping to update fmb failed, an event error
>> would be generated. After pcilg/stg/stb and rpcit interception
>> handlers issue successfully, increase the related counter. The guest
>> could pass null address to switch off FMB and stop corresponding
>> timer.
>>
>> Signed-off-by: Yi Min Zhao <zyimin@linux.ibm.com>
>> Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
>> ---
> [...]
>> +static int fmb_do_update(S390PCIBusDevice *pbdev, uint8_t offset, int len)
>> +{
>> + MemTxResult ret;
>> +
>> + ret = address_space_write(&address_space_memory,
>> + pbdev->fmb_addr + (uint64_t)offset,
>> + MEMTXATTRS_UNSPECIFIED,
>> + (uint8_t *)&pbdev->fmb + offset,
>> + len);
>> + if (ret) {
>> + s390_pci_generate_error_event(ERR_EVENT_FMBA, pbdev->fh, pbdev->fid,
>> + pbdev->fmb_addr, 0);
>> + fmb_timer_free(pbdev);
>> + }
>> +
>> + return ret;
>> +}
>> +
>> +static void fmb_update(void *opaque)
>> +{
>> + S390PCIBusDevice *pbdev = opaque;
>> + int64_t t = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
>> + uint8_t offset = offsetof(ZpciFmb, last_update);
>> +
>> + /* Update U bit */
>> + pbdev->fmb.last_update |= UPDATE_U_BIT;
>> + if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) {
>> + return;
>> + }
>> +
>> + /* Update FMB counters */
>> + pbdev->fmb.sample++;
>> + if (fmb_do_update(pbdev, 0, sizeof(ZpciFmb))) {
>> + return;
>> + }
>> +
>> + /* Clear U bit and update the time */
>> + pbdev->fmb.last_update = time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
>> + pbdev->fmb.last_update &= ~UPDATE_U_BIT;
>> + if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) {
>> + return;
>> + }
>> +
>> + timer_mod(pbdev->fmb_timer, t + DEFAULT_MUI);
>> +}
> Sorry for noticing this in v1 already, but is this code endianess-safe?
> I.e. can this also work with qemu-system-s390x running with TCG on a x86
> host? I think you might have to use something like this here instead:
>
> pbdev->fmb.sample = cpu_to_be32(be32_to_cpu(pbdev->fmb.sample) + 1);
>
> etc.
>
> Thomas
>
>
Aha!!! Yes, I think you're right. Indeed, we should consider endianess.
--
Yi Min
On Mon, 22 Oct 2018 13:17:34 +0100
Thomas Huth <thuth@redhat.com> wrote:
> On 2018-10-22 10:02, Yi Min Zhao wrote:
> > Common function measurement block is used to report counters of
> > successfully issued pcilg/stg/stb and rpcit instructions. This patch
> > introduces a new struct ZpciFmb and schedules a timer callback to
> > copy fmb to the guest memory at a interval time which is set to
> > 4s by default. While attemping to update fmb failed, an event error
> > would be generated. After pcilg/stg/stb and rpcit interception
> > handlers issue successfully, increase the related counter. The guest
> > could pass null address to switch off FMB and stop corresponding
> > timer.
> >
> > Signed-off-by: Yi Min Zhao <zyimin@linux.ibm.com>
> > Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
> > ---
> [...]
> > +static int fmb_do_update(S390PCIBusDevice *pbdev, uint8_t offset, int len)
> > +{
> > + MemTxResult ret;
> > +
> > + ret = address_space_write(&address_space_memory,
> > + pbdev->fmb_addr + (uint64_t)offset,
> > + MEMTXATTRS_UNSPECIFIED,
> > + (uint8_t *)&pbdev->fmb + offset,
> > + len);
> > + if (ret) {
> > + s390_pci_generate_error_event(ERR_EVENT_FMBA, pbdev->fh, pbdev->fid,
> > + pbdev->fmb_addr, 0);
> > + fmb_timer_free(pbdev);
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +static void fmb_update(void *opaque)
> > +{
> > + S390PCIBusDevice *pbdev = opaque;
> > + int64_t t = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
> > + uint8_t offset = offsetof(ZpciFmb, last_update);
> > +
> > + /* Update U bit */
> > + pbdev->fmb.last_update |= UPDATE_U_BIT;
> > + if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) {
> > + return;
> > + }
> > +
> > + /* Update FMB counters */
> > + pbdev->fmb.sample++;
> > + if (fmb_do_update(pbdev, 0, sizeof(ZpciFmb))) {
> > + return;
> > + }
> > +
> > + /* Clear U bit and update the time */
> > + pbdev->fmb.last_update = time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
> > + pbdev->fmb.last_update &= ~UPDATE_U_BIT;
> > + if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) {
> > + return;
> > + }
> > +
> > + timer_mod(pbdev->fmb_timer, t + DEFAULT_MUI);
> > +}
>
> Sorry for noticing this in v1 already, but is this code endianess-safe?
> I.e. can this also work with qemu-system-s390x running with TCG on a x86
> host? I think you might have to use something like this here instead:
>
> pbdev->fmb.sample = cpu_to_be32(be32_to_cpu(pbdev->fmb.sample) + 1);
>
> etc.
Agreed, that may need some endianness handling.
I would test this with tcg on a LE host, but how can I verify this? Yi
Min, do you have some kind of test tooling you can share?
在 2018/10/24 上午5:25, Cornelia Huck 写道:
> On Mon, 22 Oct 2018 13:17:34 +0100
> Thomas Huth <thuth@redhat.com> wrote:
>
>> On 2018-10-22 10:02, Yi Min Zhao wrote:
>>> Common function measurement block is used to report counters of
>>> successfully issued pcilg/stg/stb and rpcit instructions. This patch
>>> introduces a new struct ZpciFmb and schedules a timer callback to
>>> copy fmb to the guest memory at a interval time which is set to
>>> 4s by default. While attemping to update fmb failed, an event error
>>> would be generated. After pcilg/stg/stb and rpcit interception
>>> handlers issue successfully, increase the related counter. The guest
>>> could pass null address to switch off FMB and stop corresponding
>>> timer.
>>>
>>> Signed-off-by: Yi Min Zhao <zyimin@linux.ibm.com>
>>> Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
>>> ---
>> [...]
>>> +static int fmb_do_update(S390PCIBusDevice *pbdev, uint8_t offset, int len)
>>> +{
>>> + MemTxResult ret;
>>> +
>>> + ret = address_space_write(&address_space_memory,
>>> + pbdev->fmb_addr + (uint64_t)offset,
>>> + MEMTXATTRS_UNSPECIFIED,
>>> + (uint8_t *)&pbdev->fmb + offset,
>>> + len);
>>> + if (ret) {
>>> + s390_pci_generate_error_event(ERR_EVENT_FMBA, pbdev->fh, pbdev->fid,
>>> + pbdev->fmb_addr, 0);
>>> + fmb_timer_free(pbdev);
>>> + }
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +static void fmb_update(void *opaque)
>>> +{
>>> + S390PCIBusDevice *pbdev = opaque;
>>> + int64_t t = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
>>> + uint8_t offset = offsetof(ZpciFmb, last_update);
>>> +
>>> + /* Update U bit */
>>> + pbdev->fmb.last_update |= UPDATE_U_BIT;
>>> + if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) {
>>> + return;
>>> + }
>>> +
>>> + /* Update FMB counters */
>>> + pbdev->fmb.sample++;
>>> + if (fmb_do_update(pbdev, 0, sizeof(ZpciFmb))) {
>>> + return;
>>> + }
>>> +
>>> + /* Clear U bit and update the time */
>>> + pbdev->fmb.last_update = time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
>>> + pbdev->fmb.last_update &= ~UPDATE_U_BIT;
>>> + if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) {
>>> + return;
>>> + }
>>> +
>>> + timer_mod(pbdev->fmb_timer, t + DEFAULT_MUI);
>>> +}
>> Sorry for noticing this in v1 already, but is this code endianess-safe?
>> I.e. can this also work with qemu-system-s390x running with TCG on a x86
>> host? I think you might have to use something like this here instead:
>>
>> pbdev->fmb.sample = cpu_to_be32(be32_to_cpu(pbdev->fmb.sample) + 1);
>>
>> etc.
> Agreed, that may need some endianness handling.
>
> I would test this with tcg on a LE host, but how can I verify this? Yi
> Min, do you have some kind of test tooling you can share?
>
>
There's no tool now. You could startup a guest. And then in the guest,
install
PCI driver and read FMB values from /sys/kernel/debug/pci/****/statistics.
If endianness has error, I think the values must looks wrong.
The right thing is that values increase from 0 and intervally.
--
Yi Min
On Wed, 24 Oct 2018 11:58:33 +0800
Yi Min Zhao <zyimin@linux.ibm.com> wrote:
> 在 2018/10/24 上午5:25, Cornelia Huck 写道:
> > On Mon, 22 Oct 2018 13:17:34 +0100
> > Thomas Huth <thuth@redhat.com> wrote:
> >
> >> On 2018-10-22 10:02, Yi Min Zhao wrote:
> >>> Common function measurement block is used to report counters of
> >>> successfully issued pcilg/stg/stb and rpcit instructions. This patch
> >>> introduces a new struct ZpciFmb and schedules a timer callback to
> >>> copy fmb to the guest memory at a interval time which is set to
> >>> 4s by default. While attemping to update fmb failed, an event error
> >>> would be generated. After pcilg/stg/stb and rpcit interception
> >>> handlers issue successfully, increase the related counter. The guest
> >>> could pass null address to switch off FMB and stop corresponding
> >>> timer.
> >>>
> >>> Signed-off-by: Yi Min Zhao <zyimin@linux.ibm.com>
> >>> Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
> >>> ---
> >> [...]
> >>> +static int fmb_do_update(S390PCIBusDevice *pbdev, uint8_t offset, int len)
> >>> +{
> >>> + MemTxResult ret;
> >>> +
> >>> + ret = address_space_write(&address_space_memory,
> >>> + pbdev->fmb_addr + (uint64_t)offset,
> >>> + MEMTXATTRS_UNSPECIFIED,
> >>> + (uint8_t *)&pbdev->fmb + offset,
> >>> + len);
> >>> + if (ret) {
> >>> + s390_pci_generate_error_event(ERR_EVENT_FMBA, pbdev->fh, pbdev->fid,
> >>> + pbdev->fmb_addr, 0);
> >>> + fmb_timer_free(pbdev);
> >>> + }
> >>> +
> >>> + return ret;
> >>> +}
> >>> +
> >>> +static void fmb_update(void *opaque)
> >>> +{
> >>> + S390PCIBusDevice *pbdev = opaque;
> >>> + int64_t t = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
> >>> + uint8_t offset = offsetof(ZpciFmb, last_update);
> >>> +
> >>> + /* Update U bit */
> >>> + pbdev->fmb.last_update |= UPDATE_U_BIT;
> >>> + if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) {
> >>> + return;
> >>> + }
> >>> +
> >>> + /* Update FMB counters */
> >>> + pbdev->fmb.sample++;
> >>> + if (fmb_do_update(pbdev, 0, sizeof(ZpciFmb))) {
> >>> + return;
> >>> + }
> >>> +
> >>> + /* Clear U bit and update the time */
> >>> + pbdev->fmb.last_update = time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
> >>> + pbdev->fmb.last_update &= ~UPDATE_U_BIT;
> >>> + if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) {
> >>> + return;
> >>> + }
> >>> +
> >>> + timer_mod(pbdev->fmb_timer, t + DEFAULT_MUI);
> >>> +}
> >> Sorry for noticing this in v1 already, but is this code endianess-safe?
> >> I.e. can this also work with qemu-system-s390x running with TCG on a x86
> >> host? I think you might have to use something like this here instead:
> >>
> >> pbdev->fmb.sample = cpu_to_be32(be32_to_cpu(pbdev->fmb.sample) + 1);
> >>
> >> etc.
> > Agreed, that may need some endianness handling.
> >
> > I would test this with tcg on a LE host, but how can I verify this? Yi
> > Min, do you have some kind of test tooling you can share?
> >
> >
> There's no tool now. You could startup a guest. And then in the guest,
> install
> PCI driver and read FMB values from /sys/kernel/debug/pci/****/statistics.
>
> If endianness has error, I think the values must looks wrong.
> The right thing is that values increase from 0 and intervally.
>
Thanks for pointing me to that file; when I run under tcg, the values
indeed look like they have an endianness issue:
Update interval: 4000 ms
Samples: 637534208
Last update TOD: f4c01d0098000000
Load operations: 10520408729537478656
Store operations: 5980780305148018688
Store block operations: 0
Refresh operations: 0
Allocated pages: 0
Mapped pages: 0
Unmapped pages: 0
(virtio-net-pci device on a just-booted guest)
On 31/10/2018 11:49, Cornelia Huck wrote: > On Wed, 24 Oct 2018 11:58:33 +0800 > Yi Min Zhao <zyimin@linux.ibm.com> wrote: > >> 在 2018/10/24 上午5:25, Cornelia Huck 写道: >>> On Mon, 22 Oct 2018 13:17:34 +0100 >>> Thomas Huth <thuth@redhat.com> wrote: >>> ...snip... >> If endianness has error, I think the values must looks wrong. >> The right thing is that values increase from 0 and intervally. >> > > Thanks for pointing me to that file; when I run under tcg, the values > indeed look like they have an endianness issue: > > Update interval: 4000 ms > Samples: 637534208 > Last update TOD: f4c01d0098000000 > Load operations: 10520408729537478656 > Store operations: 5980780305148018688 > Store block operations: 0 > Refresh operations: 0 > Allocated pages: 0 > Mapped pages: 0 > Unmapped pages: 0 > > (virtio-net-pci device on a just-booted guest) > Hy Conny, I saw we lack a response to Thomas. Otherwise have you any remark? Regards, Pierre -- Pierre Morel Linux/KVM/QEMU in Böblingen - Germany
On Fri, 30 Nov 2018 10:23:14 +0100 Pierre Morel <pmorel@linux.ibm.com> wrote: > On 31/10/2018 11:49, Cornelia Huck wrote: > > On Wed, 24 Oct 2018 11:58:33 +0800 > > Yi Min Zhao <zyimin@linux.ibm.com> wrote: > > > >> 在 2018/10/24 上午5:25, Cornelia Huck 写道: > >>> On Mon, 22 Oct 2018 13:17:34 +0100 > >>> Thomas Huth <thuth@redhat.com> wrote: > >>> > > ...snip... > > >> If endianness has error, I think the values must looks wrong. > >> The right thing is that values increase from 0 and intervally. > >> > > > > Thanks for pointing me to that file; when I run under tcg, the values > > indeed look like they have an endianness issue: > > > > Update interval: 4000 ms > > Samples: 637534208 > > Last update TOD: f4c01d0098000000 > > Load operations: 10520408729537478656 > > Store operations: 5980780305148018688 > > Store block operations: 0 > > Refresh operations: 0 > > Allocated pages: 0 > > Mapped pages: 0 > > Unmapped pages: 0 > > > > (virtio-net-pci device on a just-booted guest) > > > > Hy Conny, > > I saw we lack a response to Thomas. > Otherwise have you any remark? I don't remember anything beyond the endianess issue.
On 11/30/2018 04:27 AM, Cornelia Huck wrote: > On Fri, 30 Nov 2018 10:23:14 +0100 > Pierre Morel <pmorel@linux.ibm.com> wrote: > >> On 31/10/2018 11:49, Cornelia Huck wrote: >>> On Wed, 24 Oct 2018 11:58:33 +0800 >>> Yi Min Zhao <zyimin@linux.ibm.com> wrote: >>> >>>> 在 2018/10/24 上午5:25, Cornelia Huck 写道: >>>>> On Mon, 22 Oct 2018 13:17:34 +0100 >>>>> Thomas Huth <thuth@redhat.com> wrote: >>>>> >> >> ...snip... >> >>>> If endianness has error, I think the values must looks wrong. >>>> The right thing is that values increase from 0 and intervally. >>>> >>> >>> Thanks for pointing me to that file; when I run under tcg, the values >>> indeed look like they have an endianness issue: >>> >>> Update interval: 4000 ms >>> Samples: 637534208 >>> Last update TOD: f4c01d0098000000 >>> Load operations: 10520408729537478656 >>> Store operations: 5980780305148018688 >>> Store block operations: 0 >>> Refresh operations: 0 >>> Allocated pages: 0 >>> Mapped pages: 0 >>> Unmapped pages: 0 >>> >>> (virtio-net-pci device on a just-booted guest) >>> >> >> Hy Conny, >> >> I saw we lack a response to Thomas. >> Otherwise have you any remark? > > I don't remember anything beyond the endianess issue. > This patch looks sane to me (I've lost the parent email on my client, else I would've replied directly to that). I'm currently awaiting getting my system up-and-running to test this thoroughly. Shall we do one more round with the endianess addressed in the mean time? -- Respectfully, - Collin Walling
On Wed, 12 Dec 2018 15:25:57 -0500 Collin Walling <walling@linux.ibm.com> wrote: > On 11/30/2018 04:27 AM, Cornelia Huck wrote: > > On Fri, 30 Nov 2018 10:23:14 +0100 > > Pierre Morel <pmorel@linux.ibm.com> wrote: > > > >> On 31/10/2018 11:49, Cornelia Huck wrote: > >>> On Wed, 24 Oct 2018 11:58:33 +0800 > >>> Yi Min Zhao <zyimin@linux.ibm.com> wrote: > >>> > >>>> 在 2018/10/24 上午5:25, Cornelia Huck 写道: > >>>>> On Mon, 22 Oct 2018 13:17:34 +0100 > >>>>> Thomas Huth <thuth@redhat.com> wrote: > >>>>> > >> > >> ...snip... > >> > >>>> If endianness has error, I think the values must looks wrong. > >>>> The right thing is that values increase from 0 and intervally. > >>>> > >>> > >>> Thanks for pointing me to that file; when I run under tcg, the values > >>> indeed look like they have an endianness issue: > >>> > >>> Update interval: 4000 ms > >>> Samples: 637534208 > >>> Last update TOD: f4c01d0098000000 > >>> Load operations: 10520408729537478656 > >>> Store operations: 5980780305148018688 > >>> Store block operations: 0 > >>> Refresh operations: 0 > >>> Allocated pages: 0 > >>> Mapped pages: 0 > >>> Unmapped pages: 0 > >>> > >>> (virtio-net-pci device on a just-booted guest) > >>> > >> > >> Hy Conny, > >> > >> I saw we lack a response to Thomas. > >> Otherwise have you any remark? > > > > I don't remember anything beyond the endianess issue. > > > > This patch looks sane to me (I've lost the parent email on my > client, else I would've replied directly to that). > > I'm currently awaiting getting my system up-and-running to test > this thoroughly. Shall we do one more round with the endianess > addressed in the mean time? Sure; I'll need to rely on your testing anyway (but I'll give it a whirl with virtio-pci).
© 2016 - 2025 Red Hat, Inc.